From d1514178cd6a47c55fe2a43fc870d1db941f3c82 Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Thu, 24 Oct 2024 15:04:44 -0700 Subject: [PATCH 01/24] generalize base state to include theta0 and 3 (instead of 1) ghost cells (#1908) --- Docs/sphinx_doc/Inputs.rst | 17 ++++- Source/ERF.H | 2 +- Source/ERF.cpp | 8 +-- Source/ERF_IndexDefines.H | 11 +++ Source/ERF_make_new_arrays.cpp | 4 +- Source/ERF_make_new_level.cpp | 2 +- Source/IO/ERF_Plotfile.cpp | 10 ++- Source/IO/ERF_Write1DProfiles.cpp | 2 +- Source/IO/ERF_Write1DProfiles_stag.cpp | 2 +- Source/IO/ERF_WriteScalarProfiles.cpp | 2 +- Source/Initialization/ERF_Metgrid_utils.H | 1 + Source/Initialization/ERF_init1d.cpp | 67 ++++++++++++------- Source/Initialization/ERF_init_custom.cpp | 4 +- Source/Initialization/ERF_init_from_hse.cpp | 10 ++- .../ERF_init_from_input_sounding.cpp | 32 +++++---- .../Initialization/ERF_init_from_metgrid.cpp | 43 +++++++----- .../Initialization/ERF_init_from_wrfinput.cpp | 18 +++-- Source/TimeIntegration/ERF_TI_slow_rhs_fun.H | 6 +- Source/TimeIntegration/ERF_advance_dycore.cpp | 6 +- Source/Utils/ERF_PoissonSolve.cpp | 2 +- 20 files changed, 158 insertions(+), 91 deletions(-) diff --git a/Docs/sphinx_doc/Inputs.rst b/Docs/sphinx_doc/Inputs.rst index b3559ff68..3ce8902f8 100644 --- a/Docs/sphinx_doc/Inputs.rst +++ b/Docs/sphinx_doc/Inputs.rst @@ -23,11 +23,21 @@ Governing Equations | | equations (instead of | | | | | the compressible equations) | | | +--------------------------+-----------------------------+---------------+-------------+ +| **erf.use_fft** | use FFT rather than | true / false | false | +| | multigrid to solve the | | | +| | the Poisson equations | | | ++--------------------------+-----------------------------+---------------+-------------+ +| **erf.mg_v** | verbosity of the multigrid | Integer >= 0 | 0 | +| | solver if used | | | +| | the Poisson equations | | | ++--------------------------+-----------------------------+---------------+-------------+ .. note:: - To solve the anelastic equations, you must set ERF_USE_POISSON_SOLVE = TRUE if using - gmake or ERF_ENABLE_POISSON_SOLVE if using cmake. + To solve the anelastic equations, you must set USE_POISSON_SOLVE = TRUE if using + gmake or ERF_ENABLE_POISSON_SOLVE if using cmake. This will enable use of the + AMReX-based Poisson solver. To optionally use the FFT solver, you must additionally + set USE_FFT = TRUE if using gmake. Problem Geometry ================ @@ -1221,7 +1231,8 @@ integrating the hydrostatic equation from the surface. If **erf.init_type = custom** or **erf.init_type = input_sounding**, ``erf.nc_init_file`` and ``erf.nc_bdy_file`` do not need to be set. -Setting **erf.project_initial_velocity = 1** will have no effect if the code is not built with **ERF_USE_POISSON_SOLVE** defined. +Setting **erf.project_initial_velocity = 1** will have no effect if the code is not built with **ERF_USE_POISSON_SOLVE** defined +if using cmake or with **USE_POISSON_SOLVE = TRUE** if using gmake. Map Scale Factors ================= diff --git a/Source/ERF.H b/Source/ERF.H index a977fa35a..6c0532a9d 100644 --- a/Source/ERF.H +++ b/Source/ERF.H @@ -348,7 +348,7 @@ public: const std::string &mfPrefix) const; void erf_enforce_hse (int lev, - amrex::MultiFab& dens, amrex::MultiFab& pres, amrex::MultiFab& pi, + amrex::MultiFab& dens, amrex::MultiFab& pres, amrex::MultiFab& pi, amrex::MultiFab& th, std::unique_ptr& z_cc); #ifdef ERF_USE_NETCDF diff --git a/Source/ERF.cpp b/Source/ERF.cpp index 97ffabcfd..1cbfba0a5 100644 --- a/Source/ERF.cpp +++ b/Source/ERF.cpp @@ -552,7 +552,7 @@ ERF::post_timestep (int nstep, Real time, Real dt_lev0) // Copy z_phs_nd and detJ_cc at end of timestep MultiFab::Copy(*z_phys_nd[lev], *z_phys_nd_new[lev], 0, 0, 1, z_phys_nd[lev]->nGrowVect()); MultiFab::Copy( *detJ_cc[lev], *detJ_cc_new[lev], 0, 0, 1, detJ_cc[lev]->nGrowVect()); - MultiFab::Copy(base_state[lev],base_state_new[lev],0,0,3,1); + MultiFab::Copy(base_state[lev],base_state_new[lev],0,0,BaseState::num_comps,base_state[lev].nGrowVect()); make_zcc(geom[lev],*z_phys_nd[lev],*z_phys_cc[lev]); } @@ -944,7 +944,7 @@ ERF::InitData_post () // For moving terrain only if (solverChoice.terrain_type != TerrainType::Static) { - MultiFab::Copy(base_state_new[lev],base_state[lev],0,0,3,1); + MultiFab::Copy(base_state_new[lev],base_state[lev],0,0,BaseState::num_comps,base_state[lev].nGrowVect()); base_state_new[lev].FillBoundary(geom[lev].periodicity()); } @@ -1680,7 +1680,7 @@ ERF::MakeHorizontalAverages () fab_arr(i, j, k, 1) = cons_arr(i, j, k, RhoTheta_comp) / dens; if (!use_moisture) { if (is_anelastic) { - fab_arr(i,j,k,2) = hse_arr(i,j,k,1); + fab_arr(i,j,k,2) = hse_arr(i,j,k,BaseState::p0_comp); } else { fab_arr(i,j,k,2) = getPgivenRTh(cons_arr(i,j,k,RhoTheta_comp)); } @@ -1700,7 +1700,7 @@ ERF::MakeHorizontalAverages () ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) { Real dens = cons_arr(i, j, k, Rho_comp); if (is_anelastic) { - fab_arr(i,j,k,2) = hse_arr(i,j,k,1); + fab_arr(i,j,k,2) = hse_arr(i,j,k,BaseState::p0_comp); } else { Real qv = cons_arr(i, j, k, RhoQ1_comp) / dens; fab_arr(i, j, k, 2) = getPgivenRTh(cons_arr(i, j, k, RhoTheta_comp), qv); diff --git a/Source/ERF_IndexDefines.H b/Source/ERF_IndexDefines.H index 811946464..f7728d1bc 100644 --- a/Source/ERF_IndexDefines.H +++ b/Source/ERF_IndexDefines.H @@ -59,6 +59,17 @@ #define PrimQ5_comp (RhoQ5_comp-1) #define PrimQ6_comp (RhoQ6_comp-1) +// Base state variables +namespace BaseState { + enum { + r0_comp = 0, + p0_comp, + pi0_comp, + th0_comp, + num_comps + }; +} + // NOTE: we still use this indexing even if no moisture // NOTE: We assume a single boundary condition for all passive scalars // NOTE: and a single boundary condition for all components of the base state diff --git a/Source/ERF_make_new_arrays.cpp b/Source/ERF_make_new_arrays.cpp index 78a249141..2c839db59 100644 --- a/Source/ERF_make_new_arrays.cpp +++ b/Source/ERF_make_new_arrays.cpp @@ -28,11 +28,11 @@ ERF::init_stuff (int lev, const BoxArray& ba, const DistributionMapping& dm, // ******************************************************************************************** // Base state holds r_0, pres_0, pi_0 (in that order) // ******************************************************************************************** - tmp_base_state.define(ba,dm,3,1); + tmp_base_state.define(ba,dm,BaseState::num_comps,3); tmp_base_state.setVal(0.); if (solverChoice.use_terrain && solverChoice.terrain_type != TerrainType::Static) { - base_state_new[lev].define(ba,dm,3,1); + base_state_new[lev].define(ba,dm,BaseState::num_comps,3); base_state_new[lev].setVal(0.); } diff --git a/Source/ERF_make_new_level.cpp b/Source/ERF_make_new_level.cpp index 64e458e80..3ed7ad42e 100644 --- a/Source/ERF_make_new_level.cpp +++ b/Source/ERF_make_new_level.cpp @@ -232,7 +232,7 @@ ERF::MakeNewLevelFromCoarse (int lev, Real time, const BoxArray& ba, // InterpFromCoarseLevel(base_state[lev], base_state[lev].nGrowVect(), IntVect(0,0,0), // do not fill ghost cells outside the domain - base_state[lev-1], 0, 0, 3, + base_state[lev-1], 0, 0, base_state[lev].nComp(), geom[lev-1], geom[lev], refRatio(lev-1), &cell_cons_interp, domain_bcs_type, BCVars::cons_bc); diff --git a/Source/IO/ERF_Plotfile.cpp b/Source/IO/ERF_Plotfile.cpp index 75557acd4..7b6635b4d 100644 --- a/Source/IO/ERF_Plotfile.cpp +++ b/Source/IO/ERF_Plotfile.cpp @@ -349,17 +349,15 @@ ERF::WritePlotFile (int which, Vector plot_var_names) mf_comp += 1; } - MultiFab r_hse(base_state[lev], make_alias, 0, 1); // r_0 is first component - MultiFab p_hse(base_state[lev], make_alias, 1, 1); // p_0 is second component + MultiFab r_hse(base_state[lev], make_alias, BaseState::r0_comp, 1); + MultiFab p_hse(base_state[lev], make_alias, BaseState::p0_comp, 1); if (containerHasElement(plot_var_names, "pres_hse")) { - // p_0 is second component of base_state MultiFab::Copy(mf[lev],p_hse,0,mf_comp,1,0); mf_comp += 1; } if (containerHasElement(plot_var_names, "dens_hse")) { - // r_0 is first component of base_state MultiFab::Copy(mf[lev],r_hse,0,mf_comp,1,0); mf_comp += 1; } @@ -531,7 +529,7 @@ ERF::WritePlotFile (int which, Vector plot_var_names) const Array4& S_arr = vars_new[lev][Vars::cons].const_array(mfi); if (solverChoice.anelastic[lev] == 1) { ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - p_arr(i,j,k) = hse_arr(i,j,k,1); + p_arr(i,j,k) = hse_arr(i,j,k,BaseState::p0_comp); }); } else { ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { @@ -625,7 +623,7 @@ ERF::WritePlotFile (int which, Vector plot_var_names) const Array4& S_arr = vars_new[lev][Vars::cons].const_array(mfi); if (solverChoice.anelastic[lev] == 1) { ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - p_arr(i,j,k) = hse_arr(i,j,k,1); + p_arr(i,j,k) = hse_arr(i,j,k,BaseState::p0_comp); }); } else { ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { diff --git a/Source/IO/ERF_Write1DProfiles.cpp b/Source/IO/ERF_Write1DProfiles.cpp index 450515a7a..94d560404 100644 --- a/Source/IO/ERF_Write1DProfiles.cpp +++ b/Source/IO/ERF_Write1DProfiles.cpp @@ -263,7 +263,7 @@ ERF::derive_diag_profiles(Real /*time*/, int nvars = vars_new[lev][Vars::cons].nComp(); MultiFab mf_cons(vars_new[lev][Vars::cons], make_alias, 0, nvars); - MultiFab p_hse (base_state[lev], make_alias, 1, 1); // p_0 is second component + MultiFab p_hse (base_state[lev], make_alias, BaseState::p0_comp, 1); bool use_moisture = (solverChoice.moisture_type != MoistureType::None); diff --git a/Source/IO/ERF_Write1DProfiles_stag.cpp b/Source/IO/ERF_Write1DProfiles_stag.cpp index 81fa117f5..1e6d1c37f 100644 --- a/Source/IO/ERF_Write1DProfiles_stag.cpp +++ b/Source/IO/ERF_Write1DProfiles_stag.cpp @@ -345,7 +345,7 @@ ERF::derive_diag_profiles_stag (Real /*time*/, int nvars = vars_new[lev][Vars::cons].nComp(); MultiFab mf_cons(vars_new[lev][Vars::cons], make_alias, 0, nvars); - MultiFab p_hse (base_state[lev], make_alias, 1, 1); // p_0 is second component + MultiFab p_hse (base_state[lev], make_alias, BaseState::p0_comp, 1); bool use_moisture = (solverChoice.moisture_type != MoistureType::None); diff --git a/Source/IO/ERF_WriteScalarProfiles.cpp b/Source/IO/ERF_WriteScalarProfiles.cpp index b531afc85..854b0136b 100644 --- a/Source/IO/ERF_WriteScalarProfiles.cpp +++ b/Source/IO/ERF_WriteScalarProfiles.cpp @@ -39,7 +39,7 @@ ERF::sum_integrated_quantities (Real time) MultiFab pert_dens(vars_new[lev][Vars::cons].boxArray(), vars_new[lev][Vars::cons].DistributionMap(), 1,0); - MultiFab r_hse (base_state[lev], make_alias, 0, 1); // r_0 is first component + MultiFab r_hse (base_state[lev], make_alias, BaseState::r0_comp, 1); for ( MFIter mfi(pert_dens,TilingIfNotGPU()); mfi.isValid(); ++mfi) { const Box& bx = mfi.tilebox(); diff --git a/Source/Initialization/ERF_Metgrid_utils.H b/Source/Initialization/ERF_Metgrid_utils.H index b0ed1f4b2..4ebfb0a18 100644 --- a/Source/Initialization/ERF_Metgrid_utils.H +++ b/Source/Initialization/ERF_Metgrid_utils.H @@ -94,6 +94,7 @@ init_base_state_from_metgrid (const bool use_moisture, amrex::FArrayBox& r_hse_fab, amrex::FArrayBox& p_hse_fab, amrex::FArrayBox& pi_hse_fab, + amrex::FArrayBox& th_hse_fab, amrex::FArrayBox& z_phys_cc_fab, const amrex::Vector& NC_ght_fab, const amrex::Vector& NC_psfc_fab, diff --git a/Source/Initialization/ERF_init1d.cpp b/Source/Initialization/ERF_init1d.cpp index 40612b852..745d8b469 100644 --- a/Source/Initialization/ERF_init1d.cpp +++ b/Source/Initialization/ERF_init1d.cpp @@ -19,17 +19,18 @@ using namespace amrex; void ERF::initHSE (int lev) { - // This integrates up through column to update p_hse, pi_hse; + // This integrates up through column to update p_hse, pi_hse, th_hse; // r_hse is not const b/c FillBoundary is called at the end for r_hse and p_hse - MultiFab r_hse (base_state[lev], make_alias, 0, 1); // r_0 is first component - MultiFab p_hse (base_state[lev], make_alias, 1, 1); // p_0 is second component - MultiFab pi_hse(base_state[lev], make_alias, 2, 1); // pi_0 is third component + MultiFab r_hse (base_state[lev], make_alias, BaseState::r0_comp, 1); + MultiFab p_hse (base_state[lev], make_alias, BaseState::p0_comp, 1); + MultiFab pi_hse(base_state[lev], make_alias, BaseState::pi0_comp, 1); + MultiFab th_hse(base_state[lev], make_alias, BaseState::th0_comp, 1); bool all_boxes_touch_bottom = true; Box domain(geom[lev].Domain()); - int icomp = 0; int bccomp = BCVars::base_bc; int ncomp = 3; + int icomp = 0; int bccomp = BCVars::base_bc; int ncomp = BaseState::num_comps; Real time = 0.; @@ -75,7 +76,7 @@ ERF::initHSE (int lev) prob->erf_init_dens_hse(r_hse, z_phys_nd[lev], z_phys_cc[lev], geom[lev]); } - erf_enforce_hse(lev, r_hse, p_hse, pi_hse, z_phys_cc[lev]); + erf_enforce_hse(lev, r_hse, p_hse, pi_hse, th_hse, z_phys_cc[lev]); } else { @@ -85,12 +86,14 @@ ERF::initHSE (int lev) DistributionMapping dm_new(ba_new); - MultiFab new_base_state(ba_new, dm_new, 3, 1); - new_base_state.ParallelCopy(base_state[lev],0,0,3,1,1); + MultiFab new_base_state(ba_new, dm_new, BaseState::num_comps, base_state[lev].nGrowVect()); + new_base_state.ParallelCopy(base_state[lev],0,0,base_state[lev].nComp(), + base_state[lev].nGrowVect(),base_state[lev].nGrowVect()); - MultiFab new_r_hse (new_base_state, make_alias, 0, 1); // r_0 is first component - MultiFab new_p_hse (new_base_state, make_alias, 1, 1); // p_0 is second component - MultiFab new_pi_hse(new_base_state, make_alias, 2, 1); // pi_0 is third component + MultiFab new_r_hse (new_base_state, make_alias, BaseState::r0_comp, 1); + MultiFab new_p_hse (new_base_state, make_alias, BaseState::p0_comp, 1); + MultiFab new_pi_hse(new_base_state, make_alias, BaseState::pi0_comp, 1); + MultiFab new_th_hse(new_base_state, make_alias, BaseState::th0_comp, 1); std::unique_ptr new_z_phys_cc; std::unique_ptr new_z_phys_nd; @@ -111,17 +114,18 @@ ERF::initHSE (int lev) prob->erf_init_dens_hse(new_r_hse, new_z_phys_nd, new_z_phys_cc, geom[lev]); } - erf_enforce_hse(lev, new_r_hse, new_p_hse, new_pi_hse, new_z_phys_cc); + erf_enforce_hse(lev, new_r_hse, new_p_hse, new_pi_hse, new_th_hse, new_z_phys_cc); // Now copy back into the original arrays - base_state[lev].ParallelCopy(new_base_state,0,0,3,1,1); + base_state[lev].ParallelCopy(new_base_state,0,0,base_state[lev].nComp(), + base_state[lev].nGrowVect(),base_state[lev].nGrowVect()); } // // Impose physical bc's on the base state -- the values outside the fine region // but inside the domain have already been filled in the call above to InterpFromCoarseLevel // - (*physbcs_base[lev])(base_state[lev],icomp,ncomp,base_state[lev].nGrowVect(),time,bccomp); + (*physbcs_base[lev])(base_state[lev],0,base_state[lev].nComp(),base_state[lev].nGrowVect(),time,bccomp); base_state[lev].FillBoundary(geom[lev].periodicity()); } @@ -147,7 +151,7 @@ ERF::initHSE () */ void ERF::erf_enforce_hse (int lev, - MultiFab& dens, MultiFab& pres, MultiFab& pi, + MultiFab& dens, MultiFab& pres, MultiFab& pi, MultiFab& theta, std::unique_ptr& z_cc) { Real l_gravity = solverChoice.gravity; @@ -181,6 +185,7 @@ ERF::erf_enforce_hse (int lev, Array4 rho_arr = dens.array(mfi); Array4 pres_arr = pres.array(mfi); Array4 pi_arr = pi.array(mfi); + Array4 th_arr = theta.array(mfi); Array4 zcc_arr; if (l_use_terrain) { zcc_arr = z_cc->array(mfi); @@ -200,12 +205,14 @@ ERF::erf_enforce_hse (int lev, hz = 0.5*dz; } - pres_arr(i,j,klo ) = p_0 - hz * rho_arr(i,j,klo) * l_gravity; - pi_arr(i,j,klo ) = getExnergivenP(pres_arr(i,j,klo ), rdOcp); + pres_arr(i,j,klo) = p_0 - hz * rho_arr(i,j,klo) * l_gravity; + pi_arr(i,j,klo) = getExnergivenP(pres_arr(i,j,klo), rdOcp); + th_arr(i,j,klo) =getRhoThetagivenP(pres_arr(i,j,klo)) / rho_arr(i,j,klo); // Set ghost cell with dz and rho at boundary pres_arr(i,j,klo-1) = p_0 + hz * rho_arr(i,j,klo) * l_gravity; - pi_arr(i,j,klo-1) = getExnergivenP(pres_arr(i,j,klo-1), rdOcp); + pi_arr(i,j,klo-1) = getExnergivenP(pres_arr(i,j,klo-1), rdOcp); + th_arr(i,j,klo-1) = getRhoThetagivenP(pres_arr(i,j,klo-1)) / rho_arr(i,j,klo-1); } else { // If level > 0 and klo > 0, we need to use the value of pres_arr(i,j,klo-1) which was @@ -222,6 +229,10 @@ ERF::erf_enforce_hse (int lev, pi_arr(i,j,klo ) = getExnergivenP(pres_arr(i,j,klo ), rdOcp); pi_arr(i,j,klo-1) = getExnergivenP(pres_arr(i,j,klo-1), rdOcp); + + th_arr(i,j,klo ) = getRhoThetagivenP(pres_arr(i,j,klo )) / rho_arr(i,j,klo ); + th_arr(i,j,klo-1) = getRhoThetagivenP(pres_arr(i,j,klo-1)) / rho_arr(i,j,klo-1); + } Real dens_interp; @@ -231,12 +242,14 @@ ERF::erf_enforce_hse (int lev, dens_interp = 0.5*(rho_arr(i,j,k) + rho_arr(i,j,k-1)); pres_arr(i,j,k) = pres_arr(i,j,k-1) - dz_loc * dens_interp * l_gravity; pi_arr(i,j,k) = getExnergivenP(pres_arr(i,j,k), rdOcp); + th_arr(i,j,k) = getRhoThetagivenP(pres_arr(i,j,k)) / rho_arr(i,j,k); } } else { for (int k = klo+1; k <= khi; k++) { dens_interp = 0.5*(rho_arr(i,j,k) + rho_arr(i,j,k-1)); pres_arr(i,j,k) = pres_arr(i,j,k-1) - dz * dens_interp * l_gravity; pi_arr(i,j,k) = getExnergivenP(pres_arr(i,j,k), rdOcp); + th_arr(i,j,k) = getRhoThetagivenP(pres_arr(i,j,k)) / rho_arr(i,j,k); } } }); @@ -251,7 +264,8 @@ ERF::erf_enforce_hse (int lev, bx.setBig(0,domlo_x-1); ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) { pres_arr(i,j,k) = pres_arr(domlo_x,j,k); - pi_arr(i,j,k) = getExnergivenP(pres_arr(i,j,k), rdOcp); + pi_arr(i,j,k) = pi_arr(domlo_x,j,k); + th_arr(i,j,k) = th_arr(domlo_x,j,k); }); } @@ -262,7 +276,8 @@ ERF::erf_enforce_hse (int lev, bx.setBig(0,domhi_x+1); ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) { pres_arr(i,j,k) = pres_arr(domhi_x,j,k); - pi_arr(i,j,k) = getExnergivenP(pres_arr(i,j,k), rdOcp); + pi_arr(i,j,k) = pi_arr(domhi_x,j,k); + th_arr(i,j,k) = th_arr(domhi_x,j,k); }); } @@ -273,7 +288,8 @@ ERF::erf_enforce_hse (int lev, bx.setBig(1,domlo_y-1); ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) { pres_arr(i,j,k) = pres_arr(i,domlo_y,k); - pi_arr(i,j,k) = getExnergivenP(pres_arr(i,j,k), rdOcp); + pi_arr(i,j,k) = pi_arr(i,domlo_y,k); + th_arr(i,j,k) = th_arr(i,domlo_y,k); }); } @@ -284,11 +300,14 @@ ERF::erf_enforce_hse (int lev, bx.setBig(1,domhi_y+1); ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) { pres_arr(i,j,k) = pres_arr(i,domhi_y,k); - pi_arr(i,j,k) = getExnergivenP(pres_arr(i,j,k), rdOcp); + pi_arr(i,j,k) = pi_arr(i,domhi_y,k); + th_arr(i,j,k) = th_arr(i,domhi_y,k); }); } } - dens.FillBoundary(geom[lev].periodicity()); - pres.FillBoundary(geom[lev].periodicity()); + dens.FillBoundary(geom[lev].periodicity()); + pres.FillBoundary(geom[lev].periodicity()); + pi.FillBoundary(geom[lev].periodicity()); + theta.FillBoundary(geom[lev].periodicity()); } diff --git a/Source/Initialization/ERF_init_custom.cpp b/Source/Initialization/ERF_init_custom.cpp index 984c57004..4fcbc9104 100644 --- a/Source/Initialization/ERF_init_custom.cpp +++ b/Source/Initialization/ERF_init_custom.cpp @@ -27,8 +27,8 @@ ERF::init_custom (int lev) { auto& lev_new = vars_new[lev]; - MultiFab r_hse(base_state[lev], make_alias, 0, 1); // r_0 is first component - MultiFab p_hse(base_state[lev], make_alias, 1, 1); // p_0 is second component + MultiFab r_hse(base_state[lev], make_alias, BaseState::r0_comp, 1); + MultiFab p_hse(base_state[lev], make_alias, BaseState::p0_comp, 1); MultiFab cons_pert(lev_new[Vars::cons].boxArray(), lev_new[Vars::cons].DistributionMap(), lev_new[Vars::cons].nComp() , lev_new[Vars::cons].nGrow()); diff --git a/Source/Initialization/ERF_init_from_hse.cpp b/Source/Initialization/ERF_init_from_hse.cpp index 9623cb8e7..6dbc3c768 100644 --- a/Source/Initialization/ERF_init_from_hse.cpp +++ b/Source/Initialization/ERF_init_from_hse.cpp @@ -6,8 +6,6 @@ #include #include -#include "AMReX_Print.H" - using namespace amrex; /** @@ -23,8 +21,8 @@ using namespace amrex; * - save r_hse * - call ERF::enforce_hse(...), calculates p_hse from saved r_hse (redundant, * but needed because p_hse is not necessarily calculated by the Problem - * implementation) and pi_hse -- note: this pressure does not exactly match - * the p_hse from before because what is calculated by init_isentropic_hse + * implementation) and pi_hse and th_hse -- note: this pressure does not exactly + * match the p_hse from before because what is calculated by init_isentropic_hse * comes from the EOS whereas what is calculated here comes from the hydro- * static equation * @@ -35,8 +33,8 @@ ERF::init_from_hse (int lev) { auto& lev_new = vars_new[lev]; - MultiFab r_hse(base_state[lev], make_alias, 0, 1); // r_0 is first component - MultiFab p_hse(base_state[lev], make_alias, 1, 1); // p_0 is second component + MultiFab r_hse(base_state[lev], make_alias, BaseState::r0_comp, 1); + MultiFab p_hse(base_state[lev], make_alias, BaseState::p0_comp, 1); #ifdef _OPENMP #pragma omp parallel if (amrex::Gpu::notInLaunchRegion()) diff --git a/Source/Initialization/ERF_init_from_input_sounding.cpp b/Source/Initialization/ERF_init_from_input_sounding.cpp index abbf40565..ec31635e5 100644 --- a/Source/Initialization/ERF_init_from_input_sounding.cpp +++ b/Source/Initialization/ERF_init_from_input_sounding.cpp @@ -23,6 +23,7 @@ init_bx_scalars_from_input_sounding_hse (const Box &bx, Array4 const &r_hse_arr, Array4 const &p_hse_arr, Array4 const &pi_hse_arr, + Array4 const &th_hse_arr, GeometryData const &geomdata, Array4 const &z_cc_arr, const Real& l_gravity, @@ -79,7 +80,7 @@ ERF::init_from_input_sounding (int lev) // InterpFromCoarseLevel(base_state[lev], base_state[lev].nGrowVect(), IntVect(0,0,0), // do not fill ghost cells outside the domain - base_state[lev-1], 0, 0, 3, + base_state[lev-1], 0, 0, base_state[lev].nComp(), geom[lev-1], geom[lev], refRatio(lev-1), &cell_cons_interp, domain_bcs_type, BCVars::base_bc); @@ -88,16 +89,17 @@ ERF::init_from_input_sounding (int lev) // when the corners need to be filled by, for example, reflection of the fine ghost // cell outside the fine region but inide the domain. int bccomp = BCVars::base_bc; - int icomp = 0; int ncomp = 3; Real dummy_time = 0.; - (*physbcs_base[lev])(base_state[lev],icomp,ncomp,base_state[lev].nGrowVect(),dummy_time,bccomp); + Real dummy_time = 0.; + (*physbcs_base[lev])(base_state[lev],0,base_state[lev].nComp(),base_state[lev].nGrowVect(),dummy_time,bccomp); } auto& lev_new = vars_new[lev]; // update if init_sounding_ideal == true - MultiFab r_hse (base_state[lev], make_alias, 0, 1); // r_0 is first component - MultiFab p_hse (base_state[lev], make_alias, 1, 1); // p_0 is second component - MultiFab pi_hse(base_state[lev], make_alias, 2, 1); // pi_0 is third component + MultiFab r_hse (base_state[lev], make_alias, BaseState::r0_comp, 1); + MultiFab p_hse (base_state[lev], make_alias, BaseState::p0_comp, 1); + MultiFab pi_hse(base_state[lev], make_alias, BaseState::pi0_comp, 1); + MultiFab th_hse(base_state[lev], make_alias, BaseState::th0_comp, 1); const Real l_gravity = solverChoice.gravity; const Real l_rdOcp = solverChoice.rdOcp; @@ -112,9 +114,10 @@ ERF::init_from_input_sounding (int lev) const auto &xvel_arr = lev_new[Vars::xvel].array(mfi); const auto &yvel_arr = lev_new[Vars::yvel].array(mfi); const auto &zvel_arr = lev_new[Vars::zvel].array(mfi); - Array4 r_hse_arr = r_hse.array(mfi); - Array4 p_hse_arr = p_hse.array(mfi); + Array4 r_hse_arr = r_hse.array(mfi); + Array4 p_hse_arr = p_hse.array(mfi); Array4 pi_hse_arr = pi_hse.array(mfi); + Array4 th_hse_arr = th_hse.array(mfi); Array4 z_cc_arr = (solverChoice.use_terrain) ? z_phys_cc[lev]->const_array(mfi) : Array4{}; Array4 z_nd_arr = (solverChoice.use_terrain) ? z_phys_nd[lev]->const_array(mfi) : Array4{}; @@ -125,7 +128,7 @@ ERF::init_from_input_sounding (int lev) // calculated by calc_rho_p() init_bx_scalars_from_input_sounding_hse( bx, cons_arr, - r_hse_arr, p_hse_arr, pi_hse_arr, + r_hse_arr, p_hse_arr, pi_hse_arr, th_hse_arr, geom[lev].data(), z_cc_arr, l_gravity, l_rdOcp, l_moist, input_sounding_data); } @@ -211,6 +214,7 @@ init_bx_scalars_from_input_sounding (const Box &bx, * @param r_hse_arr Array4 specifying the density HSE base state data we are to initialize * @param p_hse_arr Array4 specifying the pressure HSE base state data we are to initialize * @param pi_hse_arr Array4 specifying the Exner pressure HSE base state data we are to initialize + * @param th_hse_arr Array4 specifying the base state potential temperature we are to initialize * @param geomdata GeometryData object specifying the domain geometry * @param l_gravity Real number specifying the gravitational acceleration constant * @param l_rdOcp Real number specifying the Rhydberg constant ($R_d$) divided by specific heat at constant pressure ($c_p$) @@ -222,6 +226,7 @@ init_bx_scalars_from_input_sounding_hse (const Box &bx, Array4 const &r_hse_arr, Array4 const &p_hse_arr, Array4 const &pi_hse_arr, + Array4 const &th_hse_arr, GeometryData const &geomdata, Array4 const &z_cc_arr, const Real& /*l_gravity*/, @@ -269,9 +274,10 @@ init_bx_scalars_from_input_sounding_hse (const Box &bx, // Update hse quantities with values calculated from InputSoundingData.calc_rho_p() qv_k = (l_moist) ? interpolate_1d(z_inp_sound, qv_inp_sound, z, inp_sound_size) : 0.0; - r_hse_arr (i, j, k) = rho_k * (1.0 + qv_k); - p_hse_arr (i, j, k) = getPgivenRTh(rhoTh_k, qv_k); - pi_hse_arr(i, j, k) = getExnergivenRTh(rhoTh_k, l_rdOcp); + r_hse_arr (i,j,k) = rho_k * (1.0 + qv_k); + p_hse_arr (i,j,k) = getPgivenRTh(rhoTh_k, qv_k); + pi_hse_arr(i,j,k) = getExnergivenRTh(rhoTh_k, l_rdOcp); + th_hse_arr(i,j,k) = getRhoThetagivenP(p_hse_arr(i,j,k)) / r_hse_arr(i,j,k); // FOEXTRAP hse arrays if (k==kbot) @@ -279,12 +285,14 @@ init_bx_scalars_from_input_sounding_hse (const Box &bx, r_hse_arr (i, j, k-1) = r_hse_arr (i,j,k); p_hse_arr (i, j, k-1) = p_hse_arr (i,j,k); pi_hse_arr(i, j, k-1) = pi_hse_arr(i,j,k); + th_hse_arr(i, j, k-1) = th_hse_arr(i,j,k); } else if (k==ktop) { r_hse_arr (i, j, k+1) = r_hse_arr (i,j,k); p_hse_arr (i, j, k+1) = p_hse_arr (i,j,k); pi_hse_arr(i, j, k+1) = pi_hse_arr(i,j,k); + th_hse_arr(i, j, k+1) = th_hse_arr(i,j,k); } // total nonprecipitating water (Q1) == water vapor (Qv), i.e., there diff --git a/Source/Initialization/ERF_init_from_metgrid.cpp b/Source/Initialization/ERF_init_from_metgrid.cpp index 79f26c3a5..d6e2660e6 100644 --- a/Source/Initialization/ERF_init_from_metgrid.cpp +++ b/Source/Initialization/ERF_init_from_metgrid.cpp @@ -330,12 +330,14 @@ ERF::init_from_metgrid (int lev) } // mf - MultiFab r_hse (base_state[lev], make_alias, 0, 1); // r_0 is first component - MultiFab p_hse (base_state[lev], make_alias, 1, 1); // p_0 is second component - MultiFab pi_hse(base_state[lev], make_alias, 2, 1); // pi_0 is third component + MultiFab r_hse (base_state[lev], make_alias, BaseState::r0_comp, 1); + MultiFab p_hse (base_state[lev], make_alias, BaseState::p0_comp, 1); + MultiFab pi_hse(base_state[lev], make_alias, BaseState::pi0_comp, 1); + MultiFab th_hse(base_state[lev], make_alias, BaseState::th0_comp, 1); for ( MFIter mfi(lev_new[Vars::cons], TilingIfNotGPU()); mfi.isValid(); ++mfi ) { FArrayBox& p_hse_fab = p_hse[mfi]; FArrayBox& pi_hse_fab = pi_hse[mfi]; + FArrayBox& th_hse_fab = th_hse[mfi]; FArrayBox& r_hse_fab = r_hse[mfi]; FArrayBox& cons_fab = lev_new[Vars::cons][mfi]; FArrayBox& z_phys_nd_fab = (*z_phys)[mfi]; @@ -344,11 +346,12 @@ ERF::init_from_metgrid (int lev) // p_hse calculate dry pressure // r_hse calculate dry density // pi_hse calculate Exner term given pressure + // th_hse calculate potential temperature const Box valid_bx = mfi.validbox(); init_base_state_from_metgrid(use_moisture, l_rdOcp, valid_bx, flag_psfc, - cons_fab, r_hse_fab, p_hse_fab, pi_hse_fab, + cons_fab, r_hse_fab, p_hse_fab, pi_hse_fab, th_hse_fab, z_phys_nd_fab, NC_ght_fab, NC_psfc_fab, fabs_for_bcs); } // mf @@ -357,6 +360,7 @@ ERF::init_from_metgrid (int lev) r_hse.FillBoundary(geom[lev].periodicity()); p_hse.FillBoundary(geom[lev].periodicity()); pi_hse.FillBoundary(geom[lev].periodicity()); + th_hse.FillBoundary(geom[lev].periodicity()); // NOTE: fabs_for_bcs is defined over the whole domain on each rank. // However, the operations needed to define the data on the ERF @@ -763,6 +767,7 @@ init_state_from_metgrid (const bool use_moisture, * @param r_hse_fab FArrayBox holding the hydrostatic base state density we are initializing * @param p_hse_fab FArrayBox holding the hydrostatic base state pressure we are initializing * @param pi_hse_fab FArrayBox holding the hydrostatic base Exner pressure we are initializing + * @param th_hse_fab FArrayBox holding the base state potential temperature we are initializing * @param z_phys_nd_fab FArrayBox holding nodal z coordinate data for terrain * @param NC_ght_fab Vector of FArrayBox objects holding metgrid data for height of cell centers * @param NC_psfc_fab Vector of FArrayBox objects holding metgrid data for surface pressure @@ -777,6 +782,7 @@ init_base_state_from_metgrid (const bool use_moisture, FArrayBox& r_hse_fab, FArrayBox& p_hse_fab, FArrayBox& pi_hse_fab, + FArrayBox& th_hse_fab, FArrayBox& z_phys_cc_fab, const Vector& /*NC_ght_fab*/, const Vector& NC_psfc_fab, @@ -819,6 +825,7 @@ init_base_state_from_metgrid (const bool use_moisture, const Array4& r_hse_arr = r_hse_fab.array(); const Array4& p_hse_arr = p_hse_fab.array(); const Array4& pi_hse_arr = pi_hse_fab.array(); + const Array4& th_hse_arr = th_hse_fab.array(); auto psfc_flag = flag_psfc_vec[0]; // ******************************************************** @@ -934,6 +941,7 @@ init_base_state_from_metgrid (const bool use_moisture, r_hse_arr(i,j,k) *= (1.0 + Qv); pi_hse_arr(i,j,k) = getExnergivenP(p_hse_arr(i,j,k), l_rdOcp); + th_hse_arr(i,j,k) = getRhoThetagivenP(p_hse_arr(i,j,k)) / r_hse_arr(i,j,k); }); // FOEXTRAP hse arrays @@ -942,9 +950,10 @@ init_base_state_from_metgrid (const bool use_moisture, { int jj = amrex::max(j ,valid_bx.smallEnd(1)); jj = amrex::min(jj,valid_bx.bigEnd(1)); - r_hse_arr(i,j,k) = r_hse_arr(i+1,jj,k); - p_hse_arr(i,j,k) = p_hse_arr(i+1,jj,k); + r_hse_arr(i,j,k) = r_hse_arr(i+1,jj,k); + p_hse_arr(i,j,k) = p_hse_arr(i+1,jj,k); pi_hse_arr(i,j,k) = pi_hse_arr(i+1,jj,k); + th_hse_arr(i,j,k) = th_hse_arr(i+1,jj,k); }, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { @@ -953,39 +962,43 @@ init_base_state_from_metgrid (const bool use_moisture, r_hse_arr(i,j,k) = r_hse_arr(i-1,jj,k); p_hse_arr(i,j,k) = p_hse_arr(i-1,jj,k); pi_hse_arr(i,j,k) = pi_hse_arr(i-1,jj,k); + th_hse_arr(i,j,k) = th_hse_arr(i-1,jj,k); }); ParallelFor(gvbx_ylo, gvbx_yhi, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - r_hse_arr(i,j,k) = r_hse_arr(i,j+1,k); - p_hse_arr(i,j,k) = p_hse_arr(i,j+1,k); + r_hse_arr(i,j,k) = r_hse_arr(i,j+1,k); + p_hse_arr(i,j,k) = p_hse_arr(i,j+1,k); pi_hse_arr(i,j,k) = pi_hse_arr(i,j+1,k); + th_hse_arr(i,j,k) = th_hse_arr(i,j+1,k); }, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - r_hse_arr(i,j,k) = r_hse_arr(i,j-1,k); - p_hse_arr(i,j,k) = p_hse_arr(i,j-1,k); + r_hse_arr(i,j,k) = r_hse_arr(i,j-1,k); + p_hse_arr(i,j,k) = p_hse_arr(i,j-1,k); pi_hse_arr(i,j,k) = pi_hse_arr(i,j-1,k); + th_hse_arr(i,j,k) = th_hse_arr(i,j-1,k); }); ParallelFor(gvbx_zlo, gvbx_zhi, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - r_hse_arr(i,j,k) = r_hse_arr(i,j,k+1); - p_hse_arr(i,j,k) = p_hse_arr(i,j,k+1); + r_hse_arr(i,j,k) = r_hse_arr(i,j,k+1); + p_hse_arr(i,j,k) = p_hse_arr(i,j,k+1); pi_hse_arr(i,j,k) = pi_hse_arr(i,j,k+1); + th_hse_arr(i,j,k) = th_hse_arr(i,j,k+1); }, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - r_hse_arr(i,j,k) = r_hse_arr(i,j,k-1); - p_hse_arr(i,j,k) = p_hse_arr(i,j,k-1); + r_hse_arr(i,j,k) = r_hse_arr(i,j,k-1); + p_hse_arr(i,j,k) = p_hse_arr(i,j,k-1); pi_hse_arr(i,j,k) = pi_hse_arr(i,j,k-1); + th_hse_arr(i,j,k) = th_hse_arr(i,j,k-1); }); } int ntimes = NC_psfc_fab.size(); for (int itime=0; itime& NC_ALB_fab, const Vector& NC_PB_fab, @@ -270,9 +271,10 @@ ERF::init_from_wrfinput (int lev) } // use_terrain - MultiFab r_hse (base_state[lev], make_alias, 0, 1); // r_0 is first component - MultiFab p_hse (base_state[lev], make_alias, 1, 1); // p_0 is second component - MultiFab pi_hse(base_state[lev], make_alias, 2, 1); // pi_0 is third component + MultiFab r_hse (base_state[lev], make_alias, BaseState::r0_comp, 1); + MultiFab p_hse (base_state[lev], make_alias, BaseState::p0_comp, 1); + MultiFab pi_hse(base_state[lev], make_alias, BaseState::pi0_comp, 1); + MultiFab th_hse(base_state[lev], make_alias, BaseState::th0_comp, 1); IntVect ng = p_hse.nGrowVect(); const Real l_rdOcp = solverChoice.rdOcp; @@ -283,11 +285,12 @@ ERF::init_from_wrfinput (int lev) FArrayBox& cons_fab = lev_new[Vars::cons][mfi]; FArrayBox& p_hse_fab = p_hse[mfi]; FArrayBox& pi_hse_fab = pi_hse[mfi]; + FArrayBox& th_hse_fab = th_hse[mfi]; FArrayBox& r_hse_fab = r_hse[mfi]; const Box gtbx = mfi.tilebox(IntVect(0), ng); init_base_state_from_wrfinput(lev, gtbx, domain, l_rdOcp, solverChoice.moisture_type, n_qstate, - cons_fab, p_hse_fab, pi_hse_fab, r_hse_fab, + cons_fab, p_hse_fab, pi_hse_fab, th_hse_fab, r_hse_fab, NC_ALB_fab, NC_PB_fab, NC_P_fab); } @@ -295,6 +298,7 @@ ERF::init_from_wrfinput (int lev) r_hse.FillBoundary(geom[lev].periodicity()); p_hse.FillBoundary(geom[lev].periodicity()); pi_hse.FillBoundary(geom[lev].periodicity()); + th_hse.FillBoundary(geom[lev].periodicity()); } if (init_type == InitType::Real && (lev == 0)) { @@ -446,6 +450,7 @@ init_msfs_from_wrfinput (int /*lev*/, FArrayBox& msfu_fab, * @param l_rdOcp Real constant specifying Rhydberg constant ($R_d$) divided by specific heat at constant pressure ($c_p$) * @param p_hse FArrayBox specifying the hydrostatic base state pressure we initialize * @param pi_hse FArrayBox specifying the hydrostatic base state Exner pressure we initialize + * @param th_hse FArrayBox specifying the hydrostatic base state potential temperature * @param r_hse FArrayBox specifying the hydrostatic base state density we initialize * @param NC_ALB_fab Vector of FArrayBox objects containing WRF data specifying 1/density * @param NC_PB_fab Vector of FArrayBox objects containing WRF data specifying pressure @@ -460,6 +465,7 @@ init_base_state_from_wrfinput (int /*lev*/, FArrayBox& cons_fab, FArrayBox& p_hse, FArrayBox& pi_hse, + FArrayBox& th_hse, FArrayBox& r_hse, const Vector& NC_ALB_fab, const Vector& NC_PB_fab, @@ -478,6 +484,7 @@ init_base_state_from_wrfinput (int /*lev*/, const Array4& cons_arr = cons_fab.array(); const Array4& p_hse_arr = p_hse.array(); const Array4& pi_hse_arr = pi_hse.array(); + const Array4& th_hse_arr = th_hse.array(); const Array4& r_hse_arr = r_hse.array(); //const Array4& alpha_arr = NC_ALB_fab[idx].const_array(); const Array4& nc_pb_arr = NC_PB_fab[idx].const_array(); @@ -508,9 +515,10 @@ init_base_state_from_wrfinput (int /*lev*/, Real Rhse_Sum = cons_arr(ii,jj,kk,Rho_comp); for (int q_offset(0); q_offset& mom_mf, Mult MLPoisson mlpoisson(geom_tmp, ba_tmp, dm_tmp, info); - MultiFab r_hse(base_state[lev], make_alias, 0, 1); // r_0 is first component + MultiFab r_hse(base_state[lev], make_alias, Basestate::r0_comp, 1); auto bclo = get_projection_bc(Orientation::low); auto bchi = get_projection_bc(Orientation::high); From cee2934ed83c36201dc32f051e66ad91d6377d65 Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Thu, 24 Oct 2024 16:37:39 -0700 Subject: [PATCH 02/24] fix oops from previous PR (#1909) --- Source/ERF.cpp | 2 +- Source/ERF_make_new_arrays.cpp | 6 +++--- Source/Utils/ERF_PoissonSolve.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/ERF.cpp b/Source/ERF.cpp index 1cbfba0a5..f28eaf737 100644 --- a/Source/ERF.cpp +++ b/Source/ERF.cpp @@ -943,7 +943,7 @@ ERF::InitData_post () base_state[lev].FillBoundary(geom[lev].periodicity()); // For moving terrain only - if (solverChoice.terrain_type != TerrainType::Static) { + if (solverChoice.terrain_type == TerrainType::Moving) { MultiFab::Copy(base_state_new[lev],base_state[lev],0,0,BaseState::num_comps,base_state[lev].nGrowVect()); base_state_new[lev].FillBoundary(geom[lev].periodicity()); } diff --git a/Source/ERF_make_new_arrays.cpp b/Source/ERF_make_new_arrays.cpp index 2c839db59..f03c789f1 100644 --- a/Source/ERF_make_new_arrays.cpp +++ b/Source/ERF_make_new_arrays.cpp @@ -31,7 +31,7 @@ ERF::init_stuff (int lev, const BoxArray& ba, const DistributionMapping& dm, tmp_base_state.define(ba,dm,BaseState::num_comps,3); tmp_base_state.setVal(0.); - if (solverChoice.use_terrain && solverChoice.terrain_type != TerrainType::Static) { + if (solverChoice.use_terrain && solverChoice.terrain_type == TerrainType::Moving) { base_state_new[lev].define(ba,dm,BaseState::num_comps,3); base_state_new[lev].setVal(0.); } @@ -42,7 +42,7 @@ ERF::init_stuff (int lev, const BoxArray& ba, const DistributionMapping& dm, if (solverChoice.use_terrain) { z_phys_cc[lev] = std::make_unique(ba,dm,1,1); - if (solverChoice.terrain_type != TerrainType::Static) + if (solverChoice.terrain_type == TerrainType::Moving) { detJ_cc_new[lev] = std::make_unique(ba,dm,1,1); detJ_cc_src[lev] = std::make_unique(ba,dm,1,1); @@ -65,7 +65,7 @@ ERF::init_stuff (int lev, const BoxArray& ba, const DistributionMapping& dm, int ngrow = ComputeGhostCells(solverChoice.advChoice, solverChoice.use_NumDiff) + 2; tmp_zphys_nd = std::make_unique(ba_nd,dm,1,IntVect(ngrow,ngrow,ngrow)); - if (solverChoice.terrain_type != TerrainType::Static) { + if (solverChoice.terrain_type == TerrainType::Moving) { z_phys_nd_new[lev] = std::make_unique(ba_nd,dm,1,IntVect(ngrow,ngrow,ngrow)); z_phys_nd_src[lev] = std::make_unique(ba_nd,dm,1,IntVect(ngrow,ngrow,ngrow)); } diff --git a/Source/Utils/ERF_PoissonSolve.cpp b/Source/Utils/ERF_PoissonSolve.cpp index 92529141b..6e8916ca5 100644 --- a/Source/Utils/ERF_PoissonSolve.cpp +++ b/Source/Utils/ERF_PoissonSolve.cpp @@ -72,7 +72,7 @@ void ERF::project_velocities (int lev, Real l_dt, Vector& mom_mf, Mult MLPoisson mlpoisson(geom_tmp, ba_tmp, dm_tmp, info); - MultiFab r_hse(base_state[lev], make_alias, Basestate::r0_comp, 1); + MultiFab r_hse(base_state[lev], make_alias, BaseState::r0_comp, 1); auto bclo = get_projection_bc(Orientation::low); auto bchi = get_projection_bc(Orientation::high); From 65276a809b8198ffdd4752d94c1a689c2393bb71 Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Fri, 25 Oct 2024 09:44:48 -0700 Subject: [PATCH 03/24] =?UTF-8?q?fix=20checkpointing=20to=20use=20old=20ba?= =?UTF-8?q?se=5Fstate=20size=20and=20allow=20multiple=20plotf=E2=80=A6=20(?= =?UTF-8?q?#1910)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix checkpointing to use old base_state size and allow multiple plotfile types * remove unused * allow us to write two different types of plotfiles in same run; fix restart with new base state ncomp/nghost * remove unused and fix ncomp * fix unused * comment unused * fix restart --- .../ERF_BoundaryConditions_basestate.cpp | 59 +++++++++++------ Source/BoundaryConditions/ERF_PhysBCFunct.H | 9 ++- Source/BoundaryConditions/ERF_PhysBCFunct.cpp | 8 +-- Source/ERF.H | 15 ++++- Source/ERF.cpp | 65 ++++++++++++++----- Source/ERF_make_new_level.cpp | 5 +- Source/IO/ERF_Checkpoint.cpp | 46 +++++++++++-- Source/IO/ERF_Plotfile.cpp | 38 +++++++---- Source/Initialization/ERF_init1d.cpp | 36 ++++++---- .../ERF_init_from_input_sounding.cpp | 28 ++++---- 10 files changed, 213 insertions(+), 96 deletions(-) diff --git a/Source/BoundaryConditions/ERF_BoundaryConditions_basestate.cpp b/Source/BoundaryConditions/ERF_BoundaryConditions_basestate.cpp index e7a47ad52..fbd64a53c 100644 --- a/Source/BoundaryConditions/ERF_BoundaryConditions_basestate.cpp +++ b/Source/BoundaryConditions/ERF_BoundaryConditions_basestate.cpp @@ -11,13 +11,11 @@ using namespace amrex; * @param[in] domain simulation domain */ -void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest_arr, const Box& bx, const Box& domain) +void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest_arr, const Box& bx, const Box& domain, + int ncomp, const IntVect& nghost) { BL_PROFILE_VAR("impose_lateral_base_bcs()",impose_lateral_base_bcs); - int icomp = 0; - int ncomp = 3; - const int* bxlo = bx.loVect(); const int* bxhi = bx.hiVect(); const int* dlo = domain.loVect(); @@ -63,16 +61,16 @@ void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest if (!is_periodic_in_x) { // Populate ghost cells on lo-x and hi-x domain boundaries - Box bx_xlo(bx); bx_xlo.setBig (0,dom_lo.x-1); - Box bx_xhi(bx); bx_xhi.setSmall(0,dom_hi.x+1); - if (bx_xlo.smallEnd(2) != domain.smallEnd(2)) bx_xlo.growLo(2,1); - if (bx_xlo.bigEnd(2) != domain.bigEnd(2)) bx_xlo.growHi(2,1); - if (bx_xhi.smallEnd(2) != domain.smallEnd(2)) bx_xhi.growLo(2,1); - if (bx_xhi.bigEnd(2) != domain.bigEnd(2)) bx_xhi.growHi(2,1); + Box bx_xlo(bx); bx_xlo.setBig (0,dom_lo.x-nghost[0]); + Box bx_xhi(bx); bx_xhi.setSmall(0,dom_hi.x+nghost[0]); + if (bx_xlo.smallEnd(2) != domain.smallEnd(2)) bx_xlo.growLo(2,nghost[2]); + if (bx_xlo.bigEnd(2) != domain.bigEnd(2)) bx_xlo.growHi(2,nghost[2]); + if (bx_xhi.smallEnd(2) != domain.smallEnd(2)) bx_xhi.growLo(2,nghost[2]); + if (bx_xhi.bigEnd(2) != domain.bigEnd(2)) bx_xhi.growHi(2,nghost[2]); ParallelFor( bx_xlo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) { - int dest_comp = icomp+n; + int dest_comp = n; int l_bc_type = bc_ptr[n].lo(0); int iflip = dom_lo.x - 1 - i; if (l_bc_type == ERFBCType::foextrap) { @@ -85,7 +83,7 @@ void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest }, bx_xhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) { - int dest_comp = icomp+n; + int dest_comp = n; int h_bc_type = bc_ptr[n].hi(0); int iflip = 2*dom_hi.x + 1 - i; if (h_bc_type == ERFBCType::foextrap) { @@ -102,16 +100,16 @@ void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest if (!is_periodic_in_y) { // Populate ghost cells on lo-y and hi-y domain boundaries - Box bx_ylo(bx); bx_ylo.setBig (1,dom_lo.y-1); - Box bx_yhi(bx); bx_yhi.setSmall(1,dom_hi.y+1); - if (bx_ylo.smallEnd(2) != domain.smallEnd(2)) bx_ylo.growLo(2,1); - if (bx_ylo.bigEnd(2) != domain.bigEnd(2)) bx_ylo.growHi(2,1); - if (bx_yhi.smallEnd(2) != domain.smallEnd(2)) bx_yhi.growLo(2,1); - if (bx_yhi.bigEnd(2) != domain.bigEnd(2)) bx_yhi.growHi(2,1); + Box bx_ylo(bx); bx_ylo.setBig (1,dom_lo.y-nghost[1]); + Box bx_yhi(bx); bx_yhi.setSmall(1,dom_hi.y+nghost[1]); + if (bx_ylo.smallEnd(2) != domain.smallEnd(2)) bx_ylo.growLo(2,nghost[2]); + if (bx_ylo.bigEnd(2) != domain.bigEnd(2)) bx_ylo.growHi(2,nghost[2]); + if (bx_yhi.smallEnd(2) != domain.smallEnd(2)) bx_yhi.growLo(2,nghost[2]); + if (bx_yhi.bigEnd(2) != domain.bigEnd(2)) bx_yhi.growHi(2,nghost[2]); ParallelFor( bx_ylo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) { - int dest_comp = icomp+n; + int dest_comp = n; int l_bc_type = bc_ptr[n].lo(1); int jflip = dom_lo.y - 1 - j; if (l_bc_type == ERFBCType::foextrap) { @@ -125,7 +123,7 @@ void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest }, bx_yhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) { - int dest_comp = icomp+n; + int dest_comp = n; int h_bc_type = bc_ptr[n].hi(1); int jflip = 2*dom_hi.y + 1 - j; if (h_bc_type == ERFBCType::foextrap) { @@ -141,3 +139,24 @@ void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest Gpu::streamSynchronize(); } +void ERFPhysBCFunct_base::impose_vertical_basestate_bcs (const Array4& dest_arr, const Box& bx, const Box& domain, + int ncomp, const IntVect& /*nghost*/) +{ + BL_PROFILE_VAR("impose_vertical_base_bcs()",impose_vertical_base_bcs); + + const auto& dom_lo = lbound(domain); + const auto& dom_hi = ubound(domain); + + Box bx_zlo(bx); bx_zlo.setBig(2,dom_lo.z-2); + Box bx_zhi(bx); bx_zhi.setSmall(2,dom_hi.z+2); + ParallelFor( + bx_zlo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) + { + dest_arr(i,j,k,n) = dest_arr(i,j,dom_lo.z-1,n); + }, + bx_zhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) + { + dest_arr(i,j,k,n) = dest_arr(i,j,dom_hi.z+1,n); + } + ); +} diff --git a/Source/BoundaryConditions/ERF_PhysBCFunct.H b/Source/BoundaryConditions/ERF_PhysBCFunct.H index d74a9834e..3666ea06c 100644 --- a/Source/BoundaryConditions/ERF_PhysBCFunct.H +++ b/Source/BoundaryConditions/ERF_PhysBCFunct.H @@ -279,11 +279,14 @@ public: * @param[in] nghost number of ghost cells to be filled for conserved variables * @param[in] time time at which the data should be filled */ - void operator() (amrex::MultiFab& mf, int icomp, int ncomp, - amrex::IntVect const& nghost, const amrex::Real time, int bccomp_cons); + void operator() (amrex::MultiFab& mf, int icomp, int ncomp, amrex::IntVect const& nghost); void impose_lateral_basestate_bcs (const amrex::Array4& dest_arr, - const amrex::Box& bx, const amrex::Box& domain); + const amrex::Box& bx, const amrex::Box& domain, + int ncomp, const amrex::IntVect& nghost); + void impose_vertical_basestate_bcs (const amrex::Array4& dest_arr, + const amrex::Box& bx, const amrex::Box& domain, + int ncomp, const amrex::IntVect& nghost); private: int m_lev; diff --git a/Source/BoundaryConditions/ERF_PhysBCFunct.cpp b/Source/BoundaryConditions/ERF_PhysBCFunct.cpp index 5ab47fb88..3b055a9fa 100644 --- a/Source/BoundaryConditions/ERF_PhysBCFunct.cpp +++ b/Source/BoundaryConditions/ERF_PhysBCFunct.cpp @@ -366,8 +366,7 @@ void ERFPhysBCFunct_w::operator() (MultiFab& mf, MultiFab& xvel, MultiFab& yvel, } // OpenMP } // operator() -void ERFPhysBCFunct_base::operator() (MultiFab& mf, int /*icomp*/, int /*ncomp*/, - IntVect const& nghost, const Real /*time*/, int /*bccomp*/) +void ERFPhysBCFunct_base::operator() (MultiFab& mf, int /*icomp*/, int ncomp, IntVect const& nghost) { BL_PROFILE("ERFPhysBCFunct_base::()"); @@ -403,9 +402,10 @@ void ERFPhysBCFunct_base::operator() (MultiFab& mf, int /*icomp*/, int /*ncomp*/ if (!gdomain.contains(cbx2)) { - const Array4 cons_arr = mf.array(mfi); + const Array4 base_arr = mf.array(mfi); - impose_lateral_basestate_bcs(cons_arr,cbx1,domain); + impose_lateral_basestate_bcs(base_arr,cbx1,domain,ncomp,nghost); + impose_vertical_basestate_bcs(base_arr,cbx2,domain,ncomp,nghost); } } // MFIter diff --git a/Source/ERF.H b/Source/ERF.H index 6c0532a9d..b2184c884 100644 --- a/Source/ERF.H +++ b/Source/ERF.H @@ -78,6 +78,14 @@ AMREX_ENUM(InitType, None, Input_Sounding, Ideal, Real, Metgrid, Uniform ); +/** + * Enum of possible plotfile types +*/ +AMREX_ENUM(PlotFileType, + None, Amrex, Netcdf, HDF5 +); + + /** * Enum of possible coarse/fine interpolation options */ @@ -318,7 +326,7 @@ public: void derive_upwp (amrex::Vector& h_havg); // write plotfile to disk - void WritePlotFile (int which, amrex::Vector plot_var_names); + void WritePlotFile (int which, PlotFileType plotfile_type, amrex::Vector plot_var_names); void WriteMultiLevelPlotfileWithTerrain (const std::string &plotfilename, int nlevels, @@ -964,8 +972,9 @@ private: static int pert_interval; static amrex::Real sum_per; - // Native or NetCDF - static std::string plotfile_type; + // Write in native AMReX or NetCDF format for each plotfile + static PlotFileType plotfile_type_1; + static PlotFileType plotfile_type_2; static InitType init_type; diff --git a/Source/ERF.cpp b/Source/ERF.cpp index f28eaf737..10bbaf566 100644 --- a/Source/ERF.cpp +++ b/Source/ERF.cpp @@ -41,7 +41,8 @@ Real ERF::sum_per = -1.0; int ERF::pert_interval = -1; // Native AMReX vs NetCDF -std::string ERF::plotfile_type = "amrex"; +PlotFileType ERF::plotfile_type_1 = PlotFileType::None; +PlotFileType ERF::plotfile_type_2 = PlotFileType::None; InitType ERF::init_type; @@ -369,11 +370,11 @@ ERF::Evolve () if (writeNow(cur_time, dt[0], step+1, m_plot_int_1, m_plot_per_1)) { last_plot_file_step_1 = step+1; - WritePlotFile(1,plot_var_names_1); + WritePlotFile(1,plotfile_type_1,plot_var_names_1); } if (writeNow(cur_time, dt[0], step+1, m_plot_int_2, m_plot_per_2)) { last_plot_file_step_2 = step+1; - WritePlotFile(2,plot_var_names_2); + WritePlotFile(2,plotfile_type_2,plot_var_names_2); } if (writeNow(cur_time, dt[0], step+1, m_check_int, m_check_per)) { @@ -401,10 +402,10 @@ ERF::Evolve () // Write plotfiles at final time if ( (m_plot_int_1 > 0 || m_plot_per_1 > 0.) && istep[0] > last_plot_file_step_1 ) { - WritePlotFile(1,plot_var_names_1); + WritePlotFile(1,plotfile_type_1,plot_var_names_1); } if ( (m_plot_int_2 > 0 || m_plot_per_2 > 0.) && istep[0] > last_plot_file_step_2) { - WritePlotFile(2,plot_var_names_2); + WritePlotFile(2,plotfile_type_1,plot_var_names_2); } if ( (m_check_int > 0 || m_check_per > 0.) && istep[0] > last_check_file_step) { @@ -721,8 +722,10 @@ ERF::InitData_post () restart(); // Create the physbc objects for {cons, u, v, w, base state} + // We fill the additional base state ghost cells just in case we have read the old format for (int lev(0); lev <= max_level; ++lev) { make_physbcs(lev); + (*physbcs_base[lev])(base_state[lev],0,base_state[lev].nComp(),base_state[lev].nGrowVect()); } } @@ -1082,12 +1085,12 @@ ERF::InitData_post () { if (m_plot_int_1 > 0 || m_plot_per_1 > 0.) { - WritePlotFile(1,plot_var_names_1); + WritePlotFile(1,plotfile_type_1,plot_var_names_1); last_plot_file_step_1 = istep[0]; } if (m_plot_int_2 > 0 || m_plot_per_2 > 0.) { - WritePlotFile(2,plot_var_names_2); + WritePlotFile(2,plotfile_type_2,plot_var_names_2); last_plot_file_step_2 = istep[0]; } } @@ -1475,8 +1478,42 @@ ERF::ReadParameters () // Flag to trigger initialization from input_sounding like WRF's ideal.exe pp.query("init_sounding_ideal", init_sounding_ideal); - // Output format - pp.query("plotfile_type", plotfile_type); + PlotFileType plotfile_type_temp = PlotFileType::None; + pp.query_enum_case_insensitive("plotfile_type" ,plotfile_type_temp); + pp.query_enum_case_insensitive("plotfile_type_1",plotfile_type_1); + pp.query_enum_case_insensitive("plotfile_type_2",plotfile_type_2); + // + // This option is for backward consistency -- if only plotfile_type is set, + // then it will be used for both 1 and 2 if and only if they are not set + // + // Default is native amrex if no type is specified + // + if (plotfile_type_temp == PlotFileType::None) { + if (plotfile_type_1 == PlotFileType::None) { + plotfile_type_1 = PlotFileType::Amrex; + } + if (plotfile_type_2 == PlotFileType::None) { + plotfile_type_2 = PlotFileType::Amrex; + } + } else { + if (plotfile_type_1 == PlotFileType::None) { + plotfile_type_1 = plotfile_type_temp; + } else { + amrex::Abort("You must set either plotfile_type or plotfile_type_1, not both"); + } + if (plotfile_type_2 == PlotFileType::None) { + plotfile_type_2 = plotfile_type_temp; + } else { + amrex::Abort("You must set either plotfile_type or plotfile_type_2, not both"); + } + } +#ifndef ERF_USE_NETCDF + if (plotfile_type_1 == PlotFileType::Netcdf || + plotfile_type_2 == PlotFileType::Netcdf) { + amrex::Abort("Plotfile type = Netcdf is not allowed without USE_NETCDF = TRUE"); + } +#endif + pp.query("plot_file_1", plot_file_1); pp.query("plot_file_2", plot_file_2); pp.query("plot_int_1" , m_plot_int_1); @@ -1582,7 +1619,7 @@ ERF::ParameterSanityChecks () { AMREX_ALWAYS_ASSERT(cfl > 0. || fixed_dt[0] > 0.); - // We don't allow use_real_bcs to be true if init_type is not either InitType::Rreal or InitType::Metgrid + // We don't allow use_real_bcs to be true if init_type is not either InitType::Real or InitType::Metgrid AMREX_ALWAYS_ASSERT(!use_real_bcs || ((init_type == InitType::Real) || (init_type == InitType::Metgrid)) ); AMREX_ALWAYS_ASSERT(real_width >= 0); @@ -1602,14 +1639,6 @@ ERF::ParameterSanityChecks () } } - if (plotfile_type != "amrex" && - plotfile_type != "netcdf" && plotfile_type != "NetCDF" && - plotfile_type != "hdf5" && plotfile_type != "HDF5" ) - { - Print() << "User selected plotfile_type = " << plotfile_type << std::endl; - Abort("Dont know this plotfile_type"); - } - // If fixed_mri_dt_ratio is set, it must be even if (fixed_mri_dt_ratio > 0 && (fixed_mri_dt_ratio%2 != 0) ) { diff --git a/Source/ERF_make_new_level.cpp b/Source/ERF_make_new_level.cpp index 3ed7ad42e..f248edf5b 100644 --- a/Source/ERF_make_new_level.cpp +++ b/Source/ERF_make_new_level.cpp @@ -346,9 +346,6 @@ ERF::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMapp // from previous (pre-regrid) base_state array // ******************************************************************************************** if (lev > 0) { - // Interp all three components: rho, p, pi - int icomp = 0; int bccomp = 0; int ncomp = 3; - Interpolater* mapper = &cell_cons_interp; Vector fmf = {&base_state[lev ], &base_state[lev ]}; @@ -364,7 +361,7 @@ ERF::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMapp BCVars::base_bc); // Impose bc's outside the domain - (*physbcs_base[lev])(temp_base_state,icomp,ncomp,base_state[lev].nGrowVect(),time,bccomp); + (*physbcs_base[lev])(temp_base_state,0,temp_base_state.nComp(),base_state[lev].nGrowVect()); std::swap(temp_base_state, base_state[lev]); } diff --git a/Source/IO/ERF_Checkpoint.cpp b/Source/IO/ERF_Checkpoint.cpp index 7a3452a51..92b8b6438 100644 --- a/Source/IO/ERF_Checkpoint.cpp +++ b/Source/IO/ERF_Checkpoint.cpp @@ -131,14 +131,23 @@ ERF::WriteCheckpointFile () const VisMF::Write(zvel, MultiFabFileFullPrefix(lev, checkpointname, "Level_", "ZFace")); // Note that we write the ghost cells of the base state (unlike above) - IntVect ng = base_state[lev].nGrowVect(); - MultiFab base(grids[lev],dmap[lev],base_state[lev].nComp(),ng); - MultiFab::Copy(base,base_state[lev],0,0,base.nComp(),ng); + // For backward compatibility we only write the first components and 1 ghost cell + IntVect ng; int ncomp; + bool write_old_base_state = true; + if (write_old_base_state) { + ng = IntVect{1}; + ncomp = 3; + } else { + ng = base_state[lev].nGrowVect(); + ncomp = base_state[lev].nComp(); + } + MultiFab base(grids[lev],dmap[lev],ncomp,ng); + MultiFab::Copy(base,base_state[lev],0,0,ncomp,ng); VisMF::Write(base, MultiFabFileFullPrefix(lev, checkpointname, "Level_", "BaseState")); if (solverChoice.use_terrain) { // Note that we also write the ghost cells of z_phys_nd - ng = z_phys_nd[lev]->nGrowVect(); + IntVect ng = z_phys_nd[lev]->nGrowVect(); MultiFab z_height(convert(grids[lev],IntVect(1,1,1)),dmap[lev],1,ng); MultiFab::Copy(z_height,*z_phys_nd[lev],0,0,1,ng); VisMF::Write(z_height, MultiFabFileFullPrefix(lev, checkpointname, "Level_", "Z_Phys_nd")); @@ -379,10 +388,33 @@ ERF::ReadCheckpointFile () vars_new[lev][Vars::zvel].setBndry(1.0e34); // Note that we read the ghost cells of the base state (unlike above) - IntVect ng = base_state[lev].nGrowVect(); - MultiFab base(grids[lev],dmap[lev],base_state[lev].nComp(),ng); + + // The original base state only had 3 components and 1 ghost cell -- we read this + // here to be consistent with the old style + IntVect ng; int ncomp; + bool read_old_base_state = true; + if (read_old_base_state) { + ng = IntVect{1}; + ncomp = 3; + } else { + ng = base_state[lev].nGrowVect(); + ncomp = base_state[lev].nComp(); + } + MultiFab base(grids[lev],dmap[lev],ncomp,ng); VisMF::Read(base, MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "BaseState")); - MultiFab::Copy(base_state[lev],base,0,0,base.nComp(),ng); + MultiFab::Copy(base_state[lev],base,0,0,ncomp,ng); + if (read_old_base_state) { + for (MFIter mfi(base_state[lev],TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + const Box& bx = mfi.growntilebox(1); + Array4 const& fab = base_state[lev].array(mfi); + amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + fab(i,j,k,BaseState::th0_comp) = getRhoThetagivenP(fab(i,j,k,BaseState::p0_comp)) + / fab(i,j,k,BaseState::r0_comp); + }); + } + } base_state[lev].FillBoundary(geom[lev].periodicity()); if (solverChoice.use_terrain) { diff --git a/Source/IO/ERF_Plotfile.cpp b/Source/IO/ERF_Plotfile.cpp index 7b6635b4d..00350a865 100644 --- a/Source/IO/ERF_Plotfile.cpp +++ b/Source/IO/ERF_Plotfile.cpp @@ -183,8 +183,14 @@ ERF::PlotFileVarNames (Vector plot_var_names ) // Write plotfile to disk void -ERF::WritePlotFile (int which, Vector plot_var_names) +ERF::WritePlotFile (int which, PlotFileType plotfile_type, Vector plot_var_names) { + if (plotfile_type == PlotFileType::Amrex) { + amrex::Print() << "WRITE AMREX " << std::endl; + } else if (plotfile_type == PlotFileType::Netcdf) { + amrex::Print() << "WRITE NETCDF " << std::endl; + } + const Vector varnames = PlotFileVarNames(plot_var_names); const int ncomp_mf = varnames.size(); @@ -349,15 +355,17 @@ ERF::WritePlotFile (int which, Vector plot_var_names) mf_comp += 1; } - MultiFab r_hse(base_state[lev], make_alias, BaseState::r0_comp, 1); - MultiFab p_hse(base_state[lev], make_alias, BaseState::p0_comp, 1); + MultiFab r_hse(base_state[lev], make_alias, 0, 1); // r_0 is first component + MultiFab p_hse(base_state[lev], make_alias, 1, 1); // p_0 is second component if (containerHasElement(plot_var_names, "pres_hse")) { + // p_0 is second component of base_state MultiFab::Copy(mf[lev],p_hse,0,mf_comp,1,0); mf_comp += 1; } if (containerHasElement(plot_var_names, "dens_hse")) { + // r_0 is first component of base_state MultiFab::Copy(mf[lev],r_hse,0,mf_comp,1,0); mf_comp += 1; } @@ -529,7 +537,7 @@ ERF::WritePlotFile (int which, Vector plot_var_names) const Array4& S_arr = vars_new[lev][Vars::cons].const_array(mfi); if (solverChoice.anelastic[lev] == 1) { ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - p_arr(i,j,k) = hse_arr(i,j,k,BaseState::p0_comp); + p_arr(i,j,k) = hse_arr(i,j,k,1); }); } else { ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { @@ -623,7 +631,7 @@ ERF::WritePlotFile (int which, Vector plot_var_names) const Array4& S_arr = vars_new[lev][Vars::cons].const_array(mfi); if (solverChoice.anelastic[lev] == 1) { ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - p_arr(i,j,k) = hse_arr(i,j,k,BaseState::p0_comp); + p_arr(i,j,k) = hse_arr(i,j,k,1); }); } else { ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { @@ -1336,10 +1344,11 @@ ERF::WritePlotFile (int which, Vector plot_var_names) } std::string plotfilename; - if (which == 1) + if (which == 1) { plotfilename = Concatenate(plot_file_1, istep[0], 5); - else if (which == 2) + } else if (which == 2) { plotfilename = Concatenate(plot_file_2, istep[0], 5); + } // LSM writes it's own data if (which==1 && plot_lsm) { @@ -1357,7 +1366,8 @@ ERF::WritePlotFile (int which, Vector plot_var_names) // Single level if (finest_level == 0) { - if (plotfile_type == "amrex") { + if (plotfile_type == PlotFileType::Amrex) + { Print() << "Writing native plotfile " << plotfilename << "\n"; if (solverChoice.use_terrain) { WriteMultiLevelPlotfileWithTerrain(plotfilename, finest_level+1, @@ -1377,7 +1387,7 @@ ERF::WritePlotFile (int which, Vector plot_var_names) particleData.writePlotFile(plotfilename); #endif #ifdef ERF_USE_HDF5 - } else if (plotfile_type == "hdf5" || plotfile_type == "HDF5") { + } else if (plotfile_type == PlotFileType::HDF5) { Print() << "Writing plotfile " << plotfilename+"d01.h5" << "\n"; WriteMultiLevelPlotfileHDF5(plotfilename, finest_level+1, GetVecOfConstPtrs(mf), @@ -1385,19 +1395,19 @@ ERF::WritePlotFile (int which, Vector plot_var_names) Geom(), t_new[0], istep, refRatio()); #endif #ifdef ERF_USE_NETCDF - } else if (plotfile_type == "netcdf" || plotfile_type == "NetCDF") { + } else if (plotfile_type == PlotFileType::Netcdf) { int lev = 0; int l_which = 0; writeNCPlotFile(lev, l_which, plotfilename, GetVecOfConstPtrs(mf), varnames, istep, t_new[0]); #endif } else { - Print() << "User specified plot_filetype = " << plotfile_type << std::endl; - Abort("Dont know this plot_filetype"); + // Here we assume the plotfile_type is PlotFileType::None + Print() << "Writing no plotfile since plotfile_type is none" << std::endl; } } else { // Multilevel - if (plotfile_type == "amrex") { + if (plotfile_type == PlotFileType::Amrex) { int lev0 = 0; int desired_ratio = std::max(std::max(ref_ratio[lev0][0],ref_ratio[lev0][1]),ref_ratio[lev0][2]); @@ -1490,7 +1500,7 @@ ERF::WritePlotFile (int which, Vector plot_var_names) #endif #ifdef ERF_USE_NETCDF - } else if (plotfile_type == "netcdf" || plotfile_type == "NetCDF") { + } else if (plotfile_type == PlotFileType::Netcdf) { for (int lev = 0; lev <= finest_level; ++lev) { for (int which_box = 0; which_box < num_boxes_at_level[lev]; which_box++) { writeNCPlotFile(lev, which_box, plotfilename, GetVecOfConstPtrs(mf), varnames, istep, t_new[0]); diff --git a/Source/Initialization/ERF_init1d.cpp b/Source/Initialization/ERF_init1d.cpp index 745d8b469..1853ad522 100644 --- a/Source/Initialization/ERF_init1d.cpp +++ b/Source/Initialization/ERF_init1d.cpp @@ -30,9 +30,7 @@ ERF::initHSE (int lev) bool all_boxes_touch_bottom = true; Box domain(geom[lev].Domain()); - int icomp = 0; int bccomp = BCVars::base_bc; int ncomp = BaseState::num_comps; - - Real time = 0.; + int icomp = 0; int ncomp = BaseState::num_comps; if (lev == 0) { BoxArray ba(base_state[lev].boxArray()); @@ -64,7 +62,7 @@ ERF::initHSE (int lev) // We need to do this here because the interpolation above may leave corners unfilled // when the corners need to be filled by, for example, reflection of the fine ghost // cell outside the fine region but inide the domain. - (*physbcs_base[lev])(base_state[lev],icomp,ncomp,base_state[lev].nGrowVect(),time,bccomp); + (*physbcs_base[lev])(base_state[lev],icomp,ncomp,base_state[lev].nGrowVect()); } if (all_boxes_touch_bottom || lev > 0) { @@ -125,7 +123,7 @@ ERF::initHSE (int lev) // Impose physical bc's on the base state -- the values outside the fine region // but inside the domain have already been filled in the call above to InterpFromCoarseLevel // - (*physbcs_base[lev])(base_state[lev],0,base_state[lev].nComp(),base_state[lev].nGrowVect(),time,bccomp); + (*physbcs_base[lev])(base_state[lev],0,base_state[lev].nComp(),base_state[lev].nGrowVect()); base_state[lev].FillBoundary(geom[lev].periodicity()); } @@ -193,6 +191,9 @@ ERF::erf_enforce_hse (int lev, const Real rdOcp = solverChoice.rdOcp; + IntVect ngvect = base_state[lev].nGrowVect(); + int ng_z = ngvect[2]; + ParallelFor(b2d, [=] AMREX_GPU_DEVICE (int i, int j, int) { // Set value at surface from Newton iteration for rho @@ -213,6 +214,11 @@ ERF::erf_enforce_hse (int lev, pres_arr(i,j,klo-1) = p_0 + hz * rho_arr(i,j,klo) * l_gravity; pi_arr(i,j,klo-1) = getExnergivenP(pres_arr(i,j,klo-1), rdOcp); th_arr(i,j,klo-1) = getRhoThetagivenP(pres_arr(i,j,klo-1)) / rho_arr(i,j,klo-1); + for (int kk = 2; kk <= ng_z; kk++) { + pres_arr(i,j,klo-kk) = pres_arr(i,j,klo-1); + pi_arr(i,j,klo-kk) = pi_arr(i,j,klo-1); + th_arr(i,j,klo-kk) = th_arr(i,j,klo-1); + } } else { // If level > 0 and klo > 0, we need to use the value of pres_arr(i,j,klo-1) which was @@ -228,10 +234,12 @@ ERF::erf_enforce_hse (int lev, pres_arr(i,j,klo) = pres_arr(i,j,klo-1) - dz_loc * dens_interp * l_gravity; pi_arr(i,j,klo ) = getExnergivenP(pres_arr(i,j,klo ), rdOcp); - pi_arr(i,j,klo-1) = getExnergivenP(pres_arr(i,j,klo-1), rdOcp); - th_arr(i,j,klo ) = getRhoThetagivenP(pres_arr(i,j,klo )) / rho_arr(i,j,klo ); - th_arr(i,j,klo-1) = getRhoThetagivenP(pres_arr(i,j,klo-1)) / rho_arr(i,j,klo-1); + + for (int kk = 1; kk <= ng_z; kk++) { + pi_arr(i,j,klo-kk) = getExnergivenP(pres_arr(i,j,klo-kk), rdOcp); + th_arr(i,j,klo-kk) = getRhoThetagivenP(pres_arr(i,j,klo-kk)) / rho_arr(i,j,klo-kk); + } } @@ -260,8 +268,9 @@ ERF::erf_enforce_hse (int lev, if (pres[mfi].box().smallEnd(0) < domlo_x) { Box bx = mfi.nodaltilebox(2); + int ng = ngvect[0]; bx.setSmall(0,domlo_x-1); - bx.setBig(0,domlo_x-1); + bx.setBig(0,domlo_x-ng); ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) { pres_arr(i,j,k) = pres_arr(domlo_x,j,k); pi_arr(i,j,k) = pi_arr(domlo_x,j,k); @@ -272,8 +281,9 @@ ERF::erf_enforce_hse (int lev, if (pres[mfi].box().bigEnd(0) > domhi_x) { Box bx = mfi.nodaltilebox(2); + int ng = ngvect[0]; bx.setSmall(0,domhi_x+1); - bx.setBig(0,domhi_x+1); + bx.setBig(0,domhi_x+ng); ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) { pres_arr(i,j,k) = pres_arr(domhi_x,j,k); pi_arr(i,j,k) = pi_arr(domhi_x,j,k); @@ -284,7 +294,8 @@ ERF::erf_enforce_hse (int lev, if (pres[mfi].box().smallEnd(1) < domlo_y) { Box bx = mfi.nodaltilebox(2); - bx.setSmall(1,domlo_y-1); + int ng = ngvect[1]; + bx.setSmall(1,domlo_y-ng); bx.setBig(1,domlo_y-1); ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) { pres_arr(i,j,k) = pres_arr(i,domlo_y,k); @@ -296,8 +307,9 @@ ERF::erf_enforce_hse (int lev, if (pres[mfi].box().bigEnd(1) > domhi_y) { Box bx = mfi.nodaltilebox(2); + int ng = ngvect[1]; bx.setSmall(1,domhi_y+1); - bx.setBig(1,domhi_y+1); + bx.setBig(1,domhi_y+ng); ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) { pres_arr(i,j,k) = pres_arr(i,domhi_y,k); pi_arr(i,j,k) = pi_arr(i,domhi_y,k); diff --git a/Source/Initialization/ERF_init_from_input_sounding.cpp b/Source/Initialization/ERF_init_from_input_sounding.cpp index ec31635e5..e05e97043 100644 --- a/Source/Initialization/ERF_init_from_input_sounding.cpp +++ b/Source/Initialization/ERF_init_from_input_sounding.cpp @@ -88,9 +88,7 @@ ERF::init_from_input_sounding (int lev) // We need to do this here because the interpolation above may leave corners unfilled // when the corners need to be filled by, for example, reflection of the fine ghost // cell outside the fine region but inide the domain. - int bccomp = BCVars::base_bc; - Real dummy_time = 0.; - (*physbcs_base[lev])(base_state[lev],0,base_state[lev].nComp(),base_state[lev].nGrowVect(),dummy_time,bccomp); + (*physbcs_base[lev])(base_state[lev],0,base_state[lev].nComp(),base_state[lev].nGrowVect()); } auto& lev_new = vars_new[lev]; @@ -279,20 +277,28 @@ init_bx_scalars_from_input_sounding_hse (const Box &bx, pi_hse_arr(i,j,k) = getExnergivenRTh(rhoTh_k, l_rdOcp); th_hse_arr(i,j,k) = getRhoThetagivenP(p_hse_arr(i,j,k)) / r_hse_arr(i,j,k); + // TODO: we should be setting this to the number of ghost cells of base_state[lev] + // instead of hard-wiring it here! + int ng = 3; + // FOEXTRAP hse arrays if (k==kbot) { - r_hse_arr (i, j, k-1) = r_hse_arr (i,j,k); - p_hse_arr (i, j, k-1) = p_hse_arr (i,j,k); - pi_hse_arr(i, j, k-1) = pi_hse_arr(i,j,k); - th_hse_arr(i, j, k-1) = th_hse_arr(i,j,k); + for (int kk = 1; kk <= ng; kk++) { + r_hse_arr(i, j, k-kk) = r_hse_arr(i,j,k); + p_hse_arr(i, j, k-kk) = p_hse_arr(i,j,k); + pi_hse_arr(i, j, k-kk) = pi_hse_arr(i,j,k); + th_hse_arr(i, j, k-kk) = th_hse_arr(i,j,k); + } } else if (k==ktop) { - r_hse_arr (i, j, k+1) = r_hse_arr (i,j,k); - p_hse_arr (i, j, k+1) = p_hse_arr (i,j,k); - pi_hse_arr(i, j, k+1) = pi_hse_arr(i,j,k); - th_hse_arr(i, j, k+1) = th_hse_arr(i,j,k); + for (int kk = 1; kk <= ng; kk++) { + r_hse_arr(i, j, k+kk) = r_hse_arr(i,j,k); + p_hse_arr(i, j, k+kk) = p_hse_arr(i,j,k); + pi_hse_arr(i, j, k+kk) = pi_hse_arr(i,j,k); + th_hse_arr(i, j, k+kk) = th_hse_arr(i,j,k); + } } // total nonprecipitating water (Q1) == water vapor (Qv), i.e., there From 20b5be00a6b734da4054ef80ea4162f3b7da299a Mon Sep 17 00:00:00 2001 From: "Aaron M. Lattanzi" <103702284+AMLattanzi@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:42:44 -0700 Subject: [PATCH 04/24] Remove qke (#1905) * First pass at removing QKE. * Compiled with ABL in debug mode. Need to remove some unused params and test. * Cleanup and return a few options for MYNN25 with TropicalCyclone. * Add option to toggle KE numerical diffusion. * We need to create SmnSmn when using MYNN. * Revert the src terms for mynn to avoid breaking the ctests for now. * Have to remake the benchmark just due to different clipping of the variables (eps vs 1.0e-12) * Fix EkmanSpiral out of bounds due to reduced base state ghost cells. * Fix shadowed declaration. * Fix realbdy index. * Backwards compatibility for chk files. * Fix chk file. --------- Co-authored-by: Aaron Lattanzi --- Exec/ABL/ERF_prob.cpp | 10 -- Exec/ABL/inputs_GABLS1_mynn25 | 2 +- Exec/ABL/inputs_GABLS1_ysu | 2 +- Exec/ABL_input_sounding/ERF_prob.H | 2 +- Exec/ABL_input_sounding/ERF_prob.cpp | 6 +- Exec/AWAKEN/ERF_prob.H | 2 +- Exec/AWAKEN/ERF_prob.cpp | 6 +- Exec/AWAKEN/inputs_All_EWP | 2 +- Exec/AWAKEN/inputs_KingPlains_EWP | 2 +- Exec/AWAKEN/inputs_KingPlains_Fitch | 2 +- Exec/AWAKEN/inputs_KingPlains_SimpleAD | 2 +- Exec/DevTests/ABL_with_WW3/ERF_prob.H | 1 - Exec/DevTests/ABL_with_WW3/ERF_prob.cpp | 11 -- Exec/DevTests/LandSurfaceModel/inputs | 2 +- Exec/DevTests/TemperatureSource/ERF_prob.H | 2 +- Exec/DevTests/TemperatureSource/ERF_prob.cpp | 6 +- Exec/DevTests/TropicalCyclone/ERF_prob.H | 2 +- Exec/DevTests/TropicalCyclone/ERF_prob.cpp | 8 +- Exec/DevTests/TropicalCyclone/inputs | 6 +- Exec/EWP/ERF_prob.H | 2 +- Exec/EWP/ERF_prob.cpp | 6 +- Exec/EWP/inputs_1WT_lat_lon | 2 +- Exec/EWP/inputs_1WT_x_y | 2 +- Exec/EWP/inputs_WindFarm_lat_lon | 2 +- Exec/EWP/inputs_WindFarm_x_y | 2 +- Exec/RegTests/Bomex/ERF_prob.cpp | 4 +- Exec/RegTests/TurbulentInflow/ERF_prob.H | 1 - Exec/RegTests/TurbulentInflow/ERF_prob.cpp | 11 -- Exec/SimpleActuatorDisk/ERF_prob.H | 2 +- Exec/SimpleActuatorDisk/ERF_prob.cpp | 6 +- Exec/SimpleActuatorDisk/inputs_1WT_lat_lon | 2 +- Exec/SimpleActuatorDisk/inputs_1WT_x_y | 2 +- .../inputs_WindFarm_lat_lon | 2 +- Exec/SimpleActuatorDisk/inputs_WindFarm_x_y | 2 +- .../ERF_BoundaryConditions_realbdy.cpp | 15 ++- Source/DataStructs/ERF_TurbStruct.H | 14 +-- .../ERF_ComputeTurbulentViscosity.cpp | 37 ++----- .../Diffusion/ERF_DiffusionSrcForState_N.cpp | 32 +++--- .../Diffusion/ERF_DiffusionSrcForState_T.cpp | 34 +++--- Source/Diffusion/ERF_EddyViscosity.H | 12 +-- Source/ERF.H | 6 +- Source/ERF.cpp | 18 ---- Source/ERF_Derive.H | 11 -- Source/ERF_Derive.cpp | 21 ---- Source/ERF_IndexDefines.H | 15 +-- Source/ERF_make_new_arrays.cpp | 2 +- Source/IO/ERF_Checkpoint.cpp | 39 +++++-- Source/IO/ERF_Plotfile.cpp | 5 +- Source/IO/ERF_ReadBndryPlanes.H | 2 - Source/IO/ERF_ReadBndryPlanes.cpp | 7 +- Source/IO/ERF_Write1DProfiles.cpp | 6 +- Source/IO/ERF_Write1DProfiles_stag.cpp | 6 +- Source/IO/ERF_WriteBndryPlanes.cpp | 11 -- Source/Initialization/ERF_init1d.cpp | 97 ++++++++++-------- Source/Initialization/ERF_init_bcs.cpp | 12 --- Source/Initialization/ERF_init_custom.cpp | 12 +-- Source/PBL/ERF_ComputeDiffusivityMYNN25.cpp | 22 ++-- Source/PBL/ERF_ComputeDiffusivityYSU.cpp | 2 +- Source/PBL/ERF_MYNNStruct.H | 2 +- Source/PBL/ERF_PBLHeight.H | 16 +-- Source/PBL/ERF_PBLModels.H | 10 +- Source/SourceTerms/ERF_make_sources.cpp | 13 +-- Source/TimeIntegration/ERF_TI_slow_rhs_fun.H | 6 +- Source/TimeIntegration/ERF_make_tau_terms.cpp | 15 ++- Source/TimeIntegration/ERF_slow_rhs_post.cpp | 24 ++--- .../EWP/ERF_AdvanceEWP.cpp | 2 +- .../Fitch/ERF_AdvanceFitch.cpp | 2 +- Tests/ERFGoldFiles/ABL_MYNN_PBL/Header | 2 +- .../ABL_MYNN_PBL/Level_0/Cell_D_00000 | Bin 18519 -> 18519 bytes .../ERFGoldFiles/ABL_MYNN_PBL/Level_0/Cell_H | 4 +- Tests/test_files/ABL_MYNN_PBL/ABL_MYNN_PBL.i | 2 +- 71 files changed, 266 insertions(+), 394 deletions(-) diff --git a/Exec/ABL/ERF_prob.cpp b/Exec/ABL/ERF_prob.cpp index 99808abcb..2d04b9222 100644 --- a/Exec/ABL/ERF_prob.cpp +++ b/Exec/ABL/ERF_prob.cpp @@ -134,16 +134,6 @@ Problem::init_custom_pert( 1e-12); } } - if (state_pert.nComp() > RhoQKE_comp) { - // PBL - state_pert(i, j, k, RhoQKE_comp) = r_hse(i,j,k) * 2.0 * parms_d.KE_0; - if (parms_d.KE_decay_height > 0) { - // scale initial SGS kinetic energy with height - state_pert(i, j, k, RhoQKE_comp) *= max( - std::pow(1 - min(z/parms_d.KE_decay_height,1.0), parms_d.KE_decay_order), - 1e-12); - } - } if (use_moisture) { state_pert(i, j, k, RhoQ1_comp) = 0.0; diff --git a/Exec/ABL/inputs_GABLS1_mynn25 b/Exec/ABL/inputs_GABLS1_mynn25 index 3612bc9b3..bd4afb195 100644 --- a/Exec/ABL/inputs_GABLS1_mynn25 +++ b/Exec/ABL/inputs_GABLS1_mynn25 @@ -44,7 +44,7 @@ erf.check_int = -1 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 300 # number of timesteps between plotfiles -erf.plot_vars_1 = density x_velocity y_velocity z_velocity pressure theta rhoQKE Kmv Khv +erf.plot_vars_1 = density x_velocity y_velocity z_velocity pressure theta rhoKE Kmv Khv # SOLVER CHOICE diff --git a/Exec/ABL/inputs_GABLS1_ysu b/Exec/ABL/inputs_GABLS1_ysu index 96889dbce..3b65f0ae6 100644 --- a/Exec/ABL/inputs_GABLS1_ysu +++ b/Exec/ABL/inputs_GABLS1_ysu @@ -45,7 +45,7 @@ erf.check_int = -1 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 300 # number of timesteps between plotfiles -erf.plot_vars_1 = density x_velocity y_velocity z_velocity pressure theta rhoQKE Kmv Khv Lpbl +erf.plot_vars_1 = density x_velocity y_velocity z_velocity pressure theta rhoKE Kmv Khv Lpbl # SOLVER CHOICE diff --git a/Exec/ABL_input_sounding/ERF_prob.H b/Exec/ABL_input_sounding/ERF_prob.H index 1c59364b9..58b9594a7 100644 --- a/Exec/ABL_input_sounding/ERF_prob.H +++ b/Exec/ABL_input_sounding/ERF_prob.H @@ -11,7 +11,7 @@ struct ProbParm : ProbParmDefaults { amrex::Real rho_0 = 0.0; amrex::Real T_0 = 0.0; amrex::Real A_0 = 1.0; - amrex::Real QKE_0 = 0.1; + amrex::Real KE_0 = 0.1; amrex::Real U_0 = 0.0; amrex::Real V_0 = 0.0; diff --git a/Exec/ABL_input_sounding/ERF_prob.cpp b/Exec/ABL_input_sounding/ERF_prob.cpp index 73355dd84..6b3cf46d1 100644 --- a/Exec/ABL_input_sounding/ERF_prob.cpp +++ b/Exec/ABL_input_sounding/ERF_prob.cpp @@ -16,7 +16,7 @@ Problem::Problem(const amrex::Real* problo, const amrex::Real* probhi) pp.query("rho_0", parms.rho_0); pp.query("T_0", parms.T_0); pp.query("A_0", parms.A_0); - pp.query("QKE_0", parms.QKE_0); + pp.query("KE_0", parms.KE_0); pp.query("U_0", parms.U_0); pp.query("V_0", parms.V_0); @@ -80,8 +80,8 @@ Problem::init_custom_pert( // Set scalar = A_0*exp(-10r^2), where r is distance from center of domain state_pert(i, j, k, RhoScalar_comp) = parms_d.A_0 * exp(-10.*r*r); - // Set an initial value for QKE - state_pert(i, j, k, RhoQKE_comp) = parms_d.QKE_0; + // Set an initial value for KE + state_pert(i, j, k, RhoKE_comp) = parms_d.KE_0; if (use_moisture) { state_pert(i, j, k, RhoQ1_comp) = 0.0; diff --git a/Exec/AWAKEN/ERF_prob.H b/Exec/AWAKEN/ERF_prob.H index b509c8d45..b587046f4 100644 --- a/Exec/AWAKEN/ERF_prob.H +++ b/Exec/AWAKEN/ERF_prob.H @@ -11,7 +11,7 @@ struct ProbParm : ProbParmDefaults { amrex::Real rho_0 = 0.0; amrex::Real T_0 = 0.0; amrex::Real A_0 = 1.0; - amrex::Real QKE_0 = 0.1; + amrex::Real KE_0 = 0.1; amrex::Real U_0 = 0.0; amrex::Real V_0 = 0.0; diff --git a/Exec/AWAKEN/ERF_prob.cpp b/Exec/AWAKEN/ERF_prob.cpp index 7f5fdda42..75514b1d1 100644 --- a/Exec/AWAKEN/ERF_prob.cpp +++ b/Exec/AWAKEN/ERF_prob.cpp @@ -16,7 +16,7 @@ Problem::Problem(const amrex::Real* problo, const amrex::Real* probhi) pp.query("rho_0", parms.rho_0); pp.query("T_0", parms.T_0); pp.query("A_0", parms.A_0); - pp.query("QKE_0", parms.QKE_0); + pp.query("KE_0", parms.KE_0); pp.query("U_0", parms.U_0); pp.query("V_0", parms.V_0); @@ -90,8 +90,8 @@ Problem::init_custom_pert( // Set scalar = A_0*exp(-10r^2), where r is distance from center of domain state_pert(i, j, k, RhoScalar_comp) = parms_d.A_0 * exp(-10.*r*r); - // Set an initial value for QKE - state_pert(i, j, k, RhoQKE_comp) = parms_d.QKE_0; + // Set an initial value for KE + state_pert(i, j, k, RhoKE_comp) = parms_d.KE_0; if (use_moisture) { state_pert(i, j, k, RhoQ1_comp) = 0.0; diff --git a/Exec/AWAKEN/inputs_All_EWP b/Exec/AWAKEN/inputs_All_EWP index cda4dff42..87cc49fc1 100644 --- a/Exec/AWAKEN/inputs_All_EWP +++ b/Exec/AWAKEN/inputs_All_EWP @@ -68,7 +68,7 @@ erf.check_int = 10000 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 1200 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta QKE vorticity SMark +erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta KE vorticity SMark # SOLVER CHOICE erf.alpha_T = 0.0 diff --git a/Exec/AWAKEN/inputs_KingPlains_EWP b/Exec/AWAKEN/inputs_KingPlains_EWP index 653b75e3c..912911ae7 100644 --- a/Exec/AWAKEN/inputs_KingPlains_EWP +++ b/Exec/AWAKEN/inputs_KingPlains_EWP @@ -58,7 +58,7 @@ erf.check_int = 10000 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 100 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta QKE vorticity SMark +erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta KE vorticity SMark # SOLVER CHOICE erf.alpha_T = 0.0 diff --git a/Exec/AWAKEN/inputs_KingPlains_Fitch b/Exec/AWAKEN/inputs_KingPlains_Fitch index 169f2a8d5..d356cbbd0 100644 --- a/Exec/AWAKEN/inputs_KingPlains_Fitch +++ b/Exec/AWAKEN/inputs_KingPlains_Fitch @@ -58,7 +58,7 @@ erf.check_int = 10000 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 100 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta QKE vorticity SMark +erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta KE vorticity SMark # SOLVER CHOICE erf.alpha_T = 0.0 diff --git a/Exec/AWAKEN/inputs_KingPlains_SimpleAD b/Exec/AWAKEN/inputs_KingPlains_SimpleAD index 9b1822545..949916782 100644 --- a/Exec/AWAKEN/inputs_KingPlains_SimpleAD +++ b/Exec/AWAKEN/inputs_KingPlains_SimpleAD @@ -60,7 +60,7 @@ erf.check_int = 10000 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 100 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta QKE vorticity SMark +erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta KE vorticity SMark # SOLVER CHOICE erf.alpha_T = 0.0 diff --git a/Exec/DevTests/ABL_with_WW3/ERF_prob.H b/Exec/DevTests/ABL_with_WW3/ERF_prob.H index 67077f6e5..aaedb9c7b 100644 --- a/Exec/DevTests/ABL_with_WW3/ERF_prob.H +++ b/Exec/DevTests/ABL_with_WW3/ERF_prob.H @@ -12,7 +12,6 @@ struct ProbParm : ProbParmDefaults { amrex::Real T_0 = 0.0; amrex::Real A_0 = 1.0; amrex::Real KE_0 = 0.1; - amrex::Real QKE_0 = 0.1; amrex::Real KE_decay_height = -1; amrex::Real KE_decay_order = 1; diff --git a/Exec/DevTests/ABL_with_WW3/ERF_prob.cpp b/Exec/DevTests/ABL_with_WW3/ERF_prob.cpp index 8790b3ebf..2d04b9222 100644 --- a/Exec/DevTests/ABL_with_WW3/ERF_prob.cpp +++ b/Exec/DevTests/ABL_with_WW3/ERF_prob.cpp @@ -17,7 +17,6 @@ Problem::Problem(const amrex::Real* problo, const amrex::Real* probhi) pp.query("T_0", parms.T_0); pp.query("A_0", parms.A_0); pp.query("KE_0", parms.KE_0); - pp.query("QKE_0", parms.QKE_0); pp.query("KE_decay_height", parms.KE_decay_height); pp.query("KE_decay_order", parms.KE_decay_order); @@ -135,16 +134,6 @@ Problem::init_custom_pert( 1e-12); } } - if (state_pert.nComp() > RhoQKE_comp) { - // PBL - state_pert(i, j, k, RhoQKE_comp) = r_hse(i,j,k) * parms_d.QKE_0; - if (parms_d.KE_decay_height > 0) { - // scale initial SGS kinetic energy with height - state_pert(i, j, k, RhoQKE_comp) *= max( - std::pow(1 - min(z/parms_d.KE_decay_height,1.0), parms_d.KE_decay_order), - 1e-12); - } - } if (use_moisture) { state_pert(i, j, k, RhoQ1_comp) = 0.0; diff --git a/Exec/DevTests/LandSurfaceModel/inputs b/Exec/DevTests/LandSurfaceModel/inputs index cb29c9132..de93aa53d 100644 --- a/Exec/DevTests/LandSurfaceModel/inputs +++ b/Exec/DevTests/LandSurfaceModel/inputs @@ -55,7 +55,7 @@ erf.molec_diff_type = "None" erf.les_type = "Smagorinsky" erf.Cs = 0.1 #erf.pbl_type = "MYNN2.5" -#erf.QKE_0 = 0.5 +#erf.KE_0 = 0.5 erf.use_terrain = true erf.terrain_smoothing = 2 diff --git a/Exec/DevTests/TemperatureSource/ERF_prob.H b/Exec/DevTests/TemperatureSource/ERF_prob.H index df04de7c6..036f331ef 100644 --- a/Exec/DevTests/TemperatureSource/ERF_prob.H +++ b/Exec/DevTests/TemperatureSource/ERF_prob.H @@ -11,7 +11,7 @@ struct ProbParm : ProbParmDefaults { amrex::Real rho_0 = 0.0; amrex::Real T_0 = 0.0; amrex::Real A_0 = 1.0; - amrex::Real QKE_0 = 0.1; + amrex::Real KE_0 = 0.1; amrex::Real U_0 = 0.0; amrex::Real V_0 = 0.0; diff --git a/Exec/DevTests/TemperatureSource/ERF_prob.cpp b/Exec/DevTests/TemperatureSource/ERF_prob.cpp index 80e83a867..1b096f21a 100644 --- a/Exec/DevTests/TemperatureSource/ERF_prob.cpp +++ b/Exec/DevTests/TemperatureSource/ERF_prob.cpp @@ -17,7 +17,7 @@ Problem::Problem(const amrex::Real* problo, const amrex::Real* probhi) pp.query("rho_0", parms.rho_0); pp.query("T_0", parms.T_0); pp.query("A_0", parms.A_0); - pp.query("QKE_0", parms.QKE_0); + pp.query("KE_0", parms.KE_0); pp.query("U_0", parms.U_0); pp.query("V_0", parms.V_0); @@ -96,8 +96,8 @@ Problem::init_custom_pert( // Set scalar = A_0*exp(-10r^2), where r is distance from center of domain state_pert(i, j, k, RhoScalar_comp) = parms_d.A_0 * exp(-10.*r*r); - // Set an initial value for QKE - state_pert(i, j, k, RhoQKE_comp) = parms_d.QKE_0; + // Set an initial value for KE + state_pert(i, j, k, RhoKE_comp) = parms_d.KE_0; if (use_moisture) { state_pert(i, j, k, RhoQ1_comp) = 0.0; diff --git a/Exec/DevTests/TropicalCyclone/ERF_prob.H b/Exec/DevTests/TropicalCyclone/ERF_prob.H index 3c0a0319f..faf57a918 100644 --- a/Exec/DevTests/TropicalCyclone/ERF_prob.H +++ b/Exec/DevTests/TropicalCyclone/ERF_prob.H @@ -8,7 +8,7 @@ #include "ERF_prob_common.H" struct ProbParm : ProbParmDefaults { - amrex::Real QKE_0 = 0.1; + amrex::Real KE_0 = 0.1; amrex::Real Xc_0 = 0.0; amrex::Real Yc_0 = 0.0; diff --git a/Exec/DevTests/TropicalCyclone/ERF_prob.cpp b/Exec/DevTests/TropicalCyclone/ERF_prob.cpp index 5e51e818a..e28f156a3 100644 --- a/Exec/DevTests/TropicalCyclone/ERF_prob.cpp +++ b/Exec/DevTests/TropicalCyclone/ERF_prob.cpp @@ -19,7 +19,7 @@ Problem::Problem() pp.query("U_0", parms.U_0); // for Rayleigh damping pp.query("V_0", parms.V_0); // for Rayleigh damping pp.query("W_0", parms.W_0); // for Rayleigh damping - pp.query("QKE_0", parms.QKE_0); + pp.query("KE_0", parms.KE_0); pp.query("Xc_0", parms.Xc_0); pp.query("Yc_0", parms.Yc_0); @@ -60,11 +60,11 @@ Problem::init_custom_pert( // and/or set initial values for other scalars // - // QKE for PBL - Real QKE_0 = parms.QKE_0; + // KE for MYNN or Deardorff + Real KE_0 = parms.KE_0; amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { - state_pert(i, j, k, RhoQKE_comp) = r_hse(i,j,k) * QKE_0; + state_pert(i, j, k, RhoKE_comp) = r_hse(i,j,k) * KE_0; }); // diff --git a/Exec/DevTests/TropicalCyclone/inputs b/Exec/DevTests/TropicalCyclone/inputs index 66994811b..7373205bc 100644 --- a/Exec/DevTests/TropicalCyclone/inputs +++ b/Exec/DevTests/TropicalCyclone/inputs @@ -57,12 +57,12 @@ erf.check_int = 1000 # number of timesteps between checkpoints #erf.plotfile_type = netcdf erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 200 # number of timesteps between plotfiles -erf.plot_vars_1 = density x_velocity y_velocity z_velocity pressure theta QKE Kmv Khv +erf.plot_vars_1 = density x_velocity y_velocity z_velocity pressure theta KE Kmv Khv # SOLVER CHOICE erf.use_gravity = true erf.pbl_type = "MYNN2.5" -erf.advect_QKE = false +erf.advect_KE = false erf.les_type = "None" erf.molec_diff_type = "None" #erf.molec_diff_type = "Constant" @@ -92,7 +92,7 @@ prob.RZERO = 100e3 prob.ZZERO = 5e3 prob.RMAX = 20e3 prob.VMAX = 15. -prob.QKE_0 = 0.5 +prob.KE_0 = 0.5 # INITIALIZATION WITH ATM DATA erf.init_type = "input_sounding" diff --git a/Exec/EWP/ERF_prob.H b/Exec/EWP/ERF_prob.H index afbc3736f..777be4724 100644 --- a/Exec/EWP/ERF_prob.H +++ b/Exec/EWP/ERF_prob.H @@ -11,7 +11,7 @@ struct ProbParm : ProbParmDefaults { amrex::Real rho_0 = 0.0; amrex::Real T_0 = 0.0; amrex::Real A_0 = 1.0; - amrex::Real QKE_0 = 0.1; + amrex::Real KE_0 = 0.1; amrex::Real U_0 = 0.0; amrex::Real V_0 = 0.0; diff --git a/Exec/EWP/ERF_prob.cpp b/Exec/EWP/ERF_prob.cpp index adce92fe8..145f66ad6 100644 --- a/Exec/EWP/ERF_prob.cpp +++ b/Exec/EWP/ERF_prob.cpp @@ -16,7 +16,7 @@ Problem::Problem(const amrex::Real* problo, const amrex::Real* probhi) pp.query("rho_0", parms.rho_0); pp.query("T_0", parms.T_0); pp.query("A_0", parms.A_0); - pp.query("QKE_0", parms.QKE_0); + pp.query("KE_0", parms.KE_0); pp.query("U_0", parms.U_0); pp.query("V_0", parms.V_0); @@ -87,8 +87,8 @@ Problem::init_custom_pert( // Set scalar = A_0*exp(-10r^2), where r is distance from center of domain state_pert(i, j, k, RhoScalar_comp) = parms_d.A_0 * exp(-10.*r*r); - // Set an initial value for QKE - state_pert(i, j, k, RhoQKE_comp) = parms_d.QKE_0; + // Set an initial value for KE + state_pert(i, j, k, RhoKE_comp) = parms_d.KE_0; if (use_moisture) { state_pert(i, j, k, RhoQ1_comp) = 0.0; diff --git a/Exec/EWP/inputs_1WT_lat_lon b/Exec/EWP/inputs_1WT_lat_lon index 215618298..73acdfc52 100644 --- a/Exec/EWP/inputs_1WT_lat_lon +++ b/Exec/EWP/inputs_1WT_lat_lon @@ -70,7 +70,7 @@ erf.check_int = 1000 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 100 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta QKE num_turb vorticity +erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta KE num_turb vorticity # ADVECTION SCHEMES erf.dycore_horiz_adv_type = "Centered_2nd" diff --git a/Exec/EWP/inputs_1WT_x_y b/Exec/EWP/inputs_1WT_x_y index e9c1296ef..7c0b067f1 100644 --- a/Exec/EWP/inputs_1WT_x_y +++ b/Exec/EWP/inputs_1WT_x_y @@ -68,7 +68,7 @@ erf.check_int = 1000 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 100 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta QKE num_turb vorticity +erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta KE num_turb vorticity # ADVECTION SCHEMES erf.dycore_horiz_adv_type = "Centered_2nd" diff --git a/Exec/EWP/inputs_WindFarm_lat_lon b/Exec/EWP/inputs_WindFarm_lat_lon index 0b4b92a4b..6bb90ce8e 100644 --- a/Exec/EWP/inputs_WindFarm_lat_lon +++ b/Exec/EWP/inputs_WindFarm_lat_lon @@ -55,7 +55,7 @@ erf.check_int = 10000 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 1000 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta QKE num_turb vorticity +erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta KE num_turb vorticity # SOLVER CHOICE erf.alpha_T = 0.0 diff --git a/Exec/EWP/inputs_WindFarm_x_y b/Exec/EWP/inputs_WindFarm_x_y index 1f102dc4d..198eece95 100644 --- a/Exec/EWP/inputs_WindFarm_x_y +++ b/Exec/EWP/inputs_WindFarm_x_y @@ -53,7 +53,7 @@ erf.check_int = 10000 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 1000 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta QKE num_turb vorticity +erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta KE num_turb vorticity # SOLVER CHOICE erf.alpha_T = 0.0 diff --git a/Exec/RegTests/Bomex/ERF_prob.cpp b/Exec/RegTests/Bomex/ERF_prob.cpp index 078b7709b..9f77ee875 100644 --- a/Exec/RegTests/Bomex/ERF_prob.cpp +++ b/Exec/RegTests/Bomex/ERF_prob.cpp @@ -17,7 +17,7 @@ Problem::Problem (const Real* problo, const Real* probhi) pp.query("rho_0", parms.rho_0); pp.query("T_0", parms.T_0); pp.query("A_0", parms.A_0); - pp.query("QKE_0", parms.KE_0); + pp.query("KE_0", parms.KE_0); pp.query("U_0", parms.U_0); pp.query("V_0", parms.V_0); @@ -129,7 +129,7 @@ Problem::init_custom_pert ( // Set scalar = A_0*exp(-10r^2), where r is distance from center of domain state_pert(i, j, k, RhoScalar_comp) = parms_d.A_0 * exp(-10.*r*r); - // Set an initial value for QKE + // Set an initial value for KE if (parms_d.custom_TKE) { state_pert(i, j, k, RhoKE_comp) = (1.0 - z/prob_hi[2]) * r_hse(i,j,k); } else { diff --git a/Exec/RegTests/TurbulentInflow/ERF_prob.H b/Exec/RegTests/TurbulentInflow/ERF_prob.H index e24b1b914..5cf575dae 100644 --- a/Exec/RegTests/TurbulentInflow/ERF_prob.H +++ b/Exec/RegTests/TurbulentInflow/ERF_prob.H @@ -12,7 +12,6 @@ struct ProbParm : ProbParmDefaults { amrex::Real T_0 = 300.0; amrex::Real A_0 = 1.0; amrex::Real KE_0 = 0.1; - amrex::Real QKE_0 = 0.1; amrex::Real KE_decay_height = -1; amrex::Real KE_decay_order = 1; diff --git a/Exec/RegTests/TurbulentInflow/ERF_prob.cpp b/Exec/RegTests/TurbulentInflow/ERF_prob.cpp index 8790b3ebf..2d04b9222 100644 --- a/Exec/RegTests/TurbulentInflow/ERF_prob.cpp +++ b/Exec/RegTests/TurbulentInflow/ERF_prob.cpp @@ -17,7 +17,6 @@ Problem::Problem(const amrex::Real* problo, const amrex::Real* probhi) pp.query("T_0", parms.T_0); pp.query("A_0", parms.A_0); pp.query("KE_0", parms.KE_0); - pp.query("QKE_0", parms.QKE_0); pp.query("KE_decay_height", parms.KE_decay_height); pp.query("KE_decay_order", parms.KE_decay_order); @@ -135,16 +134,6 @@ Problem::init_custom_pert( 1e-12); } } - if (state_pert.nComp() > RhoQKE_comp) { - // PBL - state_pert(i, j, k, RhoQKE_comp) = r_hse(i,j,k) * parms_d.QKE_0; - if (parms_d.KE_decay_height > 0) { - // scale initial SGS kinetic energy with height - state_pert(i, j, k, RhoQKE_comp) *= max( - std::pow(1 - min(z/parms_d.KE_decay_height,1.0), parms_d.KE_decay_order), - 1e-12); - } - } if (use_moisture) { state_pert(i, j, k, RhoQ1_comp) = 0.0; diff --git a/Exec/SimpleActuatorDisk/ERF_prob.H b/Exec/SimpleActuatorDisk/ERF_prob.H index afbc3736f..777be4724 100644 --- a/Exec/SimpleActuatorDisk/ERF_prob.H +++ b/Exec/SimpleActuatorDisk/ERF_prob.H @@ -11,7 +11,7 @@ struct ProbParm : ProbParmDefaults { amrex::Real rho_0 = 0.0; amrex::Real T_0 = 0.0; amrex::Real A_0 = 1.0; - amrex::Real QKE_0 = 0.1; + amrex::Real KE_0 = 0.1; amrex::Real U_0 = 0.0; amrex::Real V_0 = 0.0; diff --git a/Exec/SimpleActuatorDisk/ERF_prob.cpp b/Exec/SimpleActuatorDisk/ERF_prob.cpp index adce92fe8..145f66ad6 100644 --- a/Exec/SimpleActuatorDisk/ERF_prob.cpp +++ b/Exec/SimpleActuatorDisk/ERF_prob.cpp @@ -16,7 +16,7 @@ Problem::Problem(const amrex::Real* problo, const amrex::Real* probhi) pp.query("rho_0", parms.rho_0); pp.query("T_0", parms.T_0); pp.query("A_0", parms.A_0); - pp.query("QKE_0", parms.QKE_0); + pp.query("KE_0", parms.KE_0); pp.query("U_0", parms.U_0); pp.query("V_0", parms.V_0); @@ -87,8 +87,8 @@ Problem::init_custom_pert( // Set scalar = A_0*exp(-10r^2), where r is distance from center of domain state_pert(i, j, k, RhoScalar_comp) = parms_d.A_0 * exp(-10.*r*r); - // Set an initial value for QKE - state_pert(i, j, k, RhoQKE_comp) = parms_d.QKE_0; + // Set an initial value for KE + state_pert(i, j, k, RhoKE_comp) = parms_d.KE_0; if (use_moisture) { state_pert(i, j, k, RhoQ1_comp) = 0.0; diff --git a/Exec/SimpleActuatorDisk/inputs_1WT_lat_lon b/Exec/SimpleActuatorDisk/inputs_1WT_lat_lon index ff237b1cc..4781b7b8a 100644 --- a/Exec/SimpleActuatorDisk/inputs_1WT_lat_lon +++ b/Exec/SimpleActuatorDisk/inputs_1WT_lat_lon @@ -70,7 +70,7 @@ erf.check_int = 1000 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 100 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta QKE num_turb vorticity +erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta KE num_turb vorticity # ADVECTION SCHEMES erf.dycore_horiz_adv_type = "Centered_2nd" diff --git a/Exec/SimpleActuatorDisk/inputs_1WT_x_y b/Exec/SimpleActuatorDisk/inputs_1WT_x_y index 4796a2cf4..56be43a86 100644 --- a/Exec/SimpleActuatorDisk/inputs_1WT_x_y +++ b/Exec/SimpleActuatorDisk/inputs_1WT_x_y @@ -68,7 +68,7 @@ erf.check_int = 1000 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 10 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta QKE num_turb vorticity_x vorticity_y vorticity_z +erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta KE num_turb vorticity_x vorticity_y vorticity_z # ADVECTION SCHEMES erf.dycore_horiz_adv_type = "Centered_2nd" diff --git a/Exec/SimpleActuatorDisk/inputs_WindFarm_lat_lon b/Exec/SimpleActuatorDisk/inputs_WindFarm_lat_lon index 8fe3e2e82..8c6e9c77d 100644 --- a/Exec/SimpleActuatorDisk/inputs_WindFarm_lat_lon +++ b/Exec/SimpleActuatorDisk/inputs_WindFarm_lat_lon @@ -55,7 +55,7 @@ erf.check_int = 10000 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 1000 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta QKE num_turb vorticity +erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta KE num_turb vorticity # SOLVER CHOICE erf.alpha_T = 0.0 diff --git a/Exec/SimpleActuatorDisk/inputs_WindFarm_x_y b/Exec/SimpleActuatorDisk/inputs_WindFarm_x_y index 72e9af156..1733cfe54 100644 --- a/Exec/SimpleActuatorDisk/inputs_WindFarm_x_y +++ b/Exec/SimpleActuatorDisk/inputs_WindFarm_x_y @@ -53,7 +53,7 @@ erf.check_int = 10000 # number of timesteps between checkpoints # PLOTFILES erf.plot_file_1 = plt # prefix of plotfile name erf.plot_int_1 = 1000 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta QKE num_turb vorticity +erf.plot_vars_1 = density rhoadv_0 x_velocity y_velocity z_velocity pressure temp theta KE num_turb vorticity # SOLVER CHOICE erf.alpha_T = 0.0 diff --git a/Source/BoundaryConditions/ERF_BoundaryConditions_realbdy.cpp b/Source/BoundaryConditions/ERF_BoundaryConditions_realbdy.cpp index 5d6be8b7d..a665685bc 100644 --- a/Source/BoundaryConditions/ERF_BoundaryConditions_realbdy.cpp +++ b/Source/BoundaryConditions/ERF_BoundaryConditions_realbdy.cpp @@ -35,14 +35,13 @@ ERF::fill_from_realbdy (const Vector& mfs, Real oma = 1.0 - alpha; // Flags for read vars and index mapping - Vector cons_read = {0, 1, 0, - 0, 0, 1, - 0, 0, 0, - 0, 0}; - Vector cons_map = {Rho_comp, RealBdyVars::T, RhoKE_comp, - RhoQKE_comp, RhoScalar_comp, RealBdyVars::QV, - RhoQ2_comp, RhoQ3_comp, RhoQ4_comp, - RhoQ5_comp, RhoQ6_comp}; + Vector cons_read = {0, 1, 0, 0, + 1, 0, 0, + 0, 0, 0}; + + Vector cons_map = {Rho_comp, RealBdyVars::T, RhoKE_comp, RhoScalar_comp, + RealBdyVars::QV, RhoQ2_comp, RhoQ3_comp, + RhoQ4_comp, RhoQ5_comp, RhoQ6_comp}; Vector> is_read; is_read.push_back( cons_read ); diff --git a/Source/DataStructs/ERF_TurbStruct.H b/Source/DataStructs/ERF_TurbStruct.H index a8a10f72a..d649d61e7 100644 --- a/Source/DataStructs/ERF_TurbStruct.H +++ b/Source/DataStructs/ERF_TurbStruct.H @@ -78,9 +78,9 @@ struct TurbChoice { // Right now, solving the QKE equation is only supported when MYNN PBL is turned on if (pbl_type == PBLType::MYNN25) { - use_QKE = true; - query_one_or_per_level(pp, "advect_QKE" , advect_QKE, lev, max_level); - query_one_or_per_level(pp, "diffuse_QKE_3D", diffuse_QKE_3D, lev, max_level); + use_KE = true; + query_one_or_per_level(pp, "advect_KE" , advect_KE, lev, max_level); + query_one_or_per_level(pp, "diffuse_KE_3D", diffuse_KE_3D, lev, max_level); } // LES constants... @@ -202,9 +202,9 @@ struct TurbChoice { amrex::Real pbl_ysu_land_Ribcr = 0.25; // Critical Bulk Richardson number of Land for stable conditions amrex::Real pbl_ysu_unst_Ribcr = 0.0; // Critical Bulk Richardson number for unstable conditions - // QKE stuff - default is not to use it, if MYNN2.5 PBL is used default is turb transport in Z-direction only - bool use_QKE = false; - bool diffuse_QKE_3D = false; - bool advect_QKE = true; + // QKE stuff - default is to use it, if MYNN2.5 PBL is used default is turb transport in Z-direction only + bool use_KE = true; + bool diffuse_KE_3D = true; + bool advect_KE = true; }; #endif diff --git a/Source/Diffusion/ERF_ComputeTurbulentViscosity.cpp b/Source/Diffusion/ERF_ComputeTurbulentViscosity.cpp index 5e9bc6e5c..9e23f43d4 100644 --- a/Source/Diffusion/ERF_ComputeTurbulentViscosity.cpp +++ b/Source/Diffusion/ERF_ComputeTurbulentViscosity.cpp @@ -207,6 +207,8 @@ void ComputeTurbulentViscosityLES (const MultiFab& Tau11, const MultiFab& Tau22, mu_turb(i,j,k,EddyDiff::Mom_v) = mu_turb(i,j,k,EddyDiff::Mom_h); // KH = (1 + 2*l/delta) * mu_turb mu_turb(i,j,k,EddyDiff::Theta_v) = (1.+2.*length/DeltaMsf) * mu_turb(i,j,k,EddyDiff::Mom_v); + // Store lengthscale for TKE source terms + mu_turb(i,j,k,EddyDiff::Turb_lengthscale) = length; // Calculate SFS quantities // - dissipation @@ -217,6 +219,7 @@ void ComputeTurbulentViscosityLES (const MultiFab& Tau11, const MultiFab& Tau22, Ce = 1.9*l_C_k + Ce_lcoeff*length / DeltaMsf; } diss(i,j,k) = cell_data(i,j,k,Rho_comp) * Ce * std::pow(E,1.5) / length; + // - heat flux // (Note: If using ERF_EXPLICIT_MOST_STRESS, the value at k=0 will // be overwritten when BCs are applied) @@ -230,14 +233,14 @@ void ComputeTurbulentViscosityLES (const MultiFab& Tau11, const MultiFab& Tau22, // Extrapolate Kturb in x/y, fill remaining elements (relevant to lev==0) //*********************************************************************************** int ngc(1); - // EddyDiff mapping : Theta_h KE_h QKE_h Scalar_h Q_h - Vector Factors = {inv_Pr_t, inv_sigma_k, inv_sigma_k, inv_Sc_t, inv_Sc_t}; // alpha = mu/Pr + // EddyDiff mapping : Theta_h KE_h Scalar_h Q_h + Vector Factors = {inv_Pr_t, inv_sigma_k, inv_Sc_t, inv_Sc_t}; // alpha = mu/Pr Gpu::AsyncVector d_Factors; d_Factors.resize(Factors.size()); Gpu::copy(Gpu::hostToDevice, Factors.begin(), Factors.end(), d_Factors.begin()); Real* fac_ptr = d_Factors.data(); - bool use_KE = (turbChoice.les_type == LESType::Deardorff); - bool use_QKE = turbChoice.use_QKE; + const bool use_KE = ( (turbChoice.les_type == LESType::Deardorff) || + (turbChoice.pbl_type == PBLType::MYNN25) ); #ifdef _OPENMP #pragma omp parallel if (Gpu::notInLaunchRegion()) @@ -324,18 +327,6 @@ void ComputeTurbulentViscosityLES (const MultiFab& Tau11, const MultiFab& Tau22, int offset = (EddyDiff::NumDiffs-1)/2; switch (n) { - case EddyDiff::QKE_h: - // Populate element other than mom_h/v on the whole grid - if(use_QKE) { - ParallelFor(bxcc, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - int indx = n; - int indx_v = indx + offset; - mu_turb(i,j,k,indx) = mu_turb(i,j,k,EddyDiff::Mom_h) * fac_ptr[indx-1]; - mu_turb(i,j,k,indx_v) = mu_turb(i,j,k,indx); - }); - } - break; case EddyDiff::KE_h: if (use_KE) { ParallelFor(bxcc, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept @@ -389,20 +380,6 @@ void ComputeTurbulentViscosityLES (const MultiFab& Tau11, const MultiFab& Tau22, int offset = (EddyDiff::NumDiffs-1)/2; switch (n) { - case EddyDiff::QKE_h: - // Extrap all components at top & bottom - if(use_QKE) { - ParallelFor(planez, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept - { - int indx = n; - int indx_v = indx + offset; - mu_turb(i, j, k_lo-k, indx ) = mu_turb(i, j, k_lo, indx ); - mu_turb(i, j, k_hi+k, indx ) = mu_turb(i, j, k_hi, indx ); - mu_turb(i, j, k_lo-k, indx_v) = mu_turb(i, j, k_lo, indx_v); - mu_turb(i, j, k_hi+k, indx_v) = mu_turb(i, j, k_hi, indx_v); - }); - } - break; case EddyDiff::KE_h: if (use_KE) { ParallelFor(planez, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept diff --git a/Source/Diffusion/ERF_DiffusionSrcForState_N.cpp b/Source/Diffusion/ERF_DiffusionSrcForState_N.cpp index 58fde87ac..e4429425b 100644 --- a/Source/Diffusion/ERF_DiffusionSrcForState_N.cpp +++ b/Source/Diffusion/ERF_DiffusionSrcForState_N.cpp @@ -79,11 +79,12 @@ DiffusionSrcForState_N (const Box& bx, const Box& domain, const auto& dom_lo = lbound(domain); const auto& dom_hi = ubound(domain); - bool l_use_QKE = turbChoice.use_QKE; - bool l_use_deardorff = (turbChoice.les_type == LESType::Deardorff); Real l_inv_theta0 = 1.0 / turbChoice.theta_ref; Real l_abs_g = std::abs(grav_gpu[2]); + bool l_use_ddorf = (turbChoice.les_type == LESType::Deardorff); + bool l_use_mynn = (turbChoice.pbl_type == PBLType::MYNN25); + bool l_consA = (diffChoice.molec_diff_type == MolecDiffType::ConstantAlpha); bool l_turb = ( (turbChoice.les_type == LESType::Smagorinsky) || (turbChoice.les_type == LESType::Deardorff ) || @@ -96,7 +97,7 @@ DiffusionSrcForState_N (const Box& bx, const Box& domain, const int end_comp = start_comp + num_comp - 1; - // Theta, KE, QKE, Scalar + // Theta, KE, Scalar Vector alpha_eff(NPRIMVAR_max, 0.0); if (l_consA) { for (int i = 0; i < NPRIMVAR_max; ++i) { @@ -164,15 +165,15 @@ DiffusionSrcForState_N (const Box& bx, const Box& domain, } } - Vector eddy_diff_idx{EddyDiff::Theta_h, EddyDiff::KE_h, EddyDiff::QKE_h, EddyDiff::Scalar_h, - EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h , - EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h }; - Vector eddy_diff_idy{EddyDiff::Theta_h, EddyDiff::KE_h, EddyDiff::QKE_h, EddyDiff::Scalar_h, - EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h , - EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h }; - Vector eddy_diff_idz{EddyDiff::Theta_v, EddyDiff::KE_v, EddyDiff::QKE_v, EddyDiff::Scalar_v, - EddyDiff::Q_v , EddyDiff::Q_v, EddyDiff::Q_v , - EddyDiff::Q_v , EddyDiff::Q_v, EddyDiff::Q_v }; + Vector eddy_diff_idx{EddyDiff::Theta_h, EddyDiff::KE_h, EddyDiff::Scalar_h, + EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h , + EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h }; + Vector eddy_diff_idy{EddyDiff::Theta_h, EddyDiff::KE_h, EddyDiff::Scalar_h, + EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h , + EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h }; + Vector eddy_diff_idz{EddyDiff::Theta_v, EddyDiff::KE_v, EddyDiff::Scalar_v, + EddyDiff::Q_v , EddyDiff::Q_v, EddyDiff::Q_v , + EddyDiff::Q_v , EddyDiff::Q_v, EddyDiff::Q_v }; // Device vectors Gpu::AsyncVector alpha_eff_d; @@ -678,7 +679,7 @@ DiffusionSrcForState_N (const Box& bx, const Box& domain, // The surface heat flux hfx_z(i,j,-1) is updated in MOSTStress at // each RK stage if using the ERF_EXPLICIT_MOST_STRESS path, but that // does not change the buoyancy production term here. - if (l_use_deardorff && start_comp <= RhoKE_comp && end_comp >=RhoKE_comp) { + if (l_use_ddorf && (start_comp <= RhoKE_comp) && (end_comp >=RhoKE_comp)) { int qty_index = RhoKE_comp; ParallelFor(bx,[=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { @@ -707,8 +708,8 @@ DiffusionSrcForState_N (const Box& bx, const Box& domain, } // Using PBL - if (l_use_QKE && start_comp <= RhoQKE_comp && end_comp >=RhoQKE_comp) { - int qty_index = RhoQKE_comp; + if (l_use_mynn && start_comp <= RhoKE_comp && end_comp >=RhoKE_comp) { + int qty_index = RhoKE_comp; auto pbl_mynn_B1_l = turbChoice.pbl_mynn.B1; const int rhoqv_comp = solverChoice.RhoQv_comp; @@ -734,5 +735,4 @@ DiffusionSrcForState_N (const Box& bx, const Box& domain, use_most); }); } - } diff --git a/Source/Diffusion/ERF_DiffusionSrcForState_T.cpp b/Source/Diffusion/ERF_DiffusionSrcForState_T.cpp index d210b512c..8b4e1bcc5 100644 --- a/Source/Diffusion/ERF_DiffusionSrcForState_T.cpp +++ b/Source/Diffusion/ERF_DiffusionSrcForState_T.cpp @@ -91,11 +91,12 @@ DiffusionSrcForState_T (const Box& bx, const Box& domain, const auto& dom_hi = ubound(domain); - bool l_use_QKE = turbChoice.use_QKE; - bool l_use_deardorff = (turbChoice.les_type == LESType::Deardorff); Real l_inv_theta0 = 1.0 / turbChoice.theta_ref; Real l_abs_g = std::abs(grav_gpu[2]); + bool l_use_ddorf = (turbChoice.les_type == LESType::Deardorff); + bool l_use_mynn = (turbChoice.pbl_type == PBLType::MYNN25); + bool l_consA = (diffChoice.molec_diff_type == MolecDiffType::ConstantAlpha); bool l_turb = ( (turbChoice.les_type == LESType::Smagorinsky) || (turbChoice.les_type == LESType::Deardorff ) || @@ -109,7 +110,7 @@ DiffusionSrcForState_T (const Box& bx, const Box& domain, const int end_comp = start_comp + num_comp - 1; - // Theta, KE, QKE, Scalar + // Theta, KE, Scalar Vector alpha_eff(NPRIMVAR_max, 0.0); if (l_consA) { for (int i = 0; i < NPRIMVAR_max; ++i) { @@ -177,15 +178,15 @@ DiffusionSrcForState_T (const Box& bx, const Box& domain, } } - Vector eddy_diff_idx{EddyDiff::Theta_h, EddyDiff::KE_h, EddyDiff::QKE_h, EddyDiff::Scalar_h, - EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h , - EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h }; - Vector eddy_diff_idy{EddyDiff::Theta_h, EddyDiff::KE_h, EddyDiff::QKE_h, EddyDiff::Scalar_h, - EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h , - EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h }; - Vector eddy_diff_idz{EddyDiff::Theta_v, EddyDiff::KE_v, EddyDiff::QKE_v, EddyDiff::Scalar_v, - EddyDiff::Q_v , EddyDiff::Q_v, EddyDiff::Q_v , - EddyDiff::Q_v , EddyDiff::Q_v, EddyDiff::Q_v }; + Vector eddy_diff_idx{EddyDiff::Theta_h, EddyDiff::KE_h, EddyDiff::Scalar_h, + EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h , + EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h }; + Vector eddy_diff_idy{EddyDiff::Theta_h, EddyDiff::KE_h, EddyDiff::Scalar_h, + EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h , + EddyDiff::Q_h , EddyDiff::Q_h, EddyDiff::Q_h }; + Vector eddy_diff_idz{EddyDiff::Theta_v, EddyDiff::KE_v, EddyDiff::Scalar_v, + EddyDiff::Q_v , EddyDiff::Q_v, EddyDiff::Q_v , + EddyDiff::Q_v , EddyDiff::Q_v, EddyDiff::Q_v }; // Device vectors Gpu::AsyncVector alpha_eff_d; @@ -789,7 +790,7 @@ DiffusionSrcForState_T (const Box& bx, const Box& domain, // The surface heat flux hfx_z(i,j,-1) is updated in MOSTStress at // each RK stage if using the ERF_EXPLICIT_MOST_STRESS path, but that // does not change the buoyancy production term here. - if (l_use_deardorff && start_comp <= RhoKE_comp && end_comp >=RhoKE_comp) { + if (l_use_ddorf && (start_comp <= RhoKE_comp) && (end_comp >= RhoKE_comp)) { int qty_index = RhoKE_comp; ParallelFor(bx,[=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { @@ -818,8 +819,8 @@ DiffusionSrcForState_T (const Box& bx, const Box& domain, } // Using PBL - if (l_use_QKE && start_comp <= RhoQKE_comp && end_comp >=RhoQKE_comp) { - int qty_index = RhoQKE_comp; + if (l_use_mynn && start_comp <= RhoKE_comp && end_comp >=RhoKE_comp) { + int qty_index = RhoKE_comp; auto pbl_mynn_B1_l = turbChoice.pbl_mynn.B1; const int rhoqv_comp = solverChoice.RhoQv_comp; @@ -834,7 +835,6 @@ DiffusionSrcForState_T (const Box& bx, const Box& domain, bool v_ext_dir_on_zlo = ( (bc_ptr[BCVars::yvel_bc].lo(2) == ERFBCType::ext_dir) ); bool v_ext_dir_on_zhi = ( (bc_ptr[BCVars::yvel_bc].lo(5) == ERFBCType::ext_dir) ); - const Real met_h_zeta = detJ(i,j,k); // This computes shear production, buoyancy production, and dissipation terms only. cell_rhs(i, j, k, qty_index) += ComputeQKESourceTerms(i,j,k,u,v,cell_data,cell_prim, mu_turb,cellSizeInv,domain, @@ -843,7 +843,7 @@ DiffusionSrcForState_T (const Box& bx, const Box& domain, c_ext_dir_on_zlo, c_ext_dir_on_zhi, u_ext_dir_on_zlo, u_ext_dir_on_zhi, v_ext_dir_on_zlo, v_ext_dir_on_zhi, - use_most, met_h_zeta); + use_most); }); } } diff --git a/Source/Diffusion/ERF_EddyViscosity.H b/Source/Diffusion/ERF_EddyViscosity.H index cc47191dc..a6f2cd317 100644 --- a/Source/Diffusion/ERF_EddyViscosity.H +++ b/Source/Diffusion/ERF_EddyViscosity.H @@ -39,12 +39,6 @@ ComputeSmnSmn (int& i, int& j, int& k, const bool& use_most, const bool& exp_most) { - amrex::Real s11bar = tau11(i,j,k); - amrex::Real s22bar = tau22(i,j,k); - amrex::Real s33bar = tau33(i,j,k); - amrex::Real s12bar = 0.25 * ( tau12(i , j , k ) + tau12(i , j+1, k ) - + tau12(i+1, j , k ) + tau12(i+1, j+1, k ) ); - // NOTES: // - If ERF_EXPLICIT_MOST_STRESS is not used, then we do not use the // strains lying on the bottom boundary with MOST. These values are @@ -76,6 +70,12 @@ ComputeSmnSmn (int& i, int& j, int& k, + tau23(i , j+1, k ) + tau23(i , j+1, k+1) ); } + amrex::Real s11bar = tau11(i,j,k); + amrex::Real s22bar = tau22(i,j,k); + amrex::Real s33bar = tau33(i,j,k); + amrex::Real s12bar = 0.25 * ( tau12(i , j , k ) + tau12(i , j+1, k ) + + tau12(i+1, j , k ) + tau12(i+1, j+1, k ) ); + amrex::Real SmnSmn = s11bar*s11bar + s22bar*s22bar + s33bar*s33bar + 2.0*s12bar*s12bar + 2.0*s13bar*s13bar + 2.0*s23bar*s23bar; diff --git a/Source/ERF.H b/Source/ERF.H index b2184c884..f5b74e630 100644 --- a/Source/ERF.H +++ b/Source/ERF.H @@ -895,12 +895,12 @@ private: amrex::Vector plot_var_names_1; amrex::Vector plot_var_names_2; - const amrex::Vector cons_names {"density", "rhotheta", "rhoKE", "rhoQKE", "rhoadv_0", + const amrex::Vector cons_names {"density", "rhotheta", "rhoKE", "rhoadv_0", "rhoQ1", "rhoQ2", "rhoQ3", "rhoQ4", "rhoQ5", "rhoQ6"}; // Note that the order of variable names here must match the order in ERF_Derive.cpp - const amrex::Vector derived_names {"soundspeed", "temp", "theta", "KE", "QKE", "scalar", + const amrex::Vector derived_names {"soundspeed", "temp", "theta", "KE", "scalar", "vorticity_x","vorticity_y","vorticity_z", "magvel", "divU", "pres_hse", "dens_hse", "pressure", "pert_pres", "pert_dens", @@ -914,7 +914,7 @@ private: // eddy diffusivity of heat "Khv","Khh", // mynn pbl lengthscale - "Lpbl", + "Lturb", // moisture vars "qt", "qv", "qc", "qi", "qp", "qrain", "qsnow", "qgraup", "qsat", "rain_accum", "snow_accum", "graup_accum" diff --git a/Source/ERF.cpp b/Source/ERF.cpp index 10bbaf566..1c81680fb 100644 --- a/Source/ERF.cpp +++ b/Source/ERF.cpp @@ -676,24 +676,6 @@ ERF::InitData_post () } // lev } - Real QKE_0; - if (pp.query("QKE_0", QKE_0)) { - Print() << "Initializing uniform QKE=" << QKE_0 << std::endl; - for (int lev = 0; lev <= finest_level; lev++) { - auto& lev_new = vars_new[lev]; - for (MFIter mfi(lev_new[Vars::cons], TilingIfNotGPU()); mfi.isValid(); ++mfi) { - const Box &bx = mfi.tilebox(); - const auto &cons_arr = lev_new[Vars::cons].array(mfi); - // We want to set the lateral BC values, too - Box gbx = bx; // Copy constructor - gbx.grow(0,1); gbx.grow(1,1); // Grow by one in the lateral directions - ParallelFor(gbx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - cons_arr(i,j,k,RhoQKE_comp) = cons_arr(i,j,k,Rho_comp) * QKE_0; - }); - } // mfi - } - } - if (solverChoice.coupling_type == CouplingType::TwoWay) { AverageDown(); } diff --git a/Source/ERF_Derive.H b/Source/ERF_Derive.H index 0090ef07b..7eb56aa5c 100644 --- a/Source/ERF_Derive.H +++ b/Source/ERF_Derive.H @@ -89,17 +89,6 @@ void erf_derKE ( const int* bcrec, const int level); -void erf_derQKE ( - const amrex::Box& bx, - amrex::FArrayBox& derfab, - int dcomp, - int ncomp, - const amrex::FArrayBox& datfab, - const amrex::Geometry& geomdata, - amrex::Real time, - const int* bcrec, - const int level); - void erf_dervortx ( const amrex::Box& bx, amrex::FArrayBox& derfab, diff --git a/Source/ERF_Derive.cpp b/Source/ERF_Derive.cpp index 75ff631ba..33fa8f118 100644 --- a/Source/ERF_Derive.cpp +++ b/Source/ERF_Derive.cpp @@ -196,27 +196,6 @@ erf_derKE (const Box& bx, erf_derrhodivide(bx, derfab, datfab, RhoKE_comp); } -/** - * Function to define QKE by dividing (rho QKE) by rho - * - * @params[in] bx box on which to divide by density - * @params[out] derfab array of derived quantity -- here it holds QKE - * @params[in] datfab array of data used to construct derived quantity -*/ -void -erf_derQKE (const Box& bx, - FArrayBox& derfab, - int /*dcomp*/, - int /*ncomp*/, - const FArrayBox& datfab, - const Geometry& /*geomdata*/, - Real /*time*/, - const int* /*bcrec*/, - const int /*level*/) -{ - erf_derrhodivide(bx, derfab, datfab, RhoQKE_comp); -} - void erf_dervortx ( const amrex::Box& bx, diff --git a/Source/ERF_IndexDefines.H b/Source/ERF_IndexDefines.H index f7728d1bc..d0eb364d9 100644 --- a/Source/ERF_IndexDefines.H +++ b/Source/ERF_IndexDefines.H @@ -9,8 +9,8 @@ */ // This defines the ACTUAL number of non-moisture vars = -// rho, rhotheta, rhoKE, rhoQKE -#define NDRY 4 +// rho, rhotheta, rhoKE +#define NDRY 3 // This defines the ACTUAL number of non-moisture scalar vars #define NSCALARS 1 @@ -35,10 +35,9 @@ // Cell-centered state variables #define Rho_comp 0 #define RhoTheta_comp (Rho_comp+1) -#define RhoKE_comp (Rho_comp+2) // for Deardorff LES Model -#define RhoQKE_comp (Rho_comp+3) // for MYNN or YSU PBL Model +#define RhoKE_comp (Rho_comp+2) // for Deardorff LES Model or MYNN PBL Model -#define RhoScalar_comp (RhoQKE_comp+1) +#define RhoScalar_comp (RhoKE_comp+1) #define RhoQ1_comp (RhoScalar_comp+NSCALARS) #define RhoQ2_comp (RhoQ1_comp+1) @@ -50,7 +49,6 @@ // Cell-centered primitive variables #define PrimTheta_comp (RhoTheta_comp -1) #define PrimKE_comp (RhoKE_comp -1) -#define PrimQKE_comp (RhoQKE_comp -1) #define PrimScalar_comp (RhoScalar_comp-1) #define PrimQ1_comp (RhoQ1_comp-1) #define PrimQ2_comp (RhoQ2_comp-1) @@ -79,7 +77,6 @@ namespace BCVars { Rho_bc_comp = 0, RhoTheta_bc_comp, RhoKE_bc_comp, - RhoQKE_bc_comp, RhoScalar_bc_comp, RhoQ1_bc_comp, RhoQ2_bc_comp, @@ -154,16 +151,14 @@ namespace EddyDiff { Mom_h = 0, Theta_h, KE_h, - QKE_h, Scalar_h, Q_h, Mom_v, Theta_v, KE_v, - QKE_v, Scalar_v, Q_v, - PBL_lengthscale, + Turb_lengthscale, NumDiffs }; } diff --git a/Source/ERF_make_new_arrays.cpp b/Source/ERF_make_new_arrays.cpp index f03c789f1..39c89acf5 100644 --- a/Source/ERF_make_new_arrays.cpp +++ b/Source/ERF_make_new_arrays.cpp @@ -362,7 +362,7 @@ ERF::update_diffusive_arrays (int lev, const BoxArray& ba, const DistributionMap (solverChoice.turbChoice[lev].pbl_type != PBLType::None) ); bool l_use_kturb = ( (solverChoice.turbChoice[lev].les_type != LESType::None) || (solverChoice.turbChoice[lev].pbl_type != PBLType::None) ); - bool l_use_ddorf = ( solverChoice.turbChoice[lev].les_type == LESType::Deardorff); + bool l_use_ddorf = (solverChoice.turbChoice[lev].les_type == LESType::Deardorff); bool l_use_moist = ( solverChoice.moisture_type != MoistureType::None ); BoxArray ba12 = convert(ba, IntVect(1,1,0)); diff --git a/Source/IO/ERF_Checkpoint.cpp b/Source/IO/ERF_Checkpoint.cpp index 92b8b6438..af211bf22 100644 --- a/Source/IO/ERF_Checkpoint.cpp +++ b/Source/IO/ERF_Checkpoint.cpp @@ -147,7 +147,7 @@ ERF::WriteCheckpointFile () const if (solverChoice.use_terrain) { // Note that we also write the ghost cells of z_phys_nd - IntVect ng = z_phys_nd[lev]->nGrowVect(); + ng = z_phys_nd[lev]->nGrowVect(); MultiFab z_height(convert(grids[lev],IntVect(1,1,1)),dmap[lev],1,ng); MultiFab::Copy(z_height,*z_phys_nd[lev],0,0,1,ng); VisMF::Write(z_height, MultiFabFileFullPrefix(lev, checkpointname, "Level_", "Z_Phys_nd")); @@ -161,7 +161,7 @@ ERF::WriteCheckpointFile () const int qmoist_nvar = qmoist_indices.size(); for (int var = 0; var < qmoist_nvar; var++) { ng = qmoist[lev][qmoist_indices[var]]->nGrowVect(); - const int ncomp = 1; + ncomp = 1; MultiFab moist_vars(grids[lev],dmap[lev],ncomp,ng); MultiFab::Copy(moist_vars,*(qmoist[lev][qmoist_indices[var]]),0,0,ncomp,ng); VisMF::Write(moist_vars, amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", qmoist_names[var])); @@ -362,15 +362,38 @@ ERF::ReadCheckpointFile () // ncomp is only valid after we MakeNewLevelFromScratch (asks micro how many vars) // NOTE: Data is written over ncomp, so check that we match the header file int ncomp_cons = vars_new[0][Vars::cons].nComp(); - AMREX_ASSERT(chk_ncomp_cons == ncomp_cons); + + // NOTE: QKE was removed so this is for backward compatibility + AMREX_ASSERT((chk_ncomp_cons==ncomp_cons) || ((chk_ncomp_cons-1)==ncomp_cons)); // read in the MultiFab data for (int lev = 0; lev <= finest_level; ++lev) { - MultiFab cons(grids[lev],dmap[lev],ncomp_cons,0); - VisMF::Read(cons, MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "Cell")); - MultiFab::Copy(vars_new[lev][Vars::cons],cons,0,0,ncomp_cons,0); - vars_new[lev][Vars::cons].setBndry(1.0e34); + // NOTE: For backward compatibility (chk file has QKE) + if ((chk_ncomp_cons-1)==ncomp_cons) { + MultiFab cons(grids[lev],dmap[lev],chk_ncomp_cons,0); + VisMF::Read(cons, MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "Cell")); + + // Copy up to RhoKE_comp + MultiFab::Copy(vars_new[lev][Vars::cons],cons,0,0,(RhoKE_comp+1),0); + + // Only if we have a PBL model do we need to copy QKE is src to KE in dst + if (solverChoice.turbChoice[lev].pbl_type == PBLType::MYNN25) { + MultiFab::Copy(vars_new[lev][Vars::cons],cons,(RhoKE_comp+1),RhoKE_comp,1,0); + vars_new[lev][Vars::cons].mult(0.5,RhoKE_comp,1,0); + } + + // Copy other components + int ncomp_remainder = ncomp_cons - (RhoKE_comp + 1); + MultiFab::Copy(vars_new[lev][Vars::cons],cons,(RhoKE_comp+2),(RhoKE_comp+1),ncomp_remainder,0); + + vars_new[lev][Vars::cons].setBndry(1.0e34); + } else { + MultiFab cons(grids[lev],dmap[lev],ncomp_cons,0); + VisMF::Read(cons, MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "Cell")); + MultiFab::Copy(vars_new[lev][Vars::cons],cons,0,0,ncomp_cons,0); + vars_new[lev][Vars::cons].setBndry(1.0e34); + } MultiFab xvel(convert(grids[lev],IntVect(1,0,0)),dmap[lev],1,0); VisMF::Read(xvel, MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "XFace")); @@ -433,7 +456,7 @@ ERF::ReadCheckpointFile () int qmoist_nvar = qmoist_indices.size(); for (int var = 0; var < qmoist_nvar; var++) { ng = qmoist[lev][qmoist_indices[var]]->nGrowVect(); - const int ncomp = 1; + ncomp = 1; MultiFab moist_vars(grids[lev],dmap[lev],ncomp,ng); VisMF::Read(moist_vars, amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", qmoist_names[var])); MultiFab::Copy(*(qmoist[lev][qmoist_indices[var]]),moist_vars,0,0,ncomp,ng); diff --git a/Source/IO/ERF_Plotfile.cpp b/Source/IO/ERF_Plotfile.cpp index 00350a865..ad08b384c 100644 --- a/Source/IO/ERF_Plotfile.cpp +++ b/Source/IO/ERF_Plotfile.cpp @@ -337,7 +337,6 @@ ERF::WritePlotFile (int which, PlotFileType plotfile_type, Vector p } calculate_derived("theta", vars_new[lev][Vars::cons], derived::erf_dertheta); calculate_derived("KE", vars_new[lev][Vars::cons], derived::erf_derKE); - calculate_derived("QKE", vars_new[lev][Vars::cons], derived::erf_derQKE); calculate_derived("scalar", vars_new[lev][Vars::cons], derived::erf_derscalar); calculate_derived("vorticity_x", mf_cc_vel[lev] , derived::erf_dervortx); calculate_derived("vorticity_y", mf_cc_vel[lev] , derived::erf_dervorty); @@ -978,8 +977,8 @@ ERF::WritePlotFile (int which, PlotFileType plotfile_type, Vector p MultiFab::Copy(mf[lev],*eddyDiffs_lev[lev],EddyDiff::Theta_h,mf_comp,1,0); mf_comp ++; } - if (containerHasElement(plot_var_names, "Lpbl")) { - MultiFab::Copy(mf[lev],*eddyDiffs_lev[lev],EddyDiff::PBL_lengthscale,mf_comp,1,0); + if (containerHasElement(plot_var_names, "Lturb")) { + MultiFab::Copy(mf[lev],*eddyDiffs_lev[lev],EddyDiff::Turb_lengthscale,mf_comp,1,0); mf_comp ++; } diff --git a/Source/IO/ERF_ReadBndryPlanes.H b/Source/IO/ERF_ReadBndryPlanes.H index 8435daedc..e6dd27e5e 100644 --- a/Source/IO/ERF_ReadBndryPlanes.H +++ b/Source/IO/ERF_ReadBndryPlanes.H @@ -45,7 +45,6 @@ public: [[nodiscard]] int ingested_q1() const {return is_q1_read;} [[nodiscard]] int ingested_q2() const {return is_q2_read;} [[nodiscard]] int ingested_KE() const {return is_KE_read;} - [[nodiscard]] int ingested_QKE() const {return is_QKE_read;} private: @@ -101,7 +100,6 @@ private: int is_q1_read; int is_q2_read; int is_KE_read; - int is_QKE_read; int last_file_read; }; diff --git a/Source/IO/ERF_ReadBndryPlanes.cpp b/Source/IO/ERF_ReadBndryPlanes.cpp index b95710f38..fff5d425c 100644 --- a/Source/IO/ERF_ReadBndryPlanes.cpp +++ b/Source/IO/ERF_ReadBndryPlanes.cpp @@ -159,7 +159,6 @@ ReadBndryPlanes::ReadBndryPlanes (const Geometry& geom, const Real& rdOcp_in) is_q1_read = 0; is_q2_read = 0; is_KE_read = 0; - is_QKE_read = 0; if (pp.contains("bndry_input_var_names")) { @@ -175,7 +174,6 @@ ReadBndryPlanes::ReadBndryPlanes (const Geometry& geom, const Real& rdOcp_in) if (m_var_names[i] == "qv") is_q1_read = 1; if (m_var_names[i] == "qc") is_q2_read = 1; if (m_var_names[i] == "ke") is_KE_read = 1; - if (m_var_names[i] == "qke") is_QKE_read = 1; } } @@ -415,7 +413,6 @@ void ReadBndryPlanes::read_file (const int idx, if (var_name == "theta") n_offset = BCVars::RhoTheta_bc_comp; if (var_name == "temperature") n_offset = BCVars::RhoTheta_bc_comp; if (var_name == "ke") n_offset = BCVars::RhoKE_bc_comp; - if (var_name == "qke") n_offset = BCVars::RhoQKE_bc_comp; if (var_name == "scalar") n_offset = BCVars::RhoScalar_bc_comp; if (var_name == "qv") n_offset = BCVars::RhoQ1_bc_comp; if (var_name == "qc") n_offset = BCVars::RhoQ2_bc_comp; @@ -480,7 +477,7 @@ void ReadBndryPlanes::read_file (const int idx, bndry_mf_arr(i, j, k, 0) = 0.5 * (R1*Th1 + R2*Th2); }); } else if (var_name == "scalar" || var_name == "qv" || var_name == "qc" || - var_name == "ke" || var_name == "qke") { + var_name == "ke") { ParallelFor( bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { Real R1 = bndry_read_r_arr(i, j, k, 0); @@ -510,7 +507,7 @@ void ReadBndryPlanes::read_file (const int idx, bndry_mf_arr(i, j, k, 0) = 0.5 * (R1*Th1 + R2*Th2); }); } else if (var_name == "scalar" || var_name == "qv" || var_name == "qc" || - var_name == "ke" || var_name == "qke") { + var_name == "ke") { ParallelFor( bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { Real R1 = l_bc_extdir_vals_d[BCVars::Rho_bc_comp][ori]; diff --git a/Source/IO/ERF_Write1DProfiles.cpp b/Source/IO/ERF_Write1DProfiles.cpp index 94d560404..d49d10567 100644 --- a/Source/IO/ERF_Write1DProfiles.cpp +++ b/Source/IO/ERF_Write1DProfiles.cpp @@ -210,8 +210,8 @@ ERF::derive_diag_profiles(Real /*time*/, bool l_use_kturb = ((solverChoice.turbChoice[lev].les_type != LESType::None) || (solverChoice.turbChoice[lev].pbl_type != PBLType::None)); - bool l_use_KE = (solverChoice.turbChoice[lev].les_type == LESType::Deardorff); - bool l_use_QKE = solverChoice.turbChoice[lev].use_QKE; + bool l_use_KE = ( (solverChoice.turbChoice[lev].les_type == LESType::Deardorff) || + (solverChoice.turbChoice[lev].pbl_type == PBLType::MYNN25) ); // This will hold rho, theta, ksgs, Kmh, Kmv, uu, uv, uw, vv, vw, ww, uth, vth, wth, // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 @@ -287,8 +287,6 @@ ERF::derive_diag_profiles(Real /*time*/, Real ksgs = 0.0; if (l_use_KE) { ksgs = cons_arr(i,j,k,RhoKE_comp) / cons_arr(i,j,k,Rho_comp); - } else if (l_use_QKE) { - ksgs = cons_arr(i,j,k,RhoQKE_comp) / cons_arr(i,j,k,Rho_comp); } fab_arr(i, j, k, 2) = ksgs; #if 1 diff --git a/Source/IO/ERF_Write1DProfiles_stag.cpp b/Source/IO/ERF_Write1DProfiles_stag.cpp index 1e6d1c37f..da0611202 100644 --- a/Source/IO/ERF_Write1DProfiles_stag.cpp +++ b/Source/IO/ERF_Write1DProfiles_stag.cpp @@ -316,8 +316,8 @@ ERF::derive_diag_profiles_stag (Real /*time*/, bool l_use_kturb = ((solverChoice.turbChoice[lev].les_type != LESType::None) || (solverChoice.turbChoice[lev].pbl_type != PBLType::None)); - bool l_use_KE = (solverChoice.turbChoice[lev].les_type == LESType::Deardorff); - bool l_use_QKE = solverChoice.turbChoice[lev].use_QKE; + bool l_use_KE = ( (solverChoice.turbChoice[lev].les_type == LESType::Deardorff) || + (solverChoice.turbChoice[lev].pbl_type == PBLType::MYNN25) ); // Note: "uiui" == u_i*u_i = u*u + v*v + w*w // This will hold rho, theta, ksgs, Kmh, Kmv, uu, uv, vv, uth, vth, @@ -375,8 +375,6 @@ ERF::derive_diag_profiles_stag (Real /*time*/, Real ksgs = 0.0; if (l_use_KE) { ksgs = cons_arr(i,j,k,RhoKE_comp) / cons_arr(i,j,k,Rho_comp); - } else if (l_use_QKE) { - ksgs = cons_arr(i,j,k,RhoQKE_comp) / cons_arr(i,j,k,Rho_comp); } fab_arr(i, j, k, 2) = ksgs; if (l_use_kturb) { diff --git a/Source/IO/ERF_WriteBndryPlanes.cpp b/Source/IO/ERF_WriteBndryPlanes.cpp index 5ddc4c458..def6541e5 100644 --- a/Source/IO/ERF_WriteBndryPlanes.cpp +++ b/Source/IO/ERF_WriteBndryPlanes.cpp @@ -196,17 +196,6 @@ void WriteBndryPlanes::write_planes (const int t_step, const Real time, derived::erf_derrhodivide(bx, Temp[mfi], S[mfi], RhoKE_comp); } bndry.copyFrom(Temp, nghost, 0, 0, ncomp, m_geom[bndry_lev].periodicity()); - - } else if (var_name == "qke") { - - MultiFab Temp(S.boxArray(),S.DistributionMap(),ncomp,0); - for (MFIter mfi(Temp, TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - const Box& bx = mfi.tilebox(); - derived::erf_derrhodivide(bx, Temp[mfi], S[mfi], RhoQKE_comp); - } - bndry.copyFrom(Temp, nghost, 0, 0, ncomp, m_geom[bndry_lev].periodicity()); - } else if (var_name == "qv") { if (S.nComp() > RhoQ2_comp) { MultiFab Temp(S.boxArray(),S.DistributionMap(),ncomp,0); diff --git a/Source/Initialization/ERF_init1d.cpp b/Source/Initialization/ERF_init1d.cpp index 1853ad522..1f6bc28f5 100644 --- a/Source/Initialization/ERF_init1d.cpp +++ b/Source/Initialization/ERF_init1d.cpp @@ -262,59 +262,66 @@ ERF::erf_enforce_hse (int lev, } }); + bool is_periodic_in_x = geom[lev].isPeriodic(0); + bool is_periodic_in_y = geom[lev].isPeriodic(1); + int domlo_x = domain.smallEnd(0); int domhi_x = domain.bigEnd(0); int domlo_y = domain.smallEnd(1); int domhi_y = domain.bigEnd(1); - if (pres[mfi].box().smallEnd(0) < domlo_x) - { - Box bx = mfi.nodaltilebox(2); - int ng = ngvect[0]; - bx.setSmall(0,domlo_x-1); - bx.setBig(0,domlo_x-ng); - ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) { - pres_arr(i,j,k) = pres_arr(domlo_x,j,k); - pi_arr(i,j,k) = pi_arr(domlo_x,j,k); - th_arr(i,j,k) = th_arr(domlo_x,j,k); - }); + if (!is_periodic_in_x) { + if (pres[mfi].box().smallEnd(0) < domlo_x) { + Box bx = mfi.nodaltilebox(2); + int ng = ngvect[0]; + bx.setSmall(0,domlo_x-1); + bx.setBig(0,domlo_x-ng); + ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + pres_arr(i,j,k) = pres_arr(domlo_x,j,k); + pi_arr(i,j,k) = pi_arr(domlo_x,j,k); + th_arr(i,j,k) = th_arr(domlo_x,j,k); + }); } - if (pres[mfi].box().bigEnd(0) > domhi_x) - { - Box bx = mfi.nodaltilebox(2); - int ng = ngvect[0]; - bx.setSmall(0,domhi_x+1); - bx.setBig(0,domhi_x+ng); - ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) { - pres_arr(i,j,k) = pres_arr(domhi_x,j,k); - pi_arr(i,j,k) = pi_arr(domhi_x,j,k); - th_arr(i,j,k) = th_arr(domhi_x,j,k); - }); + if (pres[mfi].box().bigEnd(0) > domhi_x) { + Box bx = mfi.nodaltilebox(2); + int ng = ngvect[0]; + bx.setSmall(0,domhi_x+1); + bx.setBig(0,domhi_x+ng); + ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + pres_arr(i,j,k) = pres_arr(domhi_x,j,k); + pi_arr(i,j,k) = pi_arr(domhi_x,j,k); + th_arr(i,j,k) = th_arr(domhi_x,j,k); + }); + } } - if (pres[mfi].box().smallEnd(1) < domlo_y) - { - Box bx = mfi.nodaltilebox(2); - int ng = ngvect[1]; - bx.setSmall(1,domlo_y-ng); - bx.setBig(1,domlo_y-1); - ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) { - pres_arr(i,j,k) = pres_arr(i,domlo_y,k); - pi_arr(i,j,k) = pi_arr(i,domlo_y,k); - th_arr(i,j,k) = th_arr(i,domlo_y,k); - }); - } + if (!is_periodic_in_y) { + if (pres[mfi].box().smallEnd(1) < domlo_y) { + Box bx = mfi.nodaltilebox(2); + int ng = ngvect[1]; + bx.setSmall(1,domlo_y-ng); + bx.setBig(1,domlo_y-1); + ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + pres_arr(i,j,k) = pres_arr(i,domlo_y,k); + pi_arr(i,j,k) = pi_arr(i,domlo_y,k); + th_arr(i,j,k) = th_arr(i,domlo_y,k); + }); + } - if (pres[mfi].box().bigEnd(1) > domhi_y) - { - Box bx = mfi.nodaltilebox(2); - int ng = ngvect[1]; - bx.setSmall(1,domhi_y+1); - bx.setBig(1,domhi_y+ng); - ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) { - pres_arr(i,j,k) = pres_arr(i,domhi_y,k); - pi_arr(i,j,k) = pi_arr(i,domhi_y,k); - th_arr(i,j,k) = th_arr(i,domhi_y,k); - }); + if (pres[mfi].box().bigEnd(1) > domhi_y) { + Box bx = mfi.nodaltilebox(2); + int ng = ngvect[1]; + bx.setSmall(1,domhi_y+1); + bx.setBig(1,domhi_y+ng); + ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + pres_arr(i,j,k) = pres_arr(i,domhi_y,k); + pi_arr(i,j,k) = pi_arr(i,domhi_y,k); + th_arr(i,j,k) = th_arr(i,domhi_y,k); + }); + } } } diff --git a/Source/Initialization/ERF_init_bcs.cpp b/Source/Initialization/ERF_init_bcs.cpp index f4e05cfdb..4f99b069b 100644 --- a/Source/Initialization/ERF_init_bcs.cpp +++ b/Source/Initialization/ERF_init_bcs.cpp @@ -30,7 +30,6 @@ void ERF::init_bcs () m_bc_extdir_vals[BCVars::RhoTheta_bc_comp][ori] = -1.0; // It is important to set this negative // because the sign is tested on below m_bc_extdir_vals[BCVars::RhoKE_bc_comp][ori] = 0.0; - m_bc_extdir_vals[BCVars::RhoQKE_bc_comp][ori] = 0.0; m_bc_extdir_vals[BCVars::RhoScalar_bc_comp][ori] = 0.0; m_bc_extdir_vals[BCVars::RhoQ1_bc_comp][ori] = 0.0; m_bc_extdir_vals[BCVars::RhoQ2_bc_comp][ori] = 0.0; @@ -48,7 +47,6 @@ void ERF::init_bcs () m_bc_neumann_vals[BCVars::RhoTheta_bc_comp][ori] = 0.0; m_bc_neumann_vals[BCVars::RhoKE_bc_comp][ori] = 0.0; - m_bc_neumann_vals[BCVars::RhoQKE_bc_comp][ori] = 0.0; m_bc_neumann_vals[BCVars::RhoScalar_bc_comp][ori] = 0.0; m_bc_neumann_vals[BCVars::RhoQ1_bc_comp][ori] = 0.0; m_bc_neumann_vals[BCVars::RhoQ2_bc_comp][ori] = 0.0; @@ -172,14 +170,6 @@ void ERF::init_bcs () if (pp.query("KE", KE_in)) m_bc_extdir_vals[BCVars::RhoKE_bc_comp][ori] = rho_in*KE_in; } - Real QKE_in = 0.; - if (input_bndry_planes && m_r2d->ingested_QKE()) { - m_bc_extdir_vals[BCVars::RhoQKE_bc_comp][ori] = 0.; - } else { - if (pp.query("QKE", QKE_in)) - m_bc_extdir_vals[BCVars::RhoQKE_bc_comp][ori] = rho_in*QKE_in; - } - } else if (bc_type == "noslipwall") { @@ -550,7 +540,6 @@ void ERF::init_bcs () ( (BCVars::cons_bc+i == BCVars::Rho_bc_comp) && m_r2d->ingested_density()) || ( (BCVars::cons_bc+i == BCVars::RhoTheta_bc_comp) && m_r2d->ingested_theta() ) || ( (BCVars::cons_bc+i == BCVars::RhoKE_bc_comp) && m_r2d->ingested_KE() ) || - ( (BCVars::cons_bc+i == BCVars::RhoQKE_bc_comp) && m_r2d->ingested_QKE() ) || ( (BCVars::cons_bc+i == BCVars::RhoScalar_bc_comp) && m_r2d->ingested_scalar() ) || ( (BCVars::cons_bc+i == BCVars::RhoQ1_bc_comp) && m_r2d->ingested_q1() ) || ( (BCVars::cons_bc+i == BCVars::RhoQ2_bc_comp) && m_r2d->ingested_q2() )) ) @@ -568,7 +557,6 @@ void ERF::init_bcs () ( (BCVars::cons_bc+i == BCVars::Rho_bc_comp) && m_r2d->ingested_density()) || ( (BCVars::cons_bc+i == BCVars::RhoTheta_bc_comp) && m_r2d->ingested_theta() ) || ( (BCVars::cons_bc+i == BCVars::RhoKE_bc_comp) && m_r2d->ingested_KE() ) || - ( (BCVars::cons_bc+i == BCVars::RhoQKE_bc_comp) && m_r2d->ingested_QKE() ) || ( (BCVars::cons_bc+i == BCVars::RhoScalar_bc_comp) && m_r2d->ingested_scalar() ) || ( (BCVars::cons_bc+i == BCVars::RhoQ1_bc_comp) && m_r2d->ingested_q1() ) || ( (BCVars::cons_bc+i == BCVars::RhoQ2_bc_comp) && m_r2d->ingested_q2() ) diff --git a/Source/Initialization/ERF_init_custom.cpp b/Source/Initialization/ERF_init_custom.cpp index 4fcbc9104..596135530 100644 --- a/Source/Initialization/ERF_init_custom.cpp +++ b/Source/Initialization/ERF_init_custom.cpp @@ -89,18 +89,12 @@ ERF::init_custom (int lev) MultiFab::Add(lev_new[Vars::cons], cons_pert, RhoTheta_comp, RhoTheta_comp, 1, cons_pert.nGrow()); MultiFab::Add(lev_new[Vars::cons], cons_pert, RhoScalar_comp,RhoScalar_comp,NSCALARS, cons_pert.nGrow()); - // RhoKE is only relevant if using Deardorff with LES - if (solverChoice.turbChoice[lev].les_type == LESType::Deardorff) { + // RhoKE is only relevant if using Deardorff with LES or MYNN with PBL + if ((solverChoice.turbChoice[lev].les_type == LESType::Deardorff) || + (solverChoice.turbChoice[lev].pbl_type == PBLType::MYNN25)) { MultiFab::Add(lev_new[Vars::cons], cons_pert, RhoKE_comp, RhoKE_comp, 1, cons_pert.nGrow()); } - // RhoQKE is only relevant if using MYNN2.5 - if (solverChoice.turbChoice[lev].pbl_type != PBLType::MYNN25) { - lev_new[Vars::cons].setVal(0.0,RhoQKE_comp,1); - } else { - MultiFab::Add(lev_new[Vars::cons], cons_pert, RhoQKE_comp, RhoQKE_comp, 1, cons_pert.nGrow()); - } - if (solverChoice.moisture_type != MoistureType::None) { int qstate_size = micro->Get_Qstate_Size(); MultiFab::Add(lev_new[Vars::cons], cons_pert, RhoQ1_comp, RhoQ1_comp, 1, cons_pert.nGrow()); diff --git a/Source/PBL/ERF_ComputeDiffusivityMYNN25.cpp b/Source/PBL/ERF_ComputeDiffusivityMYNN25.cpp index 3faf0dc0f..f1608f078 100644 --- a/Source/PBL/ERF_ComputeDiffusivityMYNN25.cpp +++ b/Source/PBL/ERF_ComputeDiffusivityMYNN25.cpp @@ -48,10 +48,10 @@ ComputeDiffusivityMYNN25 (const MultiFab& xvel, for ( MFIter mfi(eddyViscosity,TilingIfNotGPU()); mfi.isValid(); ++mfi) { const Box &bx = mfi.growntilebox(1); - const Array4 &cell_data = cons_in.array(mfi); - const Array4 &K_turb = eddyViscosity.array(mfi); - const Array4 &uvel = xvel.array(mfi); - const Array4 &vvel = yvel.array(mfi); + const Array4& cell_data = cons_in.array(mfi); + const Array4& K_turb = eddyViscosity.array(mfi); + const Array4& uvel = xvel.array(mfi); + const Array4& vvel = yvel.array(mfi); // Compute some quantities that are constant in each column // Sbox is shrunk to only include the interior of the domain in the vertical direction to compute integrals @@ -76,20 +76,20 @@ ComputeDiffusivityMYNN25 (const MultiFab& xvel, const auto invCellSize = geom.InvCellSizeArray(); ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - qvel(i,j,k) = std::sqrt(cell_data(i,j,k,RhoQKE_comp) / cell_data(i,j,k,Rho_comp)); - AMREX_ASSERT_WITH_MESSAGE(qvel(i,j,k) > 0.0, "QKE must have a positive value"); + qvel(i,j,k) = std::sqrt(2.0 * cell_data(i,j,k,RhoKE_comp) / cell_data(i,j,k,Rho_comp)); + AMREX_ASSERT_WITH_MESSAGE(qvel(i,j,k) > 0.0, "KE must have a positive value"); Real fac = (sbx.contains(i,j,k)) ? 1.0 : 0.0; const Real Zval = Compute_Zrel_AtCellCenter(i,j,k,z_nd_arr); - const Real dz = Compute_h_zeta_AtCellCenter(i,j,k,invCellSize,z_nd_arr); + const Real dz = Compute_h_zeta_AtCellCenter(i,j,k,invCellSize,z_nd_arr); Gpu::Atomic::Add(&qint(i,j,0,0), Zval*qvel(i,j,k)*dz*fac); Gpu::Atomic::Add(&qint(i,j,0,1), qvel(i,j,k)*dz*fac); }); } else { ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - qvel(i,j,k) = std::sqrt(cell_data(i,j,k,RhoQKE_comp) / cell_data(i,j,k,Rho_comp)); - AMREX_ASSERT_WITH_MESSAGE(qvel(i,j,k) > 0.0, "QKE must have a positive value"); + qvel(i,j,k) = std::sqrt(2.0 * cell_data(i,j,k,RhoKE_comp) / cell_data(i,j,k,Rho_comp)); + AMREX_ASSERT_WITH_MESSAGE(qvel(i,j,k) > 0.0, "KE must have a positive value"); // Not multiplying by dz: its constant and would fall out when we divide qint0/qint1 anyway @@ -237,7 +237,7 @@ ComputeDiffusivityMYNN25 (const MultiFab& xvel, const Real rho = cell_data(i,j,k,Rho_comp); K_turb(i,j,k,EddyDiff::Mom_v) = rho * Lm * qvel(i,j,k) * SM; K_turb(i,j,k,EddyDiff::Theta_v) = rho * Lm * qvel(i,j,k) * SH; - K_turb(i,j,k,EddyDiff::QKE_v) = rho * Lm * qvel(i,j,k) * SQ; + K_turb(i,j,k,EddyDiff::KE_v) = rho * Lm * qvel(i,j,k) * SQ; // TODO: implement partial-condensation scheme? // Currently, implementation matches NN09 without rain (i.e., @@ -250,7 +250,7 @@ ComputeDiffusivityMYNN25 (const MultiFab& xvel, K_turb(i,j,k,EddyDiff::Q_v) = rho * Lm * qvel(i,j,k) * SH; } - K_turb(i,j,k,EddyDiff::PBL_lengthscale) = Lm; + K_turb(i,j,k,EddyDiff::Turb_lengthscale) = Lm; }); } } diff --git a/Source/PBL/ERF_ComputeDiffusivityYSU.cpp b/Source/PBL/ERF_ComputeDiffusivityYSU.cpp index 92503e5f7..f197fdf33 100644 --- a/Source/PBL/ERF_ComputeDiffusivityYSU.cpp +++ b/Source/PBL/ERF_ComputeDiffusivityYSU.cpp @@ -238,7 +238,7 @@ ComputeDiffusivityYSU (const MultiFab& xvel, const Real rhoKmax = rho * Kmax; K_turb(i,j,k,EddyDiff::Mom_v) = std::max(std::min(K_turb(i,j,k,EddyDiff::Mom_v) ,rhoKmax), rhoKmin); K_turb(i,j,k,EddyDiff::Theta_v) = std::max(std::min(K_turb(i,j,k,EddyDiff::Theta_v) ,rhoKmax), rhoKmin); - K_turb(i,j,k,EddyDiff::PBL_lengthscale) = pblh_arr(i,j,0); + K_turb(i,j,k,EddyDiff::Turb_lengthscale) = pblh_arr(i,j,0); }); // HACK set bottom ghost cell to 1st cell diff --git a/Source/PBL/ERF_MYNNStruct.H b/Source/PBL/ERF_MYNNStruct.H index 15fbde688..8fce2c81c 100644 --- a/Source/PBL/ERF_MYNNStruct.H +++ b/Source/PBL/ERF_MYNNStruct.H @@ -10,7 +10,7 @@ struct MYNNLevel25 { /* * Calculate the stability functions that determine the eddy diffusivities - * of momentum, heat, QKE, and (optionally) moisture. + * of momentum, heat, KE, and (optionally) moisture. */ AMREX_GPU_DEVICE AMREX_FORCE_INLINE diff --git a/Source/PBL/ERF_PBLHeight.H b/Source/PBL/ERF_PBLHeight.H index 772ba6b05..1ca84631f 100644 --- a/Source/PBL/ERF_PBLHeight.H +++ b/Source/PBL/ERF_PBLHeight.H @@ -130,9 +130,9 @@ struct MYNNPBLH { // // Find PBL height based on TKE (for SBLs only) // - amrex::Real tke = 0.5 * cons_arr(i,j,k ,RhoQKE_comp) / cons_arr(i,j,k ,Rho_comp); - amrex::Real tke1 = 0.5 * cons_arr(i,j,k+1,RhoQKE_comp) / cons_arr(i,j,k+1,Rho_comp); - amrex::Real maxtke = 0.5 * cons_arr(i,j,0 ,RhoQKE_comp) / cons_arr(i,j,0 ,Rho_comp); + amrex::Real tke = cons_arr(i,j,k ,RhoKE_comp) / cons_arr(i,j,k ,Rho_comp); + amrex::Real tke1 = cons_arr(i,j,k+1,RhoKE_comp) / cons_arr(i,j,k+1,Rho_comp); + amrex::Real maxtke = cons_arr(i,j,0 ,RhoKE_comp) / cons_arr(i,j,0 ,Rho_comp); // - threshold is 5% of max TKE (Kosovic & Curry 2000, JAS) amrex::Real TKEeps = 0.05 * maxtke; TKEeps = amrex::max(TKEeps, 0.02); // min val from WRF @@ -142,7 +142,7 @@ struct MYNNPBLH { // Interpolate to get lowest height where TKE -> 0 pblh_tke_arr(i,j,0) = zphys_arr(ii,jj,k) + (zphys_arr(ii,jj,k+1)-zphys_arr(ii,jj,k))/(tke1-tke) - * (TKEeps - tke); + * (TKEeps - tke); } } }); @@ -202,9 +202,9 @@ struct MYNNPBLH { // // Find PBL height based on TKE (for SBLs only) // - amrex::Real tke = 0.5 * cons_arr(i,j,k ,RhoQKE_comp) / cons_arr(i,j,k ,Rho_comp); - amrex::Real tke1 = 0.5 * cons_arr(i,j,k+1,RhoQKE_comp) / cons_arr(i,j,k+1,Rho_comp); - amrex::Real maxtke = 0.5 * cons_arr(i,j,0 ,RhoQKE_comp) / cons_arr(i,j,0 ,Rho_comp); + amrex::Real tke = cons_arr(i,j,k ,RhoKE_comp) / cons_arr(i,j,k ,Rho_comp); + amrex::Real tke1 = cons_arr(i,j,k+1,RhoKE_comp) / cons_arr(i,j,k+1,Rho_comp); + amrex::Real maxtke = cons_arr(i,j,0 ,RhoKE_comp) / cons_arr(i,j,0 ,Rho_comp); // - threshold is 5% of max TKE (Kosovic & Curry 2000, JAS) amrex::Real TKEeps = 0.05 * maxtke; TKEeps = amrex::max(TKEeps, 0.02); // min val from WRF @@ -249,7 +249,7 @@ struct MYNNPBLH { // // Finally, blend between the two PBLH estimates // - amrex::Real maxqke = cons_arr(i,j,0 ,RhoQKE_comp) / cons_arr(i,j,0 ,Rho_comp); + amrex::Real maxqke = 2.0 * cons_arr(i,j,0 ,RhoKE_comp) / cons_arr(i,j,0 ,Rho_comp); if (maxqke > 0.05) { amrex::Real wt = 0.5*std::tanh((zi - sbl_lim)/sbl_damp) + 0.5; pblh_arr(i,j,0) = (1.-wt)*pblh_tke_arr(i,j,0) + wt*pblh_arr(i,j,0); diff --git a/Source/PBL/ERF_PBLModels.H b/Source/PBL/ERF_PBLModels.H index d2fdd9d3c..9c0ee5086 100644 --- a/Source/PBL/ERF_PBLModels.H +++ b/Source/PBL/ERF_PBLModels.H @@ -201,16 +201,16 @@ ComputeQKESourceTerms (int i, int j, int k, // DiffusionSrcForState_* is called from ERF_slow_rhs_post. // Shear Production - source_term += 2.0*K_turb(i,j,k,EddyDiff::Mom_v) * (dudz*dudz + dvdz*dvdz); + source_term += K_turb(i,j,k,EddyDiff::Mom_v) * (dudz*dudz + dvdz*dvdz); // Buoyancy Production - source_term -= 2.0*(CONST_GRAV/theta_mean)*K_turb(i,j,k,EddyDiff::Theta_v)*dthetadz; + source_term -= (CONST_GRAV/theta_mean)*K_turb(i,j,k,EddyDiff::Theta_v)*dthetadz; // Dissipation - amrex::Real qke = cell_prim(i,j,k,PrimQKE_comp); + amrex::Real qke = 2.0 * cell_prim(i,j,k,PrimKE_comp); if (std::abs(qke) > 0.0) { - source_term -= 2.0 * cell_data(i,j,k,Rho_comp) * std::pow(qke,1.5) / - (pbl_mynn_B1_l * K_turb(i,j,k,EddyDiff::PBL_lengthscale)); + source_term -= cell_data(i,j,k,Rho_comp) * std::pow(qke,1.5) / + (pbl_mynn_B1_l * K_turb(i,j,k,EddyDiff::Turb_lengthscale)); } return source_term; diff --git a/Source/SourceTerms/ERF_make_sources.cpp b/Source/SourceTerms/ERF_make_sources.cpp index a2f7000e1..2612849c2 100644 --- a/Source/SourceTerms/ERF_make_sources.cpp +++ b/Source/SourceTerms/ERF_make_sources.cpp @@ -60,8 +60,9 @@ void make_sources (int level, const bool use_terrain = solverChoice.use_terrain; TurbChoice tc = solverChoice.turbChoice[level]; - const bool l_use_deardorff = (tc.les_type == LESType::Deardorff); - const bool l_use_QKE = tc.use_QKE && tc.diffuse_QKE_3D; + const bool l_use_KE = ( (tc.les_type == LESType::Deardorff) || + (tc.pbl_type == PBLType::MYNN25) ); + const bool l_diff_KE = tc.diffuse_KE_3D; const Box& domain = geom.Domain(); @@ -338,18 +339,12 @@ void make_sources (int level, NumericalDiffusion(bx, start_comp, num_comp, dt, solverChoice.NumDiffCoeff, cell_data, cell_src, mf_u, mf_v, false, false); - if (l_use_deardorff) { + if (l_use_KE && l_diff_KE) { int sc = RhoKE_comp; int nc = 1; NumericalDiffusion(bx, sc, nc, dt, solverChoice.NumDiffCoeff, cell_data, cell_src, mf_u, mf_v, false, false); } - if (l_use_QKE) { - int sc = RhoQKE_comp; - int nc = 1; - NumericalDiffusion(bx, sc, nc, dt, solverChoice.NumDiffCoeff, - cell_data, cell_src, mf_u, mf_v, false, false); - } { int sc = RhoScalar_comp; int nc = NSCALARS; diff --git a/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H b/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H index 22b11c3b2..73976894a 100644 --- a/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H +++ b/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H @@ -342,8 +342,7 @@ if ( solverChoice.use_terrain && (solverChoice.terrain_type == TerrainType::Moving) ) { erf_slow_rhs_post(level, finest_level, nrk, slow_dt, n_qstate, S_rhs, S_old, S_new, S_data, S_prim, S_scratch, - xvel_new, yvel_new, zvel_new, - cc_src, SmnSmn, eddyDiffs, + xvel_new, yvel_new, zvel_new, cc_src, SmnSmn, eddyDiffs, Hfx1, Hfx2, Hfx3, Q1fx1, Q1fx2, Q1fx3, Q2fx3, Diss, fine_geom, solverChoice, m_most, domain_bcs_type_d, domain_bcs_type, z_phys_nd[level], ax[level], ay[level], az[level], detJ_cc[level], detJ_cc_new[level], @@ -360,8 +359,7 @@ } else { erf_slow_rhs_post(level, finest_level, nrk, slow_dt, n_qstate, S_rhs, S_old, S_new, S_data, S_prim, S_scratch, - xvel_new, yvel_new, zvel_new, - cc_src, SmnSmn, eddyDiffs, + xvel_new, yvel_new, zvel_new, cc_src, SmnSmn, eddyDiffs, Hfx1, Hfx2, Hfx3, Q1fx1, Q1fx2, Q1fx3, Q2fx3, Diss, fine_geom, solverChoice, m_most, domain_bcs_type_d, domain_bcs_type, z_phys_nd[level], ax[level], ay[level], az[level], detJ_cc[level], detJ_cc[level], diff --git a/Source/TimeIntegration/ERF_make_tau_terms.cpp b/Source/TimeIntegration/ERF_make_tau_terms.cpp index 30c8251b0..f00d1aa4f 100644 --- a/Source/TimeIntegration/ERF_make_tau_terms.cpp +++ b/Source/TimeIntegration/ERF_make_tau_terms.cpp @@ -50,6 +50,7 @@ void erf_make_tau_terms (int level, int nrk, tc.les_type == LESType::Deardorff || tc.pbl_type == PBLType::MYNN25 || tc.pbl_type == PBLType::YSU ); + const bool use_ddorf = (tc.les_type == LESType::Deardorff); const bool use_most = (most != nullptr); const bool exp_most = (solverChoice.use_explicit_most); @@ -232,11 +233,14 @@ void erf_make_tau_terms (int level, int nrk, // Populate SmnSmn if using Deardorff (used as diff src in post) // and in the first RK stage (TKE tendencies constant for nrk>0, following WRF) - if ((nrk==0) && (tc.les_type == LESType::Deardorff)) { + if ((nrk==0) && (use_ddorf)) { SmnSmn_a = SmnSmn->array(mfi); ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - SmnSmn_a(i,j,k) = ComputeSmnSmn(i,j,k,s11,s22,s33,s12,s13,s23,domlo_z,use_most,exp_most); + SmnSmn_a(i,j,k) = ComputeSmnSmn(i,j,k, + s11,s22,s33, + s12,s13,s23, + domlo_z,use_most,exp_most); }); } @@ -344,11 +348,14 @@ void erf_make_tau_terms (int level, int nrk, // Populate SmnSmn if using Deardorff (used as diff src in post) // and in the first RK stage (TKE tendencies constant for nrk>0, following WRF) - if ((nrk==0) && (tc.les_type == LESType::Deardorff)) { + if ((nrk==0) && (use_ddorf)) { SmnSmn_a = SmnSmn->array(mfi); ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - SmnSmn_a(i,j,k) = ComputeSmnSmn(i,j,k,s11,s22,s33,s12,s13,s23,domlo_z,use_most,exp_most); + SmnSmn_a(i,j,k) = ComputeSmnSmn(i,j,k, + s11,s22,s33, + s12,s13,s23, + domlo_z,use_most,exp_most); }); } diff --git a/Source/TimeIntegration/ERF_slow_rhs_post.cpp b/Source/TimeIntegration/ERF_slow_rhs_post.cpp index a91e7bdde..50491b2d8 100644 --- a/Source/TimeIntegration/ERF_slow_rhs_post.cpp +++ b/Source/TimeIntegration/ERF_slow_rhs_post.cpp @@ -120,9 +120,10 @@ void erf_slow_rhs_post (int level, int finest_level, if (l_moving_terrain) AMREX_ALWAYS_ASSERT(l_use_terrain); const bool l_use_mono_adv = solverChoice.use_mono_adv; - const bool l_use_QKE = tc.use_QKE; - const bool l_advect_QKE = tc.use_QKE && tc.advect_QKE; - const bool l_use_deardorff = (tc.les_type == LESType::Deardorff); + const bool l_use_ddorf = (tc.les_type == LESType::Deardorff); + const bool l_use_KE = ( (tc.les_type == LESType::Deardorff) || + (tc.pbl_type == PBLType::MYNN25) ); + const bool l_advect_KE = (tc.use_KE && tc.advect_KE); const bool l_use_diff = ((dc.molec_diff_type != MolecDiffType::None) || (tc.les_type != LESType::None) || (tc.pbl_type != PBLType::None) ); @@ -167,9 +168,8 @@ void erf_slow_rhs_post (int level, int finest_level, // Valid vars Vector is_valid_slow_var; is_valid_slow_var.resize(RhoQ1_comp+1,0); - if (l_use_deardorff) {is_valid_slow_var[ RhoKE_comp] = 1;} - if (l_use_QKE) {is_valid_slow_var[ RhoQKE_comp] = 1;} - is_valid_slow_var[RhoScalar_comp] = 1; + if (l_use_KE) {is_valid_slow_var[ RhoKE_comp] = 1;} + is_valid_slow_var[RhoScalar_comp] = 1; if (solverChoice.moisture_type != MoistureType::None) { is_valid_slow_var[RhoQ1_comp] = 1; } @@ -282,7 +282,7 @@ void erf_slow_rhs_post (int level, int finest_level, const Array4& mf_v = mapfac_v->const_array(mfi); // SmnSmn for KE src with Deardorff - const Array4& SmnSmn_a = l_use_deardorff ? SmnSmn->const_array(mfi) : Array4{}; + const Array4& SmnSmn_a = l_use_ddorf ? SmnSmn->const_array(mfi) : Array4{}; // ************************************************************************** // Here we fill the "current" data with "new" data because that is the result of the previous RK stage @@ -395,8 +395,8 @@ void erf_slow_rhs_post (int level, int finest_level, num_comp = 1; } - if (( ivar != RhoQKE_comp ) || - ((ivar == RhoQKE_comp) && l_advect_QKE)) + if (( ivar != RhoKE_comp ) || + ((ivar == RhoKE_comp) && l_advect_KE)) { AdvectionSrcForScalars(dt, tbx, start_comp, num_comp, avg_xmom, avg_ymom, avg_zmom, cur_cons, cur_prim, cell_rhs, @@ -408,9 +408,7 @@ void erf_slow_rhs_post (int level, int finest_level, } if (l_use_diff) { - const Array4 tm_arr = t_mean_mf ? t_mean_mf->const_array(mfi) : Array4{}; - if (l_use_terrain) { DiffusionSrcForState_T(tbx, domain, start_comp, num_comp, exp_most, rot_most, u, v, new_cons, cur_prim, cell_rhs, @@ -475,8 +473,6 @@ void erf_slow_rhs_post (int level, int finest_level, cur_cons(i,j,k,n) = temp_val / detJ_new_arr(i,j,k); if (ivar == RhoKE_comp) { cur_cons(i,j,k,n) = amrex::max(cur_cons(i,j,k,n), eps); - } else if (ivar == RhoQKE_comp) { - cur_cons(i,j,k,n) = amrex::max(cur_cons(i,j,k,n), 1e-12); } }); @@ -489,8 +485,6 @@ void erf_slow_rhs_post (int level, int finest_level, cur_cons(i,j,k,n) = old_cons(i,j,k,n) + dt * cell_rhs(i,j,k,n); if (ivar == RhoKE_comp) { cur_cons(i,j,k,n) = amrex::max(cur_cons(i,j,k,n), eps); - } else if (ivar == RhoQKE_comp) { - cur_cons(i,j,k,n) = amrex::max(cur_cons(i,j,k,n), 1e-12); } else if (ivar >= RhoQ1_comp) { cur_cons(i,j,k,n) = amrex::max(cur_cons(i,j,k,n), 0.0); } diff --git a/Source/WindFarmParametrization/EWP/ERF_AdvanceEWP.cpp b/Source/WindFarmParametrization/EWP/ERF_AdvanceEWP.cpp index 0b7915381..0522183f5 100644 --- a/Source/WindFarmParametrization/EWP/ERF_AdvanceEWP.cpp +++ b/Source/WindFarmParametrization/EWP/ERF_AdvanceEWP.cpp @@ -51,7 +51,7 @@ EWP::update (const Real& dt_advance, }, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { - cons_array(i,j,k,RhoQKE_comp) = cons_array(i,j,k,RhoQKE_comp) + ewp_array(i,j,k,2)*dt_advance; + cons_array(i,j,k,RhoKE_comp) = cons_array(i,j,k,RhoKE_comp) + ewp_array(i,j,k,2)*dt_advance; }); } } diff --git a/Source/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp b/Source/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp index 5fbf55232..7947c847a 100644 --- a/Source/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp +++ b/Source/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp @@ -91,7 +91,7 @@ Fitch::update (const Real& dt_advance, }, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { - cons_array(i,j,k,RhoQKE_comp) = cons_array(i,j,k,RhoQKE_comp) + fitch_array(i,j,k,4)*dt_advance; + cons_array(i,j,k,RhoKE_comp) = cons_array(i,j,k,RhoKE_comp) + fitch_array(i,j,k,4)*dt_advance; }); } } diff --git a/Tests/ERFGoldFiles/ABL_MYNN_PBL/Header b/Tests/ERFGoldFiles/ABL_MYNN_PBL/Header index 3b02ebe35..7d9bb4e58 100644 --- a/Tests/ERFGoldFiles/ABL_MYNN_PBL/Header +++ b/Tests/ERFGoldFiles/ABL_MYNN_PBL/Header @@ -1,7 +1,7 @@ HyperCLaw-V1.1 9 density -rhoQKE +rhoKE x_velocity y_velocity z_velocity diff --git a/Tests/ERFGoldFiles/ABL_MYNN_PBL/Level_0/Cell_D_00000 b/Tests/ERFGoldFiles/ABL_MYNN_PBL/Level_0/Cell_D_00000 index b1199550f5bf5bebcf0d0119c481b041790b152c..0394293edf72b9a31fd4ff2b3dcdf00cadcedd77 100644 GIT binary patch literal 18519 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 VtGQ%OQV4^TjqSdr8W+MK{|CZKU6=p> literal 18519 zcmeIy`Cm-$|HttuN>WmUBqh;`vQ(DNbxCB)yDT9gA|Y?bnu?k%l_g1wN=ia1Yl)Oj zB_*LxlCot>XeFJ@5c$mM`}6Z3_})IZ`QbjddE8#toO8`}X67_oJtHG)Gd&~A33?V5 zdK1U#nd@2TS#)DQZoILvS$DP8v(mHFo2WNIZ@k_(Jqu%FV6sUY6*_r>+_+0iCtJc3WV(I)9!s7l z$Txe3S}gd+6Xbnms?ocdC&-0oI+V_Q<_Yp>ki7ELI-Vdu9I^_oeZv#v(w4tm;7gt$ z6YWF$7*+EGSzB2;yy6K@kcApf1wM~?f-I@NeaGMdPmp_TzlomQ;|Vf&k=B0y0-hkp z4da;6cX)z)u&Bno_7+c&hs=zfk7e=%S(#a#Mz8V&`E9M237^Ijq@}i6#l;IeL3V`S zh+cV?CrH;lu0EOxJV7RHp1J*TEKiV?)&}CBDB1M`v$(%kMGy`Hcyb#Z#VS(ZO0R&(Q?lfrIaVg zyNMksQB!$>Oy0lXqq{XvkdXta#`p<5K|1dVu;^jV6J$m6lWA3^JV83G&Dm3Sq@5rY z_3IU1C4D5wPB%OG`~I~AsT>>eLnZnJLF%aOxvJt@Ly$j@KP(JUt0qW(s@6@5t}235 zu~*BOGo*?juZ--sWaZqa1lc!D;Y{1UN`iEfT4@f>enOD*ZYf16*H;kadzb6q;}t3h zk|s=W_+VO2kRwWi!yXNPM3CdwtzGo`^#g*8IGg@`q$}j0tjmZ^PAF4HXGe{o(J3Z)b8CWMztNzOiAI4N|>vbYSestv3Jj zfBW$N@f_?pp}DT*wK_%GDm(4uc^!&0Ikoz5qqQzYhCdK}ns`E&BG*iKxanxVE=3w_ z?{#eSOI?b5X5y?hq*0e5Q?w1%M6~NtWcl0yExJE-Dbg|PT!F)HU5b3CKr;Gw=~AR= zhC_NOxBT0w!~^Q$U5@5Ykw1otRw9W$_Mwr97ny(2 zUMkEZcR95D=w2WA#x}IOBa^&mNQ8Oh#0g5>`-?2iI@c-8Be!Ne?cN_``DJ}M;rt^j zlxpOKjx_zgzWez>4sOp^5ayA|c25GpfCVS{Bb9}`yr2f^SpEdKN z2r^|ue8c6OZ3Ova?Y`|cZf*qm?zrp67^{T@S?AWu811wtNKett)Ubc1668j&pEbYp z%n8yYydiPE(+GkbdD5-?Ub-ehYQG({b?@2j&H84U7Lr@u)5XFP+nnwC(VTD^}!em-w{V&q772HE*4 z*);AcWsqZT9ri^mM@J7gAzw6qO%}!U<7^mY*{zG#>sZ1d4cd~nmxtLf$odE2=gRA?8RS8?^)Bz@#xY1XV43FC zd_xBLb%BLmdDlP&**0>2_yO&2Hpnp_=Fghz-Ia&@XYs_wQG6CMvyH{0Ib^uMw(TK}u^ckpJI>6| zF^WTKuN5B(c1q!p2Tm1@_>q>%A!n|Akv*q8l|#;-W^M4S@gj%(oZ7sw{qqG5**fp^ zr{w9$9P)2Tyd^&`jzju}O{?=U@Z*rbpK4z^B09++PmiC-p1OFAK`NCv3_Y(3LSjHeVT9yT-jjm#lhc{>&ev_|dkS1a3I)0^f46?cX(7oKIFAVZ1)7rAQtC2xg z_IM%MHvJ2ORPB}e)qO=BgH+d_3^Kr?>wQF70fW4;e%-2XC$bsjuN$$?qlaB*kgg$93l{%9&mgZT1uxiY z8N(p+>K^9qFb-sp%}RykMmslg$Wb5P_{nF6aLAQ0=MOx)bb>>^TQjpP<$W}V6zz2@ zDe#Epkl*W@Dnk#c{~s)}vjnfpHu%NN(z<#N1d8xu>Ce?2ghH4%xT1 z$!TrzNe-!}^{TEQCz?Z!^AWdbrbThcq4OSZw}^`5kO@Yj`eFVN9P(xI!O9ws6C84- z+x(C6PT?H#cG@6?Qk&x(GH%Ey2jAt#IAlR>hi=uhqa3nl*xsG_qYrb)iq?^~w{=1| zr1(Lmv{5aHLyjxjXzn9_fJ63laM)DT9>^hY$zK{iv^ao6M(#-2Y8vmyA*$I+g$jx^zZmi3Z#q-}GaoT{uN^O`>|)s%H4t8Dv5U)GUJEpF#c zl69neznCOqT3?sBCs>LMEf`(6B!Z<#zO!B87RgfN z%z?^D9#Jes(!z<28>3l@eE;_E;(t%F6uIf9jqcVMmLdx>9elROvJ~lee&@lRaV$l? zzgfG;`;_eafyr-vweF5*De@ij)7kelOOdZNKOFN*U@6jPUsKGUM3y3zhF5s+J;PGu z!Fl(`_$RRxdAw^?q5oNyB8TTL93PO(Qe?=rr6B?5Sc<%<^`j`@JWG-C=F1xbF0d4t z6St}}AcdvK?_X3z;)^Urt~Rq4iBnmMtj?Gy5~r~gdChvfNSw}6WLuuONPLN<$Q;`- zBJpL}^#gyGn2N+#Sc-fy$5*I9}j^K`gKoWW9L!y;Xg zIFqHwG1Wsw;v2GgV3+d{kvNN`NZp!2BJoX@B40Rbio~~AiX2j{Arfb^6!~aTKau!0 zOOYy1RYl?)mLhW<`-sH3EJe0GRuYNt$bNs|wK<9+ah~k_0IN!Rh{POAk-Kc=MB;pw zA~XD*&Ael!6qztg>#9ejlp=d?mFJzqq!gJt@{h#+u#_UJ6|Uw?Iw+;c#Vwsv%*0ZP zeAcJhPuEXMku&6{`1ao=rAU{TmR3qzr4)HYwK3z*CMiV@njF#6?jfbfk=Y5K8&^vy za@mH$qz|rAirjqGOy|`SDMc=ODDPUeKsFCt7`%5)xr3AF@kGVI2n;@k~g@!eKxv^4;Tz2|+J7*%hf1uOwoVtRM zQi_yU+VG}GPfC$4u~v2WwPoi6II!VS+oOR}iVVJ9)BCBqlp=k+l}%r&NGVc#m)7DB zy`&Ur|MYfnlf0B73->17?f4_1$d$8$736+OC~}$R2uD?3LXpyj(PxKzl~Ckxr8S*K zjS`Ac-E_0LXkT9r?kaSBoz6|-!U%o zk%S_jIc*%4c3(n~SE4Sb6x@|iq}-CX6QAcvD00xXd!^s9B^0UiP~T1YhV1%*Rv)=e zgR2sXESj_O6it&*WXI|fX2p34MdqBjQ}265LXkDc6_3ZBlI=gR@bLzl+tIS~2~_WK zspUnugd#PXPMqmHDxt_V4j&f}3z1Nye%Crx+x-%X^sTKe@$i>WWM+-}zN0=8iY%$y}3uDA4Q5)hx@#v{V4K$vG}pVRtcW0$N!Fqq z&pd)W_gux3Q_CXAA}t-GrkYCx8FSk5yhGYqg0#6(ZQ}lKG(q;Syc}7)FoYn<^m)m{ zl6Mhgh2!&w2LHGbBtObATm91%f}E*nxAO4SZwyj>Le|ct-%1S9Md3{NFzI<4WY3_) zL%On#+!J~uMCeGh5zm5!j*Kc2b$4W4hh>m3kF?(GeNgDgE!l+!gpOoX26T61`{FJ8 zg?Z$|{K|boN2X;@?e55H@2&(2^GIiB!|sk8`0<=rm`9q-Fz)WigGQMF!aQ={M%(U= zw5_i87v_;Gg0^&b={ zx#GdMxeJOa2(r`kt^dQJ4+&Cn#K2Ic=fwos8oIyEJi3q|ZTirn4a^;ayjhf47IWYx zL0ZPVF1wI>ogh~){`5d=XF5T8XdDaGs5nQE#= z7(uFM#^3(1-~d5Z+~{W*8R|ojF=1taKA$!dq{)oo5l$(q2y*tNACdp5nn#fKZ`Z4u zteZfPYTM#VHk+#x Date: Mon, 28 Oct 2024 08:41:03 -0700 Subject: [PATCH 05/24] make chk file read/write public to avoid extended capture. (#1913) --- Source/ERF.H | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Source/ERF.H b/Source/ERF.H index f5b74e630..cafc46489 100644 --- a/Source/ERF.H +++ b/Source/ERF.H @@ -448,6 +448,15 @@ public: // more flexible version of AverageDown() that lets you average down across multiple levels void AverageDownTo (int crse_lev, int scomp, int ncomp); // NOLINT + // write checkpoint file to disk + void WriteCheckpointFile () const; + + // read checkpoint file from disk + void ReadCheckpointFile (); + + // read checkpoint file from disk -- called after instantiating m_most + void ReadCheckpointFileMOST (); + private: /////////////////////////// @@ -637,15 +646,6 @@ private: // Function to read and populate above vectors (if input file exists) void init_Dirichlet_bc_data (const std::string input_file); - // write checkpoint file to disk - void WriteCheckpointFile () const; - - // read checkpoint file from disk - void ReadCheckpointFile (); - - // read checkpoint file from disk -- called after instantiating m_most - void ReadCheckpointFileMOST (); - // Read the file passed to amr.restart and use it as an initial condition for // the current simulation. Supports a different number of components and // ghost cells. From 2cdda7200c0d41405e166af24b6b70e50be3d64c Mon Sep 17 00:00:00 2001 From: Mahesh Natarajan Date: Mon, 28 Oct 2024 08:46:52 -0700 Subject: [PATCH 06/24] Correction to generalized actuator disk model (#1912) * Changing actuator disk model names * Some changes to actuator disk model * Revmoing unused variable --------- Co-authored-by: Mahesh Natarajan Co-authored-by: Mahesh Natarajan --- .../ERF_InitWindFarm.cpp | 20 ++++++++++--------- .../ERF_AdvanceGeneralAD.cpp | 15 +++++++------- .../ERF_AdvanceSimpleAD.cpp | 18 ++++++----------- 3 files changed, 25 insertions(+), 28 deletions(-) diff --git a/Source/WindFarmParametrization/ERF_InitWindFarm.cpp b/Source/WindFarmParametrization/ERF_InitWindFarm.cpp index 99a6f2f20..6f48a711b 100644 --- a/Source/WindFarmParametrization/ERF_InitWindFarm.cpp +++ b/Source/WindFarmParametrization/ERF_InitWindFarm.cpp @@ -125,14 +125,6 @@ WindFarm::init_windfarm_lat_lon (const std::string windfarm_loc_table, xloc[it] = xloc[it] - xloc_min + windfarm_x_shift; yloc[it] = yloc[it] - yloc_min + windfarm_y_shift; } - - FILE* file_xy_loc; - file_xy_loc = fopen("file_xy_loc_KingPlains.txt","w"); - - for(int it = 0;it 1){ + printf("Actuator disks with indices %d and %d are overlapping\n", + turb_indices_overlap[0],turb_indices_overlap[1]); + amrex::Error("Actuator disks are overlapping. Visualize actuator_disks.vtk " + " and check the windturbine locations input file. Exiting.."); + } } - } }); } diff --git a/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp b/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp index 42f9d4be3..aaa64ceb2 100644 --- a/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp +++ b/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp @@ -239,7 +239,7 @@ compute_source_terms_Fn_Ft (const Real rad, AMREX_ALWAYS_ASSERT(std::fabs(std::exp(-fhub))<=1.0); AMREX_ALWAYS_ASSERT(std::fabs(std::exp(-ftip))<=1.0); - F = 1.0;//2.0/PI*(std::acos(std::exp(-ftip)) + std::acos(std::exp(-fhub)) ); + F = 2.0/PI*(std::acos(std::exp(-ftip)) + std::acos(std::exp(-fhub)) ); at_new = 1.0/ ( 4.0*F*std::sin(psi)*std::cos(psi)/(s*Ct+1e-10) - 1.0 ); an_new = 1.0/ ( 1.0 + 4.0*F*std::pow(std::sin(psi),2)/(s*Cn + 1e-10) ); @@ -417,7 +417,6 @@ GeneralAD::source_terms_cellcentered (const Geometry& geom, Real y = ProbLoArr[1] + (jj+0.5)*dx[1]; Real z = ProbLoArr[2] + (kk+0.5)*dx[2]; // ?? Density needed here - Real inv_dens_vol = 1.0/(1.0*dx[0]*dx[1]*dx[2]); int check_int = 0; @@ -468,17 +467,19 @@ GeneralAD::source_terms_cellcentered (const Geometry& geom, d_blade_pitch_ptr, n_spec_extra); - Real Fn = Fn_and_Ft[0]; - Real Ft = Fn_and_Ft[1]; + Real Fn = 3.0*Fn_and_Ft[0]; + Real Ft = 3.0*Fn_and_Ft[1]; // Compute the source terms - pass in radial distance, free stream velocity Real Fx = Fn*std::cos(phi) + Ft*std::sin(zeta)*std::sin(phi); Real Fy = Fn*std::sin(phi) - Ft*std::sin(zeta)*std::cos(phi); Real Fz = -Ft*std::cos(zeta); - source_x = -Fx*inv_dens_vol; - source_y = -Fy*inv_dens_vol; - source_z = -Fz*inv_dens_vol; + //Real dn = ( + + source_x = -Fx/(2.0*PI*rad*dx[0])*1.0/std::pow(2.0*PI,0.5); + source_y = -Fy/(2.0*PI*rad*dx[0])*1.0/std::pow(2.0*PI,0.5); + source_z = -Fz/(2.0*PI*rad*dx[0])*1.0/std::pow(2.0*PI,0.5); //printf("Val source_x, is %0.15g, %0.15g, %0.15g %0.15g %0.15g %0.15g\n", rad, Fn, Ft, source_x, source_y, source_z); diff --git a/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp b/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp index 38a10d65e..7709f6355 100644 --- a/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp +++ b/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp @@ -114,7 +114,7 @@ void SimpleAD::compute_freestream_velocity(const MultiFab& cons_in, amrex::ParallelContext::CommunicatorAll()); get_turb_loc(xloc, yloc); - if (ParallelDescriptor::IOProcessor()){ + /*if (ParallelDescriptor::IOProcessor()){ for(int it=0; it(SMark_array(ii,jj,kk,1)); + + if(it != -1) { Real avg_vel = d_freestream_velocity_ptr[it]/(d_disk_cell_count_ptr[it] + 1e-10); Real phi = d_freestream_phi_ptr[it]/(d_disk_cell_count_ptr[it] + 1e-10); @@ -210,8 +211,6 @@ SimpleAD::source_terms_cellcentered (const Geometry& geom, a = 0.5 - 0.5*std::pow(1.0-C_T,0.5); } Real Uinfty_dot_nhat = avg_vel*(std::cos(phi)*nx + std::sin(phi)*ny); - if(SMark_array(ii,jj,kk,1) == static_cast(it)) { - check_int++; if(C_T <= 1) { source_x = -2.0*std::pow(Uinfty_dot_nhat, 2.0)*a*(1.0-a)*dx[1]*dx[2]*std::cos(d_turb_disk_angle)/(dx[0]*dx[1]*dx[2])*std::cos(phi); source_y = -2.0*std::pow(Uinfty_dot_nhat, 2.0)*a*(1.0-a)*dx[1]*dx[2]*std::cos(d_turb_disk_angle)/(dx[0]*dx[1]*dx[2])*std::sin(phi); @@ -220,12 +219,7 @@ SimpleAD::source_terms_cellcentered (const Geometry& geom, source_x = -0.5*C_T*std::pow(Uinfty_dot_nhat, 2.0)*dx[1]*dx[2]*std::cos(d_turb_disk_angle)/(dx[0]*dx[1]*dx[2])*std::cos(phi); source_y = -0.5*C_T*std::pow(Uinfty_dot_nhat, 2.0)*dx[1]*dx[2]*std::cos(d_turb_disk_angle)/(dx[0]*dx[1]*dx[2])*std::sin(phi); } - } - } - if(check_int > 1){ - amrex::Error("Actuator disks are overlapping. Visualize actuator_disks.vtk " - "and check the windturbine locations input file. Exiting.."); - } + } simpleAD_array(i,j,k,0) = source_x; simpleAD_array(i,j,k,1) = source_y; From 651c1e5a519ca7ee343e194fe5d0a7c9835f9d53 Mon Sep 17 00:00:00 2001 From: "Aaron M. Lattanzi" <103702284+AMLattanzi@users.noreply.github.com> Date: Mon, 28 Oct 2024 16:04:10 -0700 Subject: [PATCH 07/24] Refactor buoyancy and add moist anelastic option. (#1914) * Refactor buoyancy and add moist anelastic option. * fix typo * fix omp capture and change name. * fix dry default case. * Fix EOS call and make device functions not host. * Forgot one device function. --- Source/SourceTerms/ERF_buoyancy_utils.H | 253 +++++++++++++++++++++++ Source/SourceTerms/ERF_make_buoyancy.cpp | 247 ++++++++-------------- Source/SourceTerms/Make.package | 2 +- 3 files changed, 342 insertions(+), 160 deletions(-) create mode 100644 Source/SourceTerms/ERF_buoyancy_utils.H diff --git a/Source/SourceTerms/ERF_buoyancy_utils.H b/Source/SourceTerms/ERF_buoyancy_utils.H new file mode 100644 index 000000000..91f2a8ea0 --- /dev/null +++ b/Source/SourceTerms/ERF_buoyancy_utils.H @@ -0,0 +1,253 @@ +#ifndef ERF_BUOYANCY_UTILS_H_ +#define ERF_BUOYANCY_UTILS_H_ + +#include +#include + +AMREX_GPU_DEVICE +AMREX_FORCE_INLINE +amrex::Real +buoyancy_dry_anelastic (int& i, + int& j, + int& k, + amrex::Real const& grav_gpu, + amrex::Real const& rd_over_cp, + const amrex::Array4& p0_arr, + const amrex::Array4& r0_arr, + const amrex::Array4& cell_data) +{ + amrex::Real rt0_hi = getRhoThetagivenP(p0_arr(i,j,k)); + amrex::Real t0_hi = getTgivenPandTh(p0_arr(i,j,k), rt0_hi/r0_arr(i,j,k), rd_over_cp); + amrex::Real t_hi = getTgivenPandTh(p0_arr(i,j,k), cell_data(i,j,k,RhoTheta_comp)/r0_arr(i,j,k), rd_over_cp); + amrex::Real qplus = (t_hi-t0_hi)/t0_hi; + + amrex::Real rt0_lo = getRhoThetagivenP(p0_arr(i,j,k-1)); + amrex::Real t0_lo = getTgivenPandTh(p0_arr(i,j,k-1), rt0_lo/r0_arr(i,j,k-1), rd_over_cp); + amrex::Real t_lo = getTgivenPandTh(p0_arr(i,j,k-1), cell_data(i,j,k-1,RhoTheta_comp)/r0_arr(i,j,k-1), rd_over_cp); + amrex::Real qminus = (t_lo-t0_lo)/t0_lo; + + amrex::Real r0_q_avg = amrex::Real(0.5) * (r0_arr(i,j,k) * qplus + r0_arr(i,j,k-1) * qminus); + return (-r0_q_avg * grav_gpu); +} + + +AMREX_GPU_DEVICE +AMREX_FORCE_INLINE +amrex::Real +buoyancy_moist_anelastic (int& i, + int& j, + int& k, + amrex::Real const& grav_gpu, + amrex::Real const& rv_over_rd, + const amrex::Array4& p0_arr, + const amrex::Array4& r0_arr, + const amrex::Array4& cell_data) +{ + amrex::Real theta_d_lo = cell_data(i,j,k-1,RhoTheta_comp)/r0_arr(i,j,k-1); + amrex::Real qv_lo = cell_data(i,j,k-1,RhoQ1_comp)/r0_arr(i,j,k-1); + amrex::Real qc_lo = cell_data(i,j,k-1,RhoQ2_comp)/r0_arr(i,j,k-1); + amrex::Real qt_lo = qv_lo + qc_lo; + amrex::Real theta_v_lo = theta_d_lo * (1.0 - (1.0 - rv_over_rd)*qt_lo - rv_over_rd*qc_lo); + + amrex::Real theta_d_hi = cell_data(i,j,k,RhoTheta_comp)/r0_arr(i,j,k); + amrex::Real qv_hi = cell_data(i,j,k,RhoQ1_comp)/r0_arr(i,j,k); + amrex::Real qc_hi = cell_data(i,j,k,RhoQ2_comp)/r0_arr(i,j,k); + amrex::Real qt_hi = qv_hi + qc_hi; + amrex::Real theta_v_hi = theta_d_hi * (1.0 - (1.0 - rv_over_rd)*qt_hi - rv_over_rd*qc_hi); + + amrex::Real theta_v_wface = amrex::Real(0.5) * (theta_v_lo + theta_v_hi); + + amrex::Real theta_d_0_lo = getRhoThetagivenP(p0_arr(i,j,k-1)) / r0_arr(i,j,k-1); + amrex::Real theta_d_0_hi = getRhoThetagivenP(p0_arr(i,j,k )) / r0_arr(i,j,k ); + amrex::Real theta_v_0_lo = theta_d_0_lo * (1.0 - (1.0 - rv_over_rd)*qt_lo - rv_over_rd*qc_lo); + amrex::Real theta_v_0_hi = theta_d_0_hi * (1.0 - (1.0 - rv_over_rd)*qt_hi - rv_over_rd*qc_hi); + + amrex::Real theta_v_0_wface = amrex::Real(0.5) * (theta_v_0_lo + theta_v_0_hi); + + return (-grav_gpu * (theta_v_wface - theta_v_0_wface) / theta_v_0_wface); +} + +AMREX_GPU_DEVICE +AMREX_FORCE_INLINE +amrex::Real +buoyancy_dry_default (int& i, + int& j, + int& k, + amrex::Real const& grav_gpu, + amrex::Real const& rd_over_cp, + const amrex::Array4& p0_arr, + const amrex::Array4& r0_arr, + const amrex::Array4& cell_data) +{ + amrex::Real rt0_hi = getRhoThetagivenP(p0_arr(i,j,k)); + amrex::Real t0_hi = getTgivenPandTh(p0_arr(i,j,k), rt0_hi/r0_arr(i,j,k), rd_over_cp); + amrex::Real t_hi = getTgivenRandRTh(cell_data(i,j,k ,Rho_comp), cell_data(i,j,k ,RhoTheta_comp)); + amrex::Real qplus = (t_hi-t0_hi)/t0_hi; + + amrex::Real rt0_lo = getRhoThetagivenP(p0_arr(i,j,k-1)); + amrex::Real t0_lo = getTgivenPandTh(p0_arr(i,j,k-1), rt0_lo/r0_arr(i,j,k-1), rd_over_cp); + amrex::Real t_lo = getTgivenRandRTh(cell_data(i,j,k-1,Rho_comp), cell_data(i,j,k-1,RhoTheta_comp)); + amrex::Real qminus = (t_lo-t0_lo)/t0_lo; + + amrex::Real r0_q_avg = amrex::Real(0.5) * (r0_arr(i,j,k) * qplus + r0_arr(i,j,k-1) * qminus); + return (-r0_q_avg * grav_gpu); +} + +AMREX_GPU_DEVICE +AMREX_FORCE_INLINE +amrex::Real +buoyancy_type1 (int& i, + int& j, + int& k, + const int& n_qstate, + amrex::Real const& grav_gpu, + const amrex::Array4& r0_arr, + const amrex::Array4& cell_data) +{ + amrex::Real rhop_hi = cell_data(i,j,k ,Rho_comp) - r0_arr(i,j,k ); + amrex::Real rhop_lo = cell_data(i,j,k-1,Rho_comp) - r0_arr(i,j,k-1); + for (int q_offset(0); q_offset& cell_prim, + const amrex::Array4& cell_data) +{ + amrex::Real tempp1d = getTgivenRandRTh(rho_d_ptr[k ], rho_d_ptr[k ]*theta_d_ptr[k ], qv_d_ptr[k ]); + amrex::Real tempm1d = getTgivenRandRTh(rho_d_ptr[k-1], rho_d_ptr[k-1]*theta_d_ptr[k-1], qv_d_ptr[k-1]); + + amrex::Real tempp3d = getTgivenRandRTh(cell_data(i,j,k ,Rho_comp), + cell_data(i,j,k ,RhoTheta_comp), + cell_data(i,j,k ,RhoQ1_comp)/cell_data(i,j,k ,Rho_comp)); + amrex::Real tempm3d = getTgivenRandRTh(cell_data(i,j,k-1,Rho_comp), + cell_data(i,j,k-1,RhoTheta_comp), + cell_data(i,j,k-1,RhoQ1_comp)/cell_data(i,j,k-1,Rho_comp)); + + amrex::Real qv_plus = (n_qstate >= 1) ? cell_prim(i,j,k ,PrimQ1_comp) : 0.0; + amrex::Real qv_minus = (n_qstate >= 1) ? cell_prim(i,j,k-1,PrimQ1_comp) : 0.0; + + amrex::Real qc_plus = (n_qstate >= 2) ? cell_prim(i,j,k ,PrimQ2_comp) : 0.0; + amrex::Real qc_minus = (n_qstate >= 2) ? cell_prim(i,j,k-1,PrimQ2_comp) : 0.0; + + amrex::Real qp_plus = (n_qstate >= 3) ? cell_prim(i,j,k ,PrimQ3_comp) : 0.0; + amrex::Real qp_minus = (n_qstate >= 3) ? cell_prim(i,j,k-1,PrimQ3_comp) : 0.0; + + amrex::Real qplus = 0.61 * ( qv_plus - qv_d_ptr[k] ) - + ( qc_plus - qc_d_ptr[k] + + qp_plus - qp_d_ptr[k] ) + + (tempp3d-tempp1d)/tempp1d*(amrex::Real(1.0) + amrex::Real(0.61)*qv_d_ptr[k]-qc_d_ptr[k]-qp_d_ptr[k]); + + amrex::Real qminus = 0.61 * ( qv_minus - qv_d_ptr[k-1] ) - + ( qc_minus - qc_d_ptr[k-1] + + qp_minus - qp_d_ptr[k-1] ) + + (tempm3d-tempm1d)/tempm1d*(amrex::Real(1.0) + amrex::Real(0.61)*qv_d_ptr[k-1]-qc_d_ptr[k-1]-qp_d_ptr[k-1]); + + amrex::Real qavg = amrex::Real(0.5) * (qplus + qminus); + amrex::Real r0avg = amrex::Real(0.5) * (rho_d_ptr[k] + rho_d_ptr[k-1]); + + return (-qavg * r0avg * grav_gpu); +} + + +AMREX_GPU_DEVICE +AMREX_FORCE_INLINE +amrex::Real +buoyancy_type3 (int& i, + int& j, + int& k, + const int& n_qstate, + amrex::Real const& grav_gpu, + amrex::Real* rho_d_ptr, + amrex::Real* theta_d_ptr, + amrex::Real* qv_d_ptr, + const amrex::Array4& cell_prim, + const amrex::Array4& cell_data) +{ + amrex::Real tempp1d = getTgivenRandRTh(rho_d_ptr[k ], rho_d_ptr[k ]*theta_d_ptr[k ], qv_d_ptr[k ]); + amrex::Real tempm1d = getTgivenRandRTh(rho_d_ptr[k-1], rho_d_ptr[k-1]*theta_d_ptr[k-1], qv_d_ptr[k-1]); + + amrex::Real tempp3d = getTgivenRandRTh(cell_data(i,j,k ,Rho_comp), + cell_data(i,j,k ,RhoTheta_comp), + cell_data(i,j,k ,RhoQ1_comp)/cell_data(i,j,k ,Rho_comp)); + amrex::Real tempm3d = getTgivenRandRTh(cell_data(i,j,k-1,Rho_comp), + cell_data(i,j,k-1,RhoTheta_comp), + cell_data(i,j,k-1,RhoQ1_comp)/cell_data(i,j,k-1,Rho_comp)); + + amrex::Real qv_plus = (n_qstate >= 1) ? cell_prim(i,j,k ,PrimQ1_comp) : 0.0; + amrex::Real qv_minus = (n_qstate >= 1) ? cell_prim(i,j,k-1,PrimQ1_comp) : 0.0; + + amrex::Real qc_plus = (n_qstate >= 2) ? cell_prim(i,j,k ,PrimQ2_comp) : 0.0; + amrex::Real qc_minus = (n_qstate >= 2) ? cell_prim(i,j,k-1,PrimQ2_comp) : 0.0; + + amrex::Real qp_plus = (n_qstate >= 3) ? cell_prim(i,j,k ,PrimQ3_comp) : 0.0; + amrex::Real qp_minus = (n_qstate >= 3) ? cell_prim(i,j,k-1,PrimQ3_comp) : 0.0; + + amrex::Real qplus = 0.61 * qv_plus - (qc_plus + qp_plus) + (tempp3d-tempp1d)/tempp1d; + + amrex::Real qminus = 0.61 * qv_minus - (qc_minus + qp_minus) + (tempm3d-tempm1d)/tempm1d; + + amrex::Real qavg = amrex::Real(0.5) * (qplus + qminus); + amrex::Real r0avg = amrex::Real(0.5) * (rho_d_ptr[k] + rho_d_ptr[k-1]); + + return ( -qavg * r0avg * grav_gpu ); +} + + +AMREX_GPU_DEVICE +AMREX_FORCE_INLINE +amrex::Real +buoyancy_type4 (int& i, + int& j, + int& k, + const int& n_qstate, + amrex::Real const& grav_gpu, + amrex::Real* rho_d_ptr, + amrex::Real* theta_d_ptr, + amrex::Real* qv_d_ptr, + amrex::Real* qc_d_ptr, + amrex::Real* qp_d_ptr, + const amrex::Array4& cell_prim, + const amrex::Array4& cell_data) +{ + amrex::Real qv_plus = (n_qstate >= 1) ? cell_prim(i,j,k ,PrimQ1_comp) : 0.0; + amrex::Real qv_minus = (n_qstate >= 1) ? cell_prim(i,j,k-1,PrimQ1_comp) : 0.0; + + amrex::Real qc_plus = (n_qstate >= 2) ? cell_prim(i,j,k ,PrimQ2_comp) : 0.0; + amrex::Real qc_minus = (n_qstate >= 2) ? cell_prim(i,j,k-1,PrimQ2_comp) : 0.0; + + amrex::Real qp_plus = (n_qstate >= 3) ? cell_prim(i,j,k ,PrimQ3_comp) : 0.0; + amrex::Real qp_minus = (n_qstate >= 3) ? cell_prim(i,j,k-1,PrimQ3_comp) : 0.0; + + amrex::Real qplus = amrex::Real(0.61) * ( qv_plus - qv_d_ptr[k] ) - + ( qc_plus - qc_d_ptr[k] + + qp_plus - qp_d_ptr[k] ) + + (cell_data(i,j,k ,RhoTheta_comp)/cell_data(i,j,k ,Rho_comp) - theta_d_ptr[k ])/theta_d_ptr[k ]; + + amrex::Real qminus = amrex::Real(0.61) * ( qv_minus - qv_d_ptr[k-1] ) - + ( qc_minus - qc_d_ptr[k-1] + + qp_minus - qp_d_ptr[k-1] ) + + (cell_data(i,j,k-1,RhoTheta_comp)/cell_data(i,j,k-1,Rho_comp) - theta_d_ptr[k-1])/theta_d_ptr[k-1]; + + amrex::Real qavg = amrex::Real(0.5) * (qplus + qminus); + amrex::Real r0avg = amrex::Real(0.5) * (rho_d_ptr[k] + rho_d_ptr[k-1]); + + return (-qavg * r0avg * grav_gpu); +} +#endif diff --git a/Source/SourceTerms/ERF_make_buoyancy.cpp b/Source/SourceTerms/ERF_make_buoyancy.cpp index d9ec30a53..11a3743a9 100644 --- a/Source/SourceTerms/ERF_make_buoyancy.cpp +++ b/Source/SourceTerms/ERF_make_buoyancy.cpp @@ -7,7 +7,7 @@ #include #include #include -//#include +#include using namespace amrex; @@ -48,6 +48,7 @@ void make_buoyancy (Vector& S_data, const int khi = geom.Domain().bigEnd()[2] + 1; Real rd_over_cp = solverChoice.rdOcp; + Real rv_over_rd = R_v/R_d; if (anelastic == 1) { #ifdef _OPENMP @@ -68,21 +69,24 @@ void make_buoyancy (Vector& S_data, const Array4& r0_arr = r0->const_array(mfi); const Array4& p0_arr = p0->const_array(mfi); - ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) - { - Real rt0_hi = getRhoThetagivenP(p0_arr(i,j,k)); - Real t0_hi = getTgivenPandTh(p0_arr(i,j,k), rt0_hi/r0_arr(i,j,k), rd_over_cp); - Real t_hi = getTgivenPandTh(p0_arr(i,j,k), cell_data(i,j,k,RhoTheta_comp)/r0_arr(i,j,k), rd_over_cp); - Real qplus = (t_hi-t0_hi)/t0_hi; - - Real rt0_lo = getRhoThetagivenP(p0_arr(i,j,k-1)); - Real t0_lo = getTgivenPandTh(p0_arr(i,j,k-1), rt0_lo/r0_arr(i,j,k-1), rd_over_cp); - Real t_lo = getTgivenPandTh(p0_arr(i,j,k-1), cell_data(i,j,k-1,RhoTheta_comp)/r0_arr(i,j,k-1), rd_over_cp); - Real qminus = (t_lo-t0_lo)/t0_lo; - - Real r0_q_avg = Real(0.5) * (r0_arr(i,j,k) * qplus + r0_arr(i,j,k-1) * qminus); - buoyancy_fab(i, j, k) = -r0_q_avg * grav_gpu[2]; - }); + if (solverChoice.moisture_type == MoistureType::None) { + ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + buoyancy_fab(i, j, k) = buoyancy_dry_anelastic(i,j,k, + grav_gpu[2],rd_over_cp, + p0_arr,r0_arr,cell_data); + }); + } else { + // NOTE: For decomposition in the vertical direction, klo may not + // reside in the valid box and this call will yield an out + // of bounds error since it depends upon the surface theta_l + ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + buoyancy_fab(i, j, k) = buoyancy_moist_anelastic(i,j,k, + grav_gpu[2],rv_over_rd, + p0_arr,r0_arr,cell_data); + }); + } } // mfi } else @@ -92,75 +96,66 @@ void make_buoyancy (Vector& S_data, // ****************************************************************************************** if (solverChoice.moisture_type == MoistureType::None) { - if (solverChoice.buoyancy_type == 1) { + int n_q_dry = 0; + if (solverChoice.buoyancy_type == 1) { #ifdef _OPENMP #pragma omp parallel if (amrex::Gpu::notInLaunchRegion()) #endif - for ( MFIter mfi(buoyancy,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box tbz = mfi.tilebox(); + for ( MFIter mfi(buoyancy,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box tbz = mfi.tilebox(); - // We don't compute a source term for z-momentum on the bottom or top domain boundary - if (tbz.smallEnd(2) == klo) tbz.growLo(2,-1); - if (tbz.bigEnd(2) == khi) tbz.growHi(2,-1); + // We don't compute a source term for z-momentum on the bottom or top domain boundary + if (tbz.smallEnd(2) == klo) tbz.growLo(2,-1); + if (tbz.bigEnd(2) == khi) tbz.growHi(2,-1); - const Array4 & cell_data = S_data[IntVars::cons].array(mfi); - const Array4< Real> & buoyancy_fab = buoyancy.array(mfi); + const Array4 & cell_data = S_data[IntVars::cons].array(mfi); + const Array4< Real> & buoyancy_fab = buoyancy.array(mfi); - // Base state density - const Array4& r0_arr = r0->const_array(mfi); + // Base state density + const Array4& r0_arr = r0->const_array(mfi); - ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) - { - buoyancy_fab(i, j, k) = grav_gpu[2] * 0.5 * ( (cell_data(i,j,k ) - r0_arr(i,j,k )) - +(cell_data(i,j,k-1) - r0_arr(i,j,k-1)) ); - }); - } // mfi + ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + buoyancy_fab(i, j, k) = buoyancy_type1(i,j,k,n_q_dry,grav_gpu[2],r0_arr,cell_data); + }); + } // mfi - } - else // (buoyancy_type != 1) - { - // We now use the base state rather than planar average because - // 1) we don't want to average over the limited region of the fine level if doing multilevel. - // 2) it's cheaper to use the base state than to compute the horizontal averages - // 3) when running in a smallish domain, the horizontal average may evolve over time, - // which is not necessarily the intended behavior - // + } + else // (buoyancy_type != 1) + { + // We now use the base state rather than planar average because + // 1) we don't want to average over the limited region of the fine level if doing multilevel. + // 2) it's cheaper to use the base state than to compute the horizontal averages + // 3) when running in a smallish domain, the horizontal average may evolve over time, + // which is not necessarily the intended behavior + // #ifdef _OPENMP #pragma omp parallel if (amrex::Gpu::notInLaunchRegion()) #endif - for ( MFIter mfi(buoyancy,TilingIfNotGPU()); mfi.isValid(); ++mfi) - { - Box tbz = mfi.tilebox(); + for ( MFIter mfi(buoyancy,TilingIfNotGPU()); mfi.isValid(); ++mfi) + { + Box tbz = mfi.tilebox(); - // We don't compute a source term for z-momentum on the bottom or top boundary - if (tbz.smallEnd(2) == klo) tbz.growLo(2,-1); - if (tbz.bigEnd(2) == khi) tbz.growHi(2,-1); + // We don't compute a source term for z-momentum on the bottom or top boundary + if (tbz.smallEnd(2) == klo) tbz.growLo(2,-1); + if (tbz.bigEnd(2) == khi) tbz.growHi(2,-1); - // Base state density and pressure - const Array4& r0_arr = r0->const_array(mfi); - const Array4& p0_arr = p0->const_array(mfi); + // Base state density and pressure + const Array4& r0_arr = r0->const_array(mfi); + const Array4& p0_arr = p0->const_array(mfi); - const Array4 & cell_data = S_data[IntVars::cons].array(mfi); - const Array4< Real> & buoyancy_fab = buoyancy.array(mfi); + const Array4 & cell_data = S_data[IntVars::cons].array(mfi); + const Array4< Real> & buoyancy_fab = buoyancy.array(mfi); - ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) - { - Real rt0_hi = getRhoThetagivenP(p0_arr(i,j,k)); - Real t0_hi = getTgivenPandTh(p0_arr(i,j,k), rt0_hi/r0_arr(i,j,k), rd_over_cp); - Real t_hi = getTgivenRandRTh(cell_data(i,j,k ,Rho_comp), cell_data(i,j,k ,RhoTheta_comp)); - Real qplus = (t_hi-t0_hi)/t0_hi; - - Real rt0_lo = getRhoThetagivenP(p0_arr(i,j,k-1)); - Real t0_lo = getTgivenPandTh(p0_arr(i,j,k-1), rt0_lo/r0_arr(i,j,k-1), rd_over_cp); - Real t_lo = getTgivenRandRTh(cell_data(i,j,k-1,Rho_comp), cell_data(i,j,k-1,RhoTheta_comp)); - Real qminus = (t_lo-t0_lo)/t0_lo; - - Real r0_q_avg = Real(0.5) * (r0_arr(i,j,k) * qplus + r0_arr(i,j,k-1) * qminus); - buoyancy_fab(i, j, k) = -r0_q_avg * grav_gpu[2]; - }); - } // mfi - } // buoyancy_type + ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + buoyancy_fab(i, j, k) = buoyancy_dry_default(i,j,k, + grav_gpu[2],rd_over_cp, + p0_arr,r0_arr,cell_data); + }); + } // mfi + } // buoyancy_type } // moisture type else { @@ -196,23 +191,15 @@ void make_buoyancy (Vector& S_data, ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) { - Real rhop_hi = cell_data(i,j,k ,Rho_comp) + cell_data(i,j,k ,RhoQ1_comp) - + cell_data(i,j,k ,RhoQ2_comp) - r0_arr(i,j,k ); - Real rhop_lo = cell_data(i,j,k-1,Rho_comp) + cell_data(i,j,k-1,RhoQ1_comp) - + cell_data(i,j,k-1,RhoQ2_comp) - r0_arr(i,j,k-1); - - for (int q_offset(2); q_offset& S_data, const Array4 & cell_prim = S_prim.array(mfi); // TODO: ice has not been dealt with (q1=qv, q2=qv, q3=qp) - ParallelFor(tbz, [=, buoyancy_type=solverChoice.buoyancy_type] AMREX_GPU_DEVICE (int i, int j, int k) - { - Real tempp1d = getTgivenRandRTh(rho_d_ptr[k ], rho_d_ptr[k ]*theta_d_ptr[k ], qv_d_ptr[k ]); - Real tempm1d = getTgivenRandRTh(rho_d_ptr[k-1], rho_d_ptr[k-1]*theta_d_ptr[k-1], qv_d_ptr[k-1]); - - Real tempp3d = getTgivenRandRTh(cell_data(i,j,k ,Rho_comp), - cell_data(i,j,k ,RhoTheta_comp), - cell_data(i,j,k ,RhoQ1_comp)/cell_data(i,j,k ,Rho_comp)); - Real tempm3d = getTgivenRandRTh(cell_data(i,j,k-1,Rho_comp), - cell_data(i,j,k-1,RhoTheta_comp), - cell_data(i,j,k-1,RhoQ1_comp)/cell_data(i,j,k-1,Rho_comp)); - - Real qplus, qminus; - - Real qv_plus = (n_qstate >= 1) ? cell_prim(i,j,k ,PrimQ1_comp) : 0.0; - Real qv_minus = (n_qstate >= 1) ? cell_prim(i,j,k-1,PrimQ1_comp) : 0.0; - - Real qc_plus = (n_qstate >= 2) ? cell_prim(i,j,k ,PrimQ2_comp) : 0.0; - Real qc_minus = (n_qstate >= 2) ? cell_prim(i,j,k-1,PrimQ2_comp) : 0.0; - - Real qp_plus = (n_qstate >= 3) ? cell_prim(i,j,k ,PrimQ3_comp) : 0.0; - Real qp_minus = (n_qstate >= 3) ? cell_prim(i,j,k-1,PrimQ3_comp) : 0.0; - - if (buoyancy_type == 2) { - qplus = 0.61 * ( qv_plus - qv_d_ptr[k] ) - - ( qc_plus - qc_d_ptr[k] + - qp_plus - qp_d_ptr[k] ) - + (tempp3d-tempp1d)/tempp1d*(Real(1.0) + Real(0.61)*qv_d_ptr[k]-qc_d_ptr[k]-qp_d_ptr[k]); - - qminus = 0.61 * ( qv_minus - qv_d_ptr[k-1] ) - - ( qc_minus - qc_d_ptr[k-1] + - qp_minus - qp_d_ptr[k-1] ) - + (tempm3d-tempm1d)/tempm1d*(Real(1.0) + Real(0.61)*qv_d_ptr[k-1]-qc_d_ptr[k-1]-qp_d_ptr[k-1]); - - } else { // (buoyancy_type == 4) - qplus = 0.61 * ( qv_plus - qv_d_ptr[k] ) - - ( qc_plus - qc_d_ptr[k] + - qp_plus - qp_d_ptr[k] ) - + (cell_data(i,j,k ,RhoTheta_comp)/cell_data(i,j,k ,Rho_comp) - theta_d_ptr[k ])/theta_d_ptr[k ]; - - qminus = 0.61 * ( qv_minus - qv_d_ptr[k-1] ) - - ( qc_minus - qc_d_ptr[k-1] + - qp_minus - qp_d_ptr[k-1] ) - + (cell_data(i,j,k-1,RhoTheta_comp)/cell_data(i,j,k-1,Rho_comp) - theta_d_ptr[k-1])/theta_d_ptr[k-1]; - } - - Real qavg = Real(0.5) * (qplus + qminus); - Real r0avg = Real(0.5) * (rho_d_ptr[k] + rho_d_ptr[k-1]); - - buoyancy_fab(i, j, k) = -qavg * r0avg * grav_gpu[2]; - }); + if (solverChoice.buoyancy_type == 2) { + ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + buoyancy_fab(i, j, k) = buoyancy_type2(i,j,k,n_qstate,grav_gpu[2], + rho_d_ptr,theta_d_ptr, + qv_d_ptr,qc_d_ptr,qp_d_ptr, + cell_prim,cell_data); + }); + } else { + ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + buoyancy_fab(i, j, k) = buoyancy_type4(i,j,k,n_qstate,grav_gpu[2], + rho_d_ptr,theta_d_ptr, + qv_d_ptr,qc_d_ptr,qp_d_ptr, + cell_prim,cell_data); + }); + } } // mfi } else if (solverChoice.buoyancy_type == 3) { @@ -344,33 +297,9 @@ void make_buoyancy (Vector& S_data, ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) { - Real tempp1d = getTgivenRandRTh(rho_d_ptr[k ], rho_d_ptr[k ]*theta_d_ptr[k ], qv_d_ptr[k ]); - Real tempm1d = getTgivenRandRTh(rho_d_ptr[k-1], rho_d_ptr[k-1]*theta_d_ptr[k-1], qv_d_ptr[k-1]); - - Real tempp3d = getTgivenRandRTh(cell_data(i,j,k ,Rho_comp), - cell_data(i,j,k ,RhoTheta_comp), - cell_data(i,j,k ,RhoQ1_comp)/cell_data(i,j,k ,Rho_comp)); - Real tempm3d = getTgivenRandRTh(cell_data(i,j,k-1,Rho_comp), - cell_data(i,j,k-1,RhoTheta_comp), - cell_data(i,j,k-1,RhoQ1_comp)/cell_data(i,j,k-1,Rho_comp)); - - Real qv_plus = (n_qstate >= 1) ? cell_prim(i,j,k ,PrimQ1_comp) : 0.0; - Real qv_minus = (n_qstate >= 1) ? cell_prim(i,j,k-1,PrimQ1_comp) : 0.0; - - Real qc_plus = (n_qstate >= 2) ? cell_prim(i,j,k ,PrimQ2_comp) : 0.0; - Real qc_minus = (n_qstate >= 2) ? cell_prim(i,j,k-1,PrimQ2_comp) : 0.0; - - Real qp_plus = (n_qstate >= 3) ? cell_prim(i,j,k ,PrimQ3_comp) : 0.0; - Real qp_minus = (n_qstate >= 3) ? cell_prim(i,j,k-1,PrimQ3_comp) : 0.0; - - Real qplus = 0.61 * qv_plus - (qc_plus + qp_plus) + (tempp3d-tempp1d)/tempp1d; - - Real qminus = 0.61 * qv_minus - (qc_minus + qp_minus) + (tempm3d-tempm1d)/tempm1d; - - Real qavg = Real(0.5) * (qplus + qminus); - Real r0avg = Real(0.5) * (rho_d_ptr[k] + rho_d_ptr[k-1]); - - buoyancy_fab(i, j, k) = -qavg * r0avg * grav_gpu[2]; + buoyancy_fab(i, j, k) = buoyancy_type3(i,j,k,n_qstate,grav_gpu[2], + rho_d_ptr,theta_d_ptr,qv_d_ptr, + cell_prim,cell_data); }); } // mfi } // buoyancy_type diff --git a/Source/SourceTerms/Make.package b/Source/SourceTerms/Make.package index 32cf2443a..2ed03c5a6 100644 --- a/Source/SourceTerms/Make.package +++ b/Source/SourceTerms/Make.package @@ -12,4 +12,4 @@ endif CEXE_headers += ERF_NumericalDiffusion.H CEXE_headers += ERF_Src_headers.H - +CEXE_headers += ERF_buoyancy_utils.H From 1d7b18b18477a02cca29311d71246cb20a520bfe Mon Sep 17 00:00:00 2001 From: Mahesh Natarajan Date: Tue, 29 Oct 2024 14:22:21 -0700 Subject: [PATCH 08/24] Computing power output for wind farms (#1915) * Adding power output for simple actuator disk * Adding time to power output --------- Co-authored-by: Mahesh Natarajan Co-authored-by: Mahesh Natarajan --- Exec/GeneralActuatorDisk/ERF_prob.cpp | 164 ++++++++++++++++++ Source/ERF.H | 3 +- Source/Initialization/ERF_init_windfarm.cpp | 5 +- Source/TimeIntegration/ERF_Advance.cpp | 2 +- Source/WindFarmParametrization/ERF_WindFarm.H | 5 +- .../EWP/ERF_AdvanceEWP.cpp | 4 +- Source/WindFarmParametrization/EWP/ERF_EWP.H | 3 +- .../Fitch/ERF_AdvanceFitch.cpp | 4 +- .../WindFarmParametrization/Fitch/ERF_Fitch.H | 3 +- .../ERF_AdvanceGeneralAD.cpp | 4 +- .../GeneralActuatorDisk/ERF_GeneralAD.H | 3 +- .../Null/ERF_NullWindFarm.H | 3 +- .../ERF_AdvanceSimpleAD.cpp | 33 +++- .../SimpleActuatorDisk/ERF_SimpleAD.H | 5 +- 14 files changed, 226 insertions(+), 15 deletions(-) create mode 100644 Exec/GeneralActuatorDisk/ERF_prob.cpp diff --git a/Exec/GeneralActuatorDisk/ERF_prob.cpp b/Exec/GeneralActuatorDisk/ERF_prob.cpp new file mode 100644 index 000000000..3eeff25fa --- /dev/null +++ b/Exec/GeneralActuatorDisk/ERF_prob.cpp @@ -0,0 +1,164 @@ +#include "ERF_prob.H" +#include "AMReX_Random.H" + +using namespace amrex; + +std::unique_ptr +amrex_probinit(const amrex_real* problo, const amrex_real* probhi) +{ + return std::make_unique(problo, probhi); +} + +Problem::Problem(const amrex::Real* problo, const amrex::Real* probhi) +{ + // Parse params + ParmParse pp("prob"); + pp.query("rho_0", parms.rho_0); + pp.query("T_0", parms.T_0); + pp.query("A_0", parms.A_0); + pp.query("QKE_0", parms.QKE_0); + + pp.query("U_0", parms.U_0); + pp.query("V_0", parms.V_0); + pp.query("W_0", parms.W_0); + pp.query("U_0_Pert_Mag", parms.U_0_Pert_Mag); + pp.query("V_0_Pert_Mag", parms.V_0_Pert_Mag); + pp.query("W_0_Pert_Mag", parms.W_0_Pert_Mag); + pp.query("T_0_Pert_Mag", parms.T_0_Pert_Mag); + + pp.query("pert_deltaU", parms.pert_deltaU); + pp.query("pert_deltaV", parms.pert_deltaV); + pp.query("pert_periods_U", parms.pert_periods_U); + pp.query("pert_periods_V", parms.pert_periods_V); + pp.query("pert_ref_height", parms.pert_ref_height); + parms.aval = parms.pert_periods_U * 2.0 * PI / (probhi[1] - problo[1]); + parms.bval = parms.pert_periods_V * 2.0 * PI / (probhi[0] - problo[0]); + parms.ufac = parms.pert_deltaU * std::exp(0.5) / parms.pert_ref_height; + parms.vfac = parms.pert_deltaV * std::exp(0.5) / parms.pert_ref_height; + + init_base_parms(parms.rho_0, parms.T_0); +} + +void +Problem::init_custom_pert( + const amrex::Box& bx, + const amrex::Box& xbx, + const amrex::Box& ybx, + const amrex::Box& zbx, + amrex::Array4 const& /*state*/, + amrex::Array4 const& state_pert, + amrex::Array4 const& x_vel_pert, + amrex::Array4 const& y_vel_pert, + amrex::Array4 const& z_vel_pert, + amrex::Array4 const& /*r_hse*/, + amrex::Array4 const& /*p_hse*/, + amrex::Array4 const& /*z_nd*/, + amrex::Array4 const& /*z_cc*/, + amrex::GeometryData const& geomdata, + amrex::Array4 const& /*mf_m*/, + amrex::Array4 const& /*mf_u*/, + amrex::Array4 const& /*mf_v*/, + const SolverChoice& sc) +{ + const bool use_moisture = (sc.moisture_type != MoistureType::None); + + ParallelForRNG(bx, [=, parms_d=parms] AMREX_GPU_DEVICE(int i, int j, int k, const amrex::RandomEngine& engine) noexcept { + // Geometry + const Real* prob_lo = geomdata.ProbLo(); + const Real* prob_hi = geomdata.ProbHi(); + const Real* dx = geomdata.CellSize(); + const Real x = prob_lo[0] + (i + 0.5) * dx[0]; + const Real y = prob_lo[1] + (j + 0.5) * dx[1]; + const Real z = prob_lo[2] + (k + 0.5) * dx[2]; + + // Define a point (xc,yc,zc) at the center of the domain + const Real xc = 0.5 * (prob_lo[0] + prob_hi[0]); + const Real yc = 0.5 * (prob_lo[1] + prob_hi[1]); + const Real zc = 0.5 * (prob_lo[2] + prob_hi[2]); + + const Real r = std::sqrt((x-xc)*(x-xc) + (y-yc)*(y-yc) + (z-zc)*(z-zc)); + + // Add temperature perturbations + if ((z <= parms_d.pert_ref_height) && (parms_d.T_0_Pert_Mag != 0.0)) { + Real rand_double = amrex::Random(engine); // Between 0.0 and 1.0 + state_pert(i, j, k, RhoTheta_comp) = (rand_double*2.0 - 1.0)*parms_d.T_0_Pert_Mag; + } + + // Set scalar = A_0*exp(-10r^2), where r is distance from center of domain + state_pert(i, j, k, RhoScalar_comp) = parms_d.A_0 * exp(-10.*r*r); + + // Set an initial value for QKE + //state_pert(i, j, k, RhoQKE_comp) = parms_d.QKE_0; + + if (use_moisture) { + state_pert(i, j, k, RhoQ1_comp) = 0.0; + state_pert(i, j, k, RhoQ2_comp) = 0.0; + } + }); + + // Set the x-velocity + ParallelForRNG(xbx, [=, parms_d=parms] AMREX_GPU_DEVICE(int i, int j, int k, const amrex::RandomEngine& engine) noexcept { + const Real* prob_lo = geomdata.ProbLo(); + const Real* dx = geomdata.CellSize(); + const Real y = prob_lo[1] + (j + 0.5) * dx[1]; + const Real z = prob_lo[2] + (k + 0.5) * dx[2]; + + // Set the x-velocity + x_vel_pert(i, j, k) = parms_d.U_0; + if ((z <= parms_d.pert_ref_height) && (parms_d.U_0_Pert_Mag != 0.0)) + { + Real rand_double = amrex::Random(engine); // Between 0.0 and 1.0 + Real x_vel_prime = (rand_double*2.0 - 1.0)*parms_d.U_0_Pert_Mag; + x_vel_pert(i, j, k) += x_vel_prime; + } + if (parms_d.pert_deltaU != 0.0) + { + const amrex::Real yl = y - prob_lo[1]; + const amrex::Real zl = z / parms_d.pert_ref_height; + const amrex::Real damp = std::exp(-0.5 * zl * zl); + x_vel_pert(i, j, k) += parms_d.ufac * damp * z * std::cos(parms_d.aval * yl); + } + }); + + // Set the y-velocity + ParallelForRNG(ybx, [=, parms_d=parms] AMREX_GPU_DEVICE(int i, int j, int k, const amrex::RandomEngine& engine) noexcept { + const Real* prob_lo = geomdata.ProbLo(); + const Real* dx = geomdata.CellSize(); + const Real x = prob_lo[0] + (i + 0.5) * dx[0]; + const Real z = prob_lo[2] + (k + 0.5) * dx[2]; + + // Set the y-velocity + y_vel_pert(i, j, k) = parms_d.V_0; + if ((z <= parms_d.pert_ref_height) && (parms_d.V_0_Pert_Mag != 0.0)) + { + Real rand_double = amrex::Random(engine); // Between 0.0 and 1.0 + Real y_vel_prime = (rand_double*2.0 - 1.0)*parms_d.V_0_Pert_Mag; + y_vel_pert(i, j, k) += y_vel_prime; + } + if (parms_d.pert_deltaV != 0.0) + { + const amrex::Real xl = x - prob_lo[0]; + const amrex::Real zl = z / parms_d.pert_ref_height; + const amrex::Real damp = std::exp(-0.5 * zl * zl); + y_vel_pert(i, j, k) += parms_d.vfac * damp * z * std::cos(parms_d.bval * xl); + } + }); + + // Set the z-velocity + ParallelForRNG(zbx, [=, parms_d=parms] AMREX_GPU_DEVICE(int i, int j, int k, const amrex::RandomEngine& engine) noexcept { + const int dom_lo_z = geomdata.Domain().smallEnd()[2]; + const int dom_hi_z = geomdata.Domain().bigEnd()[2]; + + // Set the z-velocity + if (k == dom_lo_z || k == dom_hi_z+1) + { + z_vel_pert(i, j, k) = 0.0; + } + else if (parms_d.W_0_Pert_Mag != 0.0) + { + Real rand_double = amrex::Random(engine); // Between 0.0 and 1.0 + Real z_vel_prime = (rand_double*2.0 - 1.0)*parms_d.W_0_Pert_Mag; + z_vel_pert(i, j, k) = parms_d.W_0 + z_vel_prime; + } + }); +} diff --git a/Source/ERF.H b/Source/ERF.H index cafc46489..3c3dda751 100644 --- a/Source/ERF.H +++ b/Source/ERF.H @@ -435,7 +435,8 @@ public: amrex::MultiFab& U_old, amrex::MultiFab& V_old, amrex::MultiFab& W_old, amrex::MultiFab& mf_vars_windfarm, const amrex::MultiFab& mf_Nturb, - const amrex::MultiFab& mf_SMark); + const amrex::MultiFab& mf_SMark, + const amrex::Real& time); #endif #ifdef ERF_USE_EB diff --git a/Source/Initialization/ERF_init_windfarm.cpp b/Source/Initialization/ERF_init_windfarm.cpp index bc41acf57..b87ededd4 100644 --- a/Source/Initialization/ERF_init_windfarm.cpp +++ b/Source/Initialization/ERF_init_windfarm.cpp @@ -59,8 +59,9 @@ ERF::advance_windfarm (const Geometry& a_geom, MultiFab& W_old, MultiFab& mf_vars_windfarm, const MultiFab& mf_Nturb, - const MultiFab& mf_SMark) + const MultiFab& mf_SMark, + const Real& time) { windfarm->advance(a_geom, dt_advance, cons_in, mf_vars_windfarm, - U_old, V_old, W_old, mf_Nturb, mf_SMark); + U_old, V_old, W_old, mf_Nturb, mf_SMark, time); } diff --git a/Source/TimeIntegration/ERF_Advance.cpp b/Source/TimeIntegration/ERF_Advance.cpp index db7cbf1a0..87fc9ee79 100644 --- a/Source/TimeIntegration/ERF_Advance.cpp +++ b/Source/TimeIntegration/ERF_Advance.cpp @@ -110,7 +110,7 @@ ERF::Advance (int lev, Real time, Real dt_lev, int iteration, int /*ncycle*/) #if defined(ERF_USE_WINDFARM) if (solverChoice.windfarm_type != WindFarmType::None) { advance_windfarm(Geom(lev), dt_lev, S_old, - U_old, V_old, W_old, vars_windfarm[lev], Nturb[lev], SMark[lev]); + U_old, V_old, W_old, vars_windfarm[lev], Nturb[lev], SMark[lev], time); } #endif diff --git a/Source/WindFarmParametrization/ERF_WindFarm.H b/Source/WindFarmParametrization/ERF_WindFarm.H index 100a81f0a..945483bbe 100644 --- a/Source/WindFarmParametrization/ERF_WindFarm.H +++ b/Source/WindFarmParametrization/ERF_WindFarm.H @@ -90,10 +90,11 @@ public: amrex::MultiFab& V_old, amrex::MultiFab& W_old, const amrex::MultiFab& mf_Nturb, - const amrex::MultiFab& mf_SMark) override + const amrex::MultiFab& mf_SMark, + const amrex::Real& time) override { m_windfarm_model[0]->advance(a_geom, dt_advance, cons_in, mf_vars_windfarm, - U_old, V_old, W_old, mf_Nturb, mf_SMark); + U_old, V_old, W_old, mf_Nturb, mf_SMark, time); } void set_turb_spec(const amrex::Real& a_rotor_rad, const amrex::Real& a_hub_height, diff --git a/Source/WindFarmParametrization/EWP/ERF_AdvanceEWP.cpp b/Source/WindFarmParametrization/EWP/ERF_AdvanceEWP.cpp index 0522183f5..8ba23af86 100644 --- a/Source/WindFarmParametrization/EWP/ERF_AdvanceEWP.cpp +++ b/Source/WindFarmParametrization/EWP/ERF_AdvanceEWP.cpp @@ -14,9 +14,11 @@ EWP::advance (const Geometry& geom, MultiFab& V_old, MultiFab& W_old, const MultiFab& mf_Nturb, - const MultiFab& mf_SMark) + const MultiFab& mf_SMark, + const Real& time) { AMREX_ALWAYS_ASSERT(mf_SMark.nComp() > 0); + AMREX_ALWAYS_ASSERT(time > -1.0); source_terms_cellcentered(geom, cons_in, mf_vars_ewp, U_old, V_old, W_old, mf_Nturb); update(dt_advance, cons_in, U_old, V_old, mf_vars_ewp); } diff --git a/Source/WindFarmParametrization/EWP/ERF_EWP.H b/Source/WindFarmParametrization/EWP/ERF_EWP.H index c62dd33e4..fbf10efca 100644 --- a/Source/WindFarmParametrization/EWP/ERF_EWP.H +++ b/Source/WindFarmParametrization/EWP/ERF_EWP.H @@ -22,7 +22,8 @@ public: amrex::MultiFab& V_old, amrex::MultiFab& W_old, const amrex::MultiFab& mf_Nturb, - const amrex::MultiFab& mf_SMark) override; + const amrex::MultiFab& mf_SMark, + const amrex::Real& time) override; void source_terms_cellcentered (const amrex::Geometry& geom, const amrex::MultiFab& cons_in, diff --git a/Source/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp b/Source/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp index 7947c847a..68cce5558 100644 --- a/Source/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp +++ b/Source/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp @@ -53,10 +53,12 @@ Fitch::advance (const Geometry& geom, MultiFab& V_old, MultiFab& W_old, const MultiFab& mf_Nturb, - const MultiFab& mf_SMark) + const MultiFab& mf_SMark, + const Real& time) { AMREX_ALWAYS_ASSERT(W_old.nComp() > 0); AMREX_ALWAYS_ASSERT(mf_SMark.nComp() > 0); + AMREX_ALWAYS_ASSERT(time > -1.0); source_terms_cellcentered(geom, cons_in, mf_vars_fitch, U_old, V_old, W_old, mf_Nturb); update(dt_advance, cons_in, U_old, V_old, mf_vars_fitch); } diff --git a/Source/WindFarmParametrization/Fitch/ERF_Fitch.H b/Source/WindFarmParametrization/Fitch/ERF_Fitch.H index ca450ecb9..906a55835 100644 --- a/Source/WindFarmParametrization/Fitch/ERF_Fitch.H +++ b/Source/WindFarmParametrization/Fitch/ERF_Fitch.H @@ -22,7 +22,8 @@ public: amrex::MultiFab& V_old, amrex::MultiFab& W_old, const amrex::MultiFab& mf_Nturb, - const amrex::MultiFab& mf_SMark) override; + const amrex::MultiFab& mf_SMark, + const amrex::Real& time) override; void source_terms_cellcentered (const amrex::Geometry& geom, const amrex::MultiFab& cons_in, diff --git a/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp b/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp index aaa64ceb2..3c4da9eb1 100644 --- a/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp +++ b/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp @@ -14,11 +14,13 @@ GeneralAD::advance (const Geometry& geom, MultiFab& V_old, MultiFab& W_old, const MultiFab& mf_Nturb, - const MultiFab& mf_SMark) + const MultiFab& mf_SMark, + const Real& time) { AMREX_ALWAYS_ASSERT(W_old.nComp() > 0); AMREX_ALWAYS_ASSERT(mf_Nturb.nComp() > 0); AMREX_ALWAYS_ASSERT(mf_vars_generalAD.nComp() > 0); + AMREX_ALWAYS_ASSERT(time > -1.0); compute_freestream_velocity(cons_in, U_old, V_old, mf_SMark); source_terms_cellcentered(geom, cons_in, mf_SMark, mf_vars_generalAD); update(dt_advance, cons_in, U_old, V_old, W_old, mf_vars_generalAD); diff --git a/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_GeneralAD.H b/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_GeneralAD.H index 593b16a48..9092ea312 100644 --- a/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_GeneralAD.H +++ b/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_GeneralAD.H @@ -21,7 +21,8 @@ public: amrex::MultiFab& V_old, amrex::MultiFab& W_old, const amrex::MultiFab& mf_Nturb, - const amrex::MultiFab& mf_SMark) override; + const amrex::MultiFab& mf_SMark, + const amrex::Real& time) override; void compute_freestream_velocity (const amrex::MultiFab& cons_in, const amrex::MultiFab& U_old, diff --git a/Source/WindFarmParametrization/Null/ERF_NullWindFarm.H b/Source/WindFarmParametrization/Null/ERF_NullWindFarm.H index 2daea0aa5..f0714eef3 100644 --- a/Source/WindFarmParametrization/Null/ERF_NullWindFarm.H +++ b/Source/WindFarmParametrization/Null/ERF_NullWindFarm.H @@ -22,7 +22,8 @@ public: amrex::MultiFab& V_old, amrex::MultiFab& W_old, const amrex::MultiFab& mf_Nturb, - const amrex::MultiFab& mf_SMark) = 0; + const amrex::MultiFab& mf_SMark, + const amrex::Real& time) = 0; virtual void set_turb_spec(const amrex::Real& rotor_rad, const amrex::Real& hub_height, const amrex::Real& thrust_coeff_standing, const amrex::Vector& wind_speed, diff --git a/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp b/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp index 7709f6355..038022c7b 100644 --- a/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp +++ b/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp @@ -13,13 +13,44 @@ SimpleAD::advance (const Geometry& geom, MultiFab& V_old, MultiFab& W_old, const MultiFab& mf_Nturb, - const MultiFab& mf_SMark) + const MultiFab& mf_SMark, + const Real& time) { AMREX_ALWAYS_ASSERT(W_old.nComp() > 0); AMREX_ALWAYS_ASSERT(mf_Nturb.nComp() > 0); compute_freestream_velocity(cons_in, U_old, V_old, mf_SMark); source_terms_cellcentered(geom, cons_in, mf_SMark, mf_vars_simpleAD); update(dt_advance, cons_in, U_old, V_old, mf_vars_simpleAD); + compute_power_output(time); +} + +void +SimpleAD::compute_power_output(const Real& time) +{ + get_turb_loc(xloc, yloc); + get_turb_spec(rotor_rad, hub_height, thrust_coeff_standing, + wind_speed, thrust_coeff, power); + + const int n_spec_table = wind_speed.size(); + // Compute power based on the look-up table + + if (ParallelDescriptor::IOProcessor()){ + static std::ofstream file("power_output.txt", std::ios::app); + // Check if the file opened successfully + if (!file.is_open()) { + std::cerr << "Error opening file!" << std::endl; + Abort("Could not open file to write power output in ERF_AdvanceSimpleAD.cpp"); + } + Real total_power = 0.0; + for(int it=0; it xloc, yloc; amrex::Real turb_disk_angle; From 4a4c136ecf04979b14d79edec2b1122124196ed6 Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Tue, 29 Oct 2024 15:31:46 -0700 Subject: [PATCH 09/24] Generalize fillpatching (#1916) * generalize fp, etc * fix re-used variable --- CMake/BuildERFExe.cmake | 1 + .../ERF_BoundaryConditions_basestate.cpp | 126 +++++++++- .../ERF_FillCoarsePatch.cpp | 17 +- .../ERF_FillIntermediatePatch.cpp | 168 ++++++++++++-- Source/BoundaryConditions/ERF_FillPatch.cpp | 215 +++++++++++++----- Source/BoundaryConditions/ERF_PhysBCFunct.H | 5 +- Source/BoundaryConditions/ERF_PhysBCFunct.cpp | 11 + Source/ERF.H | 18 ++ Source/ERF.cpp | 140 +++--------- Source/ERF_make_new_arrays.cpp | 10 +- Source/ERF_make_new_level.cpp | 55 ++--- Source/IO/ERF_Checkpoint.cpp | 64 +++--- Source/IO/ERF_NCColumnFile.cpp | 14 +- Source/IO/ERF_Plotfile.cpp | 18 +- Source/Initialization/ERF_init1d.cpp | 93 +------- Source/TimeIntegration/ERF_Advance.cpp | 24 +- Source/Utils/ERF_AverageDown.cpp | 162 +++++++++++++ Source/Utils/Make.package | 1 + 18 files changed, 780 insertions(+), 362 deletions(-) create mode 100644 Source/Utils/ERF_AverageDown.cpp diff --git a/CMake/BuildERFExe.cmake b/CMake/BuildERFExe.cmake index 6c5d6195d..78d438d47 100644 --- a/CMake/BuildERFExe.cmake +++ b/CMake/BuildERFExe.cmake @@ -187,6 +187,7 @@ function(build_erf_lib erf_lib_name) ${SRC_DIR}/TimeIntegration/ERF_fast_rhs_N.cpp ${SRC_DIR}/TimeIntegration/ERF_fast_rhs_T.cpp ${SRC_DIR}/TimeIntegration/ERF_fast_rhs_MT.cpp + ${SRC_DIR}/Utils/ERF_AverageDown.cpp ${SRC_DIR}/Utils/ERF_ChopGrids.cpp ${SRC_DIR}/Utils/ERF_MomentumToVelocity.cpp ${SRC_DIR}/Utils/ERF_TerrainMetrics.cpp diff --git a/Source/BoundaryConditions/ERF_BoundaryConditions_basestate.cpp b/Source/BoundaryConditions/ERF_BoundaryConditions_basestate.cpp index fbd64a53c..d2101ad4c 100644 --- a/Source/BoundaryConditions/ERF_BoundaryConditions_basestate.cpp +++ b/Source/BoundaryConditions/ERF_BoundaryConditions_basestate.cpp @@ -1,5 +1,6 @@ #include "AMReX_PhysBCFunct.H" #include +#include using namespace amrex; @@ -15,9 +16,14 @@ void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest int ncomp, const IntVect& nghost) { BL_PROFILE_VAR("impose_lateral_base_bcs()",impose_lateral_base_bcs); + // + // Note that the "bx" that comes in here has already been grown in the lateral directions + // but not in the vertical + // const int* bxlo = bx.loVect(); const int* bxhi = bx.hiVect(); + const int* dlo = domain.loVect(); const int* dhi = domain.hiVect(); @@ -63,6 +69,84 @@ void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest // Populate ghost cells on lo-x and hi-x domain boundaries Box bx_xlo(bx); bx_xlo.setBig (0,dom_lo.x-nghost[0]); Box bx_xhi(bx); bx_xhi.setSmall(0,dom_hi.x+nghost[0]); + + ParallelFor( + bx_xlo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) + { + int dest_comp = n; + int l_bc_type = bc_ptr[n].lo(0); + int iflip = dom_lo.x - 1 - i; + if (l_bc_type == ERFBCType::foextrap) { + dest_arr(i,j,k,dest_comp) = dest_arr(dom_lo.x,j,k,dest_comp); + } else if (l_bc_type == ERFBCType::open) { + dest_arr(i,j,k,dest_comp) = dest_arr(dom_lo.x,j,k,dest_comp); + } else if (l_bc_type == ERFBCType::reflect_even) { + dest_arr(i,j,k,dest_comp) = dest_arr(iflip,j,k,dest_comp); + } + }, + bx_xhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) + { + int dest_comp = n; + int h_bc_type = bc_ptr[n].hi(0); + int iflip = 2*dom_hi.x + 1 - i; + if (h_bc_type == ERFBCType::foextrap) { + dest_arr(i,j,k,dest_comp) = dest_arr(dom_hi.x,j,k,dest_comp); + } else if (h_bc_type == ERFBCType::open) { + dest_arr(i,j,k,dest_comp) = dest_arr(dom_hi.x,j,k,dest_comp); + } else if (h_bc_type == ERFBCType::reflect_even) { + dest_arr(i,j,k,dest_comp) = dest_arr(iflip,j,k,dest_comp); + } + } + ); + } + + if (!is_periodic_in_y) + { + // Populate ghost cells on lo-y and hi-y domain boundaries + Box bx_ylo(bx); bx_ylo.setBig (1,dom_lo.y-nghost[1]); + Box bx_yhi(bx); bx_yhi.setSmall(1,dom_hi.y+nghost[1]); + if (bx_ylo.smallEnd(2) != domain.smallEnd(2)) bx_ylo.growLo(2,nghost[2]); + if (bx_ylo.bigEnd(2) != domain.bigEnd(2)) bx_ylo.growHi(2,nghost[2]); + if (bx_yhi.smallEnd(2) != domain.smallEnd(2)) bx_yhi.growLo(2,nghost[2]); + if (bx_yhi.bigEnd(2) != domain.bigEnd(2)) bx_yhi.growHi(2,nghost[2]); + ParallelFor( + bx_ylo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) + { + int dest_comp = n; + int l_bc_type = bc_ptr[n].lo(1); + int jflip = dom_lo.y - 1 - j; + if (l_bc_type == ERFBCType::foextrap) { + dest_arr(i,j,k,dest_comp) = dest_arr(i,dom_lo.y,k,dest_comp); + } else if (l_bc_type == ERFBCType::open) { + dest_arr(i,j,k,dest_comp) = dest_arr(i,dom_lo.y,k,dest_comp); + } else if (l_bc_type == ERFBCType::reflect_even) { + dest_arr(i,j,k,dest_comp) = dest_arr(i,jflip,k,dest_comp); + } + + }, + bx_yhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) + { + int dest_comp = n; + int h_bc_type = bc_ptr[n].hi(1); + int jflip = 2*dom_hi.y + 1 - j; + if (h_bc_type == ERFBCType::foextrap) { + dest_arr(i,j,k,dest_comp) = dest_arr(i,dom_hi.y,k,dest_comp); + } else if (h_bc_type == ERFBCType::open) { + dest_arr(i,j,k,dest_comp) = dest_arr(i,dom_hi.y,k,dest_comp); + } else if (h_bc_type == ERFBCType::reflect_even) { + dest_arr(i,j,k,dest_comp) = dest_arr(i,jflip,k,dest_comp); + } + } + ); + } + + // Next do ghost cells in x-direction but not reaching out in y + // The corners we miss here will be covered in the y-loop below or by periodicity + if (!is_periodic_in_x) + { + // Populate ghost cells on lo-x and hi-x domain boundaries + Box bx_xlo(bx); bx_xlo.setBig (0,dom_lo.x-1); + Box bx_xhi(bx); bx_xhi.setSmall(0,dom_hi.x+1); if (bx_xlo.smallEnd(2) != domain.smallEnd(2)) bx_xlo.growLo(2,nghost[2]); if (bx_xlo.bigEnd(2) != domain.bigEnd(2)) bx_xlo.growHi(2,nghost[2]); if (bx_xhi.smallEnd(2) != domain.smallEnd(2)) bx_xhi.growLo(2,nghost[2]); @@ -79,6 +163,11 @@ void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest dest_arr(i,j,k,dest_comp) = dest_arr(dom_lo.x,j,k,dest_comp); } else if (l_bc_type == ERFBCType::reflect_even) { dest_arr(i,j,k,dest_comp) = dest_arr(iflip,j,k,dest_comp); + } else if (l_bc_type == ERFBCType::reflect_odd) { + dest_arr(i,j,k,dest_comp) = -dest_arr(iflip,j,k,dest_comp); + } else if (l_bc_type == ERFBCType::hoextrapcc) { + Real delta_i = (dom_lo.x - i); + dest_arr(i,j,k,dest_comp) = (1.0 + delta_i)*dest_arr(dom_lo.x,j,k,dest_comp) - delta_i*dest_arr(dom_lo.x+1,j,k,dest_comp) ; } }, bx_xhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) @@ -92,6 +181,11 @@ void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest dest_arr(i,j,k,dest_comp) = dest_arr(dom_hi.x,j,k,dest_comp); } else if (h_bc_type == ERFBCType::reflect_even) { dest_arr(i,j,k,dest_comp) = dest_arr(iflip,j,k,dest_comp); + } else if (h_bc_type == ERFBCType::reflect_odd) { + dest_arr(i,j,k,dest_comp) = -dest_arr(iflip,j,k,dest_comp); + } else if (h_bc_type == ERFBCType::hoextrapcc) { + Real delta_i = (i - dom_hi.x); + dest_arr(i,j,k,dest_comp) = (1.0 + delta_i)*dest_arr(dom_hi.x,j,k,dest_comp) - delta_i*dest_arr(dom_hi.x-1,j,k,dest_comp) ; } } ); @@ -100,8 +194,8 @@ void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest if (!is_periodic_in_y) { // Populate ghost cells on lo-y and hi-y domain boundaries - Box bx_ylo(bx); bx_ylo.setBig (1,dom_lo.y-nghost[1]); - Box bx_yhi(bx); bx_yhi.setSmall(1,dom_hi.y+nghost[1]); + Box bx_ylo(bx); bx_ylo.setBig (1,dom_lo.y-1); + Box bx_yhi(bx); bx_yhi.setSmall(1,dom_hi.y+1); if (bx_ylo.smallEnd(2) != domain.smallEnd(2)) bx_ylo.growLo(2,nghost[2]); if (bx_ylo.bigEnd(2) != domain.bigEnd(2)) bx_ylo.growHi(2,nghost[2]); if (bx_yhi.smallEnd(2) != domain.smallEnd(2)) bx_yhi.growLo(2,nghost[2]); @@ -118,6 +212,11 @@ void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest dest_arr(i,j,k,dest_comp) = dest_arr(i,dom_lo.y,k,dest_comp); } else if (l_bc_type == ERFBCType::reflect_even) { dest_arr(i,j,k,dest_comp) = dest_arr(i,jflip,k,dest_comp); + } else if (l_bc_type == ERFBCType::reflect_odd) { + dest_arr(i,j,k,dest_comp) = -dest_arr(i,jflip,k,dest_comp); + } else if (l_bc_type == ERFBCType::hoextrapcc) { + Real delta_j = (dom_lo.y - j); + dest_arr(i,j,k,dest_comp) = (1.0 + delta_j)*dest_arr(i,dom_lo.y,k,dest_comp) - delta_j*dest_arr(i,dom_lo.y+1,k,dest_comp) ; } }, @@ -132,6 +231,11 @@ void ERFPhysBCFunct_base::impose_lateral_basestate_bcs (const Array4& dest dest_arr(i,j,k,dest_comp) = dest_arr(i,dom_hi.y,k,dest_comp); } else if (h_bc_type == ERFBCType::reflect_even) { dest_arr(i,j,k,dest_comp) = dest_arr(i,jflip,k,dest_comp); + } else if (h_bc_type == ERFBCType::reflect_odd) { + dest_arr(i,j,k,dest_comp) = -dest_arr(i,jflip,k,dest_comp); + } else if (h_bc_type == ERFBCType::hoextrapcc) { + Real delta_j = (j - dom_hi.y); + dest_arr(i,j,k,dest_comp) = (1.0 + delta_j)*dest_arr(i,dom_hi.y,k,dest_comp) - delta_j*dest_arr(i,dom_hi.y-1,k,dest_comp); } } ); @@ -147,8 +251,22 @@ void ERFPhysBCFunct_base::impose_vertical_basestate_bcs (const Array4& des const auto& dom_lo = lbound(domain); const auto& dom_hi = ubound(domain); + const Real hz = Real(0.5) * m_geom.CellSize(2); + + Box bx_zlo1(bx); bx_zlo1.setBig(2,dom_lo.z-1); if (bx_zlo1.ok()) bx_zlo1.setSmall(2,dom_lo.z-1); + ParallelFor( + bx_zlo1, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + dest_arr(i,j,k,BaseState::r0_comp) = dest_arr(i,j,dom_lo.z,BaseState::r0_comp); + dest_arr(i,j,k,BaseState::p0_comp) = p_0 - + dest_arr(i,j,k,BaseState::r0_comp) * hz * 9.81; + dest_arr(i,j,k,BaseState::pi0_comp) = dest_arr(i,j,dom_lo.z,BaseState::pi0_comp); + dest_arr(i,j,k,BaseState::th0_comp) = dest_arr(i,j,dom_lo.z,BaseState::th0_comp); + } + ); + Box bx_zlo(bx); bx_zlo.setBig(2,dom_lo.z-2); - Box bx_zhi(bx); bx_zhi.setSmall(2,dom_hi.z+2); + Box bx_zhi(bx); bx_zhi.setSmall(2,dom_hi.z+1); ParallelFor( bx_zlo, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) { @@ -156,7 +274,7 @@ void ERFPhysBCFunct_base::impose_vertical_basestate_bcs (const Array4& des }, bx_zhi, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) { - dest_arr(i,j,k,n) = dest_arr(i,j,dom_hi.z+1,n); + dest_arr(i,j,k,n) = dest_arr(i,j,dom_hi.z,n); } ); } diff --git a/Source/BoundaryConditions/ERF_FillCoarsePatch.cpp b/Source/BoundaryConditions/ERF_FillCoarsePatch.cpp index 9815d050a..fb900ea7d 100644 --- a/Source/BoundaryConditions/ERF_FillCoarsePatch.cpp +++ b/Source/BoundaryConditions/ERF_FillCoarsePatch.cpp @@ -29,11 +29,18 @@ ERF::FillCoarsePatch (int lev, Real time) //**************************************************************************************************************** // bool cons_only = false; - FillPatch(lev-1, time, {&vars_new[lev-1][Vars::cons], &vars_new[lev-1][Vars::xvel], - &vars_new[lev-1][Vars::yvel], &vars_new[lev-1][Vars::zvel]}, - {&vars_new[lev-1][Vars::cons], - &rU_new[lev-1], &rV_new[lev-1], &rW_new[lev-1]}, - false, cons_only); + if (lev == 1) { + FillPatch(lev-1, time, {&vars_new[lev-1][Vars::cons], &vars_new[lev-1][Vars::xvel], + &vars_new[lev-1][Vars::yvel], &vars_new[lev-1][Vars::zvel]}, + cons_only); + } else { + FillPatch(lev-1, time, {&vars_new[lev-1][Vars::cons], &vars_new[lev-1][Vars::xvel], + &vars_new[lev-1][Vars::yvel], &vars_new[lev-1][Vars::zvel]}, + {&vars_new[lev-1][Vars::cons], + &rU_new[lev-1], &rV_new[lev-1], &rW_new[lev-1]}, + base_state[lev-1], base_state[lev-1], + false, cons_only); + } // // ************************************************ diff --git a/Source/BoundaryConditions/ERF_FillIntermediatePatch.cpp b/Source/BoundaryConditions/ERF_FillIntermediatePatch.cpp index 99be97002..6b8c013e2 100644 --- a/Source/BoundaryConditions/ERF_FillIntermediatePatch.cpp +++ b/Source/BoundaryConditions/ERF_FillIntermediatePatch.cpp @@ -61,28 +61,24 @@ ERF::FillIntermediatePatch (int lev, Real time, } } + // amrex::Print() << "CONS ONLY " << cons_only << std::endl; + // amrex::Print() << "ICOMP NCOMP " << icomp_cons << " " << ncomp_cons << " NGHOST " << ng_cons << std::endl; + AMREX_ALWAYS_ASSERT(mfs_mom.size() == IntVars::NumTypes); AMREX_ALWAYS_ASSERT(mfs_vel.size() == Vars::NumTypes); // Enforce no penetration for thin immersed body - if (xflux_imask[lev]) { - ApplyMask(*mfs_mom[IntVars::xmom], *xflux_imask[lev]); - } - if (yflux_imask[lev]) { - ApplyMask(*mfs_mom[IntVars::ymom], *yflux_imask[lev]); - } - if (zflux_imask[lev]) { - ApplyMask(*mfs_mom[IntVars::zmom], *zflux_imask[lev]); - } - - // We always come in to this call with updated momenta but we need to create updated velocity - // in order to impose the rest of the bc's if (!cons_only) { - // This only fills VALID region of velocity - MomentumToVelocity(*mfs_vel[Vars::xvel], *mfs_vel[Vars::yvel], *mfs_vel[Vars::zvel], - *mfs_vel[Vars::cons], - *mfs_mom[IntVars::xmom], *mfs_mom[IntVars::ymom], *mfs_mom[IntVars::zmom], - Geom(lev).Domain(), domain_bcs_type); + // Enforce no penetration for thin immersed body + if (xflux_imask[lev]) { + ApplyMask(*mfs_mom[IntVars::xmom], *xflux_imask[lev]); + } + if (yflux_imask[lev]) { + ApplyMask(*mfs_mom[IntVars::ymom], *yflux_imask[lev]); + } + if (zflux_imask[lev]) { + ApplyMask(*mfs_mom[IntVars::zmom], *zflux_imask[lev]); + } } // @@ -93,19 +89,82 @@ ERF::FillIntermediatePatch (int lev, Real time, // We don't do anything here because we will call the physbcs routines below, // which calls FillBoundary and fills other domain boundary conditions // Physical boundaries will be filled below + + if (!cons_only) + { + // *************************************************************************** + // We always come in to this call with updated momenta but we need to create updated velocity + // in order to impose the rest of the bc's + // *************************************************************************** + // This only fills VALID region of velocity + MomentumToVelocity(*mfs_vel[Vars::xvel], *mfs_vel[Vars::yvel], *mfs_vel[Vars::zvel], + *mfs_vel[Vars::cons], + *mfs_mom[IntVars::xmom], *mfs_mom[IntVars::ymom], *mfs_mom[IntVars::zmom], + Geom(lev).Domain(), domain_bcs_type); + } } else { - MultiFab& mf = *mfs_vel[Vars::cons]; - - Vector fmf = {&mf,&mf}; + // + // We must fill a temporary then copy it back so we don't double add/subtract + // + MultiFab mf(mfs_vel[Vars::cons]->boxArray(),mfs_vel[Vars::cons]->DistributionMap(), + mfs_vel[Vars::cons]->nComp() ,mfs_vel[Vars::cons]->nGrowVect()); + // + // Set all components to 1.789e19, then copy just the density from *mfs_vel[Vars::cons] + // + mf.setVal(1.789e19); + MultiFab::Copy(mf,*mfs_vel[Vars::cons],Rho_comp,Rho_comp,1,mf.nGrowVect()); + + Vector fmf = {mfs_vel[Vars::cons],mfs_vel[Vars::cons]}; Vector cmf = {&vars_old[lev-1][Vars::cons], &vars_new[lev-1][Vars::cons]}; Vector ctime = {t_old[lev-1], t_new[lev-1]}; Vector ftime = {time,time}; // Impose physical bc's on coarse data (note time and 0 are not used) - (*physbcs_cons[lev-1])(vars_old[lev-1][Vars::cons],0,ncomp_cons,IntVect{ng_cons},time,BCVars::cons_bc,true); - (*physbcs_cons[lev-1])(vars_new[lev-1][Vars::cons],0,ncomp_cons,IntVect{ng_cons},time,BCVars::cons_bc,true); + (*physbcs_cons[lev-1])(vars_old[lev-1][Vars::cons],icomp_cons,ncomp_cons,IntVect{ng_cons},time,BCVars::cons_bc,true); + (*physbcs_cons[lev-1])(vars_new[lev-1][Vars::cons],icomp_cons,ncomp_cons,IntVect{ng_cons},time,BCVars::cons_bc,true); + + // Impose physical bc's on fine data (note time and 0 are not used) + (*physbcs_cons[lev])(*mfs_vel[Vars::cons],icomp_cons,ncomp_cons,IntVect{ng_cons},time,BCVars::cons_bc,true); + + if ( (icomp_cons+ncomp_cons > 1) && (interpolation_type == StateInterpType::Perturbational) ) + { + // Divide (rho theta) by rho to get theta + MultiFab::Divide(*mfs_vel[Vars::cons],*mfs_vel[Vars::cons],Rho_comp,RhoTheta_comp,1,IntVect{0}); + + // Subtract theta_0 from theta + MultiFab::Subtract(*mfs_vel[Vars::cons],base_state[lev],BaseState::th0_comp,RhoTheta_comp,1,IntVect{0}); + + if (!amrex::almostEqual(time,ctime[1])) { + MultiFab::Divide(vars_old[lev-1][Vars::cons], vars_old[lev-1][Vars::cons], + Rho_comp,RhoTheta_comp,1,vars_old[lev-1][Vars::cons].nGrowVect()); + MultiFab::Subtract(vars_old[lev-1][Vars::cons], base_state[lev-1], + BaseState::th0_comp,RhoTheta_comp,1,vars_old[lev-1][Vars::cons].nGrowVect()); + } + if (!amrex::almostEqual(time,ctime[0])) { + MultiFab::Divide(vars_new[lev-1][Vars::cons], vars_new[lev-1][Vars::cons], + Rho_comp,RhoTheta_comp,1,vars_new[lev-1][Vars::cons].nGrowVect()); + MultiFab::Subtract(vars_new[lev-1][Vars::cons], base_state[lev-1], + BaseState::th0_comp,RhoTheta_comp,1,vars_new[lev-1][Vars::cons].nGrowVect()); + } + } + + // Subtract rho_0 from rho before we interpolate -- note we only subtract + // on valid region of mf since the ghost cells will be filled below + if (icomp_cons == 0 && (interpolation_type == StateInterpType::Perturbational)) + { + MultiFab::Subtract(*mfs_vel[Vars::cons],base_state[lev],BaseState::r0_comp,Rho_comp,1,IntVect{0}); + + if (!amrex::almostEqual(time,ctime[1])) { + MultiFab::Subtract(vars_old[lev-1][Vars::cons], base_state[lev-1], + BaseState::r0_comp,Rho_comp,1,vars_old[lev-1][Vars::cons].nGrowVect()); + } + if (!amrex::almostEqual(time,ctime[0])) { + MultiFab::Subtract(vars_new[lev-1][Vars::cons], base_state[lev-1], + BaseState::r0_comp,Rho_comp,1,vars_new[lev-1][Vars::cons].nGrowVect()); + } + } // Call FillPatchTwoLevels which ASSUMES that all ghost cells have already been filled mapper = &cell_cons_interp; @@ -115,10 +174,73 @@ ERF::FillIntermediatePatch (int lev, Real time, refRatio(lev-1), mapper, domain_bcs_type, icomp_cons); + if (icomp_cons == 0 && (interpolation_type == StateInterpType::Perturbational)) + { + // Restore the coarse values to what they were + if (!amrex::almostEqual(time,ctime[1])) { + MultiFab::Add(vars_old[lev-1][Vars::cons], base_state[lev-1], + BaseState::r0_comp,Rho_comp,1,vars_old[lev-1][Vars::cons].nGrowVect()); + } + if (!amrex::almostEqual(time,ctime[0])) { + MultiFab::Add(vars_new[lev-1][Vars::cons], base_state[lev-1], + BaseState::r0_comp,Rho_comp,1,vars_new[lev-1][Vars::cons].nGrowVect()); + } + + // Set values in the cells outside the domain boundary so that we can do the Add + // without worrying about uninitialized values outside the domain -- these + // will be filled in the physbcs call + mf.setDomainBndry(1.234e20,Rho_comp,1,geom[lev]); + + // Add rho_0 back to rho after we interpolate -- on all the valid + ghost region + MultiFab::Add(mf, base_state[lev],BaseState::r0_comp,Rho_comp,1,IntVect{ng_cons}); + } + + if ( (icomp_cons+ncomp_cons > 1) && (interpolation_type == StateInterpType::Perturbational) ) + { + // Add theta_0 to theta + if (!amrex::almostEqual(time,ctime[1])) { + MultiFab::Add(vars_old[lev-1][Vars::cons], base_state[lev-1], + BaseState::th0_comp,RhoTheta_comp,1,vars_old[lev-1][Vars::cons].nGrowVect()); + MultiFab::Multiply(vars_old[lev-1][Vars::cons], vars_old[lev-1][Vars::cons], + Rho_comp,RhoTheta_comp,1,vars_old[lev-1][Vars::cons].nGrowVect()); + } + if (!amrex::almostEqual(time,ctime[0])) { + MultiFab::Add(vars_new[lev-1][Vars::cons], base_state[lev-1], + BaseState::th0_comp,RhoTheta_comp,1,vars_new[lev-1][Vars::cons].nGrowVect()); + MultiFab::Multiply(vars_new[lev-1][Vars::cons], vars_new[lev-1][Vars::cons], + Rho_comp,RhoTheta_comp,1,vars_new[lev-1][Vars::cons].nGrowVect()); + } + + // Multiply theta by rho to get (rho theta) + MultiFab::Multiply(*mfs_vel[Vars::cons],*mfs_vel[Vars::cons],Rho_comp,RhoTheta_comp,1,IntVect{0}); + + // Add theta_0 to theta + MultiFab::Add(*mfs_vel[Vars::cons],base_state[lev],BaseState::th0_comp,RhoTheta_comp,1,IntVect{0}); + + // Add theta_0 back to theta + MultiFab::Add(mf,base_state[lev],BaseState::th0_comp,RhoTheta_comp,1,IntVect{ng_cons}); + + // Multiply (theta) by rho to get (rho theta) + MultiFab::Multiply(mf,mf,Rho_comp,RhoTheta_comp,1,IntVect{ng_cons}); + } + + // Make sure to only copy back the components we worked on + MultiFab::Copy(*mfs_vel[Vars::cons],mf,icomp_cons,icomp_cons,ncomp_cons,IntVect{ng_cons}); + // ***************************************************************************************** if (!cons_only) { + // *************************************************************************** + // We always come in to this call with updated momenta but we need to create updated velocity + // in order to impose the rest of the bc's + // *************************************************************************** + // This only fills VALID region of velocity + MomentumToVelocity(*mfs_vel[Vars::xvel], *mfs_vel[Vars::yvel], *mfs_vel[Vars::zvel], + *mfs_vel[Vars::cons], + *mfs_mom[IntVars::xmom], *mfs_mom[IntVars::ymom], *mfs_mom[IntVars::zmom], + Geom(lev).Domain(), domain_bcs_type); + mapper = &face_cons_linear_interp; // @@ -201,7 +323,7 @@ ERF::FillIntermediatePatch (int lev, Real time, #ifdef ERF_USE_NETCDF // We call this here because it is an ERF routine if (use_real_bcs && (lev==0)) { - fill_from_realbdy(mfs_vel,time,cons_only,icomp_cons,ncomp_cons,ngvect_cons, ngvect_vels); + fill_from_realbdy(mfs_vel,time,cons_only,icomp_cons,ncomp_cons,ngvect_cons,ngvect_vels); do_fb = false; } #endif diff --git a/Source/BoundaryConditions/ERF_FillPatch.cpp b/Source/BoundaryConditions/ERF_FillPatch.cpp index 03f272b55..5913f110b 100644 --- a/Source/BoundaryConditions/ERF_FillPatch.cpp +++ b/Source/BoundaryConditions/ERF_FillPatch.cpp @@ -20,11 +20,15 @@ void ERF::FillPatch (int lev, Real time, const Vector& mfs_vel, // This includes cc quantities and VELOCITIES const Vector& mfs_mom, // This includes cc quantities and MOMENTA + const MultiFab& old_base_state, + const MultiFab& new_base_state, bool fillset, bool cons_only) { BL_PROFILE_VAR("ERF::FillPatch()",ERF_FillPatch); Interpolater* mapper = nullptr; + AMREX_ALWAYS_ASSERT(lev > 0); + PhysBCFunctNoOp null_bc; // @@ -38,7 +42,7 @@ ERF::FillPatch (int lev, Real time, // conditions are imposed on velocity, so we convert to momentum here then // convert back. // *************************************************************************** - if (lev>0 && fillset) { + if (fillset) { if (cf_set_width > 0) { FPr_c[lev-1].FillSet(*mfs_vel[Vars::cons], time, null_bc, domain_bcs_type); } @@ -70,48 +74,56 @@ ERF::FillPatch (int lev, Real time, IntVect ngvect_cons = mfs_vel[Vars::cons]->nGrowVect(); IntVect ngvect_vels = mfs_vel[Vars::xvel]->nGrowVect(); - if (lev == 0) { Vector ftime = {t_old[lev], t_new[lev]}; - - // - // Below we call FillPatchSingleLevel which does NOT fill ghost cells outside the domain - // - - Vector fmf = {&vars_old[lev][Vars::cons], &vars_new[lev][Vars::cons]}; - const int ncomp = mfs_vel[Vars::cons]->nComp(); - - FillPatchSingleLevel(*mfs_vel[Vars::cons], ngvect_cons, time, fmf, IntVect(0,0,0), ftime, - 0, 0, ncomp, geom[lev]); - - if (!cons_only) { - fmf = {&vars_old[lev][Vars::xvel], &vars_new[lev][Vars::xvel]}; - FillPatchSingleLevel(*mfs_vel[Vars::xvel], ngvect_vels, time, fmf, - IntVect(0,0,0), ftime, 0, 0, 1, geom[lev]); - - fmf = {&vars_old[lev][Vars::yvel], &vars_new[lev][Vars::yvel]}; - FillPatchSingleLevel(*mfs_vel[Vars::yvel], ngvect_vels, time, fmf, - IntVect(0,0,0), ftime, 0, 0, 1, geom[lev]); - - fmf = {&vars_old[lev][Vars::zvel], &vars_new[lev][Vars::zvel]}; - FillPatchSingleLevel(*mfs_vel[Vars::zvel], ngvect_vels, time, fmf, - IntVect(0,0,0), ftime, 0, 0, 1, geom[lev]); - } // !cons_only - - } else { - - Vector ftime = {t_old[lev], t_new[lev]}; Vector ctime = {t_old[lev-1], t_new[lev-1]}; Vector fmf = {&vars_old[lev ][Vars::cons], &vars_new[lev ][Vars::cons]}; Vector cmf = {&vars_old[lev-1][Vars::cons], &vars_new[lev-1][Vars::cons]}; - MultiFab& mf_c = *mfs_vel[Vars::cons]; + + // We must fill a temporary then copy it back so we don't double add/subtract + MultiFab mf_c(mfs_vel[Vars::cons]->boxArray(),mfs_vel[Vars::cons]->DistributionMap(), + mfs_vel[Vars::cons]->nComp() ,mfs_vel[Vars::cons]->nGrowVect()); + mapper = &cell_cons_interp; - // Impose physical bc's on coarse data (note time and 0 are not used) - // Note that we call FillBoundary inside the physbcs call - // We should not need to call this on old data since that would have been filled before the timestep started - (*physbcs_cons[lev-1])(vars_new[lev-1][Vars::cons],0,mf_c.nComp(),ngvect_cons,time,BCVars::cons_bc,true); + if (interpolation_type == StateInterpType::Perturbational) + { + // Divide (rho theta) by rho to get theta (before we subtract rho0 from rho!) + if (!amrex::almostEqual(time,ctime[1])) { + MultiFab::Divide(vars_old[lev-1][Vars::cons],vars_old[lev-1][Vars::cons], + Rho_comp,RhoTheta_comp,1,ngvect_cons); + MultiFab::Subtract(vars_old[lev-1][Vars::cons],base_state[lev-1], + BaseState::r0_comp,Rho_comp,1,ngvect_cons); + MultiFab::Subtract(vars_old[lev-1][Vars::cons],base_state[lev-1], + BaseState::th0_comp,RhoTheta_comp,1,ngvect_cons); + } + if (!amrex::almostEqual(time,ctime[0])) { + MultiFab::Divide(vars_new[lev-1][Vars::cons],vars_new[lev-1][Vars::cons], + Rho_comp,RhoTheta_comp,1,ngvect_cons); + MultiFab::Subtract(vars_new[lev-1][Vars::cons],base_state[lev-1], + BaseState::r0_comp,Rho_comp,1,ngvect_cons); + MultiFab::Subtract(vars_new[lev-1][Vars::cons],base_state[lev-1], + BaseState::th0_comp,RhoTheta_comp,1,ngvect_cons); + } + + if (!amrex::almostEqual(time,ftime[1])) { + MultiFab::Divide(vars_old[lev ][Vars::cons],vars_old[lev ][Vars::cons], + Rho_comp,RhoTheta_comp,1,IntVect{0}); + MultiFab::Subtract(vars_old[lev ][Vars::cons],old_base_state, + BaseState::r0_comp,Rho_comp,1,IntVect{0}); + MultiFab::Subtract(vars_old[lev ][Vars::cons],old_base_state, + BaseState::th0_comp,RhoTheta_comp,1,IntVect{0}); + } + if (!amrex::almostEqual(time,ftime[0])) { + MultiFab::Divide(vars_new[lev ][Vars::cons],vars_new[lev ][Vars::cons], + Rho_comp,RhoTheta_comp,1,IntVect{0}); + MultiFab::Subtract(vars_new[lev ][Vars::cons],old_base_state, + BaseState::r0_comp,Rho_comp,1,IntVect{0}); + MultiFab::Subtract(vars_new[lev ][Vars::cons],old_base_state, + BaseState::th0_comp,RhoTheta_comp,1,IntVect{0}); + } + } // Call FillPatchTwoLevels which ASSUMES that all ghost cells have already been filled FillPatchTwoLevels(mf_c, ngvect_cons, IntVect(0,0,0), @@ -120,6 +132,56 @@ ERF::FillPatch (int lev, Real time, refRatio(lev-1), mapper, domain_bcs_type, BCVars::cons_bc); + if (interpolation_type == StateInterpType::Perturbational) + { + // Restore the coarse values to what they were + if (!amrex::almostEqual(time,ctime[1])) { + MultiFab::Add(vars_old[lev-1][Vars::cons], base_state[lev-1], + BaseState::r0_comp,Rho_comp,1,ngvect_cons); + MultiFab::Add(vars_old[lev-1][Vars::cons], base_state[lev-1], + BaseState::th0_comp,RhoTheta_comp,1,ngvect_cons); + MultiFab::Multiply(vars_old[lev-1][Vars::cons], vars_old[lev-1][Vars::cons], + Rho_comp,RhoTheta_comp,1,ngvect_cons); + } + if (!amrex::almostEqual(time,ctime[0])) { + MultiFab::Add(vars_new[lev-1][Vars::cons], base_state[lev-1], + BaseState::r0_comp,Rho_comp,1,vars_new[lev-1][Vars::cons].nGrowVect()); + MultiFab::Add(vars_new[lev-1][Vars::cons], base_state[lev-1], + BaseState::th0_comp,RhoTheta_comp,1,vars_new[lev-1][Vars::cons].nGrowVect()); + MultiFab::Multiply(vars_new[lev-1][Vars::cons], vars_new[lev-1][Vars::cons], + Rho_comp,RhoTheta_comp,1,ngvect_cons); + } + + if (!amrex::almostEqual(time,ftime[1])) { + MultiFab::Add(vars_old[lev][Vars::cons],base_state[lev ],BaseState::r0_comp,Rho_comp,1,ngvect_cons); + MultiFab::Add(vars_old[lev][Vars::cons],base_state[lev ],BaseState::th0_comp,RhoTheta_comp,1,ngvect_cons); + MultiFab::Multiply(vars_old[lev][Vars::cons], vars_old[lev][Vars::cons], + Rho_comp,RhoTheta_comp,1,ngvect_cons); + } + if (!amrex::almostEqual(time,ftime[0])) { + MultiFab::Add(vars_new[lev][Vars::cons], base_state[lev],BaseState::r0_comp,Rho_comp,1,ngvect_cons); + MultiFab::Add(vars_new[lev][Vars::cons], base_state[lev],BaseState::th0_comp,RhoTheta_comp,1,ngvect_cons); + MultiFab::Multiply(vars_new[lev][Vars::cons], vars_new[lev][Vars::cons], + Rho_comp,RhoTheta_comp,1,ngvect_cons); + } + + // Set values in the cells outside the domain boundary so that we can do the Add + // without worrying about uninitialized values outside the domain -- these + // will be filled in the physbcs call + mf_c.setDomainBndry(1.234e20,0,2,geom[lev]); // Do both rho and (rho theta) together + + // Add rho_0 back to rho and theta_0 back to theta + MultiFab::Add(mf_c, new_base_state,BaseState::r0_comp,Rho_comp,1,ngvect_cons); + MultiFab::Add(mf_c, new_base_state,BaseState::th0_comp,RhoTheta_comp,1,ngvect_cons); + + // Multiply (theta) by rho to get (rho theta) + MultiFab::Multiply(mf_c,mf_c,Rho_comp,RhoTheta_comp,1,ngvect_cons); + } + + MultiFab::Copy(*mfs_vel[Vars::cons],mf_c,0,0,mf_c.nComp(),mf_c.nGrowVect()); + + // *************************************************************************************** + if (!cons_only) { mapper = &face_cons_linear_interp; @@ -130,13 +192,6 @@ ERF::FillPatch (int lev, Real time, // ********************************************************************** - cmf = {&vars_old[lev-1][Vars::xvel], &vars_new[lev-1][Vars::xvel]}; - - // Impose physical bc's on coarse data (note time and 0 are not used) - // Note that we call FillBoundary inside the physbcs call - // We should not need to call this on old data since that would have been filled before the timestep started - (*physbcs_u[lev-1])(vars_new[lev-1][Vars::xvel],0,1,ngvect_vels,time,BCVars::xvel_bc,true); - fmf = {&vars_old[lev ][Vars::xvel], &vars_new[lev ][Vars::xvel]}; cmf = {&vars_old[lev-1][Vars::xvel], &vars_new[lev-1][Vars::xvel]}; @@ -149,13 +204,6 @@ ERF::FillPatch (int lev, Real time, // ********************************************************************** - cmf = {&vars_old[lev-1][Vars::yvel], &vars_new[lev-1][Vars::yvel]}; - - // Impose physical bc's on coarse data (note time and 0 are not used) - // Note that we call FillBoundary inside the physbcs call - // We should not need to call this on old data since that would have been filled before the timestep started - (*physbcs_v[lev-1])(vars_new[lev-1][Vars::yvel],0,1,ngvect_vels,time,BCVars::yvel_bc,true); - fmf = {&vars_old[lev ][Vars::yvel], &vars_new[lev ][Vars::yvel]}; cmf = {&vars_old[lev-1][Vars::yvel], &vars_new[lev-1][Vars::yvel]}; @@ -168,16 +216,6 @@ ERF::FillPatch (int lev, Real time, // ********************************************************************** - cmf = {&vars_old[lev-1][Vars::zvel], &vars_new[lev-1][Vars::zvel]}; - - // Impose physical bc's on coarse data (note time and 0 are not used) - // Note that we call FillBoundary inside the physbcs call - // We should not need to call this on old data since that would have been filled before the timestep started - (*physbcs_w[lev-1])(vars_new[lev-1][Vars::zvel], - vars_new[lev-1][Vars::xvel], - vars_new[lev-1][Vars::yvel], - ngvect_vels,time,BCVars::zvel_bc,true); - fmf = {&vars_old[lev ][Vars::zvel], &vars_new[lev ][Vars::zvel]}; cmf = {&vars_old[lev-1][Vars::zvel], &vars_new[lev-1][Vars::zvel]}; @@ -198,6 +236,65 @@ ERF::FillPatch (int lev, Real time, bool do_fb = true; + if (m_r2d) fill_from_bndryregs(mfs_vel,time); + + // We call these even if init_type == InitType::Real because these will fill the vertical bcs + // Note that we call FillBoundary inside the physbcs call + (*physbcs_cons[lev])(*mfs_vel[Vars::cons],icomp_cons,ncomp_cons,ngvect_cons,time,BCVars::cons_bc, do_fb); + if (!cons_only) { + (*physbcs_u[lev])(*mfs_vel[Vars::xvel],0,1,ngvect_vels,time,BCVars::xvel_bc, do_fb); + (*physbcs_v[lev])(*mfs_vel[Vars::yvel],0,1,ngvect_vels,time,BCVars::yvel_bc, do_fb); + (*physbcs_w[lev])(*mfs_vel[Vars::zvel],*mfs_vel[Vars::xvel],*mfs_vel[Vars::yvel], + ngvect_vels,time,BCVars::zvel_bc, do_fb); + } +} + +void +ERF::FillPatch (int lev, Real time, + const Vector& mfs_vel, // This includes cc quantities and VELOCITIES + bool cons_only) +{ + BL_PROFILE_VAR("ERF::FillPatch()",ERF_FillPatch); + + AMREX_ALWAYS_ASSERT(lev == 0); + + IntVect ngvect_cons = mfs_vel[Vars::cons]->nGrowVect(); + IntVect ngvect_vels = mfs_vel[Vars::xvel]->nGrowVect(); + + Vector ftime = {t_old[lev], t_new[lev]}; + + // + // Below we call FillPatchSingleLevel which does NOT fill ghost cells outside the domain + // + + Vector fmf = {&vars_old[lev][Vars::cons], &vars_new[lev][Vars::cons]}; + const int ncomp = mfs_vel[Vars::cons]->nComp(); + + FillPatchSingleLevel(*mfs_vel[Vars::cons], ngvect_cons, time, fmf, IntVect(0,0,0), ftime, + 0, 0, ncomp, geom[lev]); + + if (!cons_only) { + fmf = {&vars_old[lev][Vars::xvel], &vars_new[lev][Vars::xvel]}; + FillPatchSingleLevel(*mfs_vel[Vars::xvel], ngvect_vels, time, fmf, + IntVect(0,0,0), ftime, 0, 0, 1, geom[lev]); + + fmf = {&vars_old[lev][Vars::yvel], &vars_new[lev][Vars::yvel]}; + FillPatchSingleLevel(*mfs_vel[Vars::yvel], ngvect_vels, time, fmf, + IntVect(0,0,0), ftime, 0, 0, 1, geom[lev]); + + fmf = {&vars_old[lev][Vars::zvel], &vars_new[lev][Vars::zvel]}; + FillPatchSingleLevel(*mfs_vel[Vars::zvel], ngvect_vels, time, fmf, + IntVect(0,0,0), ftime, 0, 0, 1, geom[lev]); + } // !cons_only + + // *************************************************************************** + // Physical bc's at domain boundary + // *************************************************************************** + int icomp_cons = 0; + int ncomp_cons = mfs_vel[Vars::cons]->nComp(); + + bool do_fb = true; + #ifdef ERF_USE_NETCDF // We call this here because it is an ERF routine if (use_real_bcs && (lev==0)) { diff --git a/Source/BoundaryConditions/ERF_PhysBCFunct.H b/Source/BoundaryConditions/ERF_PhysBCFunct.H index 3666ea06c..756e4725d 100644 --- a/Source/BoundaryConditions/ERF_PhysBCFunct.H +++ b/Source/BoundaryConditions/ERF_PhysBCFunct.H @@ -262,8 +262,10 @@ class ERFPhysBCFunct_base public: ERFPhysBCFunct_base (const int lev, const amrex::Geometry& geom, const amrex::Vector& domain_bcs_type, - const amrex::Gpu::DeviceVector& domain_bcs_type_d) + const amrex::Gpu::DeviceVector& domain_bcs_type_d, + bool moving_terrain) : m_lev(lev), m_geom(geom), + m_moving_terrain(moving_terrain), m_domain_bcs_type(domain_bcs_type), m_domain_bcs_type_d(domain_bcs_type_d) {} @@ -291,6 +293,7 @@ public: private: int m_lev; amrex::Geometry m_geom; + bool m_moving_terrain; amrex::Vector m_domain_bcs_type; amrex::Gpu::DeviceVector m_domain_bcs_type_d; }; diff --git a/Source/BoundaryConditions/ERF_PhysBCFunct.cpp b/Source/BoundaryConditions/ERF_PhysBCFunct.cpp index 3b055a9fa..fb5a18f8f 100644 --- a/Source/BoundaryConditions/ERF_PhysBCFunct.cpp +++ b/Source/BoundaryConditions/ERF_PhysBCFunct.cpp @@ -372,6 +372,11 @@ void ERFPhysBCFunct_base::operator() (MultiFab& mf, int /*icomp*/, int ncomp, In if (m_geom.isAllPeriodic()) return; + if (m_moving_terrain) { + mf.FillBoundary(m_geom.periodicity()); + return; + } + const auto& domain = m_geom.Domain(); // Create a grown domain box containing valid + periodic cells @@ -382,6 +387,12 @@ void ERFPhysBCFunct_base::operator() (MultiFab& mf, int /*icomp*/, int ncomp, In } } + // + // We fill all of the interior and periodic ghost cells first, so we can fill + // those directly inside the lateral and vertical calls. + // + mf.FillBoundary(m_geom.periodicity()); + #ifdef AMREX_USE_OMP #pragma omp parallel if (Gpu::notInLaunchRegion()) #endif diff --git a/Source/ERF.H b/Source/ERF.H index 3c3dda751..2af6c99f9 100644 --- a/Source/ERF.H +++ b/Source/ERF.H @@ -78,6 +78,13 @@ AMREX_ENUM(InitType, None, Input_Sounding, Ideal, Real, Metgrid, Uniform ); +/** + * Enum of possible interpolation types between coarse/fine +*/ +AMREX_ENUM(StateInterpType, + FullState, Perturbational +); + /** * Enum of possible plotfile types */ @@ -86,6 +93,7 @@ AMREX_ENUM(PlotFileType, ); +#if 0 /** * Enum of possible coarse/fine interpolation options */ @@ -102,6 +110,7 @@ namespace InterpType { FaceConserativeLinear }; } +#endif /** * Main class in ERF code, instantiated from main.cpp @@ -516,9 +525,17 @@ private: // // NOTE: FillPatch takes in an empty MF, and returns cell-centered + velocities (not momenta) // + // This one works only at level = 0 (base state does not change) + void FillPatch (int lev, amrex::Real time, + const amrex::Vector& mfs_vel, + bool cons_only=false); + + // This one works only at level > 0 (base state does change) void FillPatch (int lev, amrex::Real time, const amrex::Vector& mfs_vel, const amrex::Vector& mfs_mom, + const amrex::MultiFab& old_base_state, + const amrex::MultiFab& new_base_state, bool fillset=true, bool cons_only=false); // Compute new multifabs by copying data from valid region and filling ghost cells. @@ -978,6 +995,7 @@ private: static PlotFileType plotfile_type_2; static InitType init_type; + static StateInterpType interpolation_type; // sponge_type: "input_sponge" static std::string sponge_type; diff --git a/Source/ERF.cpp b/Source/ERF.cpp index 1c81680fb..a39415562 100644 --- a/Source/ERF.cpp +++ b/Source/ERF.cpp @@ -45,6 +45,7 @@ PlotFileType ERF::plotfile_type_1 = PlotFileType::None; PlotFileType ERF::plotfile_type_2 = PlotFileType::None; InitType ERF::init_type; +StateInterpType ERF::interpolation_type; // use_real_bcs: only true if 1) ( (init_type == InitType::Real) or (init_type == InitGrid::Metgrid) ) // AND 2) we want to use the bc's from the WRF bdy file @@ -874,6 +875,18 @@ ERF::InitData_post () int ncomp = lev_new[Vars::cons].nComp(); + // *************************************************************************** + // Physical bc's at domain boundary + // *************************************************************************** + IntVect ngvect_cons = vars_new[lev][Vars::cons].nGrowVect(); + IntVect ngvect_vels = vars_new[lev][Vars::xvel].nGrowVect(); + + (*physbcs_cons[lev])(lev_new[Vars::cons],0,ncomp,ngvect_cons,t_new[lev],BCVars::cons_bc,true); + ( *physbcs_u[lev])(lev_new[Vars::xvel],0,1 ,ngvect_vels,t_new[lev],BCVars::xvel_bc,true); + ( *physbcs_v[lev])(lev_new[Vars::yvel],0,1 ,ngvect_vels,t_new[lev],BCVars::yvel_bc,true); + ( *physbcs_w[lev])(lev_new[Vars::zvel],lev_new[Vars::xvel],lev_new[Vars::yvel], + ngvect_vels,t_new[lev],BCVars::zvel_bc,true); + MultiFab::Copy(lev_old[Vars::cons],lev_new[Vars::cons],0,0,ncomp,lev_new[Vars::cons].nGrowVect()); MultiFab::Copy(lev_old[Vars::xvel],lev_new[Vars::xvel],0,0, 1,lev_new[Vars::xvel].nGrowVect()); MultiFab::Copy(lev_old[Vars::yvel],lev_new[Vars::yvel],0,0, 1,lev_new[Vars::yvel].nGrowVect()); @@ -905,10 +918,16 @@ ERF::InitData_post () // Fill boundary conditions -- not sure why we need this here // bool fillset = false; - FillPatch(lev, t_new[lev], - {&lev_new[Vars::cons],&lev_new[Vars::xvel],&lev_new[Vars::yvel],&lev_new[Vars::zvel]}, - {&lev_new[Vars::cons],&rU_new[lev],&rV_new[lev],&rW_new[lev]}, - fillset); + if (lev == 0) { + FillPatch(lev, t_new[lev], + {&lev_new[Vars::cons],&lev_new[Vars::xvel],&lev_new[Vars::yvel],&lev_new[Vars::zvel]}); + } else { + FillPatch(lev, t_new[lev], + {&lev_new[Vars::cons],&lev_new[Vars::xvel],&lev_new[Vars::yvel],&lev_new[Vars::zvel]}, + {&lev_new[Vars::cons],&rU_new[lev],&rV_new[lev],&rW_new[lev]}, + base_state[lev], base_state[lev], + fillset); + } // // We do this here to make sure level (lev-1) boundary conditions are filled @@ -1460,6 +1479,10 @@ ERF::ReadParameters () // Flag to trigger initialization from input_sounding like WRF's ideal.exe pp.query("init_sounding_ideal", init_sounding_ideal); + // Set default to FullState for now ... later we will try Perturbation + interpolation_type = StateInterpType::FullState; + pp.query_enum_case_insensitive("interpolation_type" ,interpolation_type); + PlotFileType plotfile_type_temp = PlotFileType::None; pp.query_enum_case_insensitive("plotfile_type" ,plotfile_type_temp); pp.query_enum_case_insensitive("plotfile_type_1",plotfile_type_1); @@ -1814,115 +1837,6 @@ ERF::MakeDiagnosticAverage (Vector& h_havg, MultiFab& S, int n) } } -// Set covered coarse cells to be the average of overlying fine cells for all levels -void -ERF::AverageDown () -{ - AMREX_ALWAYS_ASSERT(solverChoice.coupling_type == CouplingType::TwoWay); - int src_comp = 0; - int num_comp = vars_new[0][Vars::cons].nComp(); - for (int lev = finest_level-1; lev >= 0; --lev) - { - AverageDownTo(lev,src_comp,num_comp); - } -} - -// Set covered coarse cells to be the average of overlying fine cells at level crse_lev -void -ERF::AverageDownTo (int crse_lev, int scomp, int ncomp) // NOLINT -{ - AMREX_ALWAYS_ASSERT(solverChoice.coupling_type == CouplingType::TwoWay); - - // ****************************************************************************************** - // First do cell-centered quantities - // The quantity that is conserved is not (rho S), but rather (rho S / m^2) where - // m is the map scale factor at cell centers - // Here we pre-divide (rho S) by m^2 before average down - // ****************************************************************************************** - for (int lev = crse_lev; lev <= crse_lev+1; lev++) { - for (MFIter mfi(vars_new[lev][Vars::cons], TilingIfNotGPU()); mfi.isValid(); ++mfi) { - const Box& bx = mfi.tilebox(); - const Array4< Real> cons_arr = vars_new[lev][Vars::cons].array(mfi); - const Array4 mapfac_arr = mapfac_m[lev]->const_array(mfi); - if (solverChoice.use_terrain) { - const Array4 detJ_arr = detJ_cc[lev]->const_array(mfi); - ParallelFor(bx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { - cons_arr(i,j,k,scomp+n) *= detJ_arr(i,j,k) / (mapfac_arr(i,j,0)*mapfac_arr(i,j,0)); - }); - } else { - ParallelFor(bx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { - cons_arr(i,j,k,scomp+n) /= (mapfac_arr(i,j,0)*mapfac_arr(i,j,0)); - }); - } - } // mfi - } // lev - - average_down(vars_new[crse_lev+1][Vars::cons], - vars_new[crse_lev ][Vars::cons], - scomp, ncomp, refRatio(crse_lev)); - - // Here we multiply (rho S) by m^2 after average down - for (int lev = crse_lev; lev <= crse_lev+1; lev++) { - for (MFIter mfi(vars_new[lev][Vars::cons], TilingIfNotGPU()); mfi.isValid(); ++mfi) { - const Box& bx = mfi.tilebox(); - const Array4< Real> cons_arr = vars_new[lev][Vars::cons].array(mfi); - const Array4 mapfac_arr = mapfac_m[lev]->const_array(mfi); - if (solverChoice.use_terrain) { - const Array4 detJ_arr = detJ_cc[lev]->const_array(mfi); - ParallelFor(bx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { - cons_arr(i,j,k,scomp+n) *= (mapfac_arr(i,j,0)*mapfac_arr(i,j,0)) / detJ_arr(i,j,k); - }); - } else { - ParallelFor(bx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept - { - cons_arr(i,j,k,scomp+n) *= (mapfac_arr(i,j,0)*mapfac_arr(i,j,0)); - }); - } - } // mfi - } // lev - - // ****************************************************************************************** - // Now average down momenta. - // Note that vars_new holds velocities not momenta, but we want to do conservative - // averaging so we first convert to momentum, then average down, then convert - // back to velocities -- only on the valid region - // ****************************************************************************************** - for (int lev = crse_lev; lev <= crse_lev+1; lev++) - { - // FillBoundary for density so we can go back and forth between velocity and momentum - vars_new[lev][Vars::cons].FillBoundary(geom[lev].periodicity()); - - VelocityToMomentum(vars_new[lev][Vars::xvel], IntVect(0,0,0), - vars_new[lev][Vars::yvel], IntVect(0,0,0), - vars_new[lev][Vars::zvel], IntVect(0,0,0), - vars_new[lev][Vars::cons], - rU_new[lev], - rV_new[lev], - rW_new[lev], - Geom(lev).Domain(), - domain_bcs_type); - } - - average_down_faces(rU_new[crse_lev+1], rU_new[crse_lev], refRatio(crse_lev), geom[crse_lev]); - average_down_faces(rV_new[crse_lev+1], rV_new[crse_lev], refRatio(crse_lev), geom[crse_lev]); - average_down_faces(rW_new[crse_lev+1], rW_new[crse_lev], refRatio(crse_lev), geom[crse_lev]); - - for (int lev = crse_lev; lev <= crse_lev+1; lev++) { - MomentumToVelocity(vars_new[lev][Vars::xvel], - vars_new[lev][Vars::yvel], - vars_new[lev][Vars::zvel], - vars_new[lev][Vars::cons], - rU_new[lev], - rV_new[lev], - rW_new[lev], - Geom(lev).Domain(), - domain_bcs_type); - } -} - void ERF::Construct_ERFFillPatchers (int lev) { diff --git a/Source/ERF_make_new_arrays.cpp b/Source/ERF_make_new_arrays.cpp index 39c89acf5..a93d83780 100644 --- a/Source/ERF_make_new_arrays.cpp +++ b/Source/ERF_make_new_arrays.cpp @@ -26,13 +26,16 @@ ERF::init_stuff (int lev, const BoxArray& ba, const DistributionMapping& dm, std::unique_ptr& tmp_zphys_nd) { // ******************************************************************************************** - // Base state holds r_0, pres_0, pi_0 (in that order) + // Base state holds r_0, pres_0, pi_0, th_0 (in that order) + // + // Here is where we set 3 ghost cells for the base state! + // // ******************************************************************************************** tmp_base_state.define(ba,dm,BaseState::num_comps,3); tmp_base_state.setVal(0.); if (solverChoice.use_terrain && solverChoice.terrain_type == TerrainType::Moving) { - base_state_new[lev].define(ba,dm,BaseState::num_comps,3); + base_state_new[lev].define(ba,dm,BaseState::num_comps,base_state[lev].nGrowVect()); base_state_new[lev].setVal(0.); } @@ -557,5 +560,6 @@ ERF::make_physbcs (int lev) m_bc_extdir_vals, m_bc_neumann_vals, solverChoice.terrain_type, z_phys_nd[lev], use_real_bcs, zvel_bc_data[lev].data()); - physbcs_base[lev] = std::make_unique (lev, geom[lev], domain_bcs_type, domain_bcs_type_d); + physbcs_base[lev] = std::make_unique (lev, geom[lev], domain_bcs_type, domain_bcs_type_d, + (solverChoice.terrain_type == TerrainType::Moving)); } diff --git a/Source/ERF_make_new_level.cpp b/Source/ERF_make_new_level.cpp index f248edf5b..282114b7d 100644 --- a/Source/ERF_make_new_level.cpp +++ b/Source/ERF_make_new_level.cpp @@ -47,7 +47,7 @@ void ERF::MakeNewLevelFromScratch (int lev, Real time, const BoxArray& ba_in, // Define dmap[lev] to be dm SetDistributionMap(lev, dm); - amrex::Print() <<" BA FROM SCRATCH AT LEVEL " << lev << " " << ba << std::endl; + // amrex::Print() <<" BA FROM SCRATCH AT LEVEL " << lev << " " << ba << std::endl; if (lev == 0) init_bcs(); @@ -283,7 +283,7 @@ ERF::MakeNewLevelFromCoarse (int lev, Real time, const BoxArray& ba, void ERF::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMapping& dm) { - amrex::Print() <<" REMAKING WITH NEW BA AT LEVEL " << lev << " " << ba << std::endl; + // amrex::Print() <<" REMAKING WITH NEW BA AT LEVEL " << lev << " " << ba << std::endl; AMREX_ALWAYS_ASSERT(lev > 0); AMREX_ALWAYS_ASSERT(solverChoice.terrain_type != TerrainType::Moving); @@ -332,39 +332,40 @@ ERF::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMapp // ***************************************************************************************************** make_physbcs(lev); - // ************************************************************************************************* - // This will fill the temporary MultiFabs with data from vars_new - // NOTE: the momenta here are only used as scratch space, the momenta themselves are not fillpatched - // ************************************************************************************************* - FillPatch(lev, time, {&temp_lev_new[Vars::cons],&temp_lev_new[Vars::xvel], - &temp_lev_new[Vars::yvel],&temp_lev_new[Vars::zvel]}, - {&temp_lev_new[Vars::cons],&rU_new[lev],&rV_new[lev],&rW_new[lev]}, - false); - // ******************************************************************************************** // Update the base state at this level by interpolation from coarser level AND copy // from previous (pre-regrid) base_state array // ******************************************************************************************** - if (lev > 0) { - Interpolater* mapper = &cell_cons_interp; + Interpolater* mapper = &cell_cons_interp; - Vector fmf = {&base_state[lev ], &base_state[lev ]}; - Vector cmf = {&base_state[lev-1], &base_state[lev-1]}; - Vector ftime = {time, time}; - Vector ctime = {time, time}; + Vector fmf = {&base_state[lev ], &base_state[lev ]}; + Vector cmf = {&base_state[lev-1], &base_state[lev-1]}; + Vector ftime = {time, time}; + Vector ctime = {time, time}; - // Call FillPatch which ASSUMES that all ghost cells at lev-1 have already been filled - FillPatchTwoLevels(temp_base_state, temp_base_state.nGrowVect(), IntVect(0,0,0), - time, cmf, ctime, fmf, ftime, - 0, 0, temp_base_state.nComp(), geom[lev-1], geom[lev], - refRatio(lev-1), mapper, domain_bcs_type, - BCVars::base_bc); + // Call FillPatch which ASSUMES that all ghost cells at lev-1 have already been filled + FillPatchTwoLevels(temp_base_state, temp_base_state.nGrowVect(), IntVect(0,0,0), + time, cmf, ctime, fmf, ftime, + 0, 0, temp_base_state.nComp(), geom[lev-1], geom[lev], + refRatio(lev-1), mapper, domain_bcs_type, + BCVars::base_bc); - // Impose bc's outside the domain - (*physbcs_base[lev])(temp_base_state,0,temp_base_state.nComp(),base_state[lev].nGrowVect()); + // Impose bc's outside the domain + (*physbcs_base[lev])(temp_base_state,0,temp_base_state.nComp(),base_state[lev].nGrowVect()); - std::swap(temp_base_state, base_state[lev]); - } + // ************************************************************************************************* + // This will fill the temporary MultiFabs with data from vars_new + // NOTE: the momenta here are only used as scratch space, the momenta themselves are not fillpatched + // NOTE: we must create the new base state before calling FillPatch because we will + // interpolate perturbational quantities + // ************************************************************************************************* + FillPatch(lev, time, {&temp_lev_new[Vars::cons],&temp_lev_new[Vars::xvel], + &temp_lev_new[Vars::yvel],&temp_lev_new[Vars::zvel]}, + {&temp_lev_new[Vars::cons],&rU_new[lev],&rV_new[lev],&rW_new[lev]}, + base_state[lev], temp_base_state, false); + + // Now swap the pointers since we needed both old and new in the FillPatch + std::swap(temp_base_state, base_state[lev]); // ******************************************************************************************** // Copy from new into old just in case diff --git a/Source/IO/ERF_Checkpoint.cpp b/Source/IO/ERF_Checkpoint.cpp index af211bf22..9137bace2 100644 --- a/Source/IO/ERF_Checkpoint.cpp +++ b/Source/IO/ERF_Checkpoint.cpp @@ -132,22 +132,22 @@ ERF::WriteCheckpointFile () const // Note that we write the ghost cells of the base state (unlike above) // For backward compatibility we only write the first components and 1 ghost cell - IntVect ng; int ncomp; + IntVect ng_base; int ncomp_base; bool write_old_base_state = true; if (write_old_base_state) { - ng = IntVect{1}; - ncomp = 3; + ng_base = IntVect{1}; + ncomp_base = 3; } else { - ng = base_state[lev].nGrowVect(); - ncomp = base_state[lev].nComp(); + ng_base = base_state[lev].nGrowVect(); + ncomp_base = base_state[lev].nComp(); } - MultiFab base(grids[lev],dmap[lev],ncomp,ng); - MultiFab::Copy(base,base_state[lev],0,0,ncomp,ng); + MultiFab base(grids[lev],dmap[lev],ncomp_base,ng_base); + MultiFab::Copy(base,base_state[lev],0,0,ncomp_base,ng_base); VisMF::Write(base, MultiFabFileFullPrefix(lev, checkpointname, "Level_", "BaseState")); if (solverChoice.use_terrain) { // Note that we also write the ghost cells of z_phys_nd - ng = z_phys_nd[lev]->nGrowVect(); + IntVect ng = z_phys_nd[lev]->nGrowVect(); MultiFab z_height(convert(grids[lev],IntVect(1,1,1)),dmap[lev],1,ng); MultiFab::Copy(z_height,*z_phys_nd[lev],0,0,1,ng); VisMF::Write(z_height, MultiFabFileFullPrefix(lev, checkpointname, "Level_", "Z_Phys_nd")); @@ -160,10 +160,10 @@ ERF::WriteCheckpointFile () const micro->Get_Qmoist_Restart_Vars(lev, solverChoice, qmoist_indices, qmoist_names); int qmoist_nvar = qmoist_indices.size(); for (int var = 0; var < qmoist_nvar; var++) { - ng = qmoist[lev][qmoist_indices[var]]->nGrowVect(); - ncomp = 1; - MultiFab moist_vars(grids[lev],dmap[lev],ncomp,ng); - MultiFab::Copy(moist_vars,*(qmoist[lev][qmoist_indices[var]]),0,0,ncomp,ng); + IntVect ng_moist = qmoist[lev][qmoist_indices[var]]->nGrowVect(); + const int ncomp = 1; + MultiFab moist_vars(grids[lev],dmap[lev],ncomp,ng_moist); + MultiFab::Copy(moist_vars,*(qmoist[lev][qmoist_indices[var]]),0,0,ncomp,ng_moist); VisMF::Write(moist_vars, amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", qmoist_names[var])); } @@ -171,9 +171,9 @@ ERF::WriteCheckpointFile () const if(solverChoice.windfarm_type == WindFarmType::Fitch or solverChoice.windfarm_type == WindFarmType::EWP or solverChoice.windfarm_type == WindFarmType::SimpleAD){ - ng = Nturb[lev].nGrowVect(); - MultiFab mf_Nturb(grids[lev],dmap[lev],1,ng); - MultiFab::Copy(mf_Nturb,Nturb[lev],0,0,1,ng); + IntVect ng_turb = Nturb[lev].nGrowVect(); + MultiFab mf_Nturb(grids[lev],dmap[lev],1,ng_turb); + MultiFab::Copy(mf_Nturb,Nturb[lev],0,0,1,ng_turb); VisMF::Write(mf_Nturb, amrex::MultiFabFileFullPrefix(lev, checkpointname, "Level_", "NumTurb")); } #endif @@ -182,7 +182,7 @@ ERF::WriteCheckpointFile () const for (int mvar(0); mvarboxArray(); DistributionMapping dm = lsm_data[lev][mvar]->DistributionMap(); - ng = lsm_data[lev][mvar]->nGrowVect(); + IntVect ng = lsm_data[lev][mvar]->nGrowVect(); int nvar = lsm_data[lev][mvar]->nComp(); MultiFab lsm_vars(ba,dm,nvar,ng); MultiFab::Copy(lsm_vars,*(lsm_data[lev][mvar]),0,0,nvar,ng); @@ -197,7 +197,7 @@ ERF::WriteCheckpointFile () const } BoxArray ba2d(std::move(bl2d)); - ng = mapfac_m[lev]->nGrowVect(); + IntVect ng = mapfac_m[lev]->nGrowVect(); MultiFab mf_m(ba2d,dmap[lev],1,ng); MultiFab::Copy(mf_m,*mapfac_m[lev],0,0,1,ng); VisMF::Write(mf_m, MultiFabFileFullPrefix(lev, checkpointname, "Level_", "MapFactor_m")); @@ -414,18 +414,18 @@ ERF::ReadCheckpointFile () // The original base state only had 3 components and 1 ghost cell -- we read this // here to be consistent with the old style - IntVect ng; int ncomp; + IntVect ng_base; int ncomp_base; bool read_old_base_state = true; if (read_old_base_state) { - ng = IntVect{1}; - ncomp = 3; + ng_base = IntVect{1}; + ncomp_base = 3; } else { - ng = base_state[lev].nGrowVect(); - ncomp = base_state[lev].nComp(); + ng_base = base_state[lev].nGrowVect(); + ncomp_base = base_state[lev].nComp(); } - MultiFab base(grids[lev],dmap[lev],ncomp,ng); + MultiFab base(grids[lev],dmap[lev],ncomp_base,ng_base); VisMF::Read(base, MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "BaseState")); - MultiFab::Copy(base_state[lev],base,0,0,ncomp,ng); + MultiFab::Copy(base_state[lev],base,0,0,ncomp_base,ng_base); if (read_old_base_state) { for (MFIter mfi(base_state[lev],TilingIfNotGPU()); mfi.isValid(); ++mfi) { @@ -442,7 +442,7 @@ ERF::ReadCheckpointFile () if (solverChoice.use_terrain) { // Note that we also read the ghost cells of z_phys_nd - ng = z_phys_nd[lev]->nGrowVect(); + IntVect ng = z_phys_nd[lev]->nGrowVect(); MultiFab z_height(convert(grids[lev],IntVect(1,1,1)),dmap[lev],1,ng); VisMF::Read(z_height, MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "Z_Phys_nd")); MultiFab::Copy(*z_phys_nd[lev],z_height,0,0,1,ng); @@ -455,11 +455,11 @@ ERF::ReadCheckpointFile () micro->Get_Qmoist_Restart_Vars(lev, solverChoice, qmoist_indices, qmoist_names); int qmoist_nvar = qmoist_indices.size(); for (int var = 0; var < qmoist_nvar; var++) { - ng = qmoist[lev][qmoist_indices[var]]->nGrowVect(); - ncomp = 1; - MultiFab moist_vars(grids[lev],dmap[lev],ncomp,ng); + IntVect ng_moist = qmoist[lev][qmoist_indices[var]]->nGrowVect(); + const int ncomp_moist = 1; + MultiFab moist_vars(grids[lev],dmap[lev],ncomp_moist,ng_moist); VisMF::Read(moist_vars, amrex::MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", qmoist_names[var])); - MultiFab::Copy(*(qmoist[lev][qmoist_indices[var]]),moist_vars,0,0,ncomp,ng); + MultiFab::Copy(*(qmoist[lev][qmoist_indices[var]]),moist_vars,0,0,ncomp_moist,ng_moist); } #if defined(ERF_USE_WINDFARM) @@ -477,7 +477,7 @@ ERF::ReadCheckpointFile () for (int mvar(0); mvarboxArray(); DistributionMapping dm = lsm_data[lev][mvar]->DistributionMap(); - ng = lsm_data[lev][mvar]->nGrowVect(); + IntVect ng = lsm_data[lev][mvar]->nGrowVect(); int nvar = lsm_data[lev][mvar]->nComp(); MultiFab lsm_vars(ba,dm,nvar,ng); VisMF::Read(lsm_vars, MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "LsmVars")); @@ -492,7 +492,8 @@ ERF::ReadCheckpointFile () } BoxArray ba2d(std::move(bl2d)); - ng = mapfac_m[lev]->nGrowVect(); + { + IntVect ng = mapfac_m[lev]->nGrowVect(); MultiFab mf_m(ba2d,dmap[lev],1,ng); VisMF::Read(mf_m, MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "MapFactor_m")); MultiFab::Copy(*mapfac_m[lev],mf_m,0,0,1,ng); @@ -506,6 +507,7 @@ ERF::ReadCheckpointFile () MultiFab mf_v(convert(ba2d,IntVect(0,1,0)),dmap[lev],1,ng); VisMF::Read(mf_v, MultiFabFileFullPrefix(lev, restart_chkfile, "Level_", "MapFactor_v")); MultiFab::Copy(*mapfac_v[lev],mf_v,0,0,1,ng); + } } #ifdef ERF_USE_PARTICLES diff --git a/Source/IO/ERF_NCColumnFile.cpp b/Source/IO/ERF_NCColumnFile.cpp index eba2f2931..68720d353 100644 --- a/Source/IO/ERF_NCColumnFile.cpp +++ b/Source/IO/ERF_NCColumnFile.cpp @@ -121,10 +121,16 @@ ERF::writeToNCColumnFile (const int lev, // Need data in one grow cell for interpolation // Note that vars_new is what's filled here; rU_new/rV_new/rW_new are just used as scratch space - FillPatch(lev, t_new[lev], {&vars_new[lev][Vars::cons], &vars_new[lev][Vars::xvel], - &vars_new[lev][Vars::yvel], &vars_new[lev][Vars::zvel]}, - {&vars_new[lev][Vars::cons], &rU_new[lev], - &rV_new[lev], &rW_new[lev]}); + if (lev == 0) { + FillPatch(lev, t_new[lev], {&vars_new[lev][Vars::cons], &vars_new[lev][Vars::xvel], + &vars_new[lev][Vars::yvel], &vars_new[lev][Vars::zvel]}); + } else { + FillPatch(lev, t_new[lev], {&vars_new[lev][Vars::cons], &vars_new[lev][Vars::xvel], + &vars_new[lev][Vars::yvel], &vars_new[lev][Vars::zvel]}, + {&vars_new[lev][Vars::cons], &rU_new[lev], + &rV_new[lev], &rW_new[lev]}, + base_state[lev], base_state[lev]); + } MultiFab& S_new = vars_new[lev][Vars::cons]; MultiFab& U_new = vars_new[lev][Vars::xvel]; diff --git a/Source/IO/ERF_Plotfile.cpp b/Source/IO/ERF_Plotfile.cpp index ad08b384c..c8b7294e9 100644 --- a/Source/IO/ERF_Plotfile.cpp +++ b/Source/IO/ERF_Plotfile.cpp @@ -185,12 +185,6 @@ ERF::PlotFileVarNames (Vector plot_var_names ) void ERF::WritePlotFile (int which, PlotFileType plotfile_type, Vector plot_var_names) { - if (plotfile_type == PlotFileType::Amrex) { - amrex::Print() << "WRITE AMREX " << std::endl; - } else if (plotfile_type == PlotFileType::Netcdf) { - amrex::Print() << "WRITE NETCDF " << std::endl; - } - const Vector varnames = PlotFileVarNames(plot_var_names); const int ncomp_mf = varnames.size(); @@ -202,12 +196,18 @@ ERF::WritePlotFile (int which, PlotFileType plotfile_type, Vector p // which require ghost cells to be filled. We do not need to call FillPatcher // because we don't need to set interior fine points. // NOTE: the momenta here are only used as scratch space, the momenta themselves are not fillpatched - for (int lev = 0; lev <= finest_level; ++lev) { + + // Level 0 FilLPatch + FillPatch(0, t_new[0], {&vars_new[0][Vars::cons], &vars_new[0][Vars::xvel], + &vars_new[0][Vars::yvel], &vars_new[0][Vars::zvel]}); + + for (int lev = 1; lev <= finest_level; ++lev) { bool fillset = false; FillPatch(lev, t_new[lev], {&vars_new[lev][Vars::cons], &vars_new[lev][Vars::xvel], &vars_new[lev][Vars::yvel], &vars_new[lev][Vars::zvel]}, - {&vars_new[lev][Vars::cons], &rU_new[lev], - &rV_new[lev], &rW_new[lev]}, fillset); + {&vars_new[lev][Vars::cons], + &rU_new[lev], &rV_new[lev], &rW_new[lev]}, + base_state[lev], base_state[lev], fillset); } // Get qmoist pointers if using moisture diff --git a/Source/Initialization/ERF_init1d.cpp b/Source/Initialization/ERF_init1d.cpp index 1f6bc28f5..5bbe00d32 100644 --- a/Source/Initialization/ERF_init1d.cpp +++ b/Source/Initialization/ERF_init1d.cpp @@ -124,8 +124,6 @@ ERF::initHSE (int lev) // but inside the domain have already been filled in the call above to InterpFromCoarseLevel // (*physbcs_base[lev])(base_state[lev],0,base_state[lev].nComp(),base_state[lev].nGrowVect()); - - base_state[lev].FillBoundary(geom[lev].periodicity()); } void @@ -158,8 +156,6 @@ ERF::erf_enforce_hse (int lev, const auto geomdata = geom[lev].data(); const Real dz = geomdata.CellSize(2); - const Box& domain = geom[lev].Domain(); - for ( MFIter mfi(dens, TileNoZ()); mfi.isValid(); ++mfi ) { // Create a flat box with same horizontal extent but only one cell in vertical @@ -167,8 +163,10 @@ ERF::erf_enforce_hse (int lev, int klo = tbz.smallEnd(2); int khi = tbz.bigEnd(2); + // Note we only grow by 1 because that is how big z_cc is. Box b2d = tbz; // Copy constructor - b2d.grow(0,1); b2d.grow(1,1); // Grow by one in the lateral directions + b2d.grow(0,1); + b2d.grow(1,1); b2d.setRange(2,0); // We integrate to the first cell (and below) by using rho in this cell @@ -191,13 +189,11 @@ ERF::erf_enforce_hse (int lev, const Real rdOcp = solverChoice.rdOcp; - IntVect ngvect = base_state[lev].nGrowVect(); - int ng_z = ngvect[2]; - ParallelFor(b2d, [=] AMREX_GPU_DEVICE (int i, int j, int) { // Set value at surface from Newton iteration for rho - if (klo == 0) { + if (klo == 0) + { // Physical height of the terrain at cell center Real hz; if (l_use_terrain) { @@ -210,17 +206,16 @@ ERF::erf_enforce_hse (int lev, pi_arr(i,j,klo) = getExnergivenP(pres_arr(i,j,klo), rdOcp); th_arr(i,j,klo) =getRhoThetagivenP(pres_arr(i,j,klo)) / rho_arr(i,j,klo); + // // Set ghost cell with dz and rho at boundary + // (We will set the rest of the ghost cells in the boundary condition routine) + // pres_arr(i,j,klo-1) = p_0 + hz * rho_arr(i,j,klo) * l_gravity; pi_arr(i,j,klo-1) = getExnergivenP(pres_arr(i,j,klo-1), rdOcp); th_arr(i,j,klo-1) = getRhoThetagivenP(pres_arr(i,j,klo-1)) / rho_arr(i,j,klo-1); - for (int kk = 2; kk <= ng_z; kk++) { - pres_arr(i,j,klo-kk) = pres_arr(i,j,klo-1); - pi_arr(i,j,klo-kk) = pi_arr(i,j,klo-1); - th_arr(i,j,klo-kk) = th_arr(i,j,klo-1); - } } else { + // If level > 0 and klo > 0, we need to use the value of pres_arr(i,j,klo-1) which was // filled from FillPatch-ing it. Real dz_loc; @@ -236,11 +231,8 @@ ERF::erf_enforce_hse (int lev, pi_arr(i,j,klo ) = getExnergivenP(pres_arr(i,j,klo ), rdOcp); th_arr(i,j,klo ) = getRhoThetagivenP(pres_arr(i,j,klo )) / rho_arr(i,j,klo ); - for (int kk = 1; kk <= ng_z; kk++) { - pi_arr(i,j,klo-kk) = getExnergivenP(pres_arr(i,j,klo-kk), rdOcp); - th_arr(i,j,klo-kk) = getRhoThetagivenP(pres_arr(i,j,klo-kk)) / rho_arr(i,j,klo-kk); - } - + pi_arr(i,j,klo-1) = getExnergivenP(pres_arr(i,j,klo-1), rdOcp); + th_arr(i,j,klo-1) = getRhoThetagivenP(pres_arr(i,j,klo-1)) / rho_arr(i,j,klo-1); } Real dens_interp; @@ -262,68 +254,7 @@ ERF::erf_enforce_hse (int lev, } }); - bool is_periodic_in_x = geom[lev].isPeriodic(0); - bool is_periodic_in_y = geom[lev].isPeriodic(1); - - int domlo_x = domain.smallEnd(0); int domhi_x = domain.bigEnd(0); - int domlo_y = domain.smallEnd(1); int domhi_y = domain.bigEnd(1); - - if (!is_periodic_in_x) { - if (pres[mfi].box().smallEnd(0) < domlo_x) { - Box bx = mfi.nodaltilebox(2); - int ng = ngvect[0]; - bx.setSmall(0,domlo_x-1); - bx.setBig(0,domlo_x-ng); - ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) - { - pres_arr(i,j,k) = pres_arr(domlo_x,j,k); - pi_arr(i,j,k) = pi_arr(domlo_x,j,k); - th_arr(i,j,k) = th_arr(domlo_x,j,k); - }); - } - - if (pres[mfi].box().bigEnd(0) > domhi_x) { - Box bx = mfi.nodaltilebox(2); - int ng = ngvect[0]; - bx.setSmall(0,domhi_x+1); - bx.setBig(0,domhi_x+ng); - ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) - { - pres_arr(i,j,k) = pres_arr(domhi_x,j,k); - pi_arr(i,j,k) = pi_arr(domhi_x,j,k); - th_arr(i,j,k) = th_arr(domhi_x,j,k); - }); - } - } - - if (!is_periodic_in_y) { - if (pres[mfi].box().smallEnd(1) < domlo_y) { - Box bx = mfi.nodaltilebox(2); - int ng = ngvect[1]; - bx.setSmall(1,domlo_y-ng); - bx.setBig(1,domlo_y-1); - ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) - { - pres_arr(i,j,k) = pres_arr(i,domlo_y,k); - pi_arr(i,j,k) = pi_arr(i,domlo_y,k); - th_arr(i,j,k) = th_arr(i,domlo_y,k); - }); - } - - if (pres[mfi].box().bigEnd(1) > domhi_y) { - Box bx = mfi.nodaltilebox(2); - int ng = ngvect[1]; - bx.setSmall(1,domhi_y+1); - bx.setBig(1,domhi_y+ng); - ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) - { - pres_arr(i,j,k) = pres_arr(i,domhi_y,k); - pi_arr(i,j,k) = pi_arr(i,domhi_y,k); - th_arr(i,j,k) = th_arr(i,domhi_y,k); - }); - } - } - } + } // mfi dens.FillBoundary(geom[lev].periodicity()); pres.FillBoundary(geom[lev].periodicity()); diff --git a/Source/TimeIntegration/ERF_Advance.cpp b/Source/TimeIntegration/ERF_Advance.cpp index 87fc9ee79..2a8a73497 100644 --- a/Source/TimeIntegration/ERF_Advance.cpp +++ b/Source/TimeIntegration/ERF_Advance.cpp @@ -95,8 +95,14 @@ ERF::Advance (int lev, Real time, Real dt_lev, int iteration, int /*ncycle*/) // // NOTE: the momenta here are not fillpatched (they are only used as scratch space) // - FillPatch(lev, time, {&S_old, &U_old, &V_old, &W_old}, - {&S_old, &rU_old[lev], &rV_old[lev], &rW_old[lev]}); + if (lev == 0) { + FillPatch(lev, time, {&S_old, &U_old, &V_old, &W_old}); + } else { + FillPatch(lev, time, {&S_old, &U_old, &V_old, &W_old}, + {&S_old, &rU_old[lev], &rV_old[lev], &rW_old[lev]}, + base_state[lev], base_state[lev]); + } + // // So we must convert the fillpatched to momenta, including the ghost values // @@ -192,6 +198,20 @@ ERF::Advance (int lev, Real time, Real dt_lev, int iteration, int /*ncycle*/) evolveTracers( lev, dt_lev, vars_new, z_phys_nd ); #endif + // *********************************************************************************************** + // Impose domain boundary conditions here so that in FillPatching the fine data we won't + // need to re-fill these + // *********************************************************************************************** + if (lev < finest_level) { + IntVect ngvect_vels = vars_new[lev][Vars::xvel].nGrowVect(); + (*physbcs_cons[lev])(vars_new[lev][Vars::cons],0,vars_new[lev][Vars::cons].nComp(), + vars_new[lev][Vars::cons].nGrowVect(),time,BCVars::cons_bc,true); + (*physbcs_u[lev])(vars_new[lev][Vars::xvel],0,1,ngvect_vels,time,BCVars::xvel_bc,true); + (*physbcs_v[lev])(vars_new[lev][Vars::yvel],0,1,ngvect_vels,time,BCVars::yvel_bc,true); + (*physbcs_w[lev])(vars_new[lev][Vars::zvel], vars_new[lev][Vars::xvel], vars_new[lev][Vars::yvel], + ngvect_vels,time,BCVars::zvel_bc,true); + } + // ************************************************************************************** // Register old and new coarse data if we are at a level less than the finest level // ************************************************************************************** diff --git a/Source/Utils/ERF_AverageDown.cpp b/Source/Utils/ERF_AverageDown.cpp new file mode 100644 index 000000000..1741b011f --- /dev/null +++ b/Source/Utils/ERF_AverageDown.cpp @@ -0,0 +1,162 @@ +/** + * \file ERF_AverageDown.cpp + */ + +/** + * Main class in ERF code, instantiated from main.cpp +*/ + +#include +#include + +using namespace amrex; + +// Set covered coarse cells to be the average of overlying fine cells for all levels +void +ERF::AverageDown () +{ + AMREX_ALWAYS_ASSERT(solverChoice.coupling_type == CouplingType::TwoWay); + int src_comp = 0; + int num_comp = vars_new[0][Vars::cons].nComp(); + for (int lev = finest_level-1; lev >= 0; --lev) + { + AverageDownTo(lev,src_comp,num_comp); + } +} + +// Set covered coarse cells to be the average of overlying fine cells at level crse_lev +void +ERF::AverageDownTo (int crse_lev, int scomp, int ncomp) // NOLINT +{ + AMREX_ALWAYS_ASSERT(scomp == 0); + AMREX_ALWAYS_ASSERT(ncomp == vars_new[crse_lev][Vars::cons].nComp()); + AMREX_ALWAYS_ASSERT(solverChoice.coupling_type == CouplingType::TwoWay); + + // ****************************************************************************************** + // First do cell-centered quantities + // The quantity that is conserved is not (rho S), but rather (rho S / m^2) where + // m is the map scale factor at cell centers + // Here we pre-divide (rho S) by m^2 before average down + // ****************************************************************************************** + for (int lev = crse_lev; lev <= crse_lev+1; lev++) { + for (MFIter mfi(vars_new[lev][Vars::cons], TilingIfNotGPU()); mfi.isValid(); ++mfi) { + const Box& bx = mfi.tilebox(); + const Array4< Real> cons_arr = vars_new[lev][Vars::cons].array(mfi); + const Array4 mapfac_arr = mapfac_m[lev]->const_array(mfi); + if (solverChoice.use_terrain) { + const Array4 detJ_arr = detJ_cc[lev]->const_array(mfi); + ParallelFor(bx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { + cons_arr(i,j,k,scomp+n) *= detJ_arr(i,j,k) / (mapfac_arr(i,j,0)*mapfac_arr(i,j,0)); + }); + } else { + ParallelFor(bx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { + cons_arr(i,j,k,scomp+n) /= (mapfac_arr(i,j,0)*mapfac_arr(i,j,0)); + }); + } + } // mfi + } // lev + + int fine_lev = crse_lev+1; + + if (interpolation_type == StateInterpType::Perturbational) { + // Make the fine rho and (rho theta) be perturbational + MultiFab::Divide(vars_new[fine_lev][Vars::cons],vars_new[fine_lev][Vars::cons], + Rho_comp,RhoTheta_comp,1,IntVect{0}); + MultiFab::Subtract(vars_new[fine_lev][Vars::cons],base_state[fine_lev], + BaseState::r0_comp,Rho_comp,1,IntVect{0}); + MultiFab::Subtract(vars_new[fine_lev][Vars::cons],base_state[fine_lev], + BaseState::th0_comp,RhoTheta_comp,1,IntVect{0}); + + // Make the crse rho and (rho theta) be perturbational + MultiFab::Divide(vars_new[crse_lev][Vars::cons],vars_new[crse_lev][Vars::cons], + Rho_comp,RhoTheta_comp,1,IntVect{0}); + MultiFab::Subtract(vars_new[crse_lev][Vars::cons],base_state[crse_lev], + BaseState::r0_comp,Rho_comp,1,IntVect{0}); + MultiFab::Subtract(vars_new[crse_lev][Vars::cons],base_state[crse_lev], + BaseState::th0_comp,RhoTheta_comp,1,IntVect{0}); + } + + average_down(vars_new[crse_lev+1][Vars::cons],vars_new[crse_lev ][Vars::cons], + scomp, ncomp, refRatio(crse_lev)); + + if (interpolation_type == StateInterpType::Perturbational) { + // Restore the fine data to what it was + MultiFab::Add(vars_new[fine_lev][Vars::cons],base_state[fine_lev], + BaseState::r0_comp,Rho_comp,1,IntVect{0}); + MultiFab::Add(vars_new[fine_lev][Vars::cons],base_state[fine_lev], + BaseState::th0_comp,RhoTheta_comp,1,IntVect{0}); + MultiFab::Multiply(vars_new[fine_lev][Vars::cons],vars_new[fine_lev][Vars::cons], + Rho_comp,RhoTheta_comp,1,IntVect{0}); + + // Make the crse data be full values not perturbational + MultiFab::Add(vars_new[crse_lev][Vars::cons],base_state[crse_lev], + BaseState::r0_comp,Rho_comp,1,IntVect{0}); + MultiFab::Add(vars_new[crse_lev][Vars::cons],base_state[crse_lev], + BaseState::th0_comp,RhoTheta_comp,1,IntVect{0}); + MultiFab::Multiply(vars_new[crse_lev][Vars::cons],vars_new[crse_lev][Vars::cons], + Rho_comp,RhoTheta_comp,1,IntVect{0}); + } + + vars_new[crse_lev][Vars::cons].FillBoundary(geom[crse_lev].periodicity()); + + // Here we multiply (rho S) by m^2 after average down + for (int lev = crse_lev; lev <= crse_lev+1; lev++) { + for (MFIter mfi(vars_new[lev][Vars::cons], TilingIfNotGPU()); mfi.isValid(); ++mfi) { + const Box& bx = mfi.tilebox(); + const Array4< Real> cons_arr = vars_new[lev][Vars::cons].array(mfi); + const Array4 mapfac_arr = mapfac_m[lev]->const_array(mfi); + if (solverChoice.use_terrain) { + const Array4 detJ_arr = detJ_cc[lev]->const_array(mfi); + ParallelFor(bx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { + cons_arr(i,j,k,scomp+n) *= (mapfac_arr(i,j,0)*mapfac_arr(i,j,0)) / detJ_arr(i,j,k); + }); + } else { + ParallelFor(bx, ncomp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept + { + cons_arr(i,j,k,scomp+n) *= (mapfac_arr(i,j,0)*mapfac_arr(i,j,0)); + }); + } + } // mfi + } // lev + + // ****************************************************************************************** + // Now average down momenta. + // Note that vars_new holds velocities not momenta, but we want to do conservative + // averaging so we first convert to momentum, then average down, then convert + // back to velocities -- only on the valid region + // ****************************************************************************************** + for (int lev = crse_lev; lev <= crse_lev+1; lev++) + { + // FillBoundary for density so we can go back and forth between velocity and momentum + vars_new[lev][Vars::cons].FillBoundary(geom[lev].periodicity()); + + VelocityToMomentum(vars_new[lev][Vars::xvel], IntVect(0,0,0), + vars_new[lev][Vars::yvel], IntVect(0,0,0), + vars_new[lev][Vars::zvel], IntVect(0,0,0), + vars_new[lev][Vars::cons], + rU_new[lev], + rV_new[lev], + rW_new[lev], + Geom(lev).Domain(), + domain_bcs_type); + } + + average_down_faces(rU_new[crse_lev+1], rU_new[crse_lev], refRatio(crse_lev), geom[crse_lev]); + average_down_faces(rV_new[crse_lev+1], rV_new[crse_lev], refRatio(crse_lev), geom[crse_lev]); + average_down_faces(rW_new[crse_lev+1], rW_new[crse_lev], refRatio(crse_lev), geom[crse_lev]); + + for (int lev = crse_lev; lev <= crse_lev+1; lev++) { + MomentumToVelocity(vars_new[lev][Vars::xvel], + vars_new[lev][Vars::yvel], + vars_new[lev][Vars::zvel], + vars_new[lev][Vars::cons], + rU_new[lev], + rV_new[lev], + rW_new[lev], + Geom(lev).Domain(), + domain_bcs_type); + } +} diff --git a/Source/Utils/Make.package b/Source/Utils/Make.package index f757c99f9..238eccb8c 100644 --- a/Source/Utils/Make.package +++ b/Source/Utils/Make.package @@ -16,6 +16,7 @@ CEXE_headers += ERF_Sat_methods.H CEXE_headers += ERF_Water_vapor_saturation.H CEXE_headers += ERF_DirectionSelector.H +CEXE_sources += ERF_AverageDown.cpp CEXE_sources += ERF_ChopGrids.cpp CEXE_sources += ERF_MomentumToVelocity.cpp CEXE_sources += ERF_VelocityToMomentum.cpp From 36e2d55336c01d120e04baa37a5b5e9c48400f9e Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Wed, 30 Oct 2024 10:40:15 -0700 Subject: [PATCH 10/24] update dry anelastic buoyancy to be consistent with moist (#1917) --- Source/SourceTerms/ERF_buoyancy_utils.H | 21 ++++++++++----------- Source/SourceTerms/ERF_make_buoyancy.cpp | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Source/SourceTerms/ERF_buoyancy_utils.H b/Source/SourceTerms/ERF_buoyancy_utils.H index 91f2a8ea0..c5d5b75be 100644 --- a/Source/SourceTerms/ERF_buoyancy_utils.H +++ b/Source/SourceTerms/ERF_buoyancy_utils.H @@ -11,23 +11,22 @@ buoyancy_dry_anelastic (int& i, int& j, int& k, amrex::Real const& grav_gpu, - amrex::Real const& rd_over_cp, const amrex::Array4& p0_arr, const amrex::Array4& r0_arr, const amrex::Array4& cell_data) { - amrex::Real rt0_hi = getRhoThetagivenP(p0_arr(i,j,k)); - amrex::Real t0_hi = getTgivenPandTh(p0_arr(i,j,k), rt0_hi/r0_arr(i,j,k), rd_over_cp); - amrex::Real t_hi = getTgivenPandTh(p0_arr(i,j,k), cell_data(i,j,k,RhoTheta_comp)/r0_arr(i,j,k), rd_over_cp); - amrex::Real qplus = (t_hi-t0_hi)/t0_hi; + // Note: this is the same term as the moist anelastic buoyancy when qv = qc = qt = 0 + amrex::Real theta_d_lo = cell_data(i,j,k-1,RhoTheta_comp)/r0_arr(i,j,k-1); + amrex::Real theta_d_hi = cell_data(i,j,k ,RhoTheta_comp)/r0_arr(i,j,k); - amrex::Real rt0_lo = getRhoThetagivenP(p0_arr(i,j,k-1)); - amrex::Real t0_lo = getTgivenPandTh(p0_arr(i,j,k-1), rt0_lo/r0_arr(i,j,k-1), rd_over_cp); - amrex::Real t_lo = getTgivenPandTh(p0_arr(i,j,k-1), cell_data(i,j,k-1,RhoTheta_comp)/r0_arr(i,j,k-1), rd_over_cp); - amrex::Real qminus = (t_lo-t0_lo)/t0_lo; + amrex::Real theta_d_wface = amrex::Real(0.5) * (theta_d_lo + theta_d_hi); - amrex::Real r0_q_avg = amrex::Real(0.5) * (r0_arr(i,j,k) * qplus + r0_arr(i,j,k-1) * qminus); - return (-r0_q_avg * grav_gpu); + amrex::Real theta_d_0_lo = getRhoThetagivenP(p0_arr(i,j,k-1)) / r0_arr(i,j,k-1); + amrex::Real theta_d_0_hi = getRhoThetagivenP(p0_arr(i,j,k )) / r0_arr(i,j,k ); + + amrex::Real theta_d_0_wface = amrex::Real(0.5) * (theta_d_0_lo + theta_d_0_hi); + + return (-grav_gpu * (theta_d_wface - theta_d_0_wface) / theta_d_0_wface); } diff --git a/Source/SourceTerms/ERF_make_buoyancy.cpp b/Source/SourceTerms/ERF_make_buoyancy.cpp index 11a3743a9..528c82edf 100644 --- a/Source/SourceTerms/ERF_make_buoyancy.cpp +++ b/Source/SourceTerms/ERF_make_buoyancy.cpp @@ -73,7 +73,7 @@ void make_buoyancy (Vector& S_data, ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) { buoyancy_fab(i, j, k) = buoyancy_dry_anelastic(i,j,k, - grav_gpu[2],rd_over_cp, + grav_gpu[2], p0_arr,r0_arr,cell_data); }); } else { From f6dd23b65db0f0bd71c91df771bbd92dc23ff567 Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Wed, 30 Oct 2024 13:46:54 -0700 Subject: [PATCH 11/24] cleaning up buoyancy plus adding more ML-related stuff (#1918) --- Source/ERF.H | 4 ++ Source/ERF.cpp | 9 +++- Source/ERF_make_new_arrays.cpp | 9 ++++ Source/ERF_make_new_level.cpp | 51 +++++++++--------- Source/SourceTerms/ERF_Src_headers.H | 6 +-- Source/SourceTerms/ERF_buoyancy_utils.H | 55 ++++++++++++++------ Source/SourceTerms/ERF_make_buoyancy.cpp | 27 ++++++---- Source/SourceTerms/ERF_make_mom_sources.cpp | 4 +- Source/TimeIntegration/ERF_Advance.cpp | 30 +++++++++++ Source/TimeIntegration/ERF_TI_slow_headers.H | 3 ++ Source/TimeIntegration/ERF_TI_slow_rhs_fun.H | 40 ++++++++++---- Source/TimeIntegration/ERF_slow_rhs_pre.cpp | 3 ++ 12 files changed, 169 insertions(+), 72 deletions(-) diff --git a/Source/ERF.H b/Source/ERF.H index 2af6c99f9..9027c6dc7 100644 --- a/Source/ERF.H +++ b/Source/ERF.H @@ -731,6 +731,10 @@ private: amrex::Vector rW_old; amrex::Vector rW_new; + amrex::Vector xmom_crse_rhs; + amrex::Vector ymom_crse_rhs; + amrex::Vector zmom_crse_rhs; + std::unique_ptr micro; amrex::Vector> qmoist; // (lev,ncomp) This has up to 8 components: qt, qv, qc, qi, qp, qr, qs, qg diff --git a/Source/ERF.cpp b/Source/ERF.cpp index a39415562..c812c9b11 100644 --- a/Source/ERF.cpp +++ b/Source/ERF.cpp @@ -197,6 +197,10 @@ ERF::ERF_shared () rV_old.resize(nlevs_max); rW_old.resize(nlevs_max); + xmom_crse_rhs.resize(nlevs_max); + ymom_crse_rhs.resize(nlevs_max); + zmom_crse_rhs.resize(nlevs_max); + for (int lev = 0; lev < nlevs_max; ++lev) { vars_new[lev].resize(Vars::NumTypes); vars_old[lev].resize(Vars::NumTypes); @@ -460,8 +464,9 @@ ERF::post_timestep (int nstep, Real time, Real dt_lev0) } } // mfi - // This call refluxes from the lev/lev+1 interface onto lev - getAdvFluxReg(lev+1)->Reflux(vars_new[lev][Vars::cons], 0, 0, ncomp); + // This call refluxes all "slow" cell-centered variables + // (i.e. not density or (rho theta) or velocities) from the lev/lev+1 interface onto lev + getAdvFluxReg(lev+1)->Reflux(vars_new[lev][Vars::cons], 2, 2, ncomp-2); // Here we multiply (rho S) by m^2 after refluxing for (MFIter mfi(vars_new[lev][Vars::cons], TilingIfNotGPU()); mfi.isValid(); ++mfi) { diff --git a/Source/ERF_make_new_arrays.cpp b/Source/ERF_make_new_arrays.cpp index a93d83780..90ab59dff 100644 --- a/Source/ERF_make_new_arrays.cpp +++ b/Source/ERF_make_new_arrays.cpp @@ -149,6 +149,15 @@ ERF::init_stuff (int lev, const BoxArray& ba, const DistributionMapping& dm, rW_old[lev].define(convert(ba, IntVect(0,0,1)), dm, 1, ngrow_vels); rW_new[lev].define(convert(ba, IntVect(0,0,1)), dm, 1, ngrow_vels); + if (lev > 0) { + xmom_crse_rhs[lev].define(convert(ba, IntVect(1,0,0)), dm, 1, IntVect{0}); + xmom_crse_rhs[lev].setVal(3.456e22); + ymom_crse_rhs[lev].define(convert(ba, IntVect(0,1,0)), dm, 1, IntVect{0}); + ymom_crse_rhs[lev].setVal(3.456e22); + zmom_crse_rhs[lev].define(convert(ba, IntVect(0,0,1)), dm, 1, IntVect{0}); + zmom_crse_rhs[lev].setVal(3.456e22); + } + // We do this here just so they won't be undefined in the initial FillPatch rU_old[lev].setVal(1.2e21); rV_old[lev].setVal(3.4e22); diff --git a/Source/ERF_make_new_level.cpp b/Source/ERF_make_new_level.cpp index 282114b7d..3f0fd47cf 100644 --- a/Source/ERF_make_new_level.cpp +++ b/Source/ERF_make_new_level.cpp @@ -332,40 +332,39 @@ ERF::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMapp // ***************************************************************************************************** make_physbcs(lev); - // ******************************************************************************************** - // Update the base state at this level by interpolation from coarser level AND copy - // from previous (pre-regrid) base_state array - // ******************************************************************************************** - Interpolater* mapper = &cell_cons_interp; - - Vector fmf = {&base_state[lev ], &base_state[lev ]}; - Vector cmf = {&base_state[lev-1], &base_state[lev-1]}; - Vector ftime = {time, time}; - Vector ctime = {time, time}; - - // Call FillPatch which ASSUMES that all ghost cells at lev-1 have already been filled - FillPatchTwoLevels(temp_base_state, temp_base_state.nGrowVect(), IntVect(0,0,0), - time, cmf, ctime, fmf, ftime, - 0, 0, temp_base_state.nComp(), geom[lev-1], geom[lev], - refRatio(lev-1), mapper, domain_bcs_type, - BCVars::base_bc); - - // Impose bc's outside the domain - (*physbcs_base[lev])(temp_base_state,0,temp_base_state.nComp(),base_state[lev].nGrowVect()); - // ************************************************************************************************* // This will fill the temporary MultiFabs with data from vars_new // NOTE: the momenta here are only used as scratch space, the momenta themselves are not fillpatched - // NOTE: we must create the new base state before calling FillPatch because we will - // interpolate perturbational quantities // ************************************************************************************************* FillPatch(lev, time, {&temp_lev_new[Vars::cons],&temp_lev_new[Vars::xvel], &temp_lev_new[Vars::yvel],&temp_lev_new[Vars::zvel]}, {&temp_lev_new[Vars::cons],&rU_new[lev],&rV_new[lev],&rW_new[lev]}, - base_state[lev], temp_base_state, false); + base_state[lev],temp_base_state,false); - // Now swap the pointers since we needed both old and new in the FillPatch - std::swap(temp_base_state, base_state[lev]); + // ******************************************************************************************** + // Update the base state at this level by interpolation from coarser level AND copy + // from previous (pre-regrid) base_state array + // ******************************************************************************************** + if (lev > 0) { + Interpolater* mapper = &cell_cons_interp; + + Vector fmf = {&base_state[lev ], &base_state[lev ]}; + Vector cmf = {&base_state[lev-1], &base_state[lev-1]}; + Vector ftime = {time, time}; + Vector ctime = {time, time}; + + // Call FillPatch which ASSUMES that all ghost cells at lev-1 have already been filled + FillPatchTwoLevels(temp_base_state, temp_base_state.nGrowVect(), IntVect(0,0,0), + time, cmf, ctime, fmf, ftime, + 0, 0, temp_base_state.nComp(), geom[lev-1], geom[lev], + refRatio(lev-1), mapper, domain_bcs_type, + BCVars::base_bc); + + // Impose bc's outside the domain + (*physbcs_base[lev])(temp_base_state,0,temp_base_state.nComp(),base_state[lev].nGrowVect()); + + std::swap(temp_base_state, base_state[lev]); + } // ******************************************************************************************** // Copy from new into old just in case diff --git a/Source/SourceTerms/ERF_Src_headers.H b/Source/SourceTerms/ERF_Src_headers.H index d8ec184ca..7d19eeb0f 100644 --- a/Source/SourceTerms/ERF_Src_headers.H +++ b/Source/SourceTerms/ERF_Src_headers.H @@ -20,8 +20,7 @@ void make_buoyancy (amrex::Vector< amrex::MultiFab>& S_data, amrex::MultiFab& buoyancy, const amrex::Geometry geom, const SolverChoice& solverChoice, - const amrex::MultiFab* r0, - const amrex::MultiFab* p0, + const amrex::MultiFab& base_state, const int n_qstate, const int anelastic); @@ -56,8 +55,7 @@ void make_mom_sources (int level, int nrk, amrex::MultiFab& xmom_source, amrex::MultiFab& ymom_source, amrex::MultiFab& zmom_source, - amrex::MultiFab* r0, - amrex::MultiFab* p0, + const amrex::MultiFab& base_state, const amrex::Geometry geom, const SolverChoice& solverChoice, std::unique_ptr& mapfac_m, diff --git a/Source/SourceTerms/ERF_buoyancy_utils.H b/Source/SourceTerms/ERF_buoyancy_utils.H index c5d5b75be..061240ae5 100644 --- a/Source/SourceTerms/ERF_buoyancy_utils.H +++ b/Source/SourceTerms/ERF_buoyancy_utils.H @@ -11,8 +11,8 @@ buoyancy_dry_anelastic (int& i, int& j, int& k, amrex::Real const& grav_gpu, - const amrex::Array4& p0_arr, const amrex::Array4& r0_arr, + const amrex::Array4& p0_arr, const amrex::Array4& cell_data) { // Note: this is the same term as the moist anelastic buoyancy when qv = qc = qt = 0 @@ -29,6 +29,32 @@ buoyancy_dry_anelastic (int& i, return (-grav_gpu * (theta_d_wface - theta_d_0_wface) / theta_d_0_wface); } +AMREX_GPU_DEVICE +AMREX_FORCE_INLINE +amrex::Real +buoyancy_dry_anelastic_T (int& i, + int& j, + int& k, + amrex::Real const& grav_gpu, + amrex::Real const& rd_over_cp, + const amrex::Array4& r0_arr, + const amrex::Array4& p0_arr, + const amrex::Array4& cell_data) +{ + amrex::Real rt0_hi = getRhoThetagivenP(p0_arr(i,j,k)); + amrex::Real t0_hi = getTgivenPandTh(p0_arr(i,j,k), rt0_hi/r0_arr(i,j,k), rd_over_cp); + amrex::Real t_hi = getTgivenPandTh(p0_arr(i,j,k), cell_data(i,j,k,RhoTheta_comp)/r0_arr(i,j,k), rd_over_cp); + amrex::Real qplus = (t_hi-t0_hi)/t0_hi; + + amrex::Real rt0_lo = getRhoThetagivenP(p0_arr(i,j,k-1)); + amrex::Real t0_lo = getTgivenPandTh(p0_arr(i,j,k-1), rt0_lo/r0_arr(i,j,k-1), rd_over_cp); + amrex::Real t_lo = getTgivenPandTh(p0_arr(i,j,k-1), cell_data(i,j,k-1,RhoTheta_comp)/r0_arr(i,j,k-1), rd_over_cp); + amrex::Real qminus = (t_lo-t0_lo)/t0_lo; + + amrex::Real r0_q_avg = amrex::Real(0.5) * (r0_arr(i,j,k) * qplus + r0_arr(i,j,k-1) * qminus); + return (-r0_q_avg * grav_gpu); +} + AMREX_GPU_DEVICE AMREX_FORCE_INLINE @@ -38,28 +64,26 @@ buoyancy_moist_anelastic (int& i, int& k, amrex::Real const& grav_gpu, amrex::Real const& rv_over_rd, - const amrex::Array4& p0_arr, - const amrex::Array4& r0_arr, + const amrex::Array4& r0_arr, + const amrex::Array4& th0_arr, const amrex::Array4& cell_data) { amrex::Real theta_d_lo = cell_data(i,j,k-1,RhoTheta_comp)/r0_arr(i,j,k-1); - amrex::Real qv_lo = cell_data(i,j,k-1,RhoQ1_comp)/r0_arr(i,j,k-1); - amrex::Real qc_lo = cell_data(i,j,k-1,RhoQ2_comp)/r0_arr(i,j,k-1); + amrex::Real qv_lo = cell_data(i,j,k-1,RhoQ1_comp) /r0_arr(i,j,k-1); + amrex::Real qc_lo = cell_data(i,j,k-1,RhoQ2_comp) /r0_arr(i,j,k-1); amrex::Real qt_lo = qv_lo + qc_lo; amrex::Real theta_v_lo = theta_d_lo * (1.0 - (1.0 - rv_over_rd)*qt_lo - rv_over_rd*qc_lo); amrex::Real theta_d_hi = cell_data(i,j,k,RhoTheta_comp)/r0_arr(i,j,k); - amrex::Real qv_hi = cell_data(i,j,k,RhoQ1_comp)/r0_arr(i,j,k); - amrex::Real qc_hi = cell_data(i,j,k,RhoQ2_comp)/r0_arr(i,j,k); + amrex::Real qv_hi = cell_data(i,j,k,RhoQ1_comp) /r0_arr(i,j,k); + amrex::Real qc_hi = cell_data(i,j,k,RhoQ2_comp) /r0_arr(i,j,k); amrex::Real qt_hi = qv_hi + qc_hi; amrex::Real theta_v_hi = theta_d_hi * (1.0 - (1.0 - rv_over_rd)*qt_hi - rv_over_rd*qc_hi); amrex::Real theta_v_wface = amrex::Real(0.5) * (theta_v_lo + theta_v_hi); - amrex::Real theta_d_0_lo = getRhoThetagivenP(p0_arr(i,j,k-1)) / r0_arr(i,j,k-1); - amrex::Real theta_d_0_hi = getRhoThetagivenP(p0_arr(i,j,k )) / r0_arr(i,j,k ); - amrex::Real theta_v_0_lo = theta_d_0_lo * (1.0 - (1.0 - rv_over_rd)*qt_lo - rv_over_rd*qc_lo); - amrex::Real theta_v_0_hi = theta_d_0_hi * (1.0 - (1.0 - rv_over_rd)*qt_hi - rv_over_rd*qc_hi); + amrex::Real theta_v_0_lo = th0_arr(i,j,k-1) * (1.0 - (1.0 - rv_over_rd)*qt_lo - rv_over_rd*qc_lo); + amrex::Real theta_v_0_hi = th0_arr(i,j,k ) * (1.0 - (1.0 - rv_over_rd)*qt_hi - rv_over_rd*qc_hi); amrex::Real theta_v_0_wface = amrex::Real(0.5) * (theta_v_0_lo + theta_v_0_hi); @@ -74,17 +98,16 @@ buoyancy_dry_default (int& i, int& k, amrex::Real const& grav_gpu, amrex::Real const& rd_over_cp, - const amrex::Array4& p0_arr, const amrex::Array4& r0_arr, + const amrex::Array4& p0_arr, + const amrex::Array4& th0_arr, const amrex::Array4& cell_data) { - amrex::Real rt0_hi = getRhoThetagivenP(p0_arr(i,j,k)); - amrex::Real t0_hi = getTgivenPandTh(p0_arr(i,j,k), rt0_hi/r0_arr(i,j,k), rd_over_cp); + amrex::Real t0_hi = getTgivenPandTh(p0_arr(i,j,k), th0_arr(i,j,k), rd_over_cp); amrex::Real t_hi = getTgivenRandRTh(cell_data(i,j,k ,Rho_comp), cell_data(i,j,k ,RhoTheta_comp)); amrex::Real qplus = (t_hi-t0_hi)/t0_hi; - amrex::Real rt0_lo = getRhoThetagivenP(p0_arr(i,j,k-1)); - amrex::Real t0_lo = getTgivenPandTh(p0_arr(i,j,k-1), rt0_lo/r0_arr(i,j,k-1), rd_over_cp); + amrex::Real t0_lo = getTgivenPandTh(p0_arr(i,j,k-1), th0_arr(i,j,k-1), rd_over_cp); amrex::Real t_lo = getTgivenRandRTh(cell_data(i,j,k-1,Rho_comp), cell_data(i,j,k-1,RhoTheta_comp)); amrex::Real qminus = (t_lo-t0_lo)/t0_lo; diff --git a/Source/SourceTerms/ERF_make_buoyancy.cpp b/Source/SourceTerms/ERF_make_buoyancy.cpp index 528c82edf..ca101605e 100644 --- a/Source/SourceTerms/ERF_make_buoyancy.cpp +++ b/Source/SourceTerms/ERF_make_buoyancy.cpp @@ -34,8 +34,7 @@ void make_buoyancy (Vector& S_data, MultiFab& buoyancy, const amrex::Geometry geom, const SolverChoice& solverChoice, - const MultiFab* r0, - const MultiFab* p0, + const MultiFab& base_state, const int n_qstate, const int anelastic) { @@ -50,6 +49,10 @@ void make_buoyancy (Vector& S_data, Real rd_over_cp = solverChoice.rdOcp; Real rv_over_rd = R_v/R_d; + MultiFab r0 (base_state, make_alias, BaseState::r0_comp , 1); + MultiFab p0 (base_state, make_alias, BaseState::p0_comp , 1); + MultiFab th0(base_state, make_alias, BaseState::th0_comp, 1); + if (anelastic == 1) { #ifdef _OPENMP #pragma omp parallel if (amrex::Gpu::notInLaunchRegion()) @@ -66,15 +69,16 @@ void make_buoyancy (Vector& S_data, const Array4< Real> & buoyancy_fab = buoyancy.array(mfi); // Base state density and pressure - const Array4& r0_arr = r0->const_array(mfi); - const Array4& p0_arr = p0->const_array(mfi); + const Array4& r0_arr = r0.const_array(mfi); + const Array4& p0_arr = p0.const_array(mfi); + const Array4& th0_arr = th0.const_array(mfi); if (solverChoice.moisture_type == MoistureType::None) { ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) { buoyancy_fab(i, j, k) = buoyancy_dry_anelastic(i,j,k, grav_gpu[2], - p0_arr,r0_arr,cell_data); + r0_arr,p0_arr,cell_data); }); } else { // NOTE: For decomposition in the vertical direction, klo may not @@ -84,7 +88,7 @@ void make_buoyancy (Vector& S_data, { buoyancy_fab(i, j, k) = buoyancy_moist_anelastic(i,j,k, grav_gpu[2],rv_over_rd, - p0_arr,r0_arr,cell_data); + r0_arr,th0_arr,cell_data); }); } } // mfi @@ -113,7 +117,7 @@ void make_buoyancy (Vector& S_data, const Array4< Real> & buoyancy_fab = buoyancy.array(mfi); // Base state density - const Array4& r0_arr = r0->const_array(mfi); + const Array4& r0_arr = r0.const_array(mfi); ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) { @@ -142,8 +146,9 @@ void make_buoyancy (Vector& S_data, if (tbz.bigEnd(2) == khi) tbz.growHi(2,-1); // Base state density and pressure - const Array4& r0_arr = r0->const_array(mfi); - const Array4& p0_arr = p0->const_array(mfi); + const Array4& r0_arr = r0.const_array(mfi); + const Array4& p0_arr = p0.const_array(mfi); + const Array4& th0_arr = th0.const_array(mfi); const Array4 & cell_data = S_data[IntVars::cons].array(mfi); const Array4< Real> & buoyancy_fab = buoyancy.array(mfi); @@ -152,7 +157,7 @@ void make_buoyancy (Vector& S_data, { buoyancy_fab(i, j, k) = buoyancy_dry_default(i,j,k, grav_gpu[2],rd_over_cp, - p0_arr,r0_arr,cell_data); + r0_arr,p0_arr,th0_arr,cell_data); }); } // mfi } // buoyancy_type @@ -187,7 +192,7 @@ void make_buoyancy (Vector& S_data, const Array4< Real> & buoyancy_fab = buoyancy.array(mfi); // Base state density - const Array4& r0_arr = r0->const_array(mfi); + const Array4& r0_arr = r0.const_array(mfi); ParallelFor(tbz, [=] AMREX_GPU_DEVICE (int i, int j, int k) { diff --git a/Source/SourceTerms/ERF_make_mom_sources.cpp b/Source/SourceTerms/ERF_make_mom_sources.cpp index b60190bfe..2e9a4d31f 100644 --- a/Source/SourceTerms/ERF_make_mom_sources.cpp +++ b/Source/SourceTerms/ERF_make_mom_sources.cpp @@ -48,7 +48,7 @@ void make_mom_sources (int level, MultiFab & xmom_src, MultiFab & ymom_src, MultiFab & zmom_src, - MultiFab* r0, MultiFab* p0, + const MultiFab& base_state, const Geometry geom, const SolverChoice& solverChoice, std::unique_ptr& mapfac_m, @@ -190,7 +190,7 @@ void make_mom_sources (int level, // ***************************************************************************** // 1. Create the BUOYANCY forcing term in the z-direction // ***************************************************************************** - make_buoyancy(S_data, S_prim, zmom_src, geom, solverChoice, r0, p0, + make_buoyancy(S_data, S_prim, zmom_src, geom, solverChoice, base_state, n_qstate, solverChoice.anelastic[level]); // ***************************************************************************** diff --git a/Source/TimeIntegration/ERF_Advance.cpp b/Source/TimeIntegration/ERF_Advance.cpp index 2a8a73497..f634580f0 100644 --- a/Source/TimeIntegration/ERF_Advance.cpp +++ b/Source/TimeIntegration/ERF_Advance.cpp @@ -241,6 +241,36 @@ ERF::Advance (int lev, Real time, Real dt_lev, int iteration, int /*ncycle*/) state_new[IntVars::zmom].FillBoundary(geom[lev].periodicity()); FPr_w[lev].RegisterCoarseData({&state_old[IntVars::zmom], &state_new[IntVars::zmom]}, {time, time + dt_lev}); + + // + // Now create a MultiFab that holds (S_new - S_old) / dt from the coarse level interpolated + // on to the coarse/fine boundary at the fine resolution + // + PhysBCFunctNoOp null_bc; + + MultiFab tempx(vars_new[lev+1][Vars::xvel].boxArray(),vars_new[lev+1][Vars::xvel].DistributionMap(),1,0); + tempx.setVal(0.0); + xmom_crse_rhs[lev+1].setVal(0.0); + FPr_u[lev].FillSet(tempx , time , null_bc, domain_bcs_type); + FPr_u[lev].FillSet(xmom_crse_rhs[lev+1], time+dt_lev, null_bc, domain_bcs_type); + MultiFab::Subtract(xmom_crse_rhs[lev+1],tempx,0,0,1,IntVect{0}); + xmom_crse_rhs[lev+1].mult(1.0/dt_lev,0,1,0); + + MultiFab tempy(vars_new[lev+1][Vars::yvel].boxArray(),vars_new[lev+1][Vars::yvel].DistributionMap(),1,0); + tempy.setVal(0.0); + ymom_crse_rhs[lev+1].setVal(0.0); + FPr_v[lev].FillSet(tempy , time , null_bc, domain_bcs_type); + FPr_v[lev].FillSet(ymom_crse_rhs[lev+1], time+dt_lev, null_bc, domain_bcs_type); + MultiFab::Subtract(ymom_crse_rhs[lev+1],tempy,0,0,1,IntVect{0}); + ymom_crse_rhs[lev+1].mult(1.0/dt_lev,0,1,0); + + MultiFab tempz(vars_new[lev+1][Vars::zvel].boxArray(),vars_new[lev+1][Vars::zvel].DistributionMap(),1,0); + tempz.setVal(0.0); + zmom_crse_rhs[lev+1].setVal(0.0); + FPr_w[lev].FillSet(tempz , time , null_bc, domain_bcs_type); + FPr_w[lev].FillSet(zmom_crse_rhs[lev+1], time+dt_lev, null_bc, domain_bcs_type); + MultiFab::Subtract(zmom_crse_rhs[lev+1],tempz,0,0,1,IntVect{0}); + zmom_crse_rhs[lev+1].mult(1.0/dt_lev,0,1,0); } } diff --git a/Source/TimeIntegration/ERF_TI_slow_headers.H b/Source/TimeIntegration/ERF_TI_slow_headers.H index b4959ac65..86dfb38b5 100644 --- a/Source/TimeIntegration/ERF_TI_slow_headers.H +++ b/Source/TimeIntegration/ERF_TI_slow_headers.H @@ -67,6 +67,9 @@ void erf_slow_rhs_pre (int level, int finest_level, int nrk, const amrex::MultiFab& xmom_src, const amrex::MultiFab& ymom_src, const amrex::MultiFab& zmom_src, + const amrex::MultiFab* xmom_crse_rhs, + const amrex::MultiFab* ymom_crse_rhs, + const amrex::MultiFab* zmom_crse_rhs, amrex::MultiFab* Tau11, amrex::MultiFab* Tau22, amrex::MultiFab* Tau33, diff --git a/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H b/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H index 73976894a..092f87589 100644 --- a/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H +++ b/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H @@ -102,18 +102,21 @@ } // mfi - MultiFab r_hse_new (base_state_new[level], make_alias, BaseState::r0_comp, 1); - MultiFab p_hse_new (base_state_new[level], make_alias, BaseState::p0_comp, 1); - MultiFab pi_hse_new(base_state_new[level], make_alias, BaseState::pi0_comp, 1); + MultiFab r_hse_new (base_state_new[level], make_alias, BaseState::r0_comp, 1); + MultiFab p_hse_new (base_state_new[level], make_alias, BaseState::p0_comp, 1); + MultiFab pi_hse_new (base_state_new[level], make_alias, BaseState::pi0_comp, 1); + MultiFab th_hse_new (base_state_new[level], make_alias, BaseState::th0_comp, 1); - MultiFab* r0_new = &r_hse_new; - MultiFab* p0_new = &p_hse_new; + MultiFab* r0_new = &r_hse_new; + MultiFab* p0_new = &p_hse_new; + MultiFab* pi0_new = &pi_hse_new; + MultiFab* th0_new = &th_hse_new; make_mom_sources(level, nrk, slow_dt, old_stage_time, S_data, S_prim, z_phys_nd[level], z_phys_cc[level], xvel_new, yvel_new, xmom_src, ymom_src, zmom_src, - r0_new, p0_new, fine_geom, solverChoice, + base_state_new[level], fine_geom, solverChoice, mapfac_m[level], mapfac_u[level], mapfac_v[level], dptr_u_geos, dptr_v_geos, dptr_wbar_sub, d_rayleigh_ptrs_at_lev, d_sponge_ptrs_at_lev, @@ -122,6 +125,9 @@ erf_slow_rhs_pre(level, finest_level, nrk, slow_dt, S_rhs, S_old, S_data, S_prim, S_scratch, xvel_new, yvel_new, zvel_new, z_t_rk[level], Omega, cc_src, xmom_src, ymom_src, zmom_src, + (level > 0) ? &xmom_crse_rhs[level] : nullptr, + (level > 0) ? &ymom_crse_rhs[level] : nullptr, + (level > 0) ? &zmom_crse_rhs[level] : nullptr, Tau11_lev[level].get(), Tau22_lev[level].get(), Tau33_lev[level].get(), Tau12_lev[level].get(), Tau13_lev[level].get(), Tau21_lev[level].get(), Tau23_lev[level].get(), Tau31_lev[level].get(), Tau32_lev[level].get(), SmnSmn, eddyDiffs, Hfx1, Hfx2, Hfx3, Q1fx1, Q1fx2, Q1fx3, Q2fx3, Diss, @@ -156,6 +162,8 @@ const GpuArray dxInv = fine_geom.InvCellSizeArray(); + const Real l_rdOcp = solverChoice.rdOcp; + #ifdef _OPENMP #pragma omp parallel if (amrex::Gpu::notInLaunchRegion()) #endif @@ -168,8 +176,10 @@ const Array4 r0_new_arr = r0_new->array(mfi); const Array4 r0_tmp_arr = r0_temp.array(mfi); - const Array4 p0_arr = p0->const_array(mfi); - const Array4 p0_new_arr = p0_new->array(mfi); + const Array4 p0_arr = p0->const_array(mfi); + const Array4 p0_new_arr = p0_new->array(mfi); + const Array4 pi0_new_arr = pi0_new->array(mfi); + const Array4 th0_new_arr = th0_new->array(mfi); const Array4& z_t_arr = z_t_rk[level]->array(mfi); @@ -205,7 +215,9 @@ r0_new_arr(i,j,k) = rho0_new / dJ_new_arr(i,j,k); rt0_tmp_new /= dJ_new_arr(i,j,k); - p0_new_arr(i,j,k) = getPgivenRTh(rt0_tmp_new); + p0_new_arr(i,j,k) = getPgivenRTh(rt0_tmp_new); + pi0_new_arr(i,j,k) = getExnergivenRTh(rt0_tmp_new, l_rdOcp); + th0_new_arr(i,j,k) = rt0_tmp_new / r0_new_arr(i,j,k); }); } // MFIter r0_new->FillBoundary(fine_geom.periodicity()); @@ -217,7 +229,7 @@ z_phys_nd[level], z_phys_cc[level], xvel_new, yvel_new, xmom_src, ymom_src, zmom_src, - r0, p0, fine_geom, solverChoice, + base_state[level], fine_geom, solverChoice, mapfac_m[level], mapfac_u[level], mapfac_v[level], dptr_u_geos, dptr_v_geos, dptr_wbar_sub, d_rayleigh_ptrs_at_lev, d_sponge_ptrs_at_lev, @@ -226,6 +238,9 @@ erf_slow_rhs_pre(level, finest_level, nrk, slow_dt, S_rhs, S_old, S_data, S_prim, S_scratch, xvel_new, yvel_new, zvel_new, z_t_rk[level], Omega, cc_src, xmom_src, ymom_src, zmom_src, + (level > 0) ? &xmom_crse_rhs[level] : nullptr, + (level > 0) ? &ymom_crse_rhs[level] : nullptr, + (level > 0) ? &zmom_crse_rhs[level] : nullptr, Tau11_lev[level].get(), Tau22_lev[level].get(), Tau33_lev[level].get(), Tau12_lev[level].get(), Tau13_lev[level].get(), Tau21_lev[level].get(), Tau23_lev[level].get(), Tau31_lev[level].get(), Tau32_lev[level].get(), SmnSmn, eddyDiffs, Hfx1, Hfx2, Hfx3, Q1fx1, Q1fx2, Q1fx3,Q2fx3, Diss, @@ -424,7 +439,7 @@ z_phys_nd[level], z_phys_cc[level], xvel_new, yvel_new, xmom_src, ymom_src, zmom_src, - r0, p0, fine_geom, solverChoice, + base_state[level], fine_geom, solverChoice, mapfac_m[level], mapfac_u[level], mapfac_v[level], dptr_u_geos, dptr_v_geos, dptr_wbar_sub, d_rayleigh_ptrs_at_lev, d_sponge_ptrs_at_lev, @@ -434,6 +449,9 @@ S_rhs, S_old, S_data, S_prim, S_scratch, xvel_new, yvel_new, zvel_new, z_t_rk[level], Omega, cc_src, xmom_src, ymom_src, zmom_src, + (level > 0) ? &xmom_crse_rhs[level] : nullptr, + (level > 0) ? &ymom_crse_rhs[level] : nullptr, + (level > 0) ? &zmom_crse_rhs[level] : nullptr, Tau11_lev[level].get(), Tau22_lev[level].get(), Tau33_lev[level].get(), Tau12_lev[level].get(), Tau13_lev[level].get(), Tau21_lev[level].get(), Tau23_lev[level].get(), Tau31_lev[level].get(), Tau32_lev[level].get(), SmnSmn, eddyDiffs, Hfx1, Hfx2, Hfx3, Q1fx1, Q1fx2, Q1fx3, Q2fx3, Diss, diff --git a/Source/TimeIntegration/ERF_slow_rhs_pre.cpp b/Source/TimeIntegration/ERF_slow_rhs_pre.cpp index 51890a8cd..c92ed95cb 100644 --- a/Source/TimeIntegration/ERF_slow_rhs_pre.cpp +++ b/Source/TimeIntegration/ERF_slow_rhs_pre.cpp @@ -81,6 +81,9 @@ void erf_slow_rhs_pre (int level, int finest_level, const MultiFab& xmom_src, const MultiFab& ymom_src, const MultiFab& zmom_src, + const MultiFab* xmom_crse_rhs, + const MultiFab* ymom_crse_rhs, + const MultiFab* zmom_crse_rhs, MultiFab* Tau11, MultiFab* Tau22, MultiFab* Tau33, MultiFab* Tau12, MultiFab* Tau13, MultiFab* Tau21, MultiFab* Tau23, MultiFab* Tau31, MultiFab* Tau32, From f6b1c87a96589472bc73dff09a184dfd224acaff Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Wed, 30 Oct 2024 20:05:59 -0700 Subject: [PATCH 12/24] this version runs to t=900 for DensityCurrent with AMR (#1919) * this version runs to t=900 for DensityCurrent with AMR * fix cmake * removed unused --- Exec/CMakeLists.txt | 1 - Exec/RegTests/DensityCurrent/GNUmakefile | 2 + Exec/RegTests/DensityCurrent/inputs_amr | 5 +- Exec/SuperCell/CMakeLists.txt | 12 - Exec/SuperCell/ERF_prob.H | 63 ----- Exec/SuperCell/ERF_prob.cpp | 233 ------------------ Exec/SuperCell/GNUmakefile | 32 --- Exec/SuperCell/Make.package | 2 - Exec/SuperCell/README | 2 - Exec/SuperCell/inputs_moisture | 63 ----- .../ERF_FillIntermediatePatch.cpp | 22 -- Source/DataStructs/ERF_DataStruct.H | 2 +- Source/ERF_make_new_level.cpp | 55 +++-- Source/TimeIntegration/ERF_TI_fast_headers.H | 1 + Source/TimeIntegration/ERF_TI_fast_rhs_fun.H | 2 + Source/TimeIntegration/ERF_TI_slow_headers.H | 2 - Source/TimeIntegration/ERF_TI_slow_rhs_fun.H | 6 - Source/TimeIntegration/ERF_fast_rhs_N.cpp | 55 ++++- Source/TimeIntegration/ERF_slow_rhs_pre.cpp | 33 ++- 19 files changed, 110 insertions(+), 483 deletions(-) delete mode 100644 Exec/SuperCell/CMakeLists.txt delete mode 100644 Exec/SuperCell/ERF_prob.H delete mode 100644 Exec/SuperCell/ERF_prob.cpp delete mode 100644 Exec/SuperCell/GNUmakefile delete mode 100644 Exec/SuperCell/Make.package delete mode 100644 Exec/SuperCell/README delete mode 100644 Exec/SuperCell/inputs_moisture diff --git a/Exec/CMakeLists.txt b/Exec/CMakeLists.txt index a5b384ebd..046865f20 100644 --- a/Exec/CMakeLists.txt +++ b/Exec/CMakeLists.txt @@ -19,7 +19,6 @@ elseif (ERF_ENABLE_REGRESSION_TESTS_ONLY) add_subdirectory(DevTests/MovingTerrain) else () add_subdirectory(ABL) - add_subdirectory(SuperCell) add_subdirectory(SquallLine_2D) add_subdirectory(RegTests/Bubble) add_subdirectory(RegTests/Couette_Poiseuille) diff --git a/Exec/RegTests/DensityCurrent/GNUmakefile b/Exec/RegTests/DensityCurrent/GNUmakefile index 75690762b..cda34e9af 100644 --- a/Exec/RegTests/DensityCurrent/GNUmakefile +++ b/Exec/RegTests/DensityCurrent/GNUmakefile @@ -24,6 +24,8 @@ DEBUG = FALSE TEST = TRUE USE_ASSERTION = TRUE +USE_POISSON_SOLVE = TRUE + # GNU Make Bpack := ./Make.package Blocs := . diff --git a/Exec/RegTests/DensityCurrent/inputs_amr b/Exec/RegTests/DensityCurrent/inputs_amr index 11a5373d4..173529de8 100644 --- a/Exec/RegTests/DensityCurrent/inputs_amr +++ b/Exec/RegTests/DensityCurrent/inputs_amr @@ -36,8 +36,8 @@ amr.max_level = 1 # maximum level number allowed amr.n_cell = 128 1 32 # dx=dy=dz=100 m, Straka et al 1993 / Xue et al 2000 erf.fixed_dt = 2.0 # fixed time step [s] -- Straka et al 1993 erf.fixed_fast_dt = 0.5 # fixed time step [s] -- Straka et al 1993 -erf.plot_int_1 = 100 # number of timesteps between plotfiles -erf.check_int =-1000 # number of timesteps between checkpoints +erf.plot_int_1 = 150 # number of timesteps between plotfiles +erf.check_int =-100 # number of timesteps between checkpoints # DIAGNOSTICS & VERBOSITY erf.sum_interval =-1 # timesteps between computing mass @@ -73,7 +73,6 @@ prob.U_0 = 0.0 ################################ MULTILEVEL ################################ amr.ref_ratio_vect = 2 1 2 -erf.coupling_type = "OneWay" erf.regrid_int = 10 erf.refinement_indicators = lo_theta diff --git a/Exec/SuperCell/CMakeLists.txt b/Exec/SuperCell/CMakeLists.txt deleted file mode 100644 index 5fc424233..000000000 --- a/Exec/SuperCell/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -set(erf_exe_name erf_super_cell) - -add_executable(${erf_exe_name} "") -target_sources(${erf_exe_name} - PRIVATE - ERF_prob.cpp -) - -target_include_directories(${erf_exe_name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) - -include(${CMAKE_SOURCE_DIR}/CMake/BuildERFExe.cmake) -build_erf_exe(${erf_exe_name}) diff --git a/Exec/SuperCell/ERF_prob.H b/Exec/SuperCell/ERF_prob.H deleted file mode 100644 index 94f58ed36..000000000 --- a/Exec/SuperCell/ERF_prob.H +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef ERF_PROB_H_ -#define ERF_PROB_H_ - -#include - -#include "AMReX_REAL.H" - -#include "ERF_prob_common.H" - -struct ProbParm : ProbParmDefaults { - amrex::Real T_0 = 300.0; // surface temperature == mean potential temperature - amrex::Real U_0 = 10.0; - amrex::Real V_0 = 0.0; - amrex::Real x_c = 0.0; // center of thermal perturbation - amrex::Real z_c = 3200.0; - amrex::Real x_r = 1000.0; - amrex::Real z_r = 1000.0; - amrex::Real T_pert = 5.0; // perturbation temperature - // overridden physical constants - amrex::Real C_p = 1004.0; -}; // namespace ProbParm - -class Problem : public ProblemBase -{ -public: - Problem(); - -#include "Prob/ERF_init_density_hse_dry.H" - - void init_custom_pert ( - const amrex::Box& bx, - const amrex::Box& xbx, - const amrex::Box& ybx, - const amrex::Box& zbx, - amrex::Array4 const& state, - amrex::Array4 const& state_pert, - amrex::Array4 const& x_vel_pert, - amrex::Array4 const& y_vel_pert, - amrex::Array4 const& z_vel_pert, - amrex::Array4 const& r_hse, - amrex::Array4 const& p_hse, - amrex::Array4 const& z_nd, - amrex::Array4 const& z_cc, - amrex::GeometryData const& geomdata, - amrex::Array4 const& mf_m, - amrex::Array4 const& mf_u, - amrex::Array4 const& mf_v, - const SolverChoice& sc) override; - - void erf_init_rayleigh ( - amrex::Vector >& rayleigh_ptrs, - amrex::Geometry const& geom, - std::unique_ptr& z_phys_nd, - amrex::Real zdamp) override; - -protected: - std::string name() override { return "Supercell"; } - -private: - ProbParm parms; -}; - -#endif diff --git a/Exec/SuperCell/ERF_prob.cpp b/Exec/SuperCell/ERF_prob.cpp deleted file mode 100644 index 41ed24774..000000000 --- a/Exec/SuperCell/ERF_prob.cpp +++ /dev/null @@ -1,233 +0,0 @@ -#include "ERF_prob.H" -#include "ERF_EOS.H" - -using namespace amrex; - -std::unique_ptr -amrex_probinit( - const amrex_real* /*problo*/, - const amrex_real* /*probhi*/) -{ - return std::make_unique(); -} - -Problem::Problem() -{ - // Parse params - amrex::ParmParse pp("prob"); - pp.query("T_0", parms.T_0); - pp.query("U_0", parms.U_0); - pp.query("x_c", parms.x_c); - pp.query("z_c", parms.z_c); - pp.query("x_r", parms.x_r); - pp.query("z_r", parms.z_r); - pp.query("T_pert", parms.T_pert); - - init_base_parms(parms.rho_0, parms.T_0); -} - -AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE -amrex::Real -init_supercell_temperature(amrex::Real z, amrex::Real z_0, amrex::Real z_trop, amrex::Real z_top, - amrex::Real T_0, amrex::Real T_trop, amrex::Real T_top) -{ - if (z <= z_trop) { - amrex::Real lapse = - (T_trop - T_0) / (z_trop - z_0); - return T_0 - lapse * (z - z_0); - } else { - amrex::Real lapse = - (T_top - T_trop) / (z_top - z_trop); - return T_trop - lapse * (z - z_trop); - } -} - -AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE -amrex::Real -init_supercell_pressure(amrex::Real z, amrex::Real z_0, - amrex::Real z_trop, amrex::Real z_top, - amrex::Real T_0, amrex::Real T_trop, amrex::Real T_top) -{ - if (z <= z_trop) { - amrex::Real lapse = - (T_trop - T_0) / (z_trop - z_0); - amrex::Real T = init_supercell_temperature(z, z_0, z_trop, z_top, T_0, T_trop, T_top); - return p_0 * std::pow( T / T_0 , CONST_GRAV/(R_d*lapse) ); - } else { - // Get pressure at the tropopause - amrex::Real lapse = - (T_trop - T_0) / (z_trop - z_0); - amrex::Real p_trop = p_0 * std::pow( T_trop / T_0 , CONST_GRAV/(R_d*lapse) ); - // Get pressure at requested height - lapse = - (T_top - T_trop) / (z_top - z_trop); - if (lapse != 0) { - amrex::Real T = init_supercell_temperature(z, z_0, z_trop, z_top, T_0, T_trop, T_top); - return p_trop * std::pow( T / T_trop , CONST_GRAV/(R_d*lapse) ); - } else { - return p_trop * std::exp(-CONST_GRAV*(z-z_trop)/(R_d*T_trop)); - } - } -} - -AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE -amrex::Real -init_supercell_sat_mix(amrex::Real press, amrex::Real T ) { - return 380./(press) * std::exp(17.27*(T-273.)/(T-36.)); -} - -AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE -amrex::Real -init_supercell_relhum(amrex::Real z, amrex::Real z_trop) -{ - if (z <= z_trop) { - return 1. - 0.75 * pow(z / z_trop , 1.25); - } else { - return 0.25; - } -} - -void -Problem::init_custom_pert( - const Box& bx, - const Box& xbx, - const Box& ybx, - const Box& zbx, - Array4 const& /*state*/, - Array4 const& state_pert, - Array4 const& x_vel_pert, - Array4 const& y_vel_pert, - Array4 const& z_vel_pert, - Array4 const& r_hse, - Array4 const& p_hse, - Array4 const& /*z_nd*/, - Array4 const& /*z_cc*/, - GeometryData const& geomdata, - Array4 const& /*mf_m*/, - Array4 const& /*mf_u*/, - Array4 const& /*mf_v*/, - const SolverChoice& sc) -{ - const bool use_moisture = (sc.moisture_type != MoistureType::None); - - const int khi = geomdata.Domain().bigEnd()[2]; - - AMREX_ALWAYS_ASSERT(bx.length()[2] == khi+1); - - // This is what we do at k = 0 -- note we assume p = p_0 and T = T_0 at z=0 - const amrex::Real& dz = geomdata.CellSize()[2]; - const amrex::Real& prob_lo_z = geomdata.ProbLo()[2]; - const amrex::Real& prob_hi_z = geomdata.ProbHi()[2]; - - const amrex::Real rdOcp = sc.rdOcp; - - // const amrex::Real thetatr = 343.0; - // const amrex::Real theta0 = 300.0; - const amrex::Real ztr = 12000.0; - const amrex::Real Ttr = 213.0; - const amrex::Real Ttop = 213.0; - const amrex::Real deltaz = 1000.*0.0; - const amrex::Real zs = 5000.; - const amrex::Real us = 30.; - const amrex::Real uc = 15.; - - amrex::ParallelForRNG(bx, [=, parms_d=parms] AMREX_GPU_DEVICE(int i, int j, int k, const amrex::RandomEngine& engine) noexcept - { - // Geometry (note we must include these here to get the data on device) - const auto prob_lo = geomdata.ProbLo(); - const auto dx = geomdata.CellSize(); - const amrex::Real z = prob_lo[2] + (k + 0.5) * dx[2]; - - amrex::Real relhum = init_supercell_relhum(z, ztr); - amrex::Real temp = init_supercell_temperature(z, prob_lo_z, ztr, prob_hi_z, parms_d.T_0, Ttr, Ttop); - amrex::Real press = init_supercell_pressure(z, prob_lo_z, ztr, prob_hi_z, parms_d.T_0, Ttr, Ttop); - amrex::Real qvs = init_supercell_sat_mix(press, temp); - -#if 0 - amrex::Real thetaeq; - amrex::Real faceq; - if (z <= ztr) { - thetaeq = theta0 + (thetatr - theta0)*std::pow(z/ztr, 5./4.); - } - else { - thetaeq = thetatr*std::exp(CONST_GRAV*(z-ztr)/c_p*Ttr); - } - - faceq = 1.; - for (int km = 0; km < k; ++km) { - amrex::Real zloc = prob_lo[2]+(km+0.5)*dx[2]; - amrex::Real theq; - if (zloc <= ztr) { - theq = theta0 + (thetatr - theta0)*std::pow(zloc/ztr, 5./4.); - } else { - theq = thetatr*std::exp(CONST_GRAV*(zloc-ztr)/c_p*Ttr); - } - faceq -= CONST_GRAV/(c_p*theq)*dz; - } - - temp = faceq*thetaeq; -#endif - - if (relhum*qvs > 0.014) relhum = 0.014/qvs; - amrex::Real qvapor = std::min(0.014, qvs*relhum); - amrex::Real rho = press/(R_d+qvapor*R_v)/temp; - - // perturb theta - amrex::Real rand_double = amrex::Random(engine) - 1.0; // Random number in [-1,1] - amrex::Real scaling = (khi-static_cast(k))/khi; // Less effect at higher levels - amrex::Real deltaT = parms_d.T_pert*scaling*rand_double; - - amrex::Real theta = getThgivenRandT(rho, temp+deltaT, rdOcp); - - // This version perturbs rho but not p - state_pert(i, j, k, RhoTheta_comp) = rho*theta - getRhoThetagivenP(p_hse(i,j,k)); - state_pert(i, j, k, Rho_comp) = rho - r_hse(i,j,k); - - // Set scalar = 0 everywhere - state_pert(i, j, k, RhoScalar_comp) = 0.0; - - // mean states - if (use_moisture) { - state_pert(i, j, k, RhoQ1_comp) = rho*qvapor; - state_pert(i, j, k, RhoQ2_comp) = 0.0; - } - }); - - // Set the x-velocity - amrex::ParallelFor(xbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { - const amrex::Real z = prob_lo_z + (k+0.5) * dz; - if (z < zs-deltaz) { - x_vel_pert(i, j, k) = us*(z/zs) - uc; - } else if (std::abs(z-zs) < deltaz) { - x_vel_pert(i, j, k) = (-0.8+3.*(z/zs)-1.25*(z/zs)*(z/zs))*us-uc; - } else { - x_vel_pert(i, j, k) = us-uc; - } - }); - - // Set the y-velocity - amrex::ParallelFor(ybx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { - y_vel_pert(i, j, k) = 0.0; - }); - - // Set the z-velocity - amrex::ParallelFor(zbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept { - z_vel_pert(i, j, k) = 0.0; - }); - - amrex::Gpu::streamSynchronize(); -} - -void -Problem::erf_init_rayleigh( - amrex::Vector >& rayleigh_ptrs, - amrex::Geometry const& geom, - std::unique_ptr& /*z_phys_nd*/, - amrex::Real /*zdamp*/) -{ - const int khi = geom.Domain().bigEnd()[2]; - - // We just use these values to test the Rayleigh damping - for (int k = 0; k <= khi; k++) - { - rayleigh_ptrs[Rayleigh::ubar][k] = 2.0; - rayleigh_ptrs[Rayleigh::vbar][k] = 1.0; - rayleigh_ptrs[Rayleigh::wbar][k] = 0.0; - rayleigh_ptrs[Rayleigh::thetabar][k] = parms.T_0; - } -} diff --git a/Exec/SuperCell/GNUmakefile b/Exec/SuperCell/GNUmakefile deleted file mode 100644 index 968d704e3..000000000 --- a/Exec/SuperCell/GNUmakefile +++ /dev/null @@ -1,32 +0,0 @@ -# AMReX -COMP = gnu -PRECISION = DOUBLE - -# Profiling -PROFILE = FALSE -TINY_PROFILE = FALSE -COMM_PROFILE = FALSE -TRACE_PROFILE = FALSE -MEM_PROFILE = FALSE -USE_GPROF = FALSE - -# Performance -USE_MPI = TRUE -USE_OMP = FALSE - -USE_CUDA = FALSE -USE_HIP = FALSE -USE_SYCL = FALSE - -# Debugging -DEBUG = FALSE - -TEST = TRUE -USE_ASSERTION = TRUE - -# GNU Make -Bpack := ./Make.package -Blocs := . -ERF_HOME := ../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/SuperCell -include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/SuperCell/Make.package b/Exec/SuperCell/Make.package deleted file mode 100644 index 5fc21f61c..000000000 --- a/Exec/SuperCell/Make.package +++ /dev/null @@ -1,2 +0,0 @@ -CEXE_headers += ERF_prob.H -CEXE_sources += ERF_prob.cpp diff --git a/Exec/SuperCell/README b/Exec/SuperCell/README deleted file mode 100644 index 9242958db..000000000 --- a/Exec/SuperCell/README +++ /dev/null @@ -1,2 +0,0 @@ -This problem setup is the evolution of a supercell, which primarily tests the ability -of ERF to model moisture physics. diff --git a/Exec/SuperCell/inputs_moisture b/Exec/SuperCell/inputs_moisture deleted file mode 100644 index 92e812fe7..000000000 --- a/Exec/SuperCell/inputs_moisture +++ /dev/null @@ -1,63 +0,0 @@ -# ------------------ INPUTS TO MAIN PROGRAM ------------------- -max_step = 1000 -stop_time = 90000.0 - -amrex.fpe_trap_invalid = 1 - -fabarray.mfiter_tile_size = 2048 1024 2048 - -# PROBLEM SIZE & GEOMETRY -geometry.prob_lo = -25600. 0. 0. -geometry.prob_hi = 25600. 400. 12800. -amr.n_cell = 128 4 32 # dx=dy=dz=100 m - -# periodic in x to match WRF setup -# - as an alternative, could use symmetry at x=0 and outflow at x=25600 -geometry.is_periodic = 1 1 0 -zlo.type = "SlipWall" -zhi.type = "SlipWall" - -# TIME STEP CONTROL -erf.fixed_dt = 1.0 # fixed time step [s] -- Straka et al 1993 -erf.fixed_fast_dt = 0.25 # fixed time step [s] -- Straka et al 1993 - -# DIAGNOSTICS & VERBOSITY -erf.sum_interval = 1 # timesteps between computing mass -erf.v = 1 # verbosity in ERF.cpp -amr.v = 1 # verbosity in Amr.cpp - -# REFINEMENT / REGRIDDING -amr.max_level = 0 # maximum level number allowed - -# CHECKPOINT FILES -amr.check_file = chk # root name of checkpoint file -amr.check_int = 10000 # number of timesteps between checkpoints -#amr.restart = chk01000 - -# PLOTFILES -erf.plot_file_1 = plt # root name of plotfile -erf.plot_int_1 = 1 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhotheta rhoQ1 rhoQ2 rhoQ3 x_velocity y_velocity z_velocity pressure theta temp qt qp qv qc qi - -# SOLVER CHOICE -erf.use_gravity = true -erf.use_coriolis = false - -erf.moisture_model = "SAM" - -erf.les_type = "Deardorff" -erf.KE_0 = 0.1 # for Deardorff -#erf.les_type = "None" -# -# diffusion coefficient from Straka, K = 75 m^2/s -# -#erf.molec_diff_type = "ConstantAlpha" -erf.molec_diff_type = "None" -erf.rho0_trans = 1.0 # [kg/m^3], used to convert input diffusivities -erf.dynamicViscosity = 75.0 # [kg/(m-s)] ==> nu = 75.0 m^2/s -erf.alpha_T = 75.0 # [m^2/s] - -# PROBLEM PARAMETERS (optional) -prob.T_0 = 300.0 -prob.U_0 = 0 -prob.T_pert = 3 diff --git a/Source/BoundaryConditions/ERF_FillIntermediatePatch.cpp b/Source/BoundaryConditions/ERF_FillIntermediatePatch.cpp index 6b8c013e2..a494132f1 100644 --- a/Source/BoundaryConditions/ERF_FillIntermediatePatch.cpp +++ b/Source/BoundaryConditions/ERF_FillIntermediatePatch.cpp @@ -121,10 +121,6 @@ ERF::FillIntermediatePatch (int lev, Real time, Vector ctime = {t_old[lev-1], t_new[lev-1]}; Vector ftime = {time,time}; - // Impose physical bc's on coarse data (note time and 0 are not used) - (*physbcs_cons[lev-1])(vars_old[lev-1][Vars::cons],icomp_cons,ncomp_cons,IntVect{ng_cons},time,BCVars::cons_bc,true); - (*physbcs_cons[lev-1])(vars_new[lev-1][Vars::cons],icomp_cons,ncomp_cons,IntVect{ng_cons},time,BCVars::cons_bc,true); - // Impose physical bc's on fine data (note time and 0 are not used) (*physbcs_cons[lev])(*mfs_vel[Vars::cons],icomp_cons,ncomp_cons,IntVect{ng_cons},time,BCVars::cons_bc,true); @@ -257,10 +253,6 @@ ERF::FillIntermediatePatch (int lev, Real time, fmf = {&mfu,&mfu}; cmf = {&vars_old[lev-1][Vars::xvel], &vars_new[lev-1][Vars::xvel]}; - // Impose physical bc's on coarse data (note time and 0 are not used) - (*physbcs_u[lev-1])(vars_old[lev-1][Vars::xvel],0,1,IntVect{ng_vel},time,BCVars::xvel_bc,true); - (*physbcs_u[lev-1])(vars_new[lev-1][Vars::xvel],0,1,IntVect{ng_vel},time,BCVars::xvel_bc,true); - // Call FillPatchTwoLevels which ASSUMES that all ghost cells have already been filled FillPatchTwoLevels(mfu, IntVect{ng_vel}, IntVect(0,0,0), time, cmf, ctime, fmf, ftime, @@ -275,10 +267,6 @@ ERF::FillIntermediatePatch (int lev, Real time, fmf = {&mfv,&mfv}; cmf = {&vars_old[lev-1][Vars::yvel], &vars_new[lev-1][Vars::yvel]}; - // Impose physical bc's on coarse data (note time and 0 are not used) - (*physbcs_v[lev-1])(vars_old[lev-1][Vars::yvel],0,1,IntVect{ng_vel},time,BCVars::yvel_bc,true); - (*physbcs_v[lev-1])(vars_new[lev-1][Vars::yvel],0,1,IntVect{ng_vel},time,BCVars::yvel_bc,true); - // Call FillPatchTwoLevels which ASSUMES that all ghost cells have already been filled FillPatchTwoLevels(mfv, IntVect{ng_vel}, IntVect(0,0,0), time, cmf, ctime, fmf, ftime, @@ -293,16 +281,6 @@ ERF::FillIntermediatePatch (int lev, Real time, fmf = {&mfw,&mfw}; cmf = {&vars_old[lev-1][Vars::zvel], &vars_new[lev-1][Vars::zvel]}; - // Impose physical bc's on coarse data (note time and 0 are not used) - (*physbcs_w[lev-1])(vars_old[lev-1][Vars::zvel], - vars_old[lev-1][Vars::xvel], - vars_old[lev-1][Vars::yvel], - IntVect{ng_vel},time,BCVars::zvel_bc,true); - (*physbcs_w[lev-1])(vars_new[lev-1][Vars::zvel], - vars_new[lev-1][Vars::xvel], - vars_new[lev-1][Vars::yvel], - IntVect{ng_vel},time,BCVars::zvel_bc,true); - // Call FillPatchTwoLevels which ASSUMES that all ghost cells have already been filled FillPatchTwoLevels(mfw, IntVect{ng_vel}, IntVect(0,0,0), time, cmf, ctime, fmf, ftime, diff --git a/Source/DataStructs/ERF_DataStruct.H b/Source/DataStructs/ERF_DataStruct.H index 645b5c7a5..0eff71724 100644 --- a/Source/DataStructs/ERF_DataStruct.H +++ b/Source/DataStructs/ERF_DataStruct.H @@ -339,7 +339,7 @@ struct SolverChoice { // Which type of multilevel coupling - coupling_type = CouplingType::OneWay; // Default + coupling_type = CouplingType::TwoWay; // Default pp.query_enum_case_insensitive("coupling_type",coupling_type); // Which type of windfarm model diff --git a/Source/ERF_make_new_level.cpp b/Source/ERF_make_new_level.cpp index 3f0fd47cf..377eb09be 100644 --- a/Source/ERF_make_new_level.cpp +++ b/Source/ERF_make_new_level.cpp @@ -332,39 +332,40 @@ ERF::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMapp // ***************************************************************************************************** make_physbcs(lev); - // ************************************************************************************************* - // This will fill the temporary MultiFabs with data from vars_new - // NOTE: the momenta here are only used as scratch space, the momenta themselves are not fillpatched - // ************************************************************************************************* - FillPatch(lev, time, {&temp_lev_new[Vars::cons],&temp_lev_new[Vars::xvel], - &temp_lev_new[Vars::yvel],&temp_lev_new[Vars::zvel]}, - {&temp_lev_new[Vars::cons],&rU_new[lev],&rV_new[lev],&rW_new[lev]}, - base_state[lev],temp_base_state,false); - // ******************************************************************************************** // Update the base state at this level by interpolation from coarser level AND copy // from previous (pre-regrid) base_state array // ******************************************************************************************** - if (lev > 0) { - Interpolater* mapper = &cell_cons_interp; + Interpolater* mapper = &cell_cons_interp; - Vector fmf = {&base_state[lev ], &base_state[lev ]}; - Vector cmf = {&base_state[lev-1], &base_state[lev-1]}; - Vector ftime = {time, time}; - Vector ctime = {time, time}; + Vector fmf = {&base_state[lev ], &base_state[lev ]}; + Vector cmf = {&base_state[lev-1], &base_state[lev-1]}; + Vector ftime = {time, time}; + Vector ctime = {time, time}; - // Call FillPatch which ASSUMES that all ghost cells at lev-1 have already been filled - FillPatchTwoLevels(temp_base_state, temp_base_state.nGrowVect(), IntVect(0,0,0), - time, cmf, ctime, fmf, ftime, - 0, 0, temp_base_state.nComp(), geom[lev-1], geom[lev], - refRatio(lev-1), mapper, domain_bcs_type, - BCVars::base_bc); + // Call FillPatch which ASSUMES that all ghost cells at lev-1 have already been filled + FillPatchTwoLevels(temp_base_state, temp_base_state.nGrowVect(), IntVect(0,0,0), + time, cmf, ctime, fmf, ftime, + 0, 0, temp_base_state.nComp(), geom[lev-1], geom[lev], + refRatio(lev-1), mapper, domain_bcs_type, + BCVars::base_bc); - // Impose bc's outside the domain - (*physbcs_base[lev])(temp_base_state,0,temp_base_state.nComp(),base_state[lev].nGrowVect()); + // Impose bc's outside the domain + (*physbcs_base[lev])(temp_base_state,0,temp_base_state.nComp(),base_state[lev].nGrowVect()); - std::swap(temp_base_state, base_state[lev]); - } + // ************************************************************************************************* + // This will fill the temporary MultiFabs with data from vars_new + // NOTE: the momenta here are only used as scratch space, the momenta themselves are not fillpatched + // NOTE: we must create the new base state before calling FillPatch because we will + // interpolate perturbational quantities + // ************************************************************************************************* + FillPatch(lev, time, {&temp_lev_new[Vars::cons],&temp_lev_new[Vars::xvel], + &temp_lev_new[Vars::yvel],&temp_lev_new[Vars::zvel]}, + {&temp_lev_new[Vars::cons],&rU_new[lev],&rV_new[lev],&rW_new[lev]}, + base_state[lev], temp_base_state, false); + + // Now swap the pointers since we needed both old and new in the FillPatch + std::swap(temp_base_state, base_state[lev]); // ******************************************************************************************** // Copy from new into old just in case @@ -445,6 +446,10 @@ ERF::ClearLevel (int lev) rW_new[lev].clear(); rW_old[lev].clear(); + if (lev > 0) { + zmom_crse_rhs[lev].clear(); + } + if (solverChoice.anelastic[lev] == 1) { pp_inc[lev].clear(); } diff --git a/Source/TimeIntegration/ERF_TI_fast_headers.H b/Source/TimeIntegration/ERF_TI_fast_headers.H index 5c470d9da..8a244dbcb 100644 --- a/Source/TimeIntegration/ERF_TI_fast_headers.H +++ b/Source/TimeIntegration/ERF_TI_fast_headers.H @@ -26,6 +26,7 @@ void erf_fast_rhs_N (int step, int nrk, int level, int finest_level, const amrex::MultiFab& S_stage_prim, const amrex::MultiFab& pi_stage, const amrex::MultiFab& fast_coeffs, + const amrex::MultiFab* zmom_crse_rhs, amrex::Vector& S_data, amrex::Vector& S_scratch, const amrex::Geometry geom, diff --git a/Source/TimeIntegration/ERF_TI_fast_rhs_fun.H b/Source/TimeIntegration/ERF_TI_fast_rhs_fun.H index 1213b8cf6..152c60227 100644 --- a/Source/TimeIntegration/ERF_TI_fast_rhs_fun.H +++ b/Source/TimeIntegration/ERF_TI_fast_rhs_fun.H @@ -157,6 +157,7 @@ auto fast_rhs_fun = [&](int fast_step, int /*n_sub*/, int nrk, // and S_data is the new-time solution to be defined here erf_fast_rhs_N(fast_step, nrk, level, finest_level, S_slow_rhs, S_old, S_stage, S_prim, pi_stage, fast_coeffs, + (level > 0) ? &zmom_crse_rhs[level] : nullptr, S_data, S_scratch, fine_geom, solverChoice.gravity, dtau, beta_s, inv_fac, mapfac_m[level], mapfac_u[level], mapfac_v[level], @@ -166,6 +167,7 @@ auto fast_rhs_fun = [&](int fast_step, int /*n_sub*/, int nrk, // and as the new-time solution to be defined here erf_fast_rhs_N(fast_step, nrk, level, finest_level, S_slow_rhs, S_data, S_stage, S_prim, pi_stage, fast_coeffs, + (level > 0) ? &zmom_crse_rhs[level] : nullptr, S_data, S_scratch, fine_geom, solverChoice.gravity, dtau, beta_s, inv_fac, mapfac_m[level], mapfac_u[level], mapfac_v[level], diff --git a/Source/TimeIntegration/ERF_TI_slow_headers.H b/Source/TimeIntegration/ERF_TI_slow_headers.H index 86dfb38b5..14ab70cde 100644 --- a/Source/TimeIntegration/ERF_TI_slow_headers.H +++ b/Source/TimeIntegration/ERF_TI_slow_headers.H @@ -67,8 +67,6 @@ void erf_slow_rhs_pre (int level, int finest_level, int nrk, const amrex::MultiFab& xmom_src, const amrex::MultiFab& ymom_src, const amrex::MultiFab& zmom_src, - const amrex::MultiFab* xmom_crse_rhs, - const amrex::MultiFab* ymom_crse_rhs, const amrex::MultiFab* zmom_crse_rhs, amrex::MultiFab* Tau11, amrex::MultiFab* Tau22, diff --git a/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H b/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H index 092f87589..b96c2e096 100644 --- a/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H +++ b/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H @@ -125,8 +125,6 @@ erf_slow_rhs_pre(level, finest_level, nrk, slow_dt, S_rhs, S_old, S_data, S_prim, S_scratch, xvel_new, yvel_new, zvel_new, z_t_rk[level], Omega, cc_src, xmom_src, ymom_src, zmom_src, - (level > 0) ? &xmom_crse_rhs[level] : nullptr, - (level > 0) ? &ymom_crse_rhs[level] : nullptr, (level > 0) ? &zmom_crse_rhs[level] : nullptr, Tau11_lev[level].get(), Tau22_lev[level].get(), Tau33_lev[level].get(), Tau12_lev[level].get(), Tau13_lev[level].get(), Tau21_lev[level].get(), Tau23_lev[level].get(), Tau31_lev[level].get(), @@ -238,8 +236,6 @@ erf_slow_rhs_pre(level, finest_level, nrk, slow_dt, S_rhs, S_old, S_data, S_prim, S_scratch, xvel_new, yvel_new, zvel_new, z_t_rk[level], Omega, cc_src, xmom_src, ymom_src, zmom_src, - (level > 0) ? &xmom_crse_rhs[level] : nullptr, - (level > 0) ? &ymom_crse_rhs[level] : nullptr, (level > 0) ? &zmom_crse_rhs[level] : nullptr, Tau11_lev[level].get(), Tau22_lev[level].get(), Tau33_lev[level].get(), Tau12_lev[level].get(), Tau13_lev[level].get(), Tau21_lev[level].get(), Tau23_lev[level].get(), Tau31_lev[level].get(), @@ -449,8 +445,6 @@ S_rhs, S_old, S_data, S_prim, S_scratch, xvel_new, yvel_new, zvel_new, z_t_rk[level], Omega, cc_src, xmom_src, ymom_src, zmom_src, - (level > 0) ? &xmom_crse_rhs[level] : nullptr, - (level > 0) ? &ymom_crse_rhs[level] : nullptr, (level > 0) ? &zmom_crse_rhs[level] : nullptr, Tau11_lev[level].get(), Tau22_lev[level].get(), Tau33_lev[level].get(), Tau12_lev[level].get(), Tau13_lev[level].get(), Tau21_lev[level].get(), Tau23_lev[level].get(), Tau31_lev[level].get(), diff --git a/Source/TimeIntegration/ERF_fast_rhs_N.cpp b/Source/TimeIntegration/ERF_fast_rhs_N.cpp index 5bafd34bf..b11e62254 100644 --- a/Source/TimeIntegration/ERF_fast_rhs_N.cpp +++ b/Source/TimeIntegration/ERF_fast_rhs_N.cpp @@ -41,6 +41,7 @@ void erf_fast_rhs_N (int step, int nrk, const MultiFab & S_stage_prim, // Primitive version of S_stage_data[IntVars::cons] const MultiFab & pi_stage, // Exner function evaluated at last stage const MultiFab &fast_coeffs, // Coeffs for tridiagonal solve + const MultiFab* zmom_crse_rhs, // Source term from coarser level; non-zero on c/f boundary only Vector& S_data, // S_sum = most recent full solution Vector& S_scratch, // S_sum_old at most recent fast timestep for (rho theta) const Geometry geom, @@ -191,17 +192,17 @@ void erf_fast_rhs_N (int step, int nrk, // ********************************************************************* // Define updates in the RHS of {x, y, z}-momentum equations // ********************************************************************* - if (nrk == 0 and step == 0) { + if (nrk == 0 and step == 0) { // prev == stage ParallelFor(tbx, tby, [=] AMREX_GPU_DEVICE (int i, int j, int k) { - Real new_drho_u = prev_xmom(i,j,k) - stage_xmom(i,j,k) + dtau * slow_rhs_rho_u(i,j,k); + Real new_drho_u = dtau * slow_rhs_rho_u(i,j,k); avg_xmom(i,j,k) += facinv*new_drho_u; temp_cur_xmom_arr(i,j,k) = stage_xmom(i,j,k) + new_drho_u; }, [=] AMREX_GPU_DEVICE (int i, int j, int k) { - Real new_drho_v = prev_ymom(i,j,k) - stage_ymom(i,j,k) + dtau * slow_rhs_rho_v(i,j,k); + Real new_drho_v = dtau * slow_rhs_rho_v(i,j,k); avg_ymom(i,j,k) += facinv*new_drho_v; temp_cur_ymom_arr(i,j,k) = stage_ymom(i,j,k) + new_drho_v; }); @@ -220,11 +221,10 @@ void erf_fast_rhs_N (int step, int nrk, } Real pi_c = 0.5 * (pi_stage_ca(i-1,j,k,0) + pi_stage_ca(i,j,k,0)); - Real fast_rhs_rho_u = -Gamma * R_d * pi_c * gpx; Real new_drho_u = prev_xmom(i,j,k) - stage_xmom(i,j,k) - + dtau * fast_rhs_rho_u + dtau * slow_rhs_rho_u(i,j,k); + + dtau * fast_rhs_rho_u + dtau * slow_rhs_rho_u(i,j,k); avg_xmom(i,j,k) += facinv*new_drho_u; @@ -243,11 +243,10 @@ void erf_fast_rhs_N (int step, int nrk, } Real pi_c = 0.5 * (pi_stage_ca(i,j-1,k,0) + pi_stage_ca(i,j,k,0)); - Real fast_rhs_rho_v = -Gamma * R_d * pi_c * gpy; Real new_drho_v = prev_ymom(i,j,k) - stage_ymom(i,j,k) - + dtau * fast_rhs_rho_v + dtau * slow_rhs_rho_v(i,j,k); + + dtau * fast_rhs_rho_v + dtau * slow_rhs_rho_v(i,j,k); avg_ymom(i,j,k) += facinv*new_drho_v; @@ -282,6 +281,8 @@ void erf_fast_rhs_N (int step, int nrk, const Array4& slow_rhs_cons = S_slow_rhs[IntVars::cons].const_array(mfi); const Array4& slow_rhs_rho_w = S_slow_rhs[IntVars::zmom].const_array(mfi); + const Array4& rho_w_crse_arr = (level > 0) ? zmom_crse_rhs->const_array(mfi) : Array4{}; + const Array4& prev_zmom = S_prev[IntVars::zmom].const_array(mfi); const Array4< Real>& cur_zmom = S_data[IntVars::zmom].array(mfi); @@ -422,13 +423,41 @@ void erf_fast_rhs_N (int step, int nrk, ParallelFor(b2d, [=] AMREX_GPU_DEVICE (int i, int j, int) { - // w at bottom boundary of grid is 0 if at domain boundary, otherwise w = w_old + dtau * slow_rhs - RHS_a (i,j,lo.z ) = prev_zmom(i,j,lo.z ) - stage_zmom(i,j,lo.z) - + dtau * slow_rhs_rho_w(i,j,lo.z); + // w at bottom boundary of grid is 0 if at domain boundary, otherwise w = w_old + dtau * slow_rhs + RHS_a (i,j,lo.z ) = prev_zmom(i,j,lo.z ) - stage_zmom(i,j,lo.z); - // w at top boundary of grid is 0 if at domain boundary, otherwise w = w_old + dtau * slow_rhs - RHS_a (i,j,hi.z+1) = prev_zmom(i,j,hi.z+1) - stage_zmom(i,j,hi.z+1) - + dtau * slow_rhs_rho_w(i,j,hi.z+1); +#if 1 + int k = lo.z; + if (level > 0) { + if (k != 0) { + RHS_a (i,j,lo.z ) += dtau * rho_w_crse_arr(i,j,lo.z); + } else { + RHS_a (i,j,lo.z ) += dtau * slow_rhs_rho_w(i,j,lo.z); + } + } else { + RHS_a (i,j,lo.z ) += dtau * slow_rhs_rho_w(i,j,lo.z); + } +#else + RHS_a (i,j,lo.z ) += dtau * slow_rhs_rho_w(i,j,lo.z); +#endif + + // w at top boundary of grid is 0 if at domain boundary, otherwise w = w_old + dtau * slow_rhs + RHS_a (i,j,hi.z+1) = prev_zmom(i,j,hi.z+1) - stage_zmom(i,j,hi.z+1); + +#if 1 + k = hi.z+1; + if (level > 0) { + if (std::abs(rho_w_crse_arr(i,j,k)) > 0.) { + RHS_a (i,j,hi.z+1) += dtau * rho_w_crse_arr(i,j,hi.z+1); + } else { + RHS_a (i,j,hi.z+1) += dtau * slow_rhs_rho_w(i,j,hi.z+1); + } + } else { + RHS_a (i,j,hi.z+1) += dtau * slow_rhs_rho_w(i,j,hi.z+1); + } +#else + RHS_a (i,j,hi.z+1) += dtau * slow_rhs_rho_w(i,j,hi.z+1); +#endif }); // b2d #ifdef AMREX_USE_GPU diff --git a/Source/TimeIntegration/ERF_slow_rhs_pre.cpp b/Source/TimeIntegration/ERF_slow_rhs_pre.cpp index c92ed95cb..b35f3329e 100644 --- a/Source/TimeIntegration/ERF_slow_rhs_pre.cpp +++ b/Source/TimeIntegration/ERF_slow_rhs_pre.cpp @@ -32,6 +32,7 @@ using namespace amrex; * @param[in] xmom_src source terms for x-momentum * @param[in] ymom_src source terms for y-momentum * @param[in] zmom_src source terms for z-momentum + * @param[in] zmom_crse_rhs update term from coarser level for z-momentum; non-zero on c/f boundary only * @param[in] Tau11 tau_11 component of stress tensor * @param[in] Tau22 tau_22 component of stress tensor * @param[in] Tau33 tau_33 component of stress tensor @@ -81,9 +82,7 @@ void erf_slow_rhs_pre (int level, int finest_level, const MultiFab& xmom_src, const MultiFab& ymom_src, const MultiFab& zmom_src, - const MultiFab* xmom_crse_rhs, - const MultiFab* ymom_crse_rhs, - const MultiFab* zmom_crse_rhs, + const MultiFab* /*zmom_crse_rhs*/, MultiFab* Tau11, MultiFab* Tau22, MultiFab* Tau33, MultiFab* Tau12, MultiFab* Tau13, MultiFab* Tau21, MultiFab* Tau23, MultiFab* Tau31, MultiFab* Tau32, @@ -746,6 +745,34 @@ void erf_slow_rhs_pre (int level, int finest_level, } }); +#if 0 + auto const lo = lbound(bx); + auto const hi = ubound(bx); + + // Note: the logic below assumes no tiling in z! + if (level > 0) { + + const Array4& rho_w_rhs_crse = zmom_crse_rhs->const_array(mfi); + + Box b2d = bx; b2d.setRange(2,0); + + // Note: we don't need to test on being at the domain boundary + // because tbz is shrunk to not hit top and bottom domain boundaries + + ParallelFor(b2d, [=] AMREX_GPU_DEVICE (int i, int j, int ) { // bottom of box but not of domain + if (std::abs(rho_w_rhs_crse(i,j,lo.z)) > 0.) { + rho_w_rhs(i,j,lo.z) = rho_w_rhs_crse(i,j,lo.z); + } + }); + + ParallelFor(b2d, [=] AMREX_GPU_DEVICE (int i, int j, int ) { // top of box but not of domain + if (std::abs(rho_w_rhs_crse(i,j,hi.z+1)) > 0.) { + rho_w_rhs(i,j,hi.z+1) = rho_w_rhs_crse(i,j,hi.z+1); + } + }); + } +#endif + { BL_PROFILE("slow_rhs_pre_fluxreg"); // We only add to the flux registers in the final RK step From 72628167ff53cc144a2faf1374979469d1436034 Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Thu, 31 Oct 2024 11:35:30 -0700 Subject: [PATCH 13/24] fix issue at coarse/fine boundaries (#1920) * fix issue at coarse/fine boundaries * remove unused --- Source/ERF.H | 4 +- Source/ERF.cpp | 4 +- Source/ERF_make_new_arrays.cpp | 7 +-- Source/TimeIntegration/ERF_Advance.cpp | 51 ++++++++++---------- Source/TimeIntegration/ERF_TI_fast_headers.H | 1 - Source/TimeIntegration/ERF_TI_fast_rhs_fun.H | 2 - Source/TimeIntegration/ERF_fast_rhs_N.cpp | 39 ++------------- Source/TimeIntegration/ERF_slow_rhs_pre.cpp | 26 +++++----- 8 files changed, 48 insertions(+), 86 deletions(-) diff --git a/Source/ERF.H b/Source/ERF.H index 9027c6dc7..a914b926f 100644 --- a/Source/ERF.H +++ b/Source/ERF.H @@ -731,8 +731,8 @@ private: amrex::Vector rW_old; amrex::Vector rW_new; - amrex::Vector xmom_crse_rhs; - amrex::Vector ymom_crse_rhs; + // amrex::Vector xmom_crse_rhs; + // amrex::Vector ymom_crse_rhs; amrex::Vector zmom_crse_rhs; std::unique_ptr micro; diff --git a/Source/ERF.cpp b/Source/ERF.cpp index c812c9b11..65e216654 100644 --- a/Source/ERF.cpp +++ b/Source/ERF.cpp @@ -197,8 +197,8 @@ ERF::ERF_shared () rV_old.resize(nlevs_max); rW_old.resize(nlevs_max); - xmom_crse_rhs.resize(nlevs_max); - ymom_crse_rhs.resize(nlevs_max); + // xmom_crse_rhs.resize(nlevs_max); + // ymom_crse_rhs.resize(nlevs_max); zmom_crse_rhs.resize(nlevs_max); for (int lev = 0; lev < nlevs_max; ++lev) { diff --git a/Source/ERF_make_new_arrays.cpp b/Source/ERF_make_new_arrays.cpp index 90ab59dff..d1a856c19 100644 --- a/Source/ERF_make_new_arrays.cpp +++ b/Source/ERF_make_new_arrays.cpp @@ -150,12 +150,9 @@ ERF::init_stuff (int lev, const BoxArray& ba, const DistributionMapping& dm, rW_new[lev].define(convert(ba, IntVect(0,0,1)), dm, 1, ngrow_vels); if (lev > 0) { - xmom_crse_rhs[lev].define(convert(ba, IntVect(1,0,0)), dm, 1, IntVect{0}); - xmom_crse_rhs[lev].setVal(3.456e22); - ymom_crse_rhs[lev].define(convert(ba, IntVect(0,1,0)), dm, 1, IntVect{0}); - ymom_crse_rhs[lev].setVal(3.456e22); + //xmom_crse_rhs[lev].define(convert(ba, IntVect(1,0,0)), dm, 1, IntVect{0}); + //ymom_crse_rhs[lev].define(convert(ba, IntVect(0,1,0)), dm, 1, IntVect{0}); zmom_crse_rhs[lev].define(convert(ba, IntVect(0,0,1)), dm, 1, IntVect{0}); - zmom_crse_rhs[lev].setVal(3.456e22); } // We do this here just so they won't be undefined in the initial FillPatch diff --git a/Source/TimeIntegration/ERF_Advance.cpp b/Source/TimeIntegration/ERF_Advance.cpp index f634580f0..197edaddd 100644 --- a/Source/TimeIntegration/ERF_Advance.cpp +++ b/Source/TimeIntegration/ERF_Advance.cpp @@ -241,37 +241,38 @@ ERF::Advance (int lev, Real time, Real dt_lev, int iteration, int /*ncycle*/) state_new[IntVars::zmom].FillBoundary(geom[lev].periodicity()); FPr_w[lev].RegisterCoarseData({&state_old[IntVars::zmom], &state_new[IntVars::zmom]}, {time, time + dt_lev}); + } // // Now create a MultiFab that holds (S_new - S_old) / dt from the coarse level interpolated // on to the coarse/fine boundary at the fine resolution // - PhysBCFunctNoOp null_bc; - - MultiFab tempx(vars_new[lev+1][Vars::xvel].boxArray(),vars_new[lev+1][Vars::xvel].DistributionMap(),1,0); - tempx.setVal(0.0); - xmom_crse_rhs[lev+1].setVal(0.0); - FPr_u[lev].FillSet(tempx , time , null_bc, domain_bcs_type); - FPr_u[lev].FillSet(xmom_crse_rhs[lev+1], time+dt_lev, null_bc, domain_bcs_type); - MultiFab::Subtract(xmom_crse_rhs[lev+1],tempx,0,0,1,IntVect{0}); - xmom_crse_rhs[lev+1].mult(1.0/dt_lev,0,1,0); - - MultiFab tempy(vars_new[lev+1][Vars::yvel].boxArray(),vars_new[lev+1][Vars::yvel].DistributionMap(),1,0); - tempy.setVal(0.0); - ymom_crse_rhs[lev+1].setVal(0.0); - FPr_v[lev].FillSet(tempy , time , null_bc, domain_bcs_type); - FPr_v[lev].FillSet(ymom_crse_rhs[lev+1], time+dt_lev, null_bc, domain_bcs_type); - MultiFab::Subtract(ymom_crse_rhs[lev+1],tempy,0,0,1,IntVect{0}); - ymom_crse_rhs[lev+1].mult(1.0/dt_lev,0,1,0); - - MultiFab tempz(vars_new[lev+1][Vars::zvel].boxArray(),vars_new[lev+1][Vars::zvel].DistributionMap(),1,0); - tempz.setVal(0.0); - zmom_crse_rhs[lev+1].setVal(0.0); - FPr_w[lev].FillSet(tempz , time , null_bc, domain_bcs_type); - FPr_w[lev].FillSet(zmom_crse_rhs[lev+1], time+dt_lev, null_bc, domain_bcs_type); - MultiFab::Subtract(zmom_crse_rhs[lev+1],tempz,0,0,1,IntVect{0}); + Interpolater* mapper_f = &face_cons_linear_interp; + + // PhysBCFunctNoOp null_bc; + // MultiFab tempx(vars_new[lev+1][Vars::xvel].boxArray(),vars_new[lev+1][Vars::xvel].DistributionMap(),1,0); + // tempx.setVal(0.0); + // xmom_crse_rhs[lev+1].setVal(0.0); + // FPr_u[lev].FillSet(tempx , time , null_bc, domain_bcs_type); + // FPr_u[lev].FillSet(xmom_crse_rhs[lev+1], time+dt_lev, null_bc, domain_bcs_type); + // MultiFab::Subtract(xmom_crse_rhs[lev+1],tempx,0,0,1,IntVect{0}); + // xmom_crse_rhs[lev+1].mult(1.0/dt_lev,0,1,0); + + // MultiFab tempy(vars_new[lev+1][Vars::yvel].boxArray(),vars_new[lev+1][Vars::yvel].DistributionMap(),1,0); + // tempy.setVal(0.0); + // ymom_crse_rhs[lev+1].setVal(0.0); + // FPr_v[lev].FillSet(tempy , time , null_bc, domain_bcs_type); + // FPr_v[lev].FillSet(ymom_crse_rhs[lev+1], time+dt_lev, null_bc, domain_bcs_type); + // MultiFab::Subtract(ymom_crse_rhs[lev+1],tempy,0,0,1,IntVect{0}); + // ymom_crse_rhs[lev+1].mult(1.0/dt_lev,0,1,0); + + MultiFab temp_state(zmom_crse_rhs[lev+1].boxArray(),zmom_crse_rhs[lev+1].DistributionMap(),1,0); + InterpFromCoarseLevel(temp_state, IntVect{0}, IntVect{0}, state_old[IntVars::zmom], 0, 0, 1, + geom[lev], geom[lev+1], refRatio(lev), mapper_f, domain_bcs_type, BCVars::zvel_bc); + InterpFromCoarseLevel(zmom_crse_rhs[lev+1], IntVect{0}, IntVect{0}, state_new[IntVars::zmom], 0, 0, 1, + geom[lev], geom[lev+1], refRatio(lev), mapper_f, domain_bcs_type, BCVars::zvel_bc); + MultiFab::Subtract(zmom_crse_rhs[lev+1],temp_state,0,0,1,IntVect{0}); zmom_crse_rhs[lev+1].mult(1.0/dt_lev,0,1,0); - } } // *********************************************************************************************** diff --git a/Source/TimeIntegration/ERF_TI_fast_headers.H b/Source/TimeIntegration/ERF_TI_fast_headers.H index 8a244dbcb..5c470d9da 100644 --- a/Source/TimeIntegration/ERF_TI_fast_headers.H +++ b/Source/TimeIntegration/ERF_TI_fast_headers.H @@ -26,7 +26,6 @@ void erf_fast_rhs_N (int step, int nrk, int level, int finest_level, const amrex::MultiFab& S_stage_prim, const amrex::MultiFab& pi_stage, const amrex::MultiFab& fast_coeffs, - const amrex::MultiFab* zmom_crse_rhs, amrex::Vector& S_data, amrex::Vector& S_scratch, const amrex::Geometry geom, diff --git a/Source/TimeIntegration/ERF_TI_fast_rhs_fun.H b/Source/TimeIntegration/ERF_TI_fast_rhs_fun.H index 152c60227..1213b8cf6 100644 --- a/Source/TimeIntegration/ERF_TI_fast_rhs_fun.H +++ b/Source/TimeIntegration/ERF_TI_fast_rhs_fun.H @@ -157,7 +157,6 @@ auto fast_rhs_fun = [&](int fast_step, int /*n_sub*/, int nrk, // and S_data is the new-time solution to be defined here erf_fast_rhs_N(fast_step, nrk, level, finest_level, S_slow_rhs, S_old, S_stage, S_prim, pi_stage, fast_coeffs, - (level > 0) ? &zmom_crse_rhs[level] : nullptr, S_data, S_scratch, fine_geom, solverChoice.gravity, dtau, beta_s, inv_fac, mapfac_m[level], mapfac_u[level], mapfac_v[level], @@ -167,7 +166,6 @@ auto fast_rhs_fun = [&](int fast_step, int /*n_sub*/, int nrk, // and as the new-time solution to be defined here erf_fast_rhs_N(fast_step, nrk, level, finest_level, S_slow_rhs, S_data, S_stage, S_prim, pi_stage, fast_coeffs, - (level > 0) ? &zmom_crse_rhs[level] : nullptr, S_data, S_scratch, fine_geom, solverChoice.gravity, dtau, beta_s, inv_fac, mapfac_m[level], mapfac_u[level], mapfac_v[level], diff --git a/Source/TimeIntegration/ERF_fast_rhs_N.cpp b/Source/TimeIntegration/ERF_fast_rhs_N.cpp index b11e62254..a77fda150 100644 --- a/Source/TimeIntegration/ERF_fast_rhs_N.cpp +++ b/Source/TimeIntegration/ERF_fast_rhs_N.cpp @@ -41,7 +41,6 @@ void erf_fast_rhs_N (int step, int nrk, const MultiFab & S_stage_prim, // Primitive version of S_stage_data[IntVars::cons] const MultiFab & pi_stage, // Exner function evaluated at last stage const MultiFab &fast_coeffs, // Coeffs for tridiagonal solve - const MultiFab* zmom_crse_rhs, // Source term from coarser level; non-zero on c/f boundary only Vector& S_data, // S_sum = most recent full solution Vector& S_scratch, // S_sum_old at most recent fast timestep for (rho theta) const Geometry geom, @@ -281,8 +280,6 @@ void erf_fast_rhs_N (int step, int nrk, const Array4& slow_rhs_cons = S_slow_rhs[IntVars::cons].const_array(mfi); const Array4& slow_rhs_rho_w = S_slow_rhs[IntVars::zmom].const_array(mfi); - const Array4& rho_w_crse_arr = (level > 0) ? zmom_crse_rhs->const_array(mfi) : Array4{}; - const Array4& prev_zmom = S_prev[IntVars::zmom].const_array(mfi); const Array4< Real>& cur_zmom = S_data[IntVars::zmom].array(mfi); @@ -424,40 +421,12 @@ void erf_fast_rhs_N (int step, int nrk, ParallelFor(b2d, [=] AMREX_GPU_DEVICE (int i, int j, int) { // w at bottom boundary of grid is 0 if at domain boundary, otherwise w = w_old + dtau * slow_rhs - RHS_a (i,j,lo.z ) = prev_zmom(i,j,lo.z ) - stage_zmom(i,j,lo.z); - -#if 1 - int k = lo.z; - if (level > 0) { - if (k != 0) { - RHS_a (i,j,lo.z ) += dtau * rho_w_crse_arr(i,j,lo.z); - } else { - RHS_a (i,j,lo.z ) += dtau * slow_rhs_rho_w(i,j,lo.z); - } - } else { - RHS_a (i,j,lo.z ) += dtau * slow_rhs_rho_w(i,j,lo.z); - } -#else - RHS_a (i,j,lo.z ) += dtau * slow_rhs_rho_w(i,j,lo.z); -#endif + RHS_a (i,j,lo.z) = prev_zmom(i,j,lo.z) - stage_zmom(i,j,lo.z) + + dtau * slow_rhs_rho_w(i,j,lo.z); // w at top boundary of grid is 0 if at domain boundary, otherwise w = w_old + dtau * slow_rhs - RHS_a (i,j,hi.z+1) = prev_zmom(i,j,hi.z+1) - stage_zmom(i,j,hi.z+1); - -#if 1 - k = hi.z+1; - if (level > 0) { - if (std::abs(rho_w_crse_arr(i,j,k)) > 0.) { - RHS_a (i,j,hi.z+1) += dtau * rho_w_crse_arr(i,j,hi.z+1); - } else { - RHS_a (i,j,hi.z+1) += dtau * slow_rhs_rho_w(i,j,hi.z+1); - } - } else { - RHS_a (i,j,hi.z+1) += dtau * slow_rhs_rho_w(i,j,hi.z+1); - } -#else - RHS_a (i,j,hi.z+1) += dtau * slow_rhs_rho_w(i,j,hi.z+1); -#endif + RHS_a (i,j,hi.z+1) = prev_zmom(i,j,hi.z+1) - stage_zmom(i,j,hi.z+1) + + dtau * slow_rhs_rho_w(i,j,hi.z+1); }); // b2d #ifdef AMREX_USE_GPU diff --git a/Source/TimeIntegration/ERF_slow_rhs_pre.cpp b/Source/TimeIntegration/ERF_slow_rhs_pre.cpp index b35f3329e..1a42951f0 100644 --- a/Source/TimeIntegration/ERF_slow_rhs_pre.cpp +++ b/Source/TimeIntegration/ERF_slow_rhs_pre.cpp @@ -82,7 +82,7 @@ void erf_slow_rhs_pre (int level, int finest_level, const MultiFab& xmom_src, const MultiFab& ymom_src, const MultiFab& zmom_src, - const MultiFab* /*zmom_crse_rhs*/, + const MultiFab* zmom_crse_rhs, MultiFab* Tau11, MultiFab* Tau22, MultiFab* Tau33, MultiFab* Tau12, MultiFab* Tau13, MultiFab* Tau21, MultiFab* Tau23, MultiFab* Tau31, MultiFab* Tau32, @@ -169,6 +169,7 @@ void erf_slow_rhs_pre (int level, int finest_level, AMREX_ALWAYS_ASSERT(!l_use_terrain || !l_anelastic); const Box& domain = geom.Domain(); + const int domlo_z = domain.smallEnd(2); const int domhi_z = domain.bigEnd(2); const GpuArray dxInv = geom.InvCellSizeArray(); @@ -745,7 +746,6 @@ void erf_slow_rhs_pre (int level, int finest_level, } }); -#if 0 auto const lo = lbound(bx); auto const hi = ubound(bx); @@ -756,22 +756,20 @@ void erf_slow_rhs_pre (int level, int finest_level, Box b2d = bx; b2d.setRange(2,0); - // Note: we don't need to test on being at the domain boundary - // because tbz is shrunk to not hit top and bottom domain boundaries - - ParallelFor(b2d, [=] AMREX_GPU_DEVICE (int i, int j, int ) { // bottom of box but not of domain - if (std::abs(rho_w_rhs_crse(i,j,lo.z)) > 0.) { + if (lo.z > domlo_z) { + ParallelFor(b2d, [=] AMREX_GPU_DEVICE (int i, int j, int ) // bottom of box but not of domain + { rho_w_rhs(i,j,lo.z) = rho_w_rhs_crse(i,j,lo.z); - } - }); + }); + } - ParallelFor(b2d, [=] AMREX_GPU_DEVICE (int i, int j, int ) { // top of box but not of domain - if (std::abs(rho_w_rhs_crse(i,j,hi.z+1)) > 0.) { + if (hi.z < domhi_z+1) { + ParallelFor(b2d, [=] AMREX_GPU_DEVICE (int i, int j, int ) // top of box but not of domain + { rho_w_rhs(i,j,hi.z+1) = rho_w_rhs_crse(i,j,hi.z+1); - } - }); + }); + } } -#endif { BL_PROFILE("slow_rhs_pre_fluxreg"); From 2f3d72ca4922fcb8929d91cd53d630bf7303364f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 11:42:09 -0700 Subject: [PATCH 14/24] Bump Submodules/AMReX from `c333708` to `b9d549b` (#1921) Bumps [Submodules/AMReX](https://github.com/amrex-codes/amrex) from `c333708` to `b9d549b`. - [Release notes](https://github.com/amrex-codes/amrex/releases) - [Commits](https://github.com/amrex-codes/amrex/compare/c333708d59f01ab664363ba426e85ad24c1fb23d...b9d549bcf4a6e035e6050c92083d42a30a4078b1) --- updated-dependencies: - dependency-name: Submodules/AMReX dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Submodules/AMReX | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Submodules/AMReX b/Submodules/AMReX index c333708d5..b9d549bcf 160000 --- a/Submodules/AMReX +++ b/Submodules/AMReX @@ -1 +1 @@ -Subproject commit c333708d59f01ab664363ba426e85ad24c1fb23d +Subproject commit b9d549bcf4a6e035e6050c92083d42a30a4078b1 From 1412c9913df8725fa81bfc01235f9c0f180ff939 Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Fri, 1 Nov 2024 13:05:11 -0700 Subject: [PATCH 15/24] fix bcs with terrain and clean up time integrator (#1922) * fix bcs with terrain and clean up time integrator * Move Exec dirs into WindFarmTests --- CMake/BuildERFExe.cmake | 8 +-- .../{ => WindFarmTests}/AWAKEN/CMakeLists.txt | 0 Exec/{ => WindFarmTests}/AWAKEN/ERF_prob.H | 0 Exec/{ => WindFarmTests}/AWAKEN/ERF_prob.cpp | 0 Exec/{ => WindFarmTests}/AWAKEN/GNUmakefile | 0 Exec/{ => WindFarmTests}/AWAKEN/Make.package | 0 Exec/{ => WindFarmTests}/AWAKEN/README | 0 .../{ => WindFarmTests}/AWAKEN/inputs_All_EWP | 0 .../AWAKEN/inputs_KingPlains_EWP | 0 .../AWAKEN/inputs_KingPlains_Fitch | 0 .../AWAKEN/inputs_KingPlains_SimpleAD | 0 .../AWAKEN/windturbines_All.txt | 0 .../AWAKEN/windturbines_ArmadilloFlats.txt | 0 .../AWAKEN/windturbines_KingPlains.txt | 0 .../AWAKEN/windturbines_spec_AWAKEN.tbl | 0 Exec/{ => WindFarmTests}/EWP/CMakeLists.txt | 0 Exec/{ => WindFarmTests}/EWP/ERF_prob.H | 0 Exec/{ => WindFarmTests}/EWP/ERF_prob.cpp | 0 Exec/{ => WindFarmTests}/EWP/GNUmakefile | 0 Exec/{ => WindFarmTests}/EWP/Make.package | 0 Exec/{ => WindFarmTests}/EWP/README | 0 .../EWP/inputs_1WT_lat_lon | 0 Exec/{ => WindFarmTests}/EWP/inputs_1WT_x_y | 0 .../EWP/inputs_WindFarm_lat_lon | 0 .../EWP/inputs_WindFarm_x_y | 0 .../EWP/windturbines_loc_lat_lon_1WT.txt | 0 .../EWP/windturbines_loc_lat_lon_WindFarm.txt | 0 .../EWP/windturbines_loc_x_y_1WT.txt | 0 .../EWP/windturbines_loc_x_y_WindFarm.txt | 0 .../EWP/windturbines_spec_1WT.tbl | 0 .../EWP/windturbines_spec_WindFarm.tbl | 0 .../GeneralActuatorDisk/ERF_prob.cpp | 0 .../SimpleActuatorDisk/CMakeLists.txt | 0 .../SimpleActuatorDisk/ERF_prob.H | 0 .../SimpleActuatorDisk/ERF_prob.cpp | 0 .../SimpleActuatorDisk/GNUmakefile | 0 .../SimpleActuatorDisk/Make.package | 0 .../SimpleActuatorDisk/README | 0 .../SimpleActuatorDisk/inputs_1WT_lat_lon | 0 .../SimpleActuatorDisk/inputs_1WT_x_y | 0 .../inputs_WindFarm_lat_lon | 0 .../SimpleActuatorDisk/inputs_WindFarm_x_y | 0 .../windturbines_loc_lat_lon_1WT.txt | 0 .../windturbines_loc_x_y_1WT.txt | 0 .../windturbines_spec_1WT.tbl | 0 Exec/inputs.mesh_refinement | 15 ---- .../ERF_BoundaryConditions_basestate.cpp | 2 +- .../ERF_BoundaryConditions_cons.cpp | 4 +- .../ERF_FillIntermediatePatch.cpp | 14 ++-- Source/BoundaryConditions/ERF_PhysBCFunct.H | 4 +- Source/BoundaryConditions/ERF_PhysBCFunct.cpp | 70 ++----------------- Source/ERF_make_new_level.cpp | 16 +++-- Source/IO/ERF_Plotfile.cpp | 17 +++-- Source/TimeIntegration/ERF_MRI.H | 42 +++-------- Source/TimeIntegration/ERF_TI_fast_rhs_fun.H | 4 +- .../TimeIntegration/ERF_TI_no_substep_fun.H | 9 ++- Source/TimeIntegration/ERF_TI_slow_rhs_fun.H | 48 +++++++------ Source/TimeIntegration/ERF_TI_utils.H | 5 +- Source/TimeIntegration/ERF_advance_dycore.cpp | 2 - 59 files changed, 93 insertions(+), 167 deletions(-) rename Exec/{ => WindFarmTests}/AWAKEN/CMakeLists.txt (100%) rename Exec/{ => WindFarmTests}/AWAKEN/ERF_prob.H (100%) rename Exec/{ => WindFarmTests}/AWAKEN/ERF_prob.cpp (100%) rename Exec/{ => WindFarmTests}/AWAKEN/GNUmakefile (100%) rename Exec/{ => WindFarmTests}/AWAKEN/Make.package (100%) rename Exec/{ => WindFarmTests}/AWAKEN/README (100%) rename Exec/{ => WindFarmTests}/AWAKEN/inputs_All_EWP (100%) rename Exec/{ => WindFarmTests}/AWAKEN/inputs_KingPlains_EWP (100%) rename Exec/{ => WindFarmTests}/AWAKEN/inputs_KingPlains_Fitch (100%) rename Exec/{ => WindFarmTests}/AWAKEN/inputs_KingPlains_SimpleAD (100%) rename Exec/{ => WindFarmTests}/AWAKEN/windturbines_All.txt (100%) rename Exec/{ => WindFarmTests}/AWAKEN/windturbines_ArmadilloFlats.txt (100%) rename Exec/{ => WindFarmTests}/AWAKEN/windturbines_KingPlains.txt (100%) rename Exec/{ => WindFarmTests}/AWAKEN/windturbines_spec_AWAKEN.tbl (100%) rename Exec/{ => WindFarmTests}/EWP/CMakeLists.txt (100%) rename Exec/{ => WindFarmTests}/EWP/ERF_prob.H (100%) rename Exec/{ => WindFarmTests}/EWP/ERF_prob.cpp (100%) rename Exec/{ => WindFarmTests}/EWP/GNUmakefile (100%) rename Exec/{ => WindFarmTests}/EWP/Make.package (100%) rename Exec/{ => WindFarmTests}/EWP/README (100%) rename Exec/{ => WindFarmTests}/EWP/inputs_1WT_lat_lon (100%) rename Exec/{ => WindFarmTests}/EWP/inputs_1WT_x_y (100%) rename Exec/{ => WindFarmTests}/EWP/inputs_WindFarm_lat_lon (100%) rename Exec/{ => WindFarmTests}/EWP/inputs_WindFarm_x_y (100%) rename Exec/{ => WindFarmTests}/EWP/windturbines_loc_lat_lon_1WT.txt (100%) rename Exec/{ => WindFarmTests}/EWP/windturbines_loc_lat_lon_WindFarm.txt (100%) rename Exec/{ => WindFarmTests}/EWP/windturbines_loc_x_y_1WT.txt (100%) rename Exec/{ => WindFarmTests}/EWP/windturbines_loc_x_y_WindFarm.txt (100%) rename Exec/{ => WindFarmTests}/EWP/windturbines_spec_1WT.tbl (100%) rename Exec/{ => WindFarmTests}/EWP/windturbines_spec_WindFarm.tbl (100%) rename Exec/{ => WindFarmTests}/GeneralActuatorDisk/ERF_prob.cpp (100%) rename Exec/{ => WindFarmTests}/SimpleActuatorDisk/CMakeLists.txt (100%) rename Exec/{ => WindFarmTests}/SimpleActuatorDisk/ERF_prob.H (100%) rename Exec/{ => WindFarmTests}/SimpleActuatorDisk/ERF_prob.cpp (100%) rename Exec/{ => WindFarmTests}/SimpleActuatorDisk/GNUmakefile (100%) rename Exec/{ => WindFarmTests}/SimpleActuatorDisk/Make.package (100%) rename Exec/{ => WindFarmTests}/SimpleActuatorDisk/README (100%) rename Exec/{ => WindFarmTests}/SimpleActuatorDisk/inputs_1WT_lat_lon (100%) rename Exec/{ => WindFarmTests}/SimpleActuatorDisk/inputs_1WT_x_y (100%) rename Exec/{ => WindFarmTests}/SimpleActuatorDisk/inputs_WindFarm_lat_lon (100%) rename Exec/{ => WindFarmTests}/SimpleActuatorDisk/inputs_WindFarm_x_y (100%) rename Exec/{ => WindFarmTests}/SimpleActuatorDisk/windturbines_loc_lat_lon_1WT.txt (100%) rename Exec/{ => WindFarmTests}/SimpleActuatorDisk/windturbines_loc_x_y_1WT.txt (100%) rename Exec/{ => WindFarmTests}/SimpleActuatorDisk/windturbines_spec_1WT.tbl (100%) delete mode 100644 Exec/inputs.mesh_refinement diff --git a/CMake/BuildERFExe.cmake b/CMake/BuildERFExe.cmake index 78d438d47..a2ef237cb 100644 --- a/CMake/BuildERFExe.cmake +++ b/CMake/BuildERFExe.cmake @@ -203,10 +203,10 @@ function(build_erf_lib erf_lib_name) ${SRC_DIR}/Microphysics/Kessler/ERF_Init_Kessler.cpp ${SRC_DIR}/Microphysics/Kessler/ERF_Kessler.cpp ${SRC_DIR}/Microphysics/Kessler/ERF_Update_Kessler.cpp - ${SRC_DIR}/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp - ${SRC_DIR}/WindFarmParametrization/EWP/ERF_AdvanceEWP.cpp - ${SRC_DIR}/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp - ${SRC_DIR}/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp + ${SRC_DIR}/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp + ${SRC_DIR}/WindFarmParametrization/EWP/ERF_AdvanceEWP.cpp + ${SRC_DIR}/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp + ${SRC_DIR}/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp ${SRC_DIR}/LandSurfaceModel/SLM/ERF_SLM.cpp ${SRC_DIR}/LandSurfaceModel/MM5/ERF_MM5.cpp ) diff --git a/Exec/AWAKEN/CMakeLists.txt b/Exec/WindFarmTests/AWAKEN/CMakeLists.txt similarity index 100% rename from Exec/AWAKEN/CMakeLists.txt rename to Exec/WindFarmTests/AWAKEN/CMakeLists.txt diff --git a/Exec/AWAKEN/ERF_prob.H b/Exec/WindFarmTests/AWAKEN/ERF_prob.H similarity index 100% rename from Exec/AWAKEN/ERF_prob.H rename to Exec/WindFarmTests/AWAKEN/ERF_prob.H diff --git a/Exec/AWAKEN/ERF_prob.cpp b/Exec/WindFarmTests/AWAKEN/ERF_prob.cpp similarity index 100% rename from Exec/AWAKEN/ERF_prob.cpp rename to Exec/WindFarmTests/AWAKEN/ERF_prob.cpp diff --git a/Exec/AWAKEN/GNUmakefile b/Exec/WindFarmTests/AWAKEN/GNUmakefile similarity index 100% rename from Exec/AWAKEN/GNUmakefile rename to Exec/WindFarmTests/AWAKEN/GNUmakefile diff --git a/Exec/AWAKEN/Make.package b/Exec/WindFarmTests/AWAKEN/Make.package similarity index 100% rename from Exec/AWAKEN/Make.package rename to Exec/WindFarmTests/AWAKEN/Make.package diff --git a/Exec/AWAKEN/README b/Exec/WindFarmTests/AWAKEN/README similarity index 100% rename from Exec/AWAKEN/README rename to Exec/WindFarmTests/AWAKEN/README diff --git a/Exec/AWAKEN/inputs_All_EWP b/Exec/WindFarmTests/AWAKEN/inputs_All_EWP similarity index 100% rename from Exec/AWAKEN/inputs_All_EWP rename to Exec/WindFarmTests/AWAKEN/inputs_All_EWP diff --git a/Exec/AWAKEN/inputs_KingPlains_EWP b/Exec/WindFarmTests/AWAKEN/inputs_KingPlains_EWP similarity index 100% rename from Exec/AWAKEN/inputs_KingPlains_EWP rename to Exec/WindFarmTests/AWAKEN/inputs_KingPlains_EWP diff --git a/Exec/AWAKEN/inputs_KingPlains_Fitch b/Exec/WindFarmTests/AWAKEN/inputs_KingPlains_Fitch similarity index 100% rename from Exec/AWAKEN/inputs_KingPlains_Fitch rename to Exec/WindFarmTests/AWAKEN/inputs_KingPlains_Fitch diff --git a/Exec/AWAKEN/inputs_KingPlains_SimpleAD b/Exec/WindFarmTests/AWAKEN/inputs_KingPlains_SimpleAD similarity index 100% rename from Exec/AWAKEN/inputs_KingPlains_SimpleAD rename to Exec/WindFarmTests/AWAKEN/inputs_KingPlains_SimpleAD diff --git a/Exec/AWAKEN/windturbines_All.txt b/Exec/WindFarmTests/AWAKEN/windturbines_All.txt similarity index 100% rename from Exec/AWAKEN/windturbines_All.txt rename to Exec/WindFarmTests/AWAKEN/windturbines_All.txt diff --git a/Exec/AWAKEN/windturbines_ArmadilloFlats.txt b/Exec/WindFarmTests/AWAKEN/windturbines_ArmadilloFlats.txt similarity index 100% rename from Exec/AWAKEN/windturbines_ArmadilloFlats.txt rename to Exec/WindFarmTests/AWAKEN/windturbines_ArmadilloFlats.txt diff --git a/Exec/AWAKEN/windturbines_KingPlains.txt b/Exec/WindFarmTests/AWAKEN/windturbines_KingPlains.txt similarity index 100% rename from Exec/AWAKEN/windturbines_KingPlains.txt rename to Exec/WindFarmTests/AWAKEN/windturbines_KingPlains.txt diff --git a/Exec/AWAKEN/windturbines_spec_AWAKEN.tbl b/Exec/WindFarmTests/AWAKEN/windturbines_spec_AWAKEN.tbl similarity index 100% rename from Exec/AWAKEN/windturbines_spec_AWAKEN.tbl rename to Exec/WindFarmTests/AWAKEN/windturbines_spec_AWAKEN.tbl diff --git a/Exec/EWP/CMakeLists.txt b/Exec/WindFarmTests/EWP/CMakeLists.txt similarity index 100% rename from Exec/EWP/CMakeLists.txt rename to Exec/WindFarmTests/EWP/CMakeLists.txt diff --git a/Exec/EWP/ERF_prob.H b/Exec/WindFarmTests/EWP/ERF_prob.H similarity index 100% rename from Exec/EWP/ERF_prob.H rename to Exec/WindFarmTests/EWP/ERF_prob.H diff --git a/Exec/EWP/ERF_prob.cpp b/Exec/WindFarmTests/EWP/ERF_prob.cpp similarity index 100% rename from Exec/EWP/ERF_prob.cpp rename to Exec/WindFarmTests/EWP/ERF_prob.cpp diff --git a/Exec/EWP/GNUmakefile b/Exec/WindFarmTests/EWP/GNUmakefile similarity index 100% rename from Exec/EWP/GNUmakefile rename to Exec/WindFarmTests/EWP/GNUmakefile diff --git a/Exec/EWP/Make.package b/Exec/WindFarmTests/EWP/Make.package similarity index 100% rename from Exec/EWP/Make.package rename to Exec/WindFarmTests/EWP/Make.package diff --git a/Exec/EWP/README b/Exec/WindFarmTests/EWP/README similarity index 100% rename from Exec/EWP/README rename to Exec/WindFarmTests/EWP/README diff --git a/Exec/EWP/inputs_1WT_lat_lon b/Exec/WindFarmTests/EWP/inputs_1WT_lat_lon similarity index 100% rename from Exec/EWP/inputs_1WT_lat_lon rename to Exec/WindFarmTests/EWP/inputs_1WT_lat_lon diff --git a/Exec/EWP/inputs_1WT_x_y b/Exec/WindFarmTests/EWP/inputs_1WT_x_y similarity index 100% rename from Exec/EWP/inputs_1WT_x_y rename to Exec/WindFarmTests/EWP/inputs_1WT_x_y diff --git a/Exec/EWP/inputs_WindFarm_lat_lon b/Exec/WindFarmTests/EWP/inputs_WindFarm_lat_lon similarity index 100% rename from Exec/EWP/inputs_WindFarm_lat_lon rename to Exec/WindFarmTests/EWP/inputs_WindFarm_lat_lon diff --git a/Exec/EWP/inputs_WindFarm_x_y b/Exec/WindFarmTests/EWP/inputs_WindFarm_x_y similarity index 100% rename from Exec/EWP/inputs_WindFarm_x_y rename to Exec/WindFarmTests/EWP/inputs_WindFarm_x_y diff --git a/Exec/EWP/windturbines_loc_lat_lon_1WT.txt b/Exec/WindFarmTests/EWP/windturbines_loc_lat_lon_1WT.txt similarity index 100% rename from Exec/EWP/windturbines_loc_lat_lon_1WT.txt rename to Exec/WindFarmTests/EWP/windturbines_loc_lat_lon_1WT.txt diff --git a/Exec/EWP/windturbines_loc_lat_lon_WindFarm.txt b/Exec/WindFarmTests/EWP/windturbines_loc_lat_lon_WindFarm.txt similarity index 100% rename from Exec/EWP/windturbines_loc_lat_lon_WindFarm.txt rename to Exec/WindFarmTests/EWP/windturbines_loc_lat_lon_WindFarm.txt diff --git a/Exec/EWP/windturbines_loc_x_y_1WT.txt b/Exec/WindFarmTests/EWP/windturbines_loc_x_y_1WT.txt similarity index 100% rename from Exec/EWP/windturbines_loc_x_y_1WT.txt rename to Exec/WindFarmTests/EWP/windturbines_loc_x_y_1WT.txt diff --git a/Exec/EWP/windturbines_loc_x_y_WindFarm.txt b/Exec/WindFarmTests/EWP/windturbines_loc_x_y_WindFarm.txt similarity index 100% rename from Exec/EWP/windturbines_loc_x_y_WindFarm.txt rename to Exec/WindFarmTests/EWP/windturbines_loc_x_y_WindFarm.txt diff --git a/Exec/EWP/windturbines_spec_1WT.tbl b/Exec/WindFarmTests/EWP/windturbines_spec_1WT.tbl similarity index 100% rename from Exec/EWP/windturbines_spec_1WT.tbl rename to Exec/WindFarmTests/EWP/windturbines_spec_1WT.tbl diff --git a/Exec/EWP/windturbines_spec_WindFarm.tbl b/Exec/WindFarmTests/EWP/windturbines_spec_WindFarm.tbl similarity index 100% rename from Exec/EWP/windturbines_spec_WindFarm.tbl rename to Exec/WindFarmTests/EWP/windturbines_spec_WindFarm.tbl diff --git a/Exec/GeneralActuatorDisk/ERF_prob.cpp b/Exec/WindFarmTests/GeneralActuatorDisk/ERF_prob.cpp similarity index 100% rename from Exec/GeneralActuatorDisk/ERF_prob.cpp rename to Exec/WindFarmTests/GeneralActuatorDisk/ERF_prob.cpp diff --git a/Exec/SimpleActuatorDisk/CMakeLists.txt b/Exec/WindFarmTests/SimpleActuatorDisk/CMakeLists.txt similarity index 100% rename from Exec/SimpleActuatorDisk/CMakeLists.txt rename to Exec/WindFarmTests/SimpleActuatorDisk/CMakeLists.txt diff --git a/Exec/SimpleActuatorDisk/ERF_prob.H b/Exec/WindFarmTests/SimpleActuatorDisk/ERF_prob.H similarity index 100% rename from Exec/SimpleActuatorDisk/ERF_prob.H rename to Exec/WindFarmTests/SimpleActuatorDisk/ERF_prob.H diff --git a/Exec/SimpleActuatorDisk/ERF_prob.cpp b/Exec/WindFarmTests/SimpleActuatorDisk/ERF_prob.cpp similarity index 100% rename from Exec/SimpleActuatorDisk/ERF_prob.cpp rename to Exec/WindFarmTests/SimpleActuatorDisk/ERF_prob.cpp diff --git a/Exec/SimpleActuatorDisk/GNUmakefile b/Exec/WindFarmTests/SimpleActuatorDisk/GNUmakefile similarity index 100% rename from Exec/SimpleActuatorDisk/GNUmakefile rename to Exec/WindFarmTests/SimpleActuatorDisk/GNUmakefile diff --git a/Exec/SimpleActuatorDisk/Make.package b/Exec/WindFarmTests/SimpleActuatorDisk/Make.package similarity index 100% rename from Exec/SimpleActuatorDisk/Make.package rename to Exec/WindFarmTests/SimpleActuatorDisk/Make.package diff --git a/Exec/SimpleActuatorDisk/README b/Exec/WindFarmTests/SimpleActuatorDisk/README similarity index 100% rename from Exec/SimpleActuatorDisk/README rename to Exec/WindFarmTests/SimpleActuatorDisk/README diff --git a/Exec/SimpleActuatorDisk/inputs_1WT_lat_lon b/Exec/WindFarmTests/SimpleActuatorDisk/inputs_1WT_lat_lon similarity index 100% rename from Exec/SimpleActuatorDisk/inputs_1WT_lat_lon rename to Exec/WindFarmTests/SimpleActuatorDisk/inputs_1WT_lat_lon diff --git a/Exec/SimpleActuatorDisk/inputs_1WT_x_y b/Exec/WindFarmTests/SimpleActuatorDisk/inputs_1WT_x_y similarity index 100% rename from Exec/SimpleActuatorDisk/inputs_1WT_x_y rename to Exec/WindFarmTests/SimpleActuatorDisk/inputs_1WT_x_y diff --git a/Exec/SimpleActuatorDisk/inputs_WindFarm_lat_lon b/Exec/WindFarmTests/SimpleActuatorDisk/inputs_WindFarm_lat_lon similarity index 100% rename from Exec/SimpleActuatorDisk/inputs_WindFarm_lat_lon rename to Exec/WindFarmTests/SimpleActuatorDisk/inputs_WindFarm_lat_lon diff --git a/Exec/SimpleActuatorDisk/inputs_WindFarm_x_y b/Exec/WindFarmTests/SimpleActuatorDisk/inputs_WindFarm_x_y similarity index 100% rename from Exec/SimpleActuatorDisk/inputs_WindFarm_x_y rename to Exec/WindFarmTests/SimpleActuatorDisk/inputs_WindFarm_x_y diff --git a/Exec/SimpleActuatorDisk/windturbines_loc_lat_lon_1WT.txt b/Exec/WindFarmTests/SimpleActuatorDisk/windturbines_loc_lat_lon_1WT.txt similarity index 100% rename from Exec/SimpleActuatorDisk/windturbines_loc_lat_lon_1WT.txt rename to Exec/WindFarmTests/SimpleActuatorDisk/windturbines_loc_lat_lon_1WT.txt diff --git a/Exec/SimpleActuatorDisk/windturbines_loc_x_y_1WT.txt b/Exec/WindFarmTests/SimpleActuatorDisk/windturbines_loc_x_y_1WT.txt similarity index 100% rename from Exec/SimpleActuatorDisk/windturbines_loc_x_y_1WT.txt rename to Exec/WindFarmTests/SimpleActuatorDisk/windturbines_loc_x_y_1WT.txt diff --git a/Exec/SimpleActuatorDisk/windturbines_spec_1WT.tbl b/Exec/WindFarmTests/SimpleActuatorDisk/windturbines_spec_1WT.tbl similarity index 100% rename from Exec/SimpleActuatorDisk/windturbines_spec_1WT.tbl rename to Exec/WindFarmTests/SimpleActuatorDisk/windturbines_spec_1WT.tbl diff --git a/Exec/inputs.mesh_refinement b/Exec/inputs.mesh_refinement deleted file mode 100644 index 55da0226c..000000000 --- a/Exec/inputs.mesh_refinement +++ /dev/null @@ -1,15 +0,0 @@ - -# This file is meant to serve as an example of how to specify parameters -# that are only relevant when running with mesh refinement - -# REFINEMENT / REGRIDDING -amr.max_level = 1 # maximum level number allowed -amr.ref_ratio_vect = 2 2 1 3 3 1 # refinement ratio written as lev0_x lev0_y lev0_z lev1_x lev1_y lev1_z ... -amr.n_error_buf = 2 2 2 2 # number of buffer cells in error est - -erf.regrid_int = 2 2 2 2 # how often to regrid - -# How to specify a region for static refinement -erf.refinement_indicators = box1 -erf.box1.in_box_lo = .15 .25 -erf.box1.in_box_hi = .55 .65 diff --git a/Source/BoundaryConditions/ERF_BoundaryConditions_basestate.cpp b/Source/BoundaryConditions/ERF_BoundaryConditions_basestate.cpp index d2101ad4c..de97493ae 100644 --- a/Source/BoundaryConditions/ERF_BoundaryConditions_basestate.cpp +++ b/Source/BoundaryConditions/ERF_BoundaryConditions_basestate.cpp @@ -259,7 +259,7 @@ void ERFPhysBCFunct_base::impose_vertical_basestate_bcs (const Array4& des { dest_arr(i,j,k,BaseState::r0_comp) = dest_arr(i,j,dom_lo.z,BaseState::r0_comp); dest_arr(i,j,k,BaseState::p0_comp) = p_0 - - dest_arr(i,j,k,BaseState::r0_comp) * hz * 9.81; + dest_arr(i,j,k,BaseState::r0_comp) * hz * CONST_GRAV; dest_arr(i,j,k,BaseState::pi0_comp) = dest_arr(i,j,dom_lo.z,BaseState::pi0_comp); dest_arr(i,j,k,BaseState::th0_comp) = dest_arr(i,j,dom_lo.z,BaseState::th0_comp); } diff --git a/Source/BoundaryConditions/ERF_BoundaryConditions_cons.cpp b/Source/BoundaryConditions/ERF_BoundaryConditions_cons.cpp index 1a2edbd1c..5932ee22b 100644 --- a/Source/BoundaryConditions/ERF_BoundaryConditions_cons.cpp +++ b/Source/BoundaryConditions/ERF_BoundaryConditions_cons.cpp @@ -261,7 +261,7 @@ void ERFPhysBCFunct_cons::impose_lateral_cons_bcs (const Array4& dest_arr, void ERFPhysBCFunct_cons::impose_vertical_cons_bcs (const Array4& dest_arr, const Box& bx, const Box& domain, const Array4& z_phys_nd, const GpuArray dxInv, - int icomp, int ncomp) + int icomp, int ncomp, bool do_terrain_adjustment) { BL_PROFILE_VAR("impose_vertical_cons_bcs()",impose_vertical_cons_bcs); const auto& dom_lo = lbound(domain); @@ -416,7 +416,7 @@ void ERFPhysBCFunct_cons::impose_vertical_cons_bcs (const Array4& dest_arr ); } - if (m_z_phys_nd) { + if (do_terrain_adjustment && m_z_phys_nd) { const auto& bx_lo = lbound(bx); const auto& bx_hi = ubound(bx); const BCRec* bc_ptr_h = bcrs.data(); diff --git a/Source/BoundaryConditions/ERF_FillIntermediatePatch.cpp b/Source/BoundaryConditions/ERF_FillIntermediatePatch.cpp index a494132f1..982040c74 100644 --- a/Source/BoundaryConditions/ERF_FillIntermediatePatch.cpp +++ b/Source/BoundaryConditions/ERF_FillIntermediatePatch.cpp @@ -61,11 +61,13 @@ ERF::FillIntermediatePatch (int lev, Real time, } } - // amrex::Print() << "CONS ONLY " << cons_only << std::endl; - // amrex::Print() << "ICOMP NCOMP " << icomp_cons << " " << ncomp_cons << " NGHOST " << ng_cons << std::endl; + // amrex::Print() << "LEVEL " << lev << " CONS ONLY " << cons_only << + // " ICOMP NCOMP " << icomp_cons << " " << ncomp_cons << " NGHOST " << ng_cons << std::endl; - AMREX_ALWAYS_ASSERT(mfs_mom.size() == IntVars::NumTypes); - AMREX_ALWAYS_ASSERT(mfs_vel.size() == Vars::NumTypes); + if (!cons_only) { + AMREX_ALWAYS_ASSERT(mfs_mom.size() == IntVars::NumTypes); + AMREX_ALWAYS_ASSERT(mfs_vel.size() == Vars::NumTypes); + } // Enforce no penetration for thin immersed body if (!cons_only) { @@ -122,7 +124,9 @@ ERF::FillIntermediatePatch (int lev, Real time, Vector ftime = {time,time}; // Impose physical bc's on fine data (note time and 0 are not used) - (*physbcs_cons[lev])(*mfs_vel[Vars::cons],icomp_cons,ncomp_cons,IntVect{ng_cons},time,BCVars::cons_bc,true); + bool do_fb = true; bool do_terrain_adjustment = false; + (*physbcs_cons[lev])(*mfs_vel[Vars::cons],icomp_cons,ncomp_cons,IntVect{ng_cons},time,BCVars::cons_bc, + do_fb, do_terrain_adjustment); if ( (icomp_cons+ncomp_cons > 1) && (interpolation_type == StateInterpType::Perturbational) ) { diff --git a/Source/BoundaryConditions/ERF_PhysBCFunct.H b/Source/BoundaryConditions/ERF_PhysBCFunct.H index 756e4725d..6e201adb9 100644 --- a/Source/BoundaryConditions/ERF_PhysBCFunct.H +++ b/Source/BoundaryConditions/ERF_PhysBCFunct.H @@ -53,7 +53,7 @@ public: */ void operator() (amrex::MultiFab& mf, int icomp, int ncomp, amrex::IntVect const& nghost, const amrex::Real time, int bccomp_cons, - bool do_fb); + bool do_fb = true, bool do_terrain_adjustment = true); void impose_lateral_cons_bcs (const amrex::Array4& dest_arr, const amrex::Box& bx, const amrex::Box& domain, @@ -62,7 +62,7 @@ public: const amrex::Box& bx, const amrex::Box& domain, const amrex::Array4& z_nd, const amrex::GpuArray dxInv, - int icomp, int ncomp); + int icomp, int ncomp, bool do_terrain_adjustment = true); private: int m_lev; diff --git a/Source/BoundaryConditions/ERF_PhysBCFunct.cpp b/Source/BoundaryConditions/ERF_PhysBCFunct.cpp index fb5a18f8f..49714b383 100644 --- a/Source/BoundaryConditions/ERF_PhysBCFunct.cpp +++ b/Source/BoundaryConditions/ERF_PhysBCFunct.cpp @@ -15,7 +15,7 @@ using namespace amrex; void ERFPhysBCFunct_cons::operator() (MultiFab& mf, int icomp, int ncomp, IntVect const& nghost, const Real /*time*/, int /*bccomp*/, - bool do_fb) + bool do_fb, bool do_terrain_adjustment) { BL_PROFILE("ERFPhysBCFunct_cons::()"); @@ -32,21 +32,6 @@ void ERFPhysBCFunct_cons::operator() (MultiFab& mf, int icomp, int ncomp, } } - MultiFab z_nd_mf_loc; - if (m_z_phys_nd) { - m_z_phys_nd->FillBoundary(m_geom.periodicity()); - BoxList bl_z_phys = convert(mf.boxArray(),IntVect(1,1,1)).boxList(); - for (auto& b : bl_z_phys) { - b.setSmall(2,0); - b.setBig(2,1); - } - BoxArray ba_z(std::move(bl_z_phys)); - - z_nd_mf_loc.define(ba_z,mf.DistributionMap(),1,IntVect(nghost[0],nghost[1],0)); - z_nd_mf_loc.ParallelCopy(*m_z_phys_nd,0,0,1,m_z_phys_nd->nGrowVect(), - z_nd_mf_loc.nGrowVect()); - } - // // We fill all of the interior and periodic ghost cells first, so we can fill // those directly inside the lateral and vertical calls. @@ -77,7 +62,7 @@ void ERFPhysBCFunct_cons::operator() (MultiFab& mf, int icomp, int ncomp, if (m_z_phys_nd) { - z_nd_arr = z_nd_mf_loc.const_array(mfi); + z_nd_arr = m_z_phys_nd->const_array(mfi); } if (!gdomain.contains(cbx2)) @@ -91,7 +76,7 @@ void ERFPhysBCFunct_cons::operator() (MultiFab& mf, int icomp, int ncomp, } // We send the full FAB box with ghost cells - impose_vertical_cons_bcs(cons_arr,cbx2,domain,z_nd_arr,dxInv,icomp,ncomp); + impose_vertical_cons_bcs(cons_arr,cbx2,domain,z_nd_arr,dxInv,icomp,ncomp,do_terrain_adjustment); } } // MFIter @@ -116,20 +101,6 @@ void ERFPhysBCFunct_u::operator() (MultiFab& mf, int /*icomp*/, int /*ncomp*/, } } - MultiFab z_nd_mf_loc; - if (m_z_phys_nd) { - m_z_phys_nd->FillBoundary(m_geom.periodicity()); - BoxList bl_z_phys = convert(mf.boxArray(),IntVect(1,1,1)).boxList(); - for (auto& b : bl_z_phys) { - b.setSmall(2,0); - b.setBig(2,1); - } - BoxArray ba_z(std::move(bl_z_phys)); - z_nd_mf_loc.define(ba_z,mf.DistributionMap(),1,IntVect(nghost[0]+1,nghost[1],0)); - z_nd_mf_loc.ParallelCopy(*m_z_phys_nd,0,0,1,m_z_phys_nd->nGrowVect(), - z_nd_mf_loc.nGrowVect()); - } - // // We fill all of the interior and periodic ghost cells first, so we can fill // those directly inside the lateral and vertical calls. @@ -163,7 +134,7 @@ void ERFPhysBCFunct_u::operator() (MultiFab& mf, int /*icomp*/, int /*ncomp*/, if (m_z_phys_nd) { - z_nd_arr = z_nd_mf_loc.const_array(mfi); + z_nd_arr = m_z_phys_nd->const_array(mfi); } if (!gdomainx.contains(xbx2)) @@ -202,20 +173,6 @@ void ERFPhysBCFunct_v::operator() (MultiFab& mf, int /*icomp*/, int /*ncomp*/, } } - MultiFab z_nd_mf_loc; - if (m_z_phys_nd) { - m_z_phys_nd->FillBoundary(m_geom.periodicity()); - BoxList bl_z_phys = convert(mf.boxArray(),IntVect(1,1,1)).boxList(); - for (auto& b : bl_z_phys) { - b.setSmall(2,0); - b.setBig(2,1); - } - BoxArray ba_z(std::move(bl_z_phys)); - z_nd_mf_loc.define(ba_z,mf.DistributionMap(),1,IntVect(nghost[0],nghost[1]+1,0)); - z_nd_mf_loc.ParallelCopy(*m_z_phys_nd,0,0,1,m_z_phys_nd->nGrowVect(), - z_nd_mf_loc.nGrowVect()); - } - // // We fill all of the interior and periodic ghost cells first, so we can fill // those directly inside the lateral and vertical calls. @@ -249,7 +206,7 @@ void ERFPhysBCFunct_v::operator() (MultiFab& mf, int /*icomp*/, int /*ncomp*/, if (m_z_phys_nd) { - z_nd_arr = z_nd_mf_loc.const_array(mfi); + z_nd_arr = m_z_phys_nd->const_array(mfi); } if (!gdomainy.contains(ybx2)) @@ -293,21 +250,6 @@ void ERFPhysBCFunct_w::operator() (MultiFab& mf, MultiFab& xvel, MultiFab& yvel, // if (gdomainz.smallEnd(2) == 0) gdomainz.setSmall(2,1); - Box ndomain = convert(domain,IntVect(1,1,1)); - - MultiFab z_nd_mf_loc; - if (m_z_phys_nd) { - BoxList bl_z_phys = convert(mf.boxArray(),IntVect(1,1,1)).boxList(); - for (auto& b : bl_z_phys) { - b &= ndomain; - } - BoxArray ba_z(std::move(bl_z_phys)); - z_nd_mf_loc.define(ba_z,mf.DistributionMap(),1,IntVect(nghost[0],nghost[1],0)); - z_nd_mf_loc.ParallelCopy(*m_z_phys_nd,0,0,1,m_z_phys_nd->nGrowVect(), - z_nd_mf_loc.nGrowVect()); - } - z_nd_mf_loc.FillBoundary(m_geom.periodicity()); - // // We fill all of the interior and periodic ghost cells first, so we can fill // those directly inside the lateral and vertical calls. @@ -339,7 +281,7 @@ void ERFPhysBCFunct_w::operator() (MultiFab& mf, MultiFab& xvel, MultiFab& yvel, if (m_z_phys_nd) { - z_nd_arr = z_nd_mf_loc.const_array(mfi); + z_nd_arr = m_z_phys_nd->const_array(mfi); } // diff --git a/Source/ERF_make_new_level.cpp b/Source/ERF_make_new_level.cpp index 377eb09be..f9d29ce2b 100644 --- a/Source/ERF_make_new_level.cpp +++ b/Source/ERF_make_new_level.cpp @@ -47,7 +47,9 @@ void ERF::MakeNewLevelFromScratch (int lev, Real time, const BoxArray& ba_in, // Define dmap[lev] to be dm SetDistributionMap(lev, dm); - // amrex::Print() <<" BA FROM SCRATCH AT LEVEL " << lev << " " << ba << std::endl; + if (verbose) { + amrex::Print() <<" BA FROM SCRATCH AT LEVEL " << lev << " " << ba << std::endl; + } if (lev == 0) init_bcs(); @@ -179,7 +181,9 @@ ERF::MakeNewLevelFromCoarse (int lev, Real time, const BoxArray& ba, { AMREX_ALWAYS_ASSERT(lev > 0); - // amrex::Print() <<" NEW BA FROM COARSE AT LEVEL " << lev << " " << ba << std::endl; + if (verbose) { + amrex::Print() <<" NEW BA FROM COARSE AT LEVEL " << lev << " " << ba << std::endl; + } //******************************************************************************************** // This allocates all kinds of things, including but not limited to: solution arrays, @@ -283,7 +287,9 @@ ERF::MakeNewLevelFromCoarse (int lev, Real time, const BoxArray& ba, void ERF::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMapping& dm) { - // amrex::Print() <<" REMAKING WITH NEW BA AT LEVEL " << lev << " " << ba << std::endl; + if (verbose) { + amrex::Print() <<" REMAKING WITH NEW BA AT LEVEL " << lev << " " << ba << std::endl; + } AMREX_ALWAYS_ASSERT(lev > 0); AMREX_ALWAYS_ASSERT(solverChoice.terrain_type != TerrainType::Moving); @@ -291,7 +297,9 @@ ERF::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMapp BoxArray ba_old(vars_new[lev][Vars::cons].boxArray()); DistributionMapping dm_old(vars_new[lev][Vars::cons].DistributionMap()); - // amrex::Print() <<" OLD BA AT LEVEL " << lev << " " << ba_old << std::endl; + if (verbose) { + amrex::Print() <<" OLD BA AT LEVEL " << lev << " " << ba_old << std::endl; + } int ncomp_cons = vars_new[lev][Vars::cons].nComp(); IntVect ngrow_state = vars_new[lev][Vars::cons].nGrowVect(); diff --git a/Source/IO/ERF_Plotfile.cpp b/Source/IO/ERF_Plotfile.cpp index c8b7294e9..100ed7458 100644 --- a/Source/IO/ERF_Plotfile.cpp +++ b/Source/IO/ERF_Plotfile.cpp @@ -1410,10 +1410,15 @@ ERF::WritePlotFile (int which, PlotFileType plotfile_type, Vector p int lev0 = 0; int desired_ratio = std::max(std::max(ref_ratio[lev0][0],ref_ratio[lev0][1]),ref_ratio[lev0][2]); - bool any_ratio_one = ( ( (ref_ratio[lev0][0] == 0) || (ref_ratio[lev0][1] == 0) ) || - (ref_ratio[lev0][2] == 0) ); + bool any_ratio_one = ( ( (ref_ratio[lev0][0] == 1) || (ref_ratio[lev0][1] == 1) ) || + (ref_ratio[lev0][2] == 1) ); + for (int lev = 1; lev < finest_level; lev++) { + any_ratio_one = any_ratio_one || + ( ( (ref_ratio[lev][0] == 1) || (ref_ratio[lev][1] == 1) ) || + (ref_ratio[lev][2] == 1) ); + } - if (any_ratio_one == 1 && m_expand_plotvars_to_unif_rr) + if (any_ratio_one && m_expand_plotvars_to_unif_rr) { Vector r2(finest_level); Vector g2(finest_level+1); @@ -1435,9 +1440,9 @@ ERF::WritePlotFile (int which, PlotFileType plotfile_type, Vector p for (int lev = 1; lev <= finest_level; ++lev) { if (lev > 1) { - r2[lev-1][0] *= desired_ratio / ref_ratio[lev-1][0]; - r2[lev-1][1] *= desired_ratio / ref_ratio[lev-1][1]; - r2[lev-1][2] *= desired_ratio / ref_ratio[lev-1][2]; + r2[lev-1][0] = r2[lev-2][0] * desired_ratio / ref_ratio[lev-1][0]; + r2[lev-1][1] = r2[lev-2][1] * desired_ratio / ref_ratio[lev-1][1]; + r2[lev-1][2] = r2[lev-2][2] * desired_ratio / ref_ratio[lev-1][2]; } mf2[lev].define(refine(grids[lev],r2[lev-1]), dmap[lev], ncomp_mf, 0); diff --git a/Source/TimeIntegration/ERF_MRI.H b/Source/TimeIntegration/ERF_MRI.H index 0a38cc63c..9e69858d7 100644 --- a/Source/TimeIntegration/ERF_MRI.H +++ b/Source/TimeIntegration/ERF_MRI.H @@ -56,11 +56,8 @@ private: int force_stage1_single_substep; /** - * \brief The pre_update function is called by the integrator on stage data before using it to evaluate a right-hand side. - * \brief The post_update function is called by the integrator on stage data at the end of the stage + * \brief The no_substep function is called when we have no acoustic substepping */ - std::function pre_update; - std::function post_update; std::function no_substep; @@ -164,16 +161,6 @@ public: return slow_fast_timestep_ratio; } - void set_pre_update (std::function F) - { - pre_update = F; - } - - void set_post_update (std::function F) - { - post_update = F; - } - void set_no_substep (std::function F) { no_substep = F; @@ -247,8 +234,6 @@ public: // RK3 for compressible integrator for (int nrk = 0; nrk < 3; nrk++) { - // amrex::Print() << "Starting RK3: Step " << nrk+1 << std::endl; - // Capture the time we got to in the previous RK step old_time_stage = time_stage; @@ -285,12 +270,6 @@ public: // step 2 starts with S_stage = S^* and we always start substepping at the old time // step 3 starts with S_stage = S^** and we always start substepping at the old time - // All pre_update does is call cons_to_prim, and we have done this with the old - // data already before starting the RK steps - if (nrk > 0) { - pre_update(S_new, S_new[IntVars::cons].nGrow()); - } - // S_scratch also holds the average momenta over the fast iterations -- // to be used to update the slow variables -- we will initialize with // the momenta used in the first call to the slow_rhs, then update @@ -327,10 +306,6 @@ public: // (because we did update the fast variables in the substepping) // **************************************************** slow_rhs_post(*F_slow, S_old, S_new, *S_sum, *S_scratch, time, old_time_stage, time_stage, nrk); - - // Call the post-update hook for S_new after all the fast steps completed - // This will update S_prim that is used in the slow RHS - post_update(S_new, time + nsubsteps*dtau, S_new[IntVars::cons].nGrow(), S_new[IntVars::xmom].nGrow()); } // nrk } else { @@ -343,12 +318,6 @@ public: if (nrk == 0) { nsubsteps = 1; dtau = timestep; time_stage = time + timestep; } if (nrk == 1) { nsubsteps = 1; dtau = timestep; time_stage = time + timestep; } - // All pre_update does is call cons_to_prim, and we have done this with the old - // data already before starting the RK steps - if (nrk > 0) { - pre_update(S_new, S_new[IntVars::cons].nGrow()); - } - // S_scratch also holds the average momenta over the fast iterations -- // to be used to update the slow variables -- we will initialize with // the momenta used in the first call to the slow_rhs, then update @@ -358,9 +327,14 @@ public: no_substep(*S_sum, S_old, *F_slow, time + nsubsteps*dtau, nsubsteps*dtau, nrk); + // **************************************************** + // Evaluate F_slow(S_stage) only for the slow variables + // Note that we are using the current stage versions (in S_new) of the slow variables + // (because we didn't update the slow variables in the substepping) + // but we are using the "new" versions (in S_sum) of the velocities + // (because we did update the fast variables in the substepping) + // **************************************************** slow_rhs_post(*F_slow, S_old, S_new, *S_sum, *S_scratch, time, old_time_stage, time_stage, nrk); - - post_update(S_new, time + nsubsteps*dtau, S_new[IntVars::cons].nGrow(), S_new[IntVars::xmom].nGrow()); } // nrk } diff --git a/Source/TimeIntegration/ERF_TI_fast_rhs_fun.H b/Source/TimeIntegration/ERF_TI_fast_rhs_fun.H index 1213b8cf6..bddb14930 100644 --- a/Source/TimeIntegration/ERF_TI_fast_rhs_fun.H +++ b/Source/TimeIntegration/ERF_TI_fast_rhs_fun.H @@ -13,7 +13,9 @@ auto fast_rhs_fun = [&](int fast_step, int /*n_sub*/, int nrk, const Real new_substep_time) { BL_PROFILE("fast_rhs_fun"); - if (verbose) amrex::Print() << "Calling fast rhs at level " << level << " with dt = " << dtau << std::endl; + if (verbose) amrex::Print() << "Fast time integration at level " << level + << " from " << old_substep_time << " to " << new_substep_time + << " with dt = " << dtau << std::endl; // Define beta_s here so that it is consistent between where we make the fast coefficients // and where we use them diff --git a/Source/TimeIntegration/ERF_TI_no_substep_fun.H b/Source/TimeIntegration/ERF_TI_no_substep_fun.H index f49314a7c..1b7987799 100644 --- a/Source/TimeIntegration/ERF_TI_no_substep_fun.H +++ b/Source/TimeIntegration/ERF_TI_no_substep_fun.H @@ -16,6 +16,10 @@ const amrex::GpuArray scomp_fast = {0,0,0,0}; const amrex::GpuArray ncomp_fast = {2,1,1,1}; + if (verbose) amrex::Print() << " No-substepping time integration at level " << level + << " to " << time_for_fp + << " with dt = " << slow_dt << std::endl; + // Update S_sum = S_stage only for the fast variables #ifdef _OPENMP #pragma omp parallel if (amrex::Gpu::notInLaunchRegion()) @@ -127,9 +131,8 @@ // Even if we update all the conserved variables we don't need // to fillpatch the slow ones every acoustic substep - int ng_cons = S_sum[IntVars::cons].nGrow(); - int ng_vel = S_sum[IntVars::xmom].nGrow(); - apply_bcs(S_sum, time_for_fp, ng_cons, ng_vel, fast_only=true, vel_and_mom_synced=false); + apply_bcs(S_sum, time_for_fp, S_sum[IntVars::cons].nGrow(), S_sum[IntVars::xmom].nGrow(), + fast_only=true, vel_and_mom_synced=false); #ifdef ERF_USE_POISSON_SOLVE if (solverChoice.anelastic[level]) { diff --git a/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H b/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H index b96c2e096..af489069c 100644 --- a/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H +++ b/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H @@ -12,6 +12,15 @@ const Real new_stage_time, const int nrk) { + // + // Define primitive variables for all later RK stages + // (We have already done this for the first RK step) + // + if (nrk > 0) { + int ng_cons = S_data[IntVars::cons].nGrow(); + cons_to_prim(S_data[IntVars::cons], ng_cons); + } + BL_PROFILE("slow_rhs_fun_pre"); if (verbose) Print() << "Making slow rhs at time " << old_stage_time << " for fast variables advancing from " << old_step_time << " to " << new_stage_time << std::endl; @@ -281,23 +290,6 @@ #endif }; // end slow_rhs_fun_pre - // ************************************************************* - // This called before RK stage - // ************************************************************* - auto pre_update_fun = [&](Vector& S_data, int ng_cons) - { - cons_to_prim(S_data[IntVars::cons], ng_cons); - }; - - // ************************************************************* - // This called after every RK stage -- from MRI or SRI - // ************************************************************* - auto post_update_fun = [&](Vector& S_data, - const Real time_for_fp, int ng_cons, int ng_vel) - { - apply_bcs(S_data, time_for_fp, ng_cons, ng_vel, fast_only=false, vel_and_mom_synced=false); - }; - // ************************************************************* // The "slow" integrator for MRI and the only integrator for SRI // ************************************************************* @@ -312,15 +304,17 @@ const int nrk) { amrex::ignore_unused(nrk); - if (verbose) Print() << "Making slow rhs at time " << old_stage_time << - " for slow variables advancing from " << - old_step_time << " to " << new_stage_time << std::endl; // Note that the "old" and "new" metric terms correspond to // t^n and the RK stage (either t^*, t^** or t^{n+1} that this source // will be used to advance to Real slow_dt = new_stage_time - old_step_time; + if (verbose) amrex::Print() << "Time integration of scalars at level " << level + << " from " << old_step_time << " to " << new_stage_time + << " with dt = " << slow_dt + << " using RHS created at " << old_stage_time << std::endl; + int n_qstate = micro->Get_Qstate_Size(); #if defined(ERF_USE_NETCDF) @@ -385,6 +379,12 @@ #endif fr_as_crse, fr_as_fine); } + + // Apply boundary conditions on all the state variables that have been updated + // in both the fast and slow integrators + apply_bcs(S_new, new_stage_time, S_new[IntVars::cons].nGrow(), S_new[IntVars::xmom].nGrow(), + fast_only=false, vel_and_mom_synced=false); + }; // end slow_rhs_fun_post auto slow_rhs_fun_inc = [&](Vector& S_rhs, @@ -399,6 +399,14 @@ BL_PROFILE("slow_rhs_fun_inc"); if (verbose) Print() << "Making slow rhs at time " << old_stage_time << " for fast variables advancing from " << old_step_time << " to " << new_stage_time << std::endl; + // + // Define primitive variables for all later RK stages + // (We have already done this for the first RK step) + // + if (nrk > 0) { + int ng_cons = S_data[IntVars::cons].nGrow(); + cons_to_prim(S_data[IntVars::cons], ng_cons); + } Real slow_dt = new_stage_time - old_step_time; diff --git a/Source/TimeIntegration/ERF_TI_utils.H b/Source/TimeIntegration/ERF_TI_utils.H index 7870508a4..d6e581d48 100644 --- a/Source/TimeIntegration/ERF_TI_utils.H +++ b/Source/TimeIntegration/ERF_TI_utils.H @@ -45,10 +45,7 @@ }; /** - * This routine is called before the first step of the time integration, *and* in the case - * of a multi-stage method like RK3, this is called from "pre_update_fun" which is called - * before every subsequent stage. Since we advance the variables in conservative form, - * we must convert momentum to velocity before imposing the bcs. + * This routine is called after the scalars are updated for each RK stage */ auto apply_bcs = [&](Vector& S_data, const Real time_for_fp, int ng_cons, int ng_vel, diff --git a/Source/TimeIntegration/ERF_advance_dycore.cpp b/Source/TimeIntegration/ERF_advance_dycore.cpp index 182aea709..64313e133 100644 --- a/Source/TimeIntegration/ERF_advance_dycore.cpp +++ b/Source/TimeIntegration/ERF_advance_dycore.cpp @@ -288,8 +288,6 @@ void ERF::advance_dycore(int level, // any state data (e.g. at RK stages or at the end of a timestep) mri_integrator.set_slow_rhs_pre(slow_rhs_fun_pre); mri_integrator.set_slow_rhs_post(slow_rhs_fun_post); - mri_integrator.set_pre_update (pre_update_fun); - mri_integrator.set_post_update(post_update_fun); if (solverChoice.anelastic[level]) { mri_integrator.set_slow_rhs_inc(slow_rhs_fun_inc); From 84efdc3755f61b13bf751bf433bc3b51bdece933 Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Sun, 3 Nov 2024 08:19:42 -0800 Subject: [PATCH 16/24] fix how we fillpatch relative to regridding (#1923) --- Source/TimeIntegration/ERF_Advance.cpp | 56 +++++++++++++------------ Source/TimeIntegration/ERF_TimeStep.cpp | 20 +++++++++ 2 files changed, 49 insertions(+), 27 deletions(-) diff --git a/Source/TimeIntegration/ERF_Advance.cpp b/Source/TimeIntegration/ERF_Advance.cpp index 197edaddd..6f99b3a0b 100644 --- a/Source/TimeIntegration/ERF_Advance.cpp +++ b/Source/TimeIntegration/ERF_Advance.cpp @@ -35,6 +35,35 @@ ERF::Advance (int lev, Real time, Real dt_lev, int iteration, int /*ncycle*/) MultiFab& V_new = vars_new[lev][Vars::yvel]; MultiFab& W_new = vars_new[lev][Vars::zvel]; + // We need to set these because otherwise in the first call to erf_advance we may + // read uninitialized data on ghost values in setting the bc's on the velocities + U_new.setVal(1.e34,U_new.nGrowVect()); + V_new.setVal(1.e34,V_new.nGrowVect()); + W_new.setVal(1.e34,W_new.nGrowVect()); + + // + // NOTE: the momenta here are not fillpatched (they are only used as scratch space) + // If lev == 0 we have already FillPatched this in ERF::TimeStep + // +// if (lev == 0) { +// FillPatch(lev, time, {&S_old, &U_old, &V_old, &W_old}); +// } else { + if (lev > 0) { + FillPatch(lev, time, {&S_old, &U_old, &V_old, &W_old}, + {&S_old, &rU_old[lev], &rV_old[lev], &rW_old[lev]}, + base_state[lev], base_state[lev]); + } + + // + // So we must convert the fillpatched to momenta, including the ghost values + // + VelocityToMomentum(U_old, rU_old[lev].nGrowVect(), + V_old, rV_old[lev].nGrowVect(), + W_old, rW_old[lev].nGrowVect(), + S_old, rU_old[lev], rV_old[lev], rW_old[lev], + Geom(lev).Domain(), + domain_bcs_type); + // TODO: Can test on multiple levels later // Update the inflow perturbation update time and amplitude if (lev == 0) { @@ -86,33 +115,6 @@ ERF::Advance (int lev, Real time, Real dt_lev, int iteration, int /*ncycle*/) } } - // We need to set these because otherwise in the first call to erf_advance we may - // read uninitialized data on ghost values in setting the bc's on the velocities - U_new.setVal(1.e34,U_new.nGrowVect()); - V_new.setVal(1.e34,V_new.nGrowVect()); - W_new.setVal(1.e34,W_new.nGrowVect()); - - // - // NOTE: the momenta here are not fillpatched (they are only used as scratch space) - // - if (lev == 0) { - FillPatch(lev, time, {&S_old, &U_old, &V_old, &W_old}); - } else { - FillPatch(lev, time, {&S_old, &U_old, &V_old, &W_old}, - {&S_old, &rU_old[lev], &rV_old[lev], &rW_old[lev]}, - base_state[lev], base_state[lev]); - } - - // - // So we must convert the fillpatched to momenta, including the ghost values - // - VelocityToMomentum(U_old, rU_old[lev].nGrowVect(), - V_old, rV_old[lev].nGrowVect(), - W_old, rW_old[lev].nGrowVect(), - S_old, rU_old[lev], rV_old[lev], rW_old[lev], - Geom(lev).Domain(), - domain_bcs_type); - #if defined(ERF_USE_WINDFARM) if (solverChoice.windfarm_type != WindFarmType::None) { advance_windfarm(Geom(lev), dt_lev, S_old, diff --git a/Source/TimeIntegration/ERF_TimeStep.cpp b/Source/TimeIntegration/ERF_TimeStep.cpp index 3460582fd..e512a9a2b 100644 --- a/Source/TimeIntegration/ERF_TimeStep.cpp +++ b/Source/TimeIntegration/ERF_TimeStep.cpp @@ -15,6 +15,26 @@ using namespace amrex; void ERF::timeStep (int lev, Real time, int /*iteration*/) { + // + // We need to FillPatch the coarse level before assessing whether to regrid + // We have not done the swap yet so we fill the "new" which will become the "old" + // + MultiFab& S_new = vars_new[lev][Vars::cons]; + MultiFab& U_new = vars_new[lev][Vars::xvel]; + MultiFab& V_new = vars_new[lev][Vars::yvel]; + MultiFab& W_new = vars_new[lev][Vars::zvel]; + + // + // NOTE: the momenta here are not fillpatched (they are only used as scratch space) + // + if (lev == 0) { + FillPatch(lev, time, {&S_new, &U_new, &V_new, &W_new}); + } else if (lev < finest_level) { + FillPatch(lev, time, {&S_new, &U_new, &V_new, &W_new}, + {&S_new, &rU_new[lev], &rV_new[lev], &rW_new[lev]}, + base_state[lev], base_state[lev]); + } + if (regrid_int > 0) // We may need to regrid { // help keep track of whether a level was already regridded From 08ff588c1dd5a1bd314fa11745add468a68fa658 Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Sun, 3 Nov 2024 10:16:13 -0800 Subject: [PATCH 17/24] fix rho-weighting of anelastic buoyancy (#1924) --- Source/SourceTerms/ERF_buoyancy_utils.H | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/SourceTerms/ERF_buoyancy_utils.H b/Source/SourceTerms/ERF_buoyancy_utils.H index 061240ae5..e8db1015e 100644 --- a/Source/SourceTerms/ERF_buoyancy_utils.H +++ b/Source/SourceTerms/ERF_buoyancy_utils.H @@ -26,7 +26,7 @@ buoyancy_dry_anelastic (int& i, amrex::Real theta_d_0_wface = amrex::Real(0.5) * (theta_d_0_lo + theta_d_0_hi); - return (-grav_gpu * (theta_d_wface - theta_d_0_wface) / theta_d_0_wface); + return (-grav_gpu * (theta_d_wface - theta_d_0_wface) / theta_d_0_wface * 0.5 * (r0_arr(i,j,k) + r0_arr(i,j,k-1))); } AMREX_GPU_DEVICE @@ -87,7 +87,7 @@ buoyancy_moist_anelastic (int& i, amrex::Real theta_v_0_wface = amrex::Real(0.5) * (theta_v_0_lo + theta_v_0_hi); - return (-grav_gpu * (theta_v_wface - theta_v_0_wface) / theta_v_0_wface); + return (-grav_gpu * (theta_v_wface - theta_v_0_wface) / theta_v_0_wface * 0.5 * (r0_arr(i,j,k) + r0_arr(i,j,k-1))); } AMREX_GPU_DEVICE From 623c80abb516a18bf17218b4a9fafc0d419f55bf Mon Sep 17 00:00:00 2001 From: "Aaron M. Lattanzi" <103702284+AMLattanzi@users.noreply.github.com> Date: Mon, 4 Nov 2024 10:08:11 -0800 Subject: [PATCH 18/24] Updates for release. (#1925) --- CHANGES | 15 + Source/ERF_read_waves.cpp | 275 +++++++++--------- Source/Utils/ERF_InteriorGhostCells.cpp | 22 +- Source/Utils/ERF_Interpolation.H | 12 +- Source/Utils/ERF_Utils.H | 70 ++--- .../ERF_InitWindFarm.cpp | 34 +-- Source/WindFarmParametrization/ERF_WindFarm.H | 54 ++-- Source/WindFarmParametrization/EWP/ERF_EWP.H | 4 +- .../Fitch/ERF_AdvanceFitch.cpp | 14 +- .../WindFarmParametrization/Fitch/ERF_Fitch.H | 4 +- .../ERF_AdvanceGeneralAD.cpp | 48 +-- .../GeneralActuatorDisk/ERF_GeneralAD.H | 4 +- .../Null/ERF_NullWindFarm.H | 84 +++--- .../ERF_AdvanceSimpleAD.cpp | 28 +- .../SimpleActuatorDisk/ERF_SimpleAD.H | 14 +- Submodules/AMReX | 2 +- 16 files changed, 348 insertions(+), 336 deletions(-) diff --git a/CHANGES b/CHANGES index e8a03bfe6..511f819e6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,18 @@ +# 24.11 + -- AMReX submodule set to 24.11 release hash (4a6e7c8) + + -- AMR functionality (#1916-1920) + + -- GAD functionality (#1912, #1875) + + -- Remove QKE (#1905) + + -- NOAH-MP interface (#1835) + + -- Line and plane sampling (#1897) + + -- AMReX & KOKKOS docs (#1889) + # 24.10 -- Add WENO7 advection operators (#1858) diff --git a/Source/ERF_read_waves.cpp b/Source/ERF_read_waves.cpp index cbc8b83ba..d15eb2b4b 100644 --- a/Source/ERF_read_waves.cpp +++ b/Source/ERF_read_waves.cpp @@ -22,71 +22,68 @@ ERF::read_waves (int lev) for ( MFIter mfi(*Hwave_onegrid[lev],false); mfi.isValid(); ++mfi) { + const auto & bx = mfi.validbox(); + + amrex::Print() << " Just called ERF::read_waves to receive from WW3 " << bx << std::endl; + amrex::Array4 my_H_arr = Hwave_onegrid[lev]->array(mfi); + amrex::Array4 my_L_arr = Lwave_onegrid[lev]->array(mfi); + + Real* my_H_ptr = my_H_arr.dataPtr(); + Real* my_L_ptr = my_L_arr.dataPtr(); + + int rank_offset = amrex::MPMD::MyProc() - amrex::ParallelDescriptor::MyProc(); + int this_root, other_root; + if (rank_offset == 0) { // First program + this_root = 0; + other_root = amrex::ParallelDescriptor::NProcs(); + } else { + this_root = rank_offset; + other_root = 0; + } + + int nx=2147483647; + int ny=2147483647; // sanity check + + //JUST RECEIVED + if (amrex::MPMD::MyProc() == this_root) { + if (rank_offset == 0) // First program + { + MPI_Recv(&nx, 1, MPI_INT, other_root, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&ny, 1, MPI_INT, other_root, 7, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + else // Second program + { + MPI_Recv(&nx, 1, MPI_INT, other_root, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(&ny, 1, MPI_INT, other_root, 6, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + //This may not be necessary + ParallelDescriptor::Bcast(&nx, 1); + ParallelDescriptor::Bcast(&ny, 1); + } + + if((nx)*(ny) > 0) { + int nsealm = (nx)*ny; + + if (amrex::MPMD::MyProc() == this_root) { + if (rank_offset == 0) // the first program + { + MPI_Recv(my_H_ptr, nsealm, MPI_DOUBLE, other_root, 3, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(my_L_ptr, nsealm, MPI_DOUBLE, other_root, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + else // the second program + { + MPI_Recv(my_H_ptr, nsealm, MPI_DOUBLE, other_root, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + MPI_Recv(my_L_ptr, nsealm, MPI_DOUBLE, other_root, 4, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } + } - const auto & bx = mfi.validbox(); - - amrex::Print() << " Just called ERF::read_waves to receive from WW3 " << bx << std::endl; - amrex::Array4 my_H_arr = Hwave_onegrid[lev]->array(mfi); - amrex::Array4 my_L_arr = Lwave_onegrid[lev]->array(mfi); - - Real* my_H_ptr = my_H_arr.dataPtr(); - Real* my_L_ptr = my_L_arr.dataPtr(); - - int rank_offset = amrex::MPMD::MyProc() - amrex::ParallelDescriptor::MyProc(); - int this_root, other_root; - if (rank_offset == 0) { // First program - this_root = 0; - other_root = amrex::ParallelDescriptor::NProcs(); - } else { - this_root = rank_offset; - other_root = 0; - } - - - int nx=2147483647; - int ny=2147483647; // sanity check - - //JUST RECEIVED - if (amrex::MPMD::MyProc() == this_root) { - if (rank_offset == 0) // First program - { - MPI_Recv(&nx, 1, MPI_INT, other_root, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - MPI_Recv(&ny, 1, MPI_INT, other_root, 7, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } - else // Second program - { - MPI_Recv(&nx, 1, MPI_INT, other_root, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - MPI_Recv(&ny, 1, MPI_INT, other_root, 6, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } - //This may not be necessary - ParallelDescriptor::Bcast(&nx, 1); - ParallelDescriptor::Bcast(&ny, 1); - } - - if((nx)*(ny) > 0) { - int nsealm = (nx)*ny; - - if (amrex::MPMD::MyProc() == this_root) { - if (rank_offset == 0) // the first program - { - MPI_Recv(my_H_ptr, nsealm, MPI_DOUBLE, other_root, 3, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - MPI_Recv(my_L_ptr, nsealm, MPI_DOUBLE, other_root, 5, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } - else // the second program - { - MPI_Recv(my_H_ptr, nsealm, MPI_DOUBLE, other_root, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - MPI_Recv(my_L_ptr, nsealm, MPI_DOUBLE, other_root, 4, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } - } - - amrex::AllPrintToFile("output_HS_cpp.txt")<ParallelCopy(*Hwave_onegrid[lev]); @@ -99,21 +96,24 @@ ERF::read_waves (int lev) Box bx = mfi.tilebox(); const Array4& Hwave_arr = Hwave[lev]->const_array(mfi); const Array4& Lmask_arr = lmask_lev[lev][0]->array(mfi); - ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k){ + ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { if (Hwave_arr(i,j,k)<0) { Lmask_arr(i,j,k) = 1; - } else { + } else { Lmask_arr(i,j,k) = 0; } }); } - // amrex::Real myclock = ParallelDescriptor::second(); - // amrex::AllPrintToFile("timer.txt") << "At " << myclock << " seconds, I reached the end of read_waves" << std::endl; + // amrex::Real myclock = ParallelDescriptor::second(); + // amrex::AllPrintToFile("timer.txt") << "At " << myclock << " seconds, I reached the end of read_waves" << std::endl; timedif = ( ((double) clock()) / CLOCKS_PER_SEC) - clkStart; - amrex::AllPrintToFile("timer.txt") << "It took " << timedif << " seconds to reach the end of read_waves" << std::endl; + amrex::AllPrintToFile("timer.txt") << "It took " << timedif + << " seconds to reach the end of read_waves" + << std::endl; } void @@ -168,12 +168,8 @@ ERF::send_to_ww3 (int lev) // Initialize Multifabs to store x_avg, y_avg, u_mag, u_dir at cell centers MultiFab x_avg(lev_new[Vars::cons].boxArray(), lev_new[Vars::cons].DistributionMap(), 1, lev_new[Vars::cons].nGrowVect()); - MultiFab y_avg(lev_new[Vars::cons].boxArray(), lev_new[Vars::cons].DistributionMap(), 1, lev_new[Vars::cons].nGrowVect()); - MultiFab u_mag(lev_new[Vars::cons].boxArray(), lev_new[Vars::cons].DistributionMap(), 1, lev_new[Vars::cons].nGrowVect()); - - MultiFab u_dir(lev_new[Vars::cons].boxArray(), lev_new[Vars::cons].DistributionMap(), 1, lev_new[Vars::cons].nGrowVect()); @@ -191,7 +187,10 @@ ERF::send_to_ww3 (int lev) ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k){ u_vel(i,j,k) = 0.5 *( velx_arr(i,j,k) + velx_arr(i+1,j,k) ); - amrex::AllPrintToFile("uvel.txt") << amrex::IntVect(i,j,k) << " [" <> theta_onegrid; - // create a new BoxArray and DistributionMapping for a MultiFab with 1 box - BoxArray ba_onegrid(geom[lev].Domain()); - BoxList bl2d_onegrid = ba_onegrid.boxList(); - for (auto& b : bl2d_onegrid) { - b.setRange(2,0); - } - BoxArray ba2d_onegrid(std::move(bl2d_onegrid)); - Vector pmap; - pmap.resize(1); - pmap[0]=0; - DistributionMapping dm_onegrid(ba2d_onegrid); - dm_onegrid.define(pmap); - - ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k){ + // create a new BoxArray and DistributionMapping for a MultiFab with 1 box + BoxArray ba_onegrid(geom[lev].Domain()); + BoxList bl2d_onegrid = ba_onegrid.boxList(); + for (auto& b : bl2d_onegrid) { + b.setRange(2,0); + } + BoxArray ba2d_onegrid(std::move(bl2d_onegrid)); + Vector pmap; + pmap.resize(1); + pmap[0]=0; + DistributionMapping dm_onegrid(ba2d_onegrid); + dm_onegrid.define(pmap); - // magnitude(i,j,k) = std::sqrt( pow(u(i,j,k), 2) + pow(v(i,j,k), 2) ); + ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) + { + //magnitude(i,j,k) = std::sqrt( pow(u(i,j,k), 2) + pow(v(i,j,k), 2) ); double u_val = u(i, j, k); double v_val = v(i, j, k); @@ -257,47 +259,49 @@ ERF::send_to_ww3 (int lev) theta(i,j,k) = atan ( v_val / u_val ); } - - amrex::AllPrintToFile("mag_theta.txt") << amrex::IntVect(i,j,k) << " Magnitude: " << magnitude(i,j,k) << " Theta: " << theta(i,j,k) < magnitude_values(n_elements); - std::vector theta_values(n_elements); - std::vector indices(n_elements); - // Copy values - int counter = 0; - for (BoxIterator bi(slice_box_ref); bi.ok(); ++bi) { - IntVect iv = bi(); - magnitude_values[counter] = magnitude(iv); - theta_values[counter] = theta(iv); - indices[counter] = iv; - ++counter; - } -// timedif2 = ( ((double) clock()) / CLOCKS_PER_SEC) - clkStart2; -// amrex::AllPrintToFile("timer.txt") << "It took " << (double) timedif2 << " seconds to reach the part before sending" << std::endl; -//amrex::Print() << "It took " << (double) timedif2 << " seconds to reach the part before sending" << std::endl; - -// Print magnitude values and corresponding IntVect indices -for (int j = 0; j < n_elements; ++j) { - amrex::AllPrintToFile("debug_send.txt") - << "dz, k_ref " << dz << ", " << k_ref << " " - << "Index: " << j - << ", IntVect: (" << indices[j][0] << ", " << indices[j][1] << ", " << indices[j][2] << ")" - << ", Magnitude: " << magnitude_values[j] - << ", Theta: " << theta_values[j] - << std::endl; -} + // Calculate the number of elements in the current box + int n_elements = slice_box_ref.numPts(); + + // Initialize vectors to send to WW3 + std::vector magnitude_values(n_elements); + std::vector theta_values(n_elements); + std::vector indices(n_elements); + // Copy values + int counter = 0; + for (BoxIterator bi(slice_box_ref); bi.ok(); ++bi) { + IntVect iv = bi(); + magnitude_values[counter] = magnitude(iv); + theta_values[counter] = theta(iv); + indices[counter] = iv; + ++counter; + } + + // timedif2 = ( ((double) clock()) / CLOCKS_PER_SEC) - clkStart2; + // amrex::AllPrintToFile("timer.txt") << "It took " << (double) timedif2 << " seconds to reach the part before sending" << std::endl; + //amrex::Print() << "It took " << (double) timedif2 << " seconds to reach the part before sending" << std::endl; + + // Print magnitude values and corresponding IntVect indices + for (int j = 0; j < n_elements; ++j) { + amrex::AllPrintToFile("debug_send.txt") + << "dz, k_ref " << dz << ", " << k_ref << " " + << "Index: " << j + << ", IntVect: (" << indices[j][0] << ", " << indices[j][1] << ", " << indices[j][2] << ")" + << ", Magnitude: " << magnitude_values[j] + << ", Theta: " << theta_values[j] + << std::endl; + } int rank_offset = amrex::MPMD::MyProc() - amrex::ParallelDescriptor::MyProc(); int this_root, other_root; @@ -309,35 +313,32 @@ for (int j = 0; j < n_elements; ++j) { other_root = 0; } - amrex::Print()<< "Sending " << n_elements << " from ERF::send_to_ww3 now" << std::endl; if (amrex::MPMD::MyProc() == this_root) { - if (rank_offset == 0) // First program - { - MPI_Send(&n_elements, 1, MPI_INT, other_root, 11, MPI_COMM_WORLD); -MPI_Send(magnitude_values.data(), n_elements, MPI_DOUBLE, other_root, 13, MPI_COMM_WORLD); -MPI_Send(theta_values.data(), n_elements, MPI_DOUBLE, other_root, 15, MPI_COMM_WORLD); + if (rank_offset == 0) { // First program + MPI_Send(&n_elements, 1, MPI_INT, other_root, 11, MPI_COMM_WORLD); + MPI_Send(magnitude_values.data(), n_elements, MPI_DOUBLE, other_root, 13, MPI_COMM_WORLD); + MPI_Send(theta_values.data(), n_elements, MPI_DOUBLE, other_root, 15, MPI_COMM_WORLD); } else // Second program { MPI_Send(&n_elements, 1, MPI_INT, other_root, 10, MPI_COMM_WORLD); -MPI_Send(magnitude_values.data(), n_elements, MPI_DOUBLE, other_root, 12, MPI_COMM_WORLD); -MPI_Send(theta_values.data(), n_elements, MPI_DOUBLE, other_root, 14, MPI_COMM_WORLD); + MPI_Send(magnitude_values.data(), n_elements, MPI_DOUBLE, other_root, 12, MPI_COMM_WORLD); + MPI_Send(theta_values.data(), n_elements, MPI_DOUBLE, other_root, 14, MPI_COMM_WORLD); //MPI_Recv(&nx, 1, MPI_INT, other_root, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); //MPI_Recv(&ny, 1, MPI_INT, other_root, 6, MPI_COMM_WORLD, MPI_STATUS_IGNORE); } } - timedif = ( ((double) clock()) / CLOCKS_PER_SEC) - clkStart; - -// amrex::Real myclock = ParallelDescriptor::second(); -// amrex::AllPrintToFile("timer.txt") << "At " << myclock << " seconds I reached the end of send_to_ww3" << std::endl; + timedif = ( ((double) clock()) / CLOCKS_PER_SEC) - clkStart; - amrex::AllPrintToFile("timer.txt") << "It took " << timedif << " seconds to reach the end of send_to_WW3" << std::endl; - - -} + // amrex::Real myclock = ParallelDescriptor::second(); + // amrex::AllPrintToFile("timer.txt") << "At " << myclock << " seconds I reached the end of send_to_ww3" << std::endl; + amrex::AllPrintToFile("timer.txt") << "It took " << timedif + << " seconds to reach the end of send_to_WW3" + << std::endl; + } // mfi } #endif diff --git a/Source/Utils/ERF_InteriorGhostCells.cpp b/Source/Utils/ERF_InteriorGhostCells.cpp index 76a57beea..19c07d684 100644 --- a/Source/Utils/ERF_InteriorGhostCells.cpp +++ b/Source/Utils/ERF_InteriorGhostCells.cpp @@ -119,7 +119,7 @@ realbdy_compute_interior_ghost_rhs (const Real& bdy_time_interval, Vector>& bdy_data_ylo, Vector>& bdy_data_yhi) { - BL_PROFILE_REGION("wrfbdy_compute_interior_ghost_RHS()"); + BL_PROFILE_REGION("realbdy_compute_interior_ghost_RHS()"); // NOTE: We pass the full width into this routine. // For relaxation, the last cell is a halo @@ -395,11 +395,11 @@ realbdy_compute_interior_ghost_rhs (const Real& bdy_time_interval, continue; } - wrfbdy_set_rhs_in_spec_region(delta_t, icomp, 1, - width, set_width, dom_lo, dom_hi, - tbx_xlo, tbx_xhi, tbx_ylo, tbx_yhi, - arr_xlo, arr_xhi, arr_ylo, arr_yhi, - data_arr, rhs_arr); + realbdy_set_rhs_in_spec_region(delta_t, icomp, 1, + width, set_width, dom_lo, dom_hi, + tbx_xlo, tbx_xhi, tbx_ylo, tbx_yhi, + arr_xlo, arr_xhi, arr_ylo, arr_yhi, + data_arr, rhs_arr); } // mfi } // ivar } // set_width @@ -455,11 +455,11 @@ realbdy_compute_interior_ghost_rhs (const Real& bdy_time_interval, continue; } - wrfbdy_compute_laplacian_relaxation(icomp, 1, - width2, set_width, dom_lo, dom_hi, F1, F2, - tbx_xlo, tbx_xhi, tbx_ylo, tbx_yhi, - arr_xlo, arr_xhi, arr_ylo, arr_yhi, - data_arr, rhs_arr); + realbdy_compute_laplacian_relaxation(icomp, 1, + width2, set_width, dom_lo, dom_hi, F1, F2, + tbx_xlo, tbx_xhi, tbx_ylo, tbx_yhi, + arr_xlo, arr_xhi, arr_ylo, arr_yhi, + data_arr, rhs_arr); /* // UNIT TEST DEBUG diff --git a/Source/Utils/ERF_Interpolation.H b/Source/Utils/ERF_Interpolation.H index a1a8f05fb..f2e196e76 100644 --- a/Source/Utils/ERF_Interpolation.H +++ b/Source/Utils/ERF_Interpolation.H @@ -49,8 +49,7 @@ InterpolateInX (int i, int j, int k, const amrex::Array4& qty amrex::Real scaled_upw = 0.; // // The value that comes in has not been normalized so we do that here - if (upw != 0.) - scaled_upw = (upw > 0) ? 1. : -1.; + if (upw != 0.) { scaled_upw = (upw > 0) ? 1. : -1.; } avg1 = (qty(i, j, k, qty_index) + qty(i-1, j, k, qty_index)); diff1 = (qty(i, j, k, qty_index) - qty(i-1, j, k, qty_index)); @@ -80,8 +79,7 @@ InterpolateInY (int i, int j, int k, const amrex::Array4& qty amrex::Real scaled_upw = 0.; // The value that comes in has not been normalized so we do that here - if (upw != 0.) - scaled_upw = (upw > 0) ? 1. : -1.; + if (upw != 0.) { scaled_upw = (upw > 0) ? 1. : -1.; } avg1 = (qty(i, j , k, qty_index) + qty(i, j-1, k, qty_index)); diff1 = (qty(i, j , k, qty_index) - qty(i, j-1, k, qty_index)); @@ -110,8 +108,7 @@ InterpolateInZ (int i, int j, int k, const amrex::Array4& qty amrex::Real diff1 = 0.; amrex::Real diff2 = 0.; amrex::Real diff3 = 0.; amrex::Real scaled_upw = 0.; // The value that comes in has not been normalized so we do that here - if (upw != 0.) - scaled_upw = (upw > 0) ? 1. : -1.; + if (upw != 0.) { scaled_upw = (upw > 0) ? 1. : -1.; } avg1 = (qty(i, j, k , qty_index) + qty(i, j, k-1, qty_index)); diff1 = (qty(i, j, k , qty_index) - qty(i, j, k-1, qty_index)); @@ -139,8 +136,7 @@ InterpolatePertFromCell (int i, int j, int k, amrex::Real scaled_upw = 0.; // The value that comes in has not been normalized so we do that here - if (upw != 0.) - scaled_upw = upw / std::abs(upw); + if (upw != 0.) { scaled_upw = (upw > 0) ? 1. : -1.; } if (coordDir == Coord::x) { avg1 = (qty(i , j, k, qty_index) + qty(i-1, j, k, qty_index)); diff --git a/Source/Utils/ERF_Utils.H b/Source/Utils/ERF_Utils.H index f713347f2..cfe2922d2 100644 --- a/Source/Utils/ERF_Utils.H +++ b/Source/Utils/ERF_Utils.H @@ -145,23 +145,23 @@ Time_Avg_Vel_atCC (const amrex::Real& dt, AMREX_GPU_HOST AMREX_FORCE_INLINE void -wrfbdy_set_rhs_in_spec_region (const amrex::Real& dt, - const int& icomp, - const int& num_var, - const int& width, - const int& set_width, - const amrex::Dim3& dom_lo, - const amrex::Dim3& dom_hi, - const amrex::Box& bx_xlo, - const amrex::Box& bx_xhi, - const amrex::Box& bx_ylo, - const amrex::Box& bx_yhi, - const amrex::Array4& arr_xlo, - const amrex::Array4& arr_xhi, - const amrex::Array4& arr_ylo, - const amrex::Array4& arr_yhi, - const amrex::Array4& data_arr, - const amrex::Array4& rhs_arr) +realbdy_set_rhs_in_spec_region (const amrex::Real& dt, + const int& icomp, + const int& num_var, + const int& width, + const int& set_width, + const amrex::Dim3& dom_lo, + const amrex::Dim3& dom_hi, + const amrex::Box& bx_xlo, + const amrex::Box& bx_xhi, + const amrex::Box& bx_ylo, + const amrex::Box& bx_yhi, + const amrex::Array4& arr_xlo, + const amrex::Array4& arr_xhi, + const amrex::Array4& arr_ylo, + const amrex::Array4& arr_yhi, + const amrex::Array4& data_arr, + const amrex::Array4& rhs_arr) { int Spec_z = set_width; amrex::ParallelFor(bx_xlo, num_var, [=] AMREX_GPU_DEVICE (int i, int j, int k, int n) noexcept @@ -235,24 +235,24 @@ wrfbdy_set_rhs_in_spec_region (const amrex::Real& dt, AMREX_GPU_HOST AMREX_FORCE_INLINE void -wrfbdy_compute_laplacian_relaxation (const int& icomp, - const int& num_var, - const int& width, - const int& set_width, - const amrex::Dim3& dom_lo, - const amrex::Dim3& dom_hi, - const amrex::Real& F1, - const amrex::Real& F2, - const amrex::Box& bx_xlo, - const amrex::Box& bx_xhi, - const amrex::Box& bx_ylo, - const amrex::Box& bx_yhi, - const amrex::Array4& arr_xlo, - const amrex::Array4& arr_xhi, - const amrex::Array4& arr_ylo, - const amrex::Array4& arr_yhi, - const amrex::Array4& data_arr, - const amrex::Array4& rhs_arr) +realbdy_compute_laplacian_relaxation (const int& icomp, + const int& num_var, + const int& width, + const int& set_width, + const amrex::Dim3& dom_lo, + const amrex::Dim3& dom_hi, + const amrex::Real& F1, + const amrex::Real& F2, + const amrex::Box& bx_xlo, + const amrex::Box& bx_xhi, + const amrex::Box& bx_ylo, + const amrex::Box& bx_yhi, + const amrex::Array4& arr_xlo, + const amrex::Array4& arr_xhi, + const amrex::Array4& arr_ylo, + const amrex::Array4& arr_yhi, + const amrex::Array4& data_arr, + const amrex::Array4& rhs_arr) { // RHS computation int Spec_z = set_width; diff --git a/Source/WindFarmParametrization/ERF_InitWindFarm.cpp b/Source/WindFarmParametrization/ERF_InitWindFarm.cpp index 6f48a711b..933e1ada8 100644 --- a/Source/WindFarmParametrization/ERF_InitWindFarm.cpp +++ b/Source/WindFarmParametrization/ERF_InitWindFarm.cpp @@ -31,10 +31,10 @@ WindFarm::read_tables (std::string windfarm_loc_table, } void -WindFarm::read_windfarm_locations_table(const std::string windfarm_loc_table, - bool x_y, bool lat_lon, - const Real windfarm_x_shift, - const Real windfarm_y_shift) +WindFarm::read_windfarm_locations_table (const std::string windfarm_loc_table, + bool x_y, bool lat_lon, + const Real windfarm_x_shift, + const Real windfarm_y_shift) { if(x_y) { init_windfarm_x_y(windfarm_loc_table); @@ -150,7 +150,7 @@ WindFarm::init_windfarm_x_y (const std::string windfarm_loc_table) void -WindFarm::read_windfarm_spec_table(const std::string windfarm_spec_table) +WindFarm::read_windfarm_spec_table (const std::string windfarm_spec_table) { //The first line is the number of pairs entries for the power curve and thrust coefficient. //The second line gives first the height in meters of the turbine hub, second, the diameter in @@ -198,7 +198,7 @@ WindFarm::read_windfarm_spec_table(const std::string windfarm_spec_table) } void -WindFarm::read_windfarm_blade_table(const std::string windfarm_blade_table) +WindFarm::read_windfarm_blade_table (const std::string windfarm_blade_table) { std::ifstream filename(windfarm_blade_table); std::string line; @@ -231,7 +231,7 @@ WindFarm::read_windfarm_blade_table(const std::string windfarm_blade_table) } void -WindFarm::read_windfarm_spec_table_extra(const std::string windfarm_spec_table_extra) +WindFarm::read_windfarm_spec_table_extra (const std::string windfarm_spec_table_extra) { // Open the file std::ifstream file(windfarm_spec_table_extra); @@ -270,8 +270,8 @@ WindFarm::read_windfarm_spec_table_extra(const std::string windfarm_spec_table_e void -WindFarm::read_windfarm_airfoil_tables(const std::string windfarm_airfoil_tables, - const std::string windfarm_blade_table) +WindFarm::read_windfarm_airfoil_tables (const std::string windfarm_airfoil_tables, + const std::string windfarm_blade_table) { DIR* dir; struct dirent* entry; @@ -350,8 +350,8 @@ WindFarm::read_windfarm_airfoil_tables(const std::string windfarm_airfoil_tables } void -WindFarm::fill_Nturb_multifab(const Geometry& geom, - MultiFab& mf_Nturb) +WindFarm::fill_Nturb_multifab (const Geometry& geom, + MultiFab& mf_Nturb) { amrex::Gpu::DeviceVector d_xloc(xloc.size()); @@ -398,10 +398,10 @@ WindFarm::fill_Nturb_multifab(const Geometry& geom, } void -WindFarm::fill_SMark_multifab(const Geometry& geom, - MultiFab& mf_SMark, - const Real& sampling_distance_by_D, - const Real& turb_disk_angle) +WindFarm::fill_SMark_multifab (const Geometry& geom, + MultiFab& mf_SMark, + const Real& sampling_distance_by_D, + const Real& turb_disk_angle) { amrex::Gpu::DeviceVector d_xloc(xloc.size()); amrex::Gpu::DeviceVector d_yloc(yloc.size()); @@ -482,7 +482,7 @@ WindFarm::fill_SMark_multifab(const Geometry& geom, } void -WindFarm::write_turbine_locations_vtk() +WindFarm::write_turbine_locations_vtk () { if (ParallelDescriptor::IOProcessor()){ FILE* file_turbloc_vtk; @@ -501,7 +501,7 @@ WindFarm::write_turbine_locations_vtk() void -WindFarm::write_actuator_disks_vtk(const Geometry& geom) +WindFarm::write_actuator_disks_vtk (const Geometry& geom) { if (ParallelDescriptor::IOProcessor()){ diff --git a/Source/WindFarmParametrization/ERF_WindFarm.H b/Source/WindFarmParametrization/ERF_WindFarm.H index 945483bbe..a94778fdf 100644 --- a/Source/WindFarmParametrization/ERF_WindFarm.H +++ b/Source/WindFarmParametrization/ERF_WindFarm.H @@ -15,9 +15,9 @@ class WindFarm : public NullWindFarm { public: - WindFarm(){} + WindFarm (){} - virtual ~WindFarm() = default; + virtual ~WindFarm () = default; WindFarm (int nlev, const WindFarmType& a_windfarm_type) @@ -50,37 +50,37 @@ public: const amrex::Real windfarm_x_shift = 0.0, const amrex::Real windfarm_y_shift = 0.0); - void init_windfarm_lat_lon(const std::string windfarm_loc_table, - const amrex::Real windfarm_x_shift, - const amrex::Real windfarm_y_shift); + void init_windfarm_lat_lon (const std::string windfarm_loc_table, + const amrex::Real windfarm_x_shift, + const amrex::Real windfarm_y_shift); - void init_windfarm_x_y(const std::string windfarm_loc_table); + void init_windfarm_x_y (const std::string windfarm_loc_table); - void read_windfarm_locations_table(const std::string windfarm_loc_table, - bool x_y, bool lat_lon, - const amrex::Real windfarm_x_shift = 0.0, - const amrex::Real windfarm_y_shift = 0.0); + void read_windfarm_locations_table (const std::string windfarm_loc_table, + bool x_y, bool lat_lon, + const amrex::Real windfarm_x_shift = 0.0, + const amrex::Real windfarm_y_shift = 0.0); - void read_windfarm_spec_table(const std::string windfarm_spec_table); + void read_windfarm_spec_table (const std::string windfarm_spec_table); - void read_windfarm_blade_table(const std::string windfarm_blade_table); + void read_windfarm_blade_table (const std::string windfarm_blade_table); - void read_windfarm_airfoil_tables(const std::string windfarm_airfoil_tables, - const std::string windfarm_blade_table); + void read_windfarm_airfoil_tables (const std::string windfarm_airfoil_tables, + const std::string windfarm_blade_table); - void read_windfarm_spec_table_extra(const std::string windfarm_spec_table_extra); + void read_windfarm_spec_table_extra (const std::string windfarm_spec_table_extra); - void fill_Nturb_multifab(const amrex::Geometry& geom, - amrex::MultiFab& mf_Nturb); + void fill_Nturb_multifab (const amrex::Geometry& geom, + amrex::MultiFab& mf_Nturb); - void fill_SMark_multifab(const amrex::Geometry& geom, - amrex::MultiFab& mf_SMark, - const amrex::Real& sampling_distance_by_D, - const amrex::Real& turb_disk_angle); + void fill_SMark_multifab (const amrex::Geometry& geom, + amrex::MultiFab& mf_SMark, + const amrex::Real& sampling_distance_by_D, + const amrex::Real& turb_disk_angle); - void write_turbine_locations_vtk(); + void write_turbine_locations_vtk (); - void write_actuator_disks_vtk(const amrex::Geometry& geom); + void write_actuator_disks_vtk (const amrex::Geometry& geom); void advance (const amrex::Geometry& a_geom, const amrex::Real& dt_advance, @@ -97,10 +97,10 @@ public: U_old, V_old, W_old, mf_Nturb, mf_SMark, time); } - void set_turb_spec(const amrex::Real& a_rotor_rad, const amrex::Real& a_hub_height, - const amrex::Real& a_thrust_coeff_standing, const amrex::Vector& a_wind_speed, - const amrex::Vector& a_thrust_coeff, - const amrex::Vector& a_power) override + void set_turb_spec (const amrex::Real& a_rotor_rad, const amrex::Real& a_hub_height, + const amrex::Real& a_thrust_coeff_standing, const amrex::Vector& a_wind_speed, + const amrex::Vector& a_thrust_coeff, + const amrex::Vector& a_power) override { m_windfarm_model[0]->set_turb_spec(a_rotor_rad, a_hub_height, a_thrust_coeff_standing, a_wind_speed, a_thrust_coeff, a_power); diff --git a/Source/WindFarmParametrization/EWP/ERF_EWP.H b/Source/WindFarmParametrization/EWP/ERF_EWP.H index fbf10efca..119590a27 100644 --- a/Source/WindFarmParametrization/EWP/ERF_EWP.H +++ b/Source/WindFarmParametrization/EWP/ERF_EWP.H @@ -10,9 +10,9 @@ class EWP : public NullWindFarm { public: - EWP(){} + EWP (){} - virtual ~EWP() = default; + virtual ~EWP () = default; void advance (const amrex::Geometry& geom, const amrex::Real& dt_advance, diff --git a/Source/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp b/Source/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp index 68cce5558..6f1036339 100644 --- a/Source/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp +++ b/Source/WindFarmParametrization/Fitch/ERF_AdvanceFitch.cpp @@ -7,9 +7,9 @@ using namespace amrex; AMREX_FORCE_INLINE AMREX_GPU_DEVICE -Real compute_A(const Real z, - const Real hub_height, - const Real rotor_rad) +Real compute_A (const Real z, + const Real hub_height, + const Real rotor_rad) { Real d = std::min(std::fabs(z - hub_height), rotor_rad); @@ -22,10 +22,10 @@ Real compute_A(const Real z, AMREX_FORCE_INLINE AMREX_GPU_DEVICE -Real compute_Aijk(const Real z_k, - const Real z_kp1, - const Real hub_height, - const Real rotor_rad) +Real compute_Aijk (const Real z_k, + const Real z_kp1, + const Real hub_height, + const Real rotor_rad) { Real A_k = compute_A(z_k, hub_height, rotor_rad); diff --git a/Source/WindFarmParametrization/Fitch/ERF_Fitch.H b/Source/WindFarmParametrization/Fitch/ERF_Fitch.H index 906a55835..baa557e22 100644 --- a/Source/WindFarmParametrization/Fitch/ERF_Fitch.H +++ b/Source/WindFarmParametrization/Fitch/ERF_Fitch.H @@ -10,9 +10,9 @@ class Fitch : public NullWindFarm { public: - Fitch() {} + Fitch () {} - virtual ~Fitch() = default; + virtual ~Fitch () = default; void advance (const amrex::Geometry& geom, const amrex::Real& dt_advance, diff --git a/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp b/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp index 3c4da9eb1..2f5873f63 100644 --- a/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp +++ b/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_AdvanceGeneralAD.cpp @@ -7,15 +7,15 @@ using namespace amrex; void GeneralAD::advance (const Geometry& geom, - const Real& dt_advance, - MultiFab& cons_in, - MultiFab& mf_vars_generalAD, - MultiFab& U_old, - MultiFab& V_old, - MultiFab& W_old, - const MultiFab& mf_Nturb, - const MultiFab& mf_SMark, - const Real& time) + const Real& dt_advance, + MultiFab& cons_in, + MultiFab& mf_vars_generalAD, + MultiFab& U_old, + MultiFab& V_old, + MultiFab& W_old, + const MultiFab& mf_Nturb, + const MultiFab& mf_SMark, + const Real& time) { AMREX_ALWAYS_ASSERT(W_old.nComp() > 0); AMREX_ALWAYS_ASSERT(mf_Nturb.nComp() > 0); @@ -28,11 +28,11 @@ GeneralAD::advance (const Geometry& geom, void GeneralAD::update (const Real& dt_advance, - MultiFab& cons_in, - MultiFab& U_old, - MultiFab& V_old, - MultiFab& W_old, - const MultiFab& mf_vars_generalAD) + MultiFab& cons_in, + MultiFab& U_old, + MultiFab& V_old, + MultiFab& W_old, + const MultiFab& mf_vars_generalAD) { for ( MFIter mfi(cons_in,TilingIfNotGPU()); mfi.isValid(); ++mfi) { @@ -63,10 +63,10 @@ GeneralAD::update (const Real& dt_advance, } } -void GeneralAD::compute_freestream_velocity(const MultiFab& cons_in, - const MultiFab& U_old, - const MultiFab& V_old, - const MultiFab& mf_SMark) +void GeneralAD::compute_freestream_velocity (const MultiFab& cons_in, + const MultiFab& U_old, + const MultiFab& V_old, + const MultiFab& mf_SMark) { get_turb_loc(xloc, yloc); freestream_velocity.clear(); @@ -141,9 +141,9 @@ void GeneralAD::compute_freestream_velocity(const MultiFab& cons_in, AMREX_FORCE_INLINE AMREX_GPU_DEVICE -int find_rad_loc_index(const Real rad, - const Real* bld_rad_loc, - const int n_bld_sections) +int find_rad_loc_index (const Real rad, + const Real* bld_rad_loc, + const int n_bld_sections) { // Find the index of the radial location int index=-1; @@ -285,9 +285,9 @@ compute_source_terms_Fn_Ft (const Real rad, void GeneralAD::source_terms_cellcentered (const Geometry& geom, - const MultiFab& cons_in, - const MultiFab& mf_SMark, - MultiFab& mf_vars_generalAD) + const MultiFab& cons_in, + const MultiFab& mf_SMark, + MultiFab& mf_vars_generalAD) { get_turb_loc(xloc, yloc); diff --git a/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_GeneralAD.H b/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_GeneralAD.H index 9092ea312..e4f8d75ed 100644 --- a/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_GeneralAD.H +++ b/Source/WindFarmParametrization/GeneralActuatorDisk/ERF_GeneralAD.H @@ -9,9 +9,9 @@ class GeneralAD : public NullWindFarm { public: - GeneralAD() {} + GeneralAD () {} - virtual ~GeneralAD() = default; + virtual ~GeneralAD () = default; void advance (const amrex::Geometry& geom, const amrex::Real& dt_advance, diff --git a/Source/WindFarmParametrization/Null/ERF_NullWindFarm.H b/Source/WindFarmParametrization/Null/ERF_NullWindFarm.H index f0714eef3..6134e976c 100644 --- a/Source/WindFarmParametrization/Null/ERF_NullWindFarm.H +++ b/Source/WindFarmParametrization/Null/ERF_NullWindFarm.H @@ -10,25 +10,25 @@ class NullWindFarm { public: - NullWindFarm() {} + NullWindFarm () {} - virtual ~NullWindFarm() = default; + virtual ~NullWindFarm () = default; virtual void advance (const amrex::Geometry& a_geom, - const amrex::Real& dt_advance, - amrex::MultiFab& cons_in, - amrex::MultiFab& mf_vars_windfarm, - amrex::MultiFab& U_old, - amrex::MultiFab& V_old, - amrex::MultiFab& W_old, - const amrex::MultiFab& mf_Nturb, - const amrex::MultiFab& mf_SMark, - const amrex::Real& time) = 0; - - virtual void set_turb_spec(const amrex::Real& rotor_rad, const amrex::Real& hub_height, - const amrex::Real& thrust_coeff_standing, const amrex::Vector& wind_speed, - const amrex::Vector& thrust_coeff, - const amrex::Vector& power) + const amrex::Real& dt_advance, + amrex::MultiFab& cons_in, + amrex::MultiFab& mf_vars_windfarm, + amrex::MultiFab& U_old, + amrex::MultiFab& V_old, + amrex::MultiFab& W_old, + const amrex::MultiFab& mf_Nturb, + const amrex::MultiFab& mf_SMark, + const amrex::Real& time) = 0; + + virtual void set_turb_spec (const amrex::Real& rotor_rad, const amrex::Real& hub_height, + const amrex::Real& thrust_coeff_standing, const amrex::Vector& wind_speed, + const amrex::Vector& thrust_coeff, + const amrex::Vector& power) { m_rotor_rad = rotor_rad; m_hub_height = hub_height; @@ -50,29 +50,29 @@ public: m_turb_disk_angle = turb_disk_angle; } - virtual void set_blade_spec(const amrex::Vector& bld_rad_loc, - const amrex::Vector& bld_twist, - const amrex::Vector& bld_chord) + virtual void set_blade_spec (const amrex::Vector& bld_rad_loc, + const amrex::Vector& bld_twist, + const amrex::Vector& bld_chord) { m_bld_rad_loc = bld_rad_loc; m_bld_twist = bld_twist; m_bld_chord = bld_chord; } - virtual void set_blade_airfoil_spec(const amrex::Vector>& bld_airfoil_aoa, - const amrex::Vector>& bld_airfoil_Cl, - const amrex::Vector>& bld_airfoil_Cd) + virtual void set_blade_airfoil_spec (const amrex::Vector>& bld_airfoil_aoa, + const amrex::Vector>& bld_airfoil_Cl, + const amrex::Vector>& bld_airfoil_Cd) { m_bld_airfoil_aoa = bld_airfoil_aoa; m_bld_airfoil_Cl = bld_airfoil_Cl; m_bld_airfoil_Cd = bld_airfoil_Cd; } - virtual void set_turb_spec_extra(const amrex::Vector& velocity, - const amrex::Vector& C_P, - const amrex::Vector& C_T, - const amrex::Vector& rotor_RPM, - const amrex::Vector& blade_pitch) + virtual void set_turb_spec_extra (const amrex::Vector& velocity, + const amrex::Vector& C_P, + const amrex::Vector& C_T, + const amrex::Vector& rotor_RPM, + const amrex::Vector& blade_pitch) { m_velocity = velocity; m_C_P = C_P; @@ -105,29 +105,29 @@ public: turb_disk_angle = m_turb_disk_angle; } - void get_blade_spec(amrex::Vector& bld_rad_loc, - amrex::Vector& bld_twist, - amrex::Vector& bld_chord) + void get_blade_spec (amrex::Vector& bld_rad_loc, + amrex::Vector& bld_twist, + amrex::Vector& bld_chord) { bld_rad_loc = m_bld_rad_loc; bld_twist = m_bld_twist; bld_chord = m_bld_chord; } - void get_blade_airfoil_spec(amrex::Vector>& bld_airfoil_aoa, - amrex::Vector>& bld_airfoil_Cl, - amrex::Vector>& bld_airfoil_Cd) + void get_blade_airfoil_spec (amrex::Vector>& bld_airfoil_aoa, + amrex::Vector>& bld_airfoil_Cl, + amrex::Vector>& bld_airfoil_Cd) { bld_airfoil_aoa = m_bld_airfoil_aoa; bld_airfoil_Cl = m_bld_airfoil_Cl; bld_airfoil_Cd = m_bld_airfoil_Cd; } - void get_turb_spec_extra(amrex::Vector& velocity, - amrex::Vector& C_P, - amrex::Vector& C_T, - amrex::Vector& rotor_RPM, - amrex::Vector& blade_pitch) + void get_turb_spec_extra (amrex::Vector& velocity, + amrex::Vector& C_P, + amrex::Vector& C_T, + amrex::Vector& rotor_RPM, + amrex::Vector& blade_pitch) { velocity = m_velocity; C_P = m_C_P; @@ -137,10 +137,10 @@ public: } static AMREX_GPU_DEVICE -bool find_if_marked(amrex::Real x1, amrex::Real x2, amrex::Real y1, amrex::Real y2, - amrex::Real x0, amrex::Real y0, amrex::Real nx, amrex::Real ny, - amrex::Real d_hub_height, amrex::Real d_rotor_rad, - amrex::Real z) +bool find_if_marked (amrex::Real x1, amrex::Real x2, amrex::Real y1, amrex::Real y2, + amrex::Real x0, amrex::Real y0, amrex::Real nx, amrex::Real ny, + amrex::Real d_hub_height, amrex::Real d_rotor_rad, + amrex::Real z) { // Plane is (x-x0)*nx + (y-y0)*ny = 0. And the planes to intersect are diff --git a/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp b/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp index 038022c7b..116de0b48 100644 --- a/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp +++ b/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_AdvanceSimpleAD.cpp @@ -6,15 +6,15 @@ using namespace amrex; void SimpleAD::advance (const Geometry& geom, - const Real& dt_advance, - MultiFab& cons_in, - MultiFab& mf_vars_simpleAD, - MultiFab& U_old, - MultiFab& V_old, - MultiFab& W_old, - const MultiFab& mf_Nturb, - const MultiFab& mf_SMark, - const Real& time) + const Real& dt_advance, + MultiFab& cons_in, + MultiFab& mf_vars_simpleAD, + MultiFab& U_old, + MultiFab& V_old, + MultiFab& W_old, + const MultiFab& mf_Nturb, + const MultiFab& mf_SMark, + const Real& time) { AMREX_ALWAYS_ASSERT(W_old.nComp() > 0); AMREX_ALWAYS_ASSERT(mf_Nturb.nComp() > 0); @@ -25,7 +25,7 @@ SimpleAD::advance (const Geometry& geom, } void -SimpleAD::compute_power_output(const Real& time) +SimpleAD::compute_power_output (const Real& time) { get_turb_loc(xloc, yloc); get_turb_spec(rotor_rad, hub_height, thrust_coeff_standing, @@ -81,10 +81,10 @@ SimpleAD::update (const Real& dt_advance, } } -void SimpleAD::compute_freestream_velocity(const MultiFab& cons_in, - const MultiFab& U_old, - const MultiFab& V_old, - const MultiFab& mf_SMark) +void SimpleAD::compute_freestream_velocity (const MultiFab& cons_in, + const MultiFab& U_old, + const MultiFab& V_old, + const MultiFab& mf_SMark) { get_turb_loc(xloc, yloc); freestream_velocity.clear(); diff --git a/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_SimpleAD.H b/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_SimpleAD.H index 855f4a99e..2889e8ecb 100644 --- a/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_SimpleAD.H +++ b/Source/WindFarmParametrization/SimpleActuatorDisk/ERF_SimpleAD.H @@ -9,9 +9,9 @@ class SimpleAD : public NullWindFarm { public: - SimpleAD() {} + SimpleAD () {} - virtual ~SimpleAD() = default; + virtual ~SimpleAD () = default; void advance (const amrex::Geometry& geom, const amrex::Real& dt_advance, @@ -24,10 +24,10 @@ public: const amrex::MultiFab& mf_SMark, const amrex::Real& time) override; - void compute_freestream_velocity(const amrex::MultiFab& cons_in, - const amrex::MultiFab& U_old, - const amrex::MultiFab& V_old, - const amrex::MultiFab& mf_SMark); + void compute_freestream_velocity (const amrex::MultiFab& cons_in, + const amrex::MultiFab& U_old, + const amrex::MultiFab& V_old, + const amrex::MultiFab& mf_SMark); void source_terms_cellcentered (const amrex::Geometry& geom, const amrex::MultiFab& cons_in, @@ -40,7 +40,7 @@ public: amrex::MultiFab& V_old, const amrex::MultiFab& mf_vars); - void compute_power_output(const amrex::Real& time); + void compute_power_output (const amrex::Real& time); protected: amrex::Vector xloc, yloc; diff --git a/Submodules/AMReX b/Submodules/AMReX index b9d549bcf..4a6e7c87e 160000 --- a/Submodules/AMReX +++ b/Submodules/AMReX @@ -1 +1 @@ -Subproject commit b9d549bcf4a6e035e6050c92083d42a30a4078b1 +Subproject commit 4a6e7c87e1494d10893b36f0d7ce6bf9df19fe0d From d7c4a84209b19c134067b679165ed9d890fbb139 Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Mon, 4 Nov 2024 15:27:26 -0800 Subject: [PATCH 19/24] Move run directories into new locations (#1926) * Move run directories into new locations * remove unused * fix test dirs --- Docs/sphinx_doc/Verification.rst | 2 +- Exec/CMakeLists.txt | 43 +++-- Exec/DevTests/Radiation/ERF_prob.H | 2 +- .../Couette_Poiseuille/CMakeLists.txt | 0 .../Couette_Poiseuille/ERF_prob.H | 0 .../Couette_Poiseuille/ERF_prob.cpp | 0 .../Couette_Poiseuille/GNUmakefile | 0 .../Couette_Poiseuille}/Make.package | 0 .../Couette_Poiseuille/README | 0 .../Couette_Poiseuille/couette_helpers.py | 0 .../Couette_Poiseuille/inputs_couette_x | 0 .../Couette_Poiseuille/inputs_couette_y | 0 .../Couette_Poiseuille/inputs_poiseuille_x | 0 .../Couette_Poiseuille/inputs_poiseuille_y | 0 .../plot_couette_flow_evolution.py | 0 .../DensityCurrent/CMakeLists.txt | 0 .../DensityCurrent/ERF_prob.H | 0 .../DensityCurrent/ERF_prob.cpp | 0 .../DensityCurrent/GNUmakefile | 0 .../DensityCurrent}/Make.package | 0 .../DensityCurrent/README | 0 .../DensityCurrent/inputs_amr | 0 .../DensityCurrent/inputs_crse_halfdomain | 0 .../inputs_crse_halfdomain_zlev | 0 .../DensityCurrent/inputs_refsoln | 0 .../DensityCurrent/inputs_wrf_baseline | 0 .../DensityCurrent/runscript_baseline | 0 .../DensityCurrent/runscript_refsoln | 0 .../EkmanSpiral/CMakeLists.txt | 0 .../EkmanSpiral/ERF_prob.H | 0 .../EkmanSpiral/ERF_prob.cpp | 0 .../EkmanSpiral/GNUmakefile | 0 .../EkmanSpiral}/Make.package | 0 .../EkmanSpiral/README | 0 .../EkmanSpiral/check_convergence.py | 0 .../EkmanSpiral/input_sounding_file | 0 .../EkmanSpiral/inputs_custom | 0 .../EkmanSpiral/inputs_ideal | 0 .../EkmanSpiral/inputs_input_sounding | 0 .../EkmanSpiral/run_convergence_study.sh | 0 .../EkmanSpiral/wrfinput_ekman_d01 | Bin .../IsentropicVortex/CMakeLists.txt | 0 .../IsentropicVortex/ERF_prob.H | 0 .../IsentropicVortex/ERF_prob.cpp | 0 .../IsentropicVortex/GNUmakefile | 0 .../IsentropicVortex}/Make.package | 0 .../IsentropicVortex/animate.py | 0 .../check_initial_solution.py | 0 .../check_stationary_vortex_rmse.py | 0 .../IsentropicVortex/check_vortex_rmse.py | 0 .../IsentropicVortex/inputs_advecting | 0 .../IsentropicVortex/inputs_advecting_ml | 0 .../IsentropicVortex/inputs_advecting_msf | 0 .../IsentropicVortex/inputs_advecting_no_msf | 0 .../IsentropicVortex/inputs_stationary | 0 .../IsentropicVortex/inputs_stationary_msf | 0 .../IsentropicVortex/inputs_stationary_no_msf | 0 .../isentropic_vortex_helpers.py | 0 .../ParticlesOverWoA/CMakeLists.txt | 0 .../ParticlesOverWoA/ERF_prob.H | 0 .../ParticlesOverWoA/ERF_prob.cpp | 0 .../ParticlesOverWoA/GNUmakefile | 0 .../ParticlesOverWoA}/Make.package | 0 .../ParticlesOverWoA/README | 0 .../ParticlesOverWoA/inputs | 0 .../ScalarAdvDiff/CMakeLists.txt | 0 .../ScalarAdvDiff/ERF_prob.H | 0 .../ScalarAdvDiff/ERF_prob.cpp | 0 .../ScalarAdvDiff/GNUmakefile | 0 .../ScalarAdvDiff}/Make.package | 0 .../ScalarAdvDiff/README | 0 .../ScalarAdvDiff/inputs_WENO | 0 .../ScalarAdvDiff/inputs_WENO_Z | 0 .../ScalarAdvDiff/inputs_adv_diff_uniformU | 0 .../ScalarAdvDiff/inputs_advdiffinflowoutflow | 0 .../ScalarAdvDiff/inputs_advect_shearU | 0 .../ScalarAdvDiff/inputs_advect_shearU_msf | 0 .../ScalarAdvDiff/inputs_advect_shearU_no_msf | 0 .../ScalarAdvDiff/inputs_advect_uniformU | 0 .../ScalarAdvDiff/inputs_advect_uniformU_msf | 0 .../inputs_advect_uniformU_no_msf | 0 .../ScalarAdvDiff/inputs_diffuse_gaussian | 0 .../ScalarAdvDiff/inputs_diffuse_msf | 0 .../ScalarAdvDiff/inputs_diffuse_no_msf | 0 .../ScalarAdvDiff/inputs_diffuse_sine | 0 .../ScalarAdvDiff/inputs_ml | 0 .../ScalarAdvDiff/inputs_test_rayleigh | 0 .../ScalarAdvDiff/prob.cpp.convergence | 0 .../StokesSecondProblem/CMakeLists.txt | 0 .../StokesSecondProblem/ERF_prob.H | 0 .../StokesSecondProblem/ERF_prob.cpp | 0 .../StokesSecondProblem/GNUmakefile | 0 .../StokesSecondProblem/Make.package | 0 .../StokesSecondProblem/inputs | 0 .../inputs_stretched_z_levels | 0 .../TaylorGreenVortex/CMakeLists.txt | 0 .../TaylorGreenVortex/ERF_prob.H | 0 .../TaylorGreenVortex/ERF_prob.cpp | 0 .../TaylorGreenVortex/GNUmakefile | 0 .../TaylorGreenVortex}/Make.package | 0 .../TaylorGreenVortex/README | 0 .../TaylorGreenVortex/inputs_advdiff | 0 .../TaylorGreenVortex/inputs_advonly | 0 .../TaylorGreenVortex/inputs_multilevel | 0 .../Terrain2d_Cylinder/CMakeLists.txt | 0 .../Terrain2d_Cylinder/ERF_prob.H | 0 .../Terrain2d_Cylinder/ERF_prob.cpp | 0 .../Terrain2d_Cylinder/GNUmakefile | 0 .../Terrain2d_Cylinder}/Make.package | 0 .../Terrain2d_Cylinder/inputs | 0 .../Terrain2d_Cylinder/inputs.amr | 0 .../Terrain2d_Cylinder/inputs_most_test | 0 .../inputs_stretched_z_levels | 0 .../inputs_verification_final | 0 .../Terrain3d_Hemisphere/CMakeLists.txt | 0 .../Terrain3d_Hemisphere/ERF_prob.H | 0 .../Terrain3d_Hemisphere/ERF_prob.cpp | 0 .../Terrain3d_Hemisphere/GNUmakefile | 0 .../Terrain3d_Hemisphere}/Make.package | 0 .../Terrain3d_Hemisphere/inputs | 0 .../Terrain3d_Hemisphere/inputs.amr | 0 .../Terrain3d_Hemisphere/inputs_most_test | 0 .../Terrain3d_Hemisphere/run_3d.sh | 0 .../TurbulentInflow/CMakeLists.txt | 0 .../TurbulentInflow/ERF_prob.H | 0 .../TurbulentInflow/ERF_prob.cpp | 0 .../TurbulentInflow/GNUmakefile | 0 .../InflowPerturbationGeneration_HowTo.pdf | Bin .../TurbulentInflow}/Make.package | 0 .../TurbulentInflow/README | 0 .../compressible_direct_inputs | 0 .../compressible_source_inputs | 0 .../TurbulentInflow/generateLogLawProfile.py | 0 .../incompressible_direct_inputs | 0 .../incompressible_source_inputs | 0 .../TurbulentInflow/sourceRun.sh | 0 .../WPS_Test/CMakeLists.txt | 0 .../WPS_Test/ERF_prob.H | 0 .../WPS_Test/ERF_prob.cpp | 0 .../WPS_Test/GNUmakefile | 0 .../WPS_Test}/Make.package | 0 .../{RegTests => DryRegTests}/WPS_Test/README | 0 .../WPS_Test/inputs_real_ChisholmView | 0 .../WitchOfAgnesi/CMakeLists.txt | 0 .../WitchOfAgnesi/ERF_prob.H | 0 .../WitchOfAgnesi/ERF_prob.cpp | 0 .../WitchOfAgnesi/GNUmakefile | 0 .../WitchOfAgnesi}/Make.package | 0 .../WitchOfAgnesi/README | 0 .../WitchOfAgnesi/input_sounding | 0 .../WitchOfAgnesi/inputs | 0 .../WitchOfAgnesi/inputs_most_test | 0 .../WitchOfAgnesi/inputs_static_twolevel | 0 .../WitchOfAgnesi/inputs_zlevels | 0 .../Bomex/CMakeLists.txt | 0 .../Bomex/ERF_prob.H | 0 .../Bomex/ERF_prob.cpp | 0 .../Bomex/GNUmakefile | 2 +- .../Bomex}/Make.package | 0 Exec/{RegTests => MoistRegTests}/Bomex/README | 0 .../Bomex/input_Kessler | 0 .../Bomex/input_SAM | 0 .../Bomex/input_sounding | 0 .../Bubble/CMakeLists.txt | 0 .../Bubble/ERF_prob.H | 0 .../Bubble/ERF_prob.cpp | 0 .../Bubble/GNUmakefile | 2 +- .../Bubble}/Make.package | 0 .../Bubble/input_sounding_squall2d | 0 .../Bubble/inputs_BF02_dry_bubble | 0 .../Bubble/inputs_BF02_moist_bubble | 0 .../Bubble/inputs_BF02_moist_bubble_Kessler | 0 .../Bubble/inputs_BF02_moist_bubble_OpenBC | 0 .../Bubble/inputs_BF02_moist_bubble_SAM | 0 .../Bubble/inputs_BF02_moist_bubble_SAM_NoIce | 0 ...nputs_BF02_moist_bubble_SAM_NoPrecip_NoIce | 0 .../Bubble/inputs_grav2d_x | 0 .../Bubble/inputs_squall2d_x | 0 .../Bubble/inputs_test_outflow | 0 .../SquallLine_2D/CMakeLists.txt | 0 .../SquallLine_2D/ERF_prob.H | 2 +- .../SquallLine_2D/ERF_prob.cpp | 0 .../SquallLine_2D/GNUmakefile | 4 +- .../SquallLine_2D}/Make.package | 0 Exec/{ => MoistRegTests}/SquallLine_2D/README | 0 .../SquallLine_2D/inputs_ml | 0 .../SquallLine_2D/inputs_moisture_Gabersek | 0 .../SquallLine_2D/inputs_moisture_SAM | 0 .../SquallLine_2D/inputs_moisture_WRF | 0 .../SuperCell_3D/CMakeLists.txt | 0 .../SuperCell_3D/ERF_prob.H | 0 .../SuperCell_3D/ERF_prob.cpp | 3 - .../SuperCell_3D/GNUmakefile | 4 +- .../SuperCell_3D}/Make.package | 0 Exec/{ => MoistRegTests}/SuperCell_3D/README | 0 .../SuperCell_3D/inputs_Supercell_3D | 0 .../RegTests/DynamicRefinement/CMakeLists.txt | 12 -- Exec/RegTests/DynamicRefinement/ERF_prob.H | 62 ------ Exec/RegTests/DynamicRefinement/ERF_prob.cpp | 177 ------------------ Exec/RegTests/DynamicRefinement/GNUmakefile | 33 ---- .../DynamicRefinement/inputs_threelevel | 83 -------- .../DynamicRefinement/inputs_twolevel | 87 --------- Exec/SuperCell_3D/Make.package | 2 - Tests/CTestList.cmake | 130 +++++++------ 204 files changed, 94 insertions(+), 556 deletions(-) rename Exec/{RegTests => DryRegTests}/Couette_Poiseuille/CMakeLists.txt (100%) rename Exec/{RegTests => DryRegTests}/Couette_Poiseuille/ERF_prob.H (100%) rename Exec/{RegTests => DryRegTests}/Couette_Poiseuille/ERF_prob.cpp (100%) rename Exec/{RegTests => DryRegTests}/Couette_Poiseuille/GNUmakefile (100%) rename Exec/{RegTests/Bomex => DryRegTests/Couette_Poiseuille}/Make.package (100%) rename Exec/{RegTests => DryRegTests}/Couette_Poiseuille/README (100%) rename Exec/{RegTests => DryRegTests}/Couette_Poiseuille/couette_helpers.py (100%) rename Exec/{RegTests => DryRegTests}/Couette_Poiseuille/inputs_couette_x (100%) rename Exec/{RegTests => DryRegTests}/Couette_Poiseuille/inputs_couette_y (100%) rename Exec/{RegTests => DryRegTests}/Couette_Poiseuille/inputs_poiseuille_x (100%) rename Exec/{RegTests => DryRegTests}/Couette_Poiseuille/inputs_poiseuille_y (100%) rename Exec/{RegTests => DryRegTests}/Couette_Poiseuille/plot_couette_flow_evolution.py (100%) rename Exec/{RegTests => DryRegTests}/DensityCurrent/CMakeLists.txt (100%) rename Exec/{RegTests => DryRegTests}/DensityCurrent/ERF_prob.H (100%) rename Exec/{RegTests => DryRegTests}/DensityCurrent/ERF_prob.cpp (100%) rename Exec/{RegTests => DryRegTests}/DensityCurrent/GNUmakefile (100%) rename Exec/{RegTests/Bubble => DryRegTests/DensityCurrent}/Make.package (100%) rename Exec/{RegTests => DryRegTests}/DensityCurrent/README (100%) rename Exec/{RegTests => DryRegTests}/DensityCurrent/inputs_amr (100%) rename Exec/{RegTests => DryRegTests}/DensityCurrent/inputs_crse_halfdomain (100%) rename Exec/{RegTests => DryRegTests}/DensityCurrent/inputs_crse_halfdomain_zlev (100%) rename Exec/{RegTests => DryRegTests}/DensityCurrent/inputs_refsoln (100%) rename Exec/{RegTests => DryRegTests}/DensityCurrent/inputs_wrf_baseline (100%) rename Exec/{RegTests => DryRegTests}/DensityCurrent/runscript_baseline (100%) rename Exec/{RegTests => DryRegTests}/DensityCurrent/runscript_refsoln (100%) rename Exec/{RegTests => DryRegTests}/EkmanSpiral/CMakeLists.txt (100%) rename Exec/{RegTests => DryRegTests}/EkmanSpiral/ERF_prob.H (100%) rename Exec/{RegTests => DryRegTests}/EkmanSpiral/ERF_prob.cpp (100%) rename Exec/{RegTests => DryRegTests}/EkmanSpiral/GNUmakefile (100%) rename Exec/{RegTests/Couette_Poiseuille => DryRegTests/EkmanSpiral}/Make.package (100%) rename Exec/{RegTests => DryRegTests}/EkmanSpiral/README (100%) rename Exec/{RegTests => DryRegTests}/EkmanSpiral/check_convergence.py (100%) rename Exec/{RegTests => DryRegTests}/EkmanSpiral/input_sounding_file (100%) rename Exec/{RegTests => DryRegTests}/EkmanSpiral/inputs_custom (100%) rename Exec/{RegTests => DryRegTests}/EkmanSpiral/inputs_ideal (100%) rename Exec/{RegTests => DryRegTests}/EkmanSpiral/inputs_input_sounding (100%) rename Exec/{RegTests => DryRegTests}/EkmanSpiral/run_convergence_study.sh (100%) rename Exec/{RegTests => DryRegTests}/EkmanSpiral/wrfinput_ekman_d01 (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/CMakeLists.txt (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/ERF_prob.H (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/ERF_prob.cpp (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/GNUmakefile (100%) rename Exec/{RegTests/DensityCurrent => DryRegTests/IsentropicVortex}/Make.package (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/animate.py (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/check_initial_solution.py (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/check_stationary_vortex_rmse.py (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/check_vortex_rmse.py (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/inputs_advecting (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/inputs_advecting_ml (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/inputs_advecting_msf (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/inputs_advecting_no_msf (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/inputs_stationary (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/inputs_stationary_msf (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/inputs_stationary_no_msf (100%) rename Exec/{RegTests => DryRegTests}/IsentropicVortex/isentropic_vortex_helpers.py (100%) rename Exec/{RegTests => DryRegTests}/ParticlesOverWoA/CMakeLists.txt (100%) rename Exec/{RegTests => DryRegTests}/ParticlesOverWoA/ERF_prob.H (100%) rename Exec/{RegTests => DryRegTests}/ParticlesOverWoA/ERF_prob.cpp (100%) rename Exec/{RegTests => DryRegTests}/ParticlesOverWoA/GNUmakefile (100%) rename Exec/{RegTests/DynamicRefinement => DryRegTests/ParticlesOverWoA}/Make.package (100%) rename Exec/{RegTests => DryRegTests}/ParticlesOverWoA/README (100%) rename Exec/{RegTests => DryRegTests}/ParticlesOverWoA/inputs (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/CMakeLists.txt (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/ERF_prob.H (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/ERF_prob.cpp (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/GNUmakefile (100%) rename Exec/{RegTests/EkmanSpiral => DryRegTests/ScalarAdvDiff}/Make.package (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/README (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_WENO (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_WENO_Z (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_adv_diff_uniformU (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_advdiffinflowoutflow (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_advect_shearU (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_advect_shearU_msf (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_advect_shearU_no_msf (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_advect_uniformU (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_advect_uniformU_msf (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_advect_uniformU_no_msf (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_diffuse_gaussian (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_diffuse_msf (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_diffuse_no_msf (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_diffuse_sine (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_ml (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/inputs_test_rayleigh (100%) rename Exec/{RegTests => DryRegTests}/ScalarAdvDiff/prob.cpp.convergence (100%) rename Exec/{RegTests => DryRegTests}/StokesSecondProblem/CMakeLists.txt (100%) rename Exec/{RegTests => DryRegTests}/StokesSecondProblem/ERF_prob.H (100%) rename Exec/{RegTests => DryRegTests}/StokesSecondProblem/ERF_prob.cpp (100%) rename Exec/{RegTests => DryRegTests}/StokesSecondProblem/GNUmakefile (100%) rename Exec/{RegTests => DryRegTests}/StokesSecondProblem/Make.package (100%) rename Exec/{RegTests => DryRegTests}/StokesSecondProblem/inputs (100%) rename Exec/{RegTests => DryRegTests}/StokesSecondProblem/inputs_stretched_z_levels (100%) rename Exec/{RegTests => DryRegTests}/TaylorGreenVortex/CMakeLists.txt (100%) rename Exec/{RegTests => DryRegTests}/TaylorGreenVortex/ERF_prob.H (100%) rename Exec/{RegTests => DryRegTests}/TaylorGreenVortex/ERF_prob.cpp (100%) rename Exec/{RegTests => DryRegTests}/TaylorGreenVortex/GNUmakefile (100%) rename Exec/{RegTests/IsentropicVortex => DryRegTests/TaylorGreenVortex}/Make.package (100%) rename Exec/{RegTests => DryRegTests}/TaylorGreenVortex/README (100%) rename Exec/{RegTests => DryRegTests}/TaylorGreenVortex/inputs_advdiff (100%) rename Exec/{RegTests => DryRegTests}/TaylorGreenVortex/inputs_advonly (100%) rename Exec/{RegTests => DryRegTests}/TaylorGreenVortex/inputs_multilevel (100%) rename Exec/{RegTests => DryRegTests}/Terrain2d_Cylinder/CMakeLists.txt (100%) rename Exec/{RegTests => DryRegTests}/Terrain2d_Cylinder/ERF_prob.H (100%) rename Exec/{RegTests => DryRegTests}/Terrain2d_Cylinder/ERF_prob.cpp (100%) rename Exec/{RegTests => DryRegTests}/Terrain2d_Cylinder/GNUmakefile (100%) rename Exec/{RegTests/ParticlesOverWoA => DryRegTests/Terrain2d_Cylinder}/Make.package (100%) rename Exec/{RegTests => DryRegTests}/Terrain2d_Cylinder/inputs (100%) rename Exec/{RegTests => DryRegTests}/Terrain2d_Cylinder/inputs.amr (100%) rename Exec/{RegTests => DryRegTests}/Terrain2d_Cylinder/inputs_most_test (100%) rename Exec/{RegTests => DryRegTests}/Terrain2d_Cylinder/inputs_stretched_z_levels (100%) rename Exec/{RegTests => DryRegTests}/Terrain2d_Cylinder/inputs_verification_final (100%) rename Exec/{RegTests => DryRegTests}/Terrain3d_Hemisphere/CMakeLists.txt (100%) rename Exec/{RegTests => DryRegTests}/Terrain3d_Hemisphere/ERF_prob.H (100%) rename Exec/{RegTests => DryRegTests}/Terrain3d_Hemisphere/ERF_prob.cpp (100%) rename Exec/{RegTests => DryRegTests}/Terrain3d_Hemisphere/GNUmakefile (100%) rename Exec/{RegTests/ScalarAdvDiff => DryRegTests/Terrain3d_Hemisphere}/Make.package (100%) rename Exec/{RegTests => DryRegTests}/Terrain3d_Hemisphere/inputs (100%) rename Exec/{RegTests => DryRegTests}/Terrain3d_Hemisphere/inputs.amr (100%) rename Exec/{RegTests => DryRegTests}/Terrain3d_Hemisphere/inputs_most_test (100%) rename Exec/{RegTests => DryRegTests}/Terrain3d_Hemisphere/run_3d.sh (100%) rename Exec/{RegTests => DryRegTests}/TurbulentInflow/CMakeLists.txt (100%) rename Exec/{RegTests => DryRegTests}/TurbulentInflow/ERF_prob.H (100%) rename Exec/{RegTests => DryRegTests}/TurbulentInflow/ERF_prob.cpp (100%) rename Exec/{RegTests => DryRegTests}/TurbulentInflow/GNUmakefile (100%) rename Exec/{RegTests => DryRegTests}/TurbulentInflow/InflowPerturbationGeneration_HowTo.pdf (100%) rename Exec/{RegTests/TaylorGreenVortex => DryRegTests/TurbulentInflow}/Make.package (100%) rename Exec/{RegTests => DryRegTests}/TurbulentInflow/README (100%) rename Exec/{RegTests => DryRegTests}/TurbulentInflow/compressible_direct_inputs (100%) rename Exec/{RegTests => DryRegTests}/TurbulentInflow/compressible_source_inputs (100%) rename Exec/{RegTests => DryRegTests}/TurbulentInflow/generateLogLawProfile.py (100%) rename Exec/{RegTests => DryRegTests}/TurbulentInflow/incompressible_direct_inputs (100%) rename Exec/{RegTests => DryRegTests}/TurbulentInflow/incompressible_source_inputs (100%) rename Exec/{RegTests => DryRegTests}/TurbulentInflow/sourceRun.sh (100%) rename Exec/{RegTests => DryRegTests}/WPS_Test/CMakeLists.txt (100%) rename Exec/{RegTests => DryRegTests}/WPS_Test/ERF_prob.H (100%) rename Exec/{RegTests => DryRegTests}/WPS_Test/ERF_prob.cpp (100%) rename Exec/{RegTests => DryRegTests}/WPS_Test/GNUmakefile (100%) rename Exec/{RegTests/Terrain2d_Cylinder => DryRegTests/WPS_Test}/Make.package (100%) rename Exec/{RegTests => DryRegTests}/WPS_Test/README (100%) rename Exec/{RegTests => DryRegTests}/WPS_Test/inputs_real_ChisholmView (100%) rename Exec/{RegTests => DryRegTests}/WitchOfAgnesi/CMakeLists.txt (100%) rename Exec/{RegTests => DryRegTests}/WitchOfAgnesi/ERF_prob.H (100%) rename Exec/{RegTests => DryRegTests}/WitchOfAgnesi/ERF_prob.cpp (100%) rename Exec/{RegTests => DryRegTests}/WitchOfAgnesi/GNUmakefile (100%) rename Exec/{RegTests/Terrain3d_Hemisphere => DryRegTests/WitchOfAgnesi}/Make.package (100%) rename Exec/{RegTests => DryRegTests}/WitchOfAgnesi/README (100%) rename Exec/{RegTests => DryRegTests}/WitchOfAgnesi/input_sounding (100%) rename Exec/{RegTests => DryRegTests}/WitchOfAgnesi/inputs (100%) rename Exec/{RegTests => DryRegTests}/WitchOfAgnesi/inputs_most_test (100%) rename Exec/{RegTests => DryRegTests}/WitchOfAgnesi/inputs_static_twolevel (100%) rename Exec/{RegTests => DryRegTests}/WitchOfAgnesi/inputs_zlevels (100%) rename Exec/{RegTests => MoistRegTests}/Bomex/CMakeLists.txt (100%) rename Exec/{RegTests => MoistRegTests}/Bomex/ERF_prob.H (100%) rename Exec/{RegTests => MoistRegTests}/Bomex/ERF_prob.cpp (100%) rename Exec/{RegTests => MoistRegTests}/Bomex/GNUmakefile (89%) rename Exec/{RegTests/TurbulentInflow => MoistRegTests/Bomex}/Make.package (100%) rename Exec/{RegTests => MoistRegTests}/Bomex/README (100%) rename Exec/{RegTests => MoistRegTests}/Bomex/input_Kessler (100%) rename Exec/{RegTests => MoistRegTests}/Bomex/input_SAM (100%) rename Exec/{RegTests => MoistRegTests}/Bomex/input_sounding (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/CMakeLists.txt (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/ERF_prob.H (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/ERF_prob.cpp (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/GNUmakefile (88%) rename Exec/{RegTests/WPS_Test => MoistRegTests/Bubble}/Make.package (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/input_sounding_squall2d (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/inputs_BF02_dry_bubble (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/inputs_BF02_moist_bubble (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/inputs_BF02_moist_bubble_Kessler (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/inputs_BF02_moist_bubble_OpenBC (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/inputs_BF02_moist_bubble_SAM (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/inputs_BF02_moist_bubble_SAM_NoIce (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/inputs_BF02_moist_bubble_SAM_NoPrecip_NoIce (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/inputs_grav2d_x (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/inputs_squall2d_x (100%) rename Exec/{RegTests => MoistRegTests}/Bubble/inputs_test_outflow (100%) rename Exec/{ => MoistRegTests}/SquallLine_2D/CMakeLists.txt (100%) rename Exec/{ => MoistRegTests}/SquallLine_2D/ERF_prob.H (98%) rename Exec/{ => MoistRegTests}/SquallLine_2D/ERF_prob.cpp (100%) rename Exec/{ => MoistRegTests}/SquallLine_2D/GNUmakefile (83%) rename Exec/{RegTests/WitchOfAgnesi => MoistRegTests/SquallLine_2D}/Make.package (100%) rename Exec/{ => MoistRegTests}/SquallLine_2D/README (100%) rename Exec/{ => MoistRegTests}/SquallLine_2D/inputs_ml (100%) rename Exec/{ => MoistRegTests}/SquallLine_2D/inputs_moisture_Gabersek (100%) rename Exec/{ => MoistRegTests}/SquallLine_2D/inputs_moisture_SAM (100%) rename Exec/{ => MoistRegTests}/SquallLine_2D/inputs_moisture_WRF (100%) rename Exec/{ => MoistRegTests}/SuperCell_3D/CMakeLists.txt (100%) rename Exec/{ => MoistRegTests}/SuperCell_3D/ERF_prob.H (100%) rename Exec/{ => MoistRegTests}/SuperCell_3D/ERF_prob.cpp (99%) rename Exec/{ => MoistRegTests}/SuperCell_3D/GNUmakefile (83%) rename Exec/{SquallLine_2D => MoistRegTests/SuperCell_3D}/Make.package (100%) rename Exec/{ => MoistRegTests}/SuperCell_3D/README (100%) rename Exec/{ => MoistRegTests}/SuperCell_3D/inputs_Supercell_3D (100%) delete mode 100644 Exec/RegTests/DynamicRefinement/CMakeLists.txt delete mode 100644 Exec/RegTests/DynamicRefinement/ERF_prob.H delete mode 100644 Exec/RegTests/DynamicRefinement/ERF_prob.cpp delete mode 100644 Exec/RegTests/DynamicRefinement/GNUmakefile delete mode 100644 Exec/RegTests/DynamicRefinement/inputs_threelevel delete mode 100644 Exec/RegTests/DynamicRefinement/inputs_twolevel delete mode 100644 Exec/SuperCell_3D/Make.package diff --git a/Docs/sphinx_doc/Verification.rst b/Docs/sphinx_doc/Verification.rst index 1e995be4b..c0f5b89fe 100644 --- a/Docs/sphinx_doc/Verification.rst +++ b/Docs/sphinx_doc/Verification.rst @@ -159,7 +159,7 @@ Dry bubble and moist bubble rise simulations Benchmark simulations of dry and moist bubble rises in `Bryan and Fritsch`_ are reproduced. The test case consists of a warm bubble rising in dry and moist conditions. The potential temperature perturbation and the vertical velocity are compared as shown in the figures below. Excellent quantitative comparisons are obtained. The dry and moist bubble cases are -in ``Exec/RegTests/Bubble`` with the corresponding input files ``inputs_BF02_dry_bubble`` and ``inputs_BF02_moist_bubble``. +in ``Exec/DryRegTests/Bubble`` with the corresponding input files ``inputs_BF02_dry_bubble`` and ``inputs_BF02_moist_bubble``. .. _`Bryan and Fritsch`: https://journals.ametsoc.org/view/journals/mwre/130/12/1520-0493_2002_130_2917_absfmn_2.0.co_2.xml diff --git a/Exec/CMakeLists.txt b/Exec/CMakeLists.txt index 046865f20..16e72968c 100644 --- a/Exec/CMakeLists.txt +++ b/Exec/CMakeLists.txt @@ -8,31 +8,30 @@ build_erf_lib(${erf_lib_name}) if (ERF_ENABLE_MULTIBLOCK) add_subdirectory(DevTests/MultiBlock) elseif (ERF_ENABLE_REGRESSION_TESTS_ONLY) -# add_subdirectory(RegTests/Bubble) - add_subdirectory(RegTests/Couette_Poiseuille) - add_subdirectory(RegTests/DensityCurrent) - add_subdirectory(RegTests/DynamicRefinement) - add_subdirectory(RegTests/EkmanSpiral) - add_subdirectory(RegTests/IsentropicVortex) - add_subdirectory(RegTests/ScalarAdvDiff) - add_subdirectory(RegTests/TaylorGreenVortex) + add_subdirectory(DryRegTests/Couette_Poiseuille) + add_subdirectory(DryRegTests/DensityCurrent) + add_subdirectory(DryRegTests/EkmanSpiral) + add_subdirectory(DryRegTests/IsentropicVortex) + add_subdirectory(DryRegTests/ScalarAdvDiff) + add_subdirectory(DryRegTests/TaylorGreenVortex) + add_subdirectory(DryRegTests/TurbulentInflow) add_subdirectory(DevTests/MovingTerrain) else () add_subdirectory(ABL) - add_subdirectory(SquallLine_2D) - add_subdirectory(RegTests/Bubble) - add_subdirectory(RegTests/Couette_Poiseuille) - add_subdirectory(RegTests/DensityCurrent) - add_subdirectory(RegTests/DynamicRefinement) - add_subdirectory(RegTests/EkmanSpiral) - add_subdirectory(RegTests/IsentropicVortex) - add_subdirectory(RegTests/ParticlesOverWoA) - add_subdirectory(RegTests/ScalarAdvDiff) - add_subdirectory(RegTests/TaylorGreenVortex) - add_subdirectory(RegTests/WitchOfAgnesi) - add_subdirectory(RegTests/WPS_Test) - add_subdirectory(RegTests/Bomex) - add_subdirectory(RegTests/TurbulentInflow) + add_subdirectory(MoistRegTests/Bomex) + add_subdirectory(MoistRegTests/Bubble) + add_subdirectory(MoistRegTests/SquallLine_2D) + add_subdirectory(MoistRegTests/SuperCell_3D) + add_subdirectory(DryRegTests/Couette_Poiseuille) + add_subdirectory(DryRegTests/DensityCurrent) + add_subdirectory(DryRegTests/EkmanSpiral) + add_subdirectory(DryRegTests/IsentropicVortex) + add_subdirectory(DryRegTests/ParticlesOverWoA) + add_subdirectory(DryRegTests/ScalarAdvDiff) + add_subdirectory(DryRegTests/TaylorGreenVortex) + add_subdirectory(DryRegTests/TurbulentInflow) + add_subdirectory(DryRegTests/WitchOfAgnesi) + add_subdirectory(DryRegTests/WPS_Test) add_subdirectory(DevTests/LandSurfaceModel) add_subdirectory(DevTests/MetGrid) add_subdirectory(DevTests/MovingTerrain) diff --git a/Exec/DevTests/Radiation/ERF_prob.H b/Exec/DevTests/Radiation/ERF_prob.H index 94f58ed36..6e5afd46c 100644 --- a/Exec/DevTests/Radiation/ERF_prob.H +++ b/Exec/DevTests/Radiation/ERF_prob.H @@ -54,7 +54,7 @@ public: amrex::Real zdamp) override; protected: - std::string name() override { return "Supercell"; } + std::string name() override { return "Radiation"; } private: ProbParm parms; diff --git a/Exec/RegTests/Couette_Poiseuille/CMakeLists.txt b/Exec/DryRegTests/Couette_Poiseuille/CMakeLists.txt similarity index 100% rename from Exec/RegTests/Couette_Poiseuille/CMakeLists.txt rename to Exec/DryRegTests/Couette_Poiseuille/CMakeLists.txt diff --git a/Exec/RegTests/Couette_Poiseuille/ERF_prob.H b/Exec/DryRegTests/Couette_Poiseuille/ERF_prob.H similarity index 100% rename from Exec/RegTests/Couette_Poiseuille/ERF_prob.H rename to Exec/DryRegTests/Couette_Poiseuille/ERF_prob.H diff --git a/Exec/RegTests/Couette_Poiseuille/ERF_prob.cpp b/Exec/DryRegTests/Couette_Poiseuille/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/Couette_Poiseuille/ERF_prob.cpp rename to Exec/DryRegTests/Couette_Poiseuille/ERF_prob.cpp diff --git a/Exec/RegTests/Couette_Poiseuille/GNUmakefile b/Exec/DryRegTests/Couette_Poiseuille/GNUmakefile similarity index 100% rename from Exec/RegTests/Couette_Poiseuille/GNUmakefile rename to Exec/DryRegTests/Couette_Poiseuille/GNUmakefile diff --git a/Exec/RegTests/Bomex/Make.package b/Exec/DryRegTests/Couette_Poiseuille/Make.package similarity index 100% rename from Exec/RegTests/Bomex/Make.package rename to Exec/DryRegTests/Couette_Poiseuille/Make.package diff --git a/Exec/RegTests/Couette_Poiseuille/README b/Exec/DryRegTests/Couette_Poiseuille/README similarity index 100% rename from Exec/RegTests/Couette_Poiseuille/README rename to Exec/DryRegTests/Couette_Poiseuille/README diff --git a/Exec/RegTests/Couette_Poiseuille/couette_helpers.py b/Exec/DryRegTests/Couette_Poiseuille/couette_helpers.py similarity index 100% rename from Exec/RegTests/Couette_Poiseuille/couette_helpers.py rename to Exec/DryRegTests/Couette_Poiseuille/couette_helpers.py diff --git a/Exec/RegTests/Couette_Poiseuille/inputs_couette_x b/Exec/DryRegTests/Couette_Poiseuille/inputs_couette_x similarity index 100% rename from Exec/RegTests/Couette_Poiseuille/inputs_couette_x rename to Exec/DryRegTests/Couette_Poiseuille/inputs_couette_x diff --git a/Exec/RegTests/Couette_Poiseuille/inputs_couette_y b/Exec/DryRegTests/Couette_Poiseuille/inputs_couette_y similarity index 100% rename from Exec/RegTests/Couette_Poiseuille/inputs_couette_y rename to Exec/DryRegTests/Couette_Poiseuille/inputs_couette_y diff --git a/Exec/RegTests/Couette_Poiseuille/inputs_poiseuille_x b/Exec/DryRegTests/Couette_Poiseuille/inputs_poiseuille_x similarity index 100% rename from Exec/RegTests/Couette_Poiseuille/inputs_poiseuille_x rename to Exec/DryRegTests/Couette_Poiseuille/inputs_poiseuille_x diff --git a/Exec/RegTests/Couette_Poiseuille/inputs_poiseuille_y b/Exec/DryRegTests/Couette_Poiseuille/inputs_poiseuille_y similarity index 100% rename from Exec/RegTests/Couette_Poiseuille/inputs_poiseuille_y rename to Exec/DryRegTests/Couette_Poiseuille/inputs_poiseuille_y diff --git a/Exec/RegTests/Couette_Poiseuille/plot_couette_flow_evolution.py b/Exec/DryRegTests/Couette_Poiseuille/plot_couette_flow_evolution.py similarity index 100% rename from Exec/RegTests/Couette_Poiseuille/plot_couette_flow_evolution.py rename to Exec/DryRegTests/Couette_Poiseuille/plot_couette_flow_evolution.py diff --git a/Exec/RegTests/DensityCurrent/CMakeLists.txt b/Exec/DryRegTests/DensityCurrent/CMakeLists.txt similarity index 100% rename from Exec/RegTests/DensityCurrent/CMakeLists.txt rename to Exec/DryRegTests/DensityCurrent/CMakeLists.txt diff --git a/Exec/RegTests/DensityCurrent/ERF_prob.H b/Exec/DryRegTests/DensityCurrent/ERF_prob.H similarity index 100% rename from Exec/RegTests/DensityCurrent/ERF_prob.H rename to Exec/DryRegTests/DensityCurrent/ERF_prob.H diff --git a/Exec/RegTests/DensityCurrent/ERF_prob.cpp b/Exec/DryRegTests/DensityCurrent/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/DensityCurrent/ERF_prob.cpp rename to Exec/DryRegTests/DensityCurrent/ERF_prob.cpp diff --git a/Exec/RegTests/DensityCurrent/GNUmakefile b/Exec/DryRegTests/DensityCurrent/GNUmakefile similarity index 100% rename from Exec/RegTests/DensityCurrent/GNUmakefile rename to Exec/DryRegTests/DensityCurrent/GNUmakefile diff --git a/Exec/RegTests/Bubble/Make.package b/Exec/DryRegTests/DensityCurrent/Make.package similarity index 100% rename from Exec/RegTests/Bubble/Make.package rename to Exec/DryRegTests/DensityCurrent/Make.package diff --git a/Exec/RegTests/DensityCurrent/README b/Exec/DryRegTests/DensityCurrent/README similarity index 100% rename from Exec/RegTests/DensityCurrent/README rename to Exec/DryRegTests/DensityCurrent/README diff --git a/Exec/RegTests/DensityCurrent/inputs_amr b/Exec/DryRegTests/DensityCurrent/inputs_amr similarity index 100% rename from Exec/RegTests/DensityCurrent/inputs_amr rename to Exec/DryRegTests/DensityCurrent/inputs_amr diff --git a/Exec/RegTests/DensityCurrent/inputs_crse_halfdomain b/Exec/DryRegTests/DensityCurrent/inputs_crse_halfdomain similarity index 100% rename from Exec/RegTests/DensityCurrent/inputs_crse_halfdomain rename to Exec/DryRegTests/DensityCurrent/inputs_crse_halfdomain diff --git a/Exec/RegTests/DensityCurrent/inputs_crse_halfdomain_zlev b/Exec/DryRegTests/DensityCurrent/inputs_crse_halfdomain_zlev similarity index 100% rename from Exec/RegTests/DensityCurrent/inputs_crse_halfdomain_zlev rename to Exec/DryRegTests/DensityCurrent/inputs_crse_halfdomain_zlev diff --git a/Exec/RegTests/DensityCurrent/inputs_refsoln b/Exec/DryRegTests/DensityCurrent/inputs_refsoln similarity index 100% rename from Exec/RegTests/DensityCurrent/inputs_refsoln rename to Exec/DryRegTests/DensityCurrent/inputs_refsoln diff --git a/Exec/RegTests/DensityCurrent/inputs_wrf_baseline b/Exec/DryRegTests/DensityCurrent/inputs_wrf_baseline similarity index 100% rename from Exec/RegTests/DensityCurrent/inputs_wrf_baseline rename to Exec/DryRegTests/DensityCurrent/inputs_wrf_baseline diff --git a/Exec/RegTests/DensityCurrent/runscript_baseline b/Exec/DryRegTests/DensityCurrent/runscript_baseline similarity index 100% rename from Exec/RegTests/DensityCurrent/runscript_baseline rename to Exec/DryRegTests/DensityCurrent/runscript_baseline diff --git a/Exec/RegTests/DensityCurrent/runscript_refsoln b/Exec/DryRegTests/DensityCurrent/runscript_refsoln similarity index 100% rename from Exec/RegTests/DensityCurrent/runscript_refsoln rename to Exec/DryRegTests/DensityCurrent/runscript_refsoln diff --git a/Exec/RegTests/EkmanSpiral/CMakeLists.txt b/Exec/DryRegTests/EkmanSpiral/CMakeLists.txt similarity index 100% rename from Exec/RegTests/EkmanSpiral/CMakeLists.txt rename to Exec/DryRegTests/EkmanSpiral/CMakeLists.txt diff --git a/Exec/RegTests/EkmanSpiral/ERF_prob.H b/Exec/DryRegTests/EkmanSpiral/ERF_prob.H similarity index 100% rename from Exec/RegTests/EkmanSpiral/ERF_prob.H rename to Exec/DryRegTests/EkmanSpiral/ERF_prob.H diff --git a/Exec/RegTests/EkmanSpiral/ERF_prob.cpp b/Exec/DryRegTests/EkmanSpiral/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/EkmanSpiral/ERF_prob.cpp rename to Exec/DryRegTests/EkmanSpiral/ERF_prob.cpp diff --git a/Exec/RegTests/EkmanSpiral/GNUmakefile b/Exec/DryRegTests/EkmanSpiral/GNUmakefile similarity index 100% rename from Exec/RegTests/EkmanSpiral/GNUmakefile rename to Exec/DryRegTests/EkmanSpiral/GNUmakefile diff --git a/Exec/RegTests/Couette_Poiseuille/Make.package b/Exec/DryRegTests/EkmanSpiral/Make.package similarity index 100% rename from Exec/RegTests/Couette_Poiseuille/Make.package rename to Exec/DryRegTests/EkmanSpiral/Make.package diff --git a/Exec/RegTests/EkmanSpiral/README b/Exec/DryRegTests/EkmanSpiral/README similarity index 100% rename from Exec/RegTests/EkmanSpiral/README rename to Exec/DryRegTests/EkmanSpiral/README diff --git a/Exec/RegTests/EkmanSpiral/check_convergence.py b/Exec/DryRegTests/EkmanSpiral/check_convergence.py similarity index 100% rename from Exec/RegTests/EkmanSpiral/check_convergence.py rename to Exec/DryRegTests/EkmanSpiral/check_convergence.py diff --git a/Exec/RegTests/EkmanSpiral/input_sounding_file b/Exec/DryRegTests/EkmanSpiral/input_sounding_file similarity index 100% rename from Exec/RegTests/EkmanSpiral/input_sounding_file rename to Exec/DryRegTests/EkmanSpiral/input_sounding_file diff --git a/Exec/RegTests/EkmanSpiral/inputs_custom b/Exec/DryRegTests/EkmanSpiral/inputs_custom similarity index 100% rename from Exec/RegTests/EkmanSpiral/inputs_custom rename to Exec/DryRegTests/EkmanSpiral/inputs_custom diff --git a/Exec/RegTests/EkmanSpiral/inputs_ideal b/Exec/DryRegTests/EkmanSpiral/inputs_ideal similarity index 100% rename from Exec/RegTests/EkmanSpiral/inputs_ideal rename to Exec/DryRegTests/EkmanSpiral/inputs_ideal diff --git a/Exec/RegTests/EkmanSpiral/inputs_input_sounding b/Exec/DryRegTests/EkmanSpiral/inputs_input_sounding similarity index 100% rename from Exec/RegTests/EkmanSpiral/inputs_input_sounding rename to Exec/DryRegTests/EkmanSpiral/inputs_input_sounding diff --git a/Exec/RegTests/EkmanSpiral/run_convergence_study.sh b/Exec/DryRegTests/EkmanSpiral/run_convergence_study.sh similarity index 100% rename from Exec/RegTests/EkmanSpiral/run_convergence_study.sh rename to Exec/DryRegTests/EkmanSpiral/run_convergence_study.sh diff --git a/Exec/RegTests/EkmanSpiral/wrfinput_ekman_d01 b/Exec/DryRegTests/EkmanSpiral/wrfinput_ekman_d01 similarity index 100% rename from Exec/RegTests/EkmanSpiral/wrfinput_ekman_d01 rename to Exec/DryRegTests/EkmanSpiral/wrfinput_ekman_d01 diff --git a/Exec/RegTests/IsentropicVortex/CMakeLists.txt b/Exec/DryRegTests/IsentropicVortex/CMakeLists.txt similarity index 100% rename from Exec/RegTests/IsentropicVortex/CMakeLists.txt rename to Exec/DryRegTests/IsentropicVortex/CMakeLists.txt diff --git a/Exec/RegTests/IsentropicVortex/ERF_prob.H b/Exec/DryRegTests/IsentropicVortex/ERF_prob.H similarity index 100% rename from Exec/RegTests/IsentropicVortex/ERF_prob.H rename to Exec/DryRegTests/IsentropicVortex/ERF_prob.H diff --git a/Exec/RegTests/IsentropicVortex/ERF_prob.cpp b/Exec/DryRegTests/IsentropicVortex/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/IsentropicVortex/ERF_prob.cpp rename to Exec/DryRegTests/IsentropicVortex/ERF_prob.cpp diff --git a/Exec/RegTests/IsentropicVortex/GNUmakefile b/Exec/DryRegTests/IsentropicVortex/GNUmakefile similarity index 100% rename from Exec/RegTests/IsentropicVortex/GNUmakefile rename to Exec/DryRegTests/IsentropicVortex/GNUmakefile diff --git a/Exec/RegTests/DensityCurrent/Make.package b/Exec/DryRegTests/IsentropicVortex/Make.package similarity index 100% rename from Exec/RegTests/DensityCurrent/Make.package rename to Exec/DryRegTests/IsentropicVortex/Make.package diff --git a/Exec/RegTests/IsentropicVortex/animate.py b/Exec/DryRegTests/IsentropicVortex/animate.py similarity index 100% rename from Exec/RegTests/IsentropicVortex/animate.py rename to Exec/DryRegTests/IsentropicVortex/animate.py diff --git a/Exec/RegTests/IsentropicVortex/check_initial_solution.py b/Exec/DryRegTests/IsentropicVortex/check_initial_solution.py similarity index 100% rename from Exec/RegTests/IsentropicVortex/check_initial_solution.py rename to Exec/DryRegTests/IsentropicVortex/check_initial_solution.py diff --git a/Exec/RegTests/IsentropicVortex/check_stationary_vortex_rmse.py b/Exec/DryRegTests/IsentropicVortex/check_stationary_vortex_rmse.py similarity index 100% rename from Exec/RegTests/IsentropicVortex/check_stationary_vortex_rmse.py rename to Exec/DryRegTests/IsentropicVortex/check_stationary_vortex_rmse.py diff --git a/Exec/RegTests/IsentropicVortex/check_vortex_rmse.py b/Exec/DryRegTests/IsentropicVortex/check_vortex_rmse.py similarity index 100% rename from Exec/RegTests/IsentropicVortex/check_vortex_rmse.py rename to Exec/DryRegTests/IsentropicVortex/check_vortex_rmse.py diff --git a/Exec/RegTests/IsentropicVortex/inputs_advecting b/Exec/DryRegTests/IsentropicVortex/inputs_advecting similarity index 100% rename from Exec/RegTests/IsentropicVortex/inputs_advecting rename to Exec/DryRegTests/IsentropicVortex/inputs_advecting diff --git a/Exec/RegTests/IsentropicVortex/inputs_advecting_ml b/Exec/DryRegTests/IsentropicVortex/inputs_advecting_ml similarity index 100% rename from Exec/RegTests/IsentropicVortex/inputs_advecting_ml rename to Exec/DryRegTests/IsentropicVortex/inputs_advecting_ml diff --git a/Exec/RegTests/IsentropicVortex/inputs_advecting_msf b/Exec/DryRegTests/IsentropicVortex/inputs_advecting_msf similarity index 100% rename from Exec/RegTests/IsentropicVortex/inputs_advecting_msf rename to Exec/DryRegTests/IsentropicVortex/inputs_advecting_msf diff --git a/Exec/RegTests/IsentropicVortex/inputs_advecting_no_msf b/Exec/DryRegTests/IsentropicVortex/inputs_advecting_no_msf similarity index 100% rename from Exec/RegTests/IsentropicVortex/inputs_advecting_no_msf rename to Exec/DryRegTests/IsentropicVortex/inputs_advecting_no_msf diff --git a/Exec/RegTests/IsentropicVortex/inputs_stationary b/Exec/DryRegTests/IsentropicVortex/inputs_stationary similarity index 100% rename from Exec/RegTests/IsentropicVortex/inputs_stationary rename to Exec/DryRegTests/IsentropicVortex/inputs_stationary diff --git a/Exec/RegTests/IsentropicVortex/inputs_stationary_msf b/Exec/DryRegTests/IsentropicVortex/inputs_stationary_msf similarity index 100% rename from Exec/RegTests/IsentropicVortex/inputs_stationary_msf rename to Exec/DryRegTests/IsentropicVortex/inputs_stationary_msf diff --git a/Exec/RegTests/IsentropicVortex/inputs_stationary_no_msf b/Exec/DryRegTests/IsentropicVortex/inputs_stationary_no_msf similarity index 100% rename from Exec/RegTests/IsentropicVortex/inputs_stationary_no_msf rename to Exec/DryRegTests/IsentropicVortex/inputs_stationary_no_msf diff --git a/Exec/RegTests/IsentropicVortex/isentropic_vortex_helpers.py b/Exec/DryRegTests/IsentropicVortex/isentropic_vortex_helpers.py similarity index 100% rename from Exec/RegTests/IsentropicVortex/isentropic_vortex_helpers.py rename to Exec/DryRegTests/IsentropicVortex/isentropic_vortex_helpers.py diff --git a/Exec/RegTests/ParticlesOverWoA/CMakeLists.txt b/Exec/DryRegTests/ParticlesOverWoA/CMakeLists.txt similarity index 100% rename from Exec/RegTests/ParticlesOverWoA/CMakeLists.txt rename to Exec/DryRegTests/ParticlesOverWoA/CMakeLists.txt diff --git a/Exec/RegTests/ParticlesOverWoA/ERF_prob.H b/Exec/DryRegTests/ParticlesOverWoA/ERF_prob.H similarity index 100% rename from Exec/RegTests/ParticlesOverWoA/ERF_prob.H rename to Exec/DryRegTests/ParticlesOverWoA/ERF_prob.H diff --git a/Exec/RegTests/ParticlesOverWoA/ERF_prob.cpp b/Exec/DryRegTests/ParticlesOverWoA/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/ParticlesOverWoA/ERF_prob.cpp rename to Exec/DryRegTests/ParticlesOverWoA/ERF_prob.cpp diff --git a/Exec/RegTests/ParticlesOverWoA/GNUmakefile b/Exec/DryRegTests/ParticlesOverWoA/GNUmakefile similarity index 100% rename from Exec/RegTests/ParticlesOverWoA/GNUmakefile rename to Exec/DryRegTests/ParticlesOverWoA/GNUmakefile diff --git a/Exec/RegTests/DynamicRefinement/Make.package b/Exec/DryRegTests/ParticlesOverWoA/Make.package similarity index 100% rename from Exec/RegTests/DynamicRefinement/Make.package rename to Exec/DryRegTests/ParticlesOverWoA/Make.package diff --git a/Exec/RegTests/ParticlesOverWoA/README b/Exec/DryRegTests/ParticlesOverWoA/README similarity index 100% rename from Exec/RegTests/ParticlesOverWoA/README rename to Exec/DryRegTests/ParticlesOverWoA/README diff --git a/Exec/RegTests/ParticlesOverWoA/inputs b/Exec/DryRegTests/ParticlesOverWoA/inputs similarity index 100% rename from Exec/RegTests/ParticlesOverWoA/inputs rename to Exec/DryRegTests/ParticlesOverWoA/inputs diff --git a/Exec/RegTests/ScalarAdvDiff/CMakeLists.txt b/Exec/DryRegTests/ScalarAdvDiff/CMakeLists.txt similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/CMakeLists.txt rename to Exec/DryRegTests/ScalarAdvDiff/CMakeLists.txt diff --git a/Exec/RegTests/ScalarAdvDiff/ERF_prob.H b/Exec/DryRegTests/ScalarAdvDiff/ERF_prob.H similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/ERF_prob.H rename to Exec/DryRegTests/ScalarAdvDiff/ERF_prob.H diff --git a/Exec/RegTests/ScalarAdvDiff/ERF_prob.cpp b/Exec/DryRegTests/ScalarAdvDiff/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/ERF_prob.cpp rename to Exec/DryRegTests/ScalarAdvDiff/ERF_prob.cpp diff --git a/Exec/RegTests/ScalarAdvDiff/GNUmakefile b/Exec/DryRegTests/ScalarAdvDiff/GNUmakefile similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/GNUmakefile rename to Exec/DryRegTests/ScalarAdvDiff/GNUmakefile diff --git a/Exec/RegTests/EkmanSpiral/Make.package b/Exec/DryRegTests/ScalarAdvDiff/Make.package similarity index 100% rename from Exec/RegTests/EkmanSpiral/Make.package rename to Exec/DryRegTests/ScalarAdvDiff/Make.package diff --git a/Exec/RegTests/ScalarAdvDiff/README b/Exec/DryRegTests/ScalarAdvDiff/README similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/README rename to Exec/DryRegTests/ScalarAdvDiff/README diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_WENO b/Exec/DryRegTests/ScalarAdvDiff/inputs_WENO similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_WENO rename to Exec/DryRegTests/ScalarAdvDiff/inputs_WENO diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_WENO_Z b/Exec/DryRegTests/ScalarAdvDiff/inputs_WENO_Z similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_WENO_Z rename to Exec/DryRegTests/ScalarAdvDiff/inputs_WENO_Z diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_adv_diff_uniformU b/Exec/DryRegTests/ScalarAdvDiff/inputs_adv_diff_uniformU similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_adv_diff_uniformU rename to Exec/DryRegTests/ScalarAdvDiff/inputs_adv_diff_uniformU diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_advdiffinflowoutflow b/Exec/DryRegTests/ScalarAdvDiff/inputs_advdiffinflowoutflow similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_advdiffinflowoutflow rename to Exec/DryRegTests/ScalarAdvDiff/inputs_advdiffinflowoutflow diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_advect_shearU b/Exec/DryRegTests/ScalarAdvDiff/inputs_advect_shearU similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_advect_shearU rename to Exec/DryRegTests/ScalarAdvDiff/inputs_advect_shearU diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_advect_shearU_msf b/Exec/DryRegTests/ScalarAdvDiff/inputs_advect_shearU_msf similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_advect_shearU_msf rename to Exec/DryRegTests/ScalarAdvDiff/inputs_advect_shearU_msf diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_advect_shearU_no_msf b/Exec/DryRegTests/ScalarAdvDiff/inputs_advect_shearU_no_msf similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_advect_shearU_no_msf rename to Exec/DryRegTests/ScalarAdvDiff/inputs_advect_shearU_no_msf diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_advect_uniformU b/Exec/DryRegTests/ScalarAdvDiff/inputs_advect_uniformU similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_advect_uniformU rename to Exec/DryRegTests/ScalarAdvDiff/inputs_advect_uniformU diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_advect_uniformU_msf b/Exec/DryRegTests/ScalarAdvDiff/inputs_advect_uniformU_msf similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_advect_uniformU_msf rename to Exec/DryRegTests/ScalarAdvDiff/inputs_advect_uniformU_msf diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_advect_uniformU_no_msf b/Exec/DryRegTests/ScalarAdvDiff/inputs_advect_uniformU_no_msf similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_advect_uniformU_no_msf rename to Exec/DryRegTests/ScalarAdvDiff/inputs_advect_uniformU_no_msf diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_diffuse_gaussian b/Exec/DryRegTests/ScalarAdvDiff/inputs_diffuse_gaussian similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_diffuse_gaussian rename to Exec/DryRegTests/ScalarAdvDiff/inputs_diffuse_gaussian diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_diffuse_msf b/Exec/DryRegTests/ScalarAdvDiff/inputs_diffuse_msf similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_diffuse_msf rename to Exec/DryRegTests/ScalarAdvDiff/inputs_diffuse_msf diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_diffuse_no_msf b/Exec/DryRegTests/ScalarAdvDiff/inputs_diffuse_no_msf similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_diffuse_no_msf rename to Exec/DryRegTests/ScalarAdvDiff/inputs_diffuse_no_msf diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_diffuse_sine b/Exec/DryRegTests/ScalarAdvDiff/inputs_diffuse_sine similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_diffuse_sine rename to Exec/DryRegTests/ScalarAdvDiff/inputs_diffuse_sine diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_ml b/Exec/DryRegTests/ScalarAdvDiff/inputs_ml similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_ml rename to Exec/DryRegTests/ScalarAdvDiff/inputs_ml diff --git a/Exec/RegTests/ScalarAdvDiff/inputs_test_rayleigh b/Exec/DryRegTests/ScalarAdvDiff/inputs_test_rayleigh similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/inputs_test_rayleigh rename to Exec/DryRegTests/ScalarAdvDiff/inputs_test_rayleigh diff --git a/Exec/RegTests/ScalarAdvDiff/prob.cpp.convergence b/Exec/DryRegTests/ScalarAdvDiff/prob.cpp.convergence similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/prob.cpp.convergence rename to Exec/DryRegTests/ScalarAdvDiff/prob.cpp.convergence diff --git a/Exec/RegTests/StokesSecondProblem/CMakeLists.txt b/Exec/DryRegTests/StokesSecondProblem/CMakeLists.txt similarity index 100% rename from Exec/RegTests/StokesSecondProblem/CMakeLists.txt rename to Exec/DryRegTests/StokesSecondProblem/CMakeLists.txt diff --git a/Exec/RegTests/StokesSecondProblem/ERF_prob.H b/Exec/DryRegTests/StokesSecondProblem/ERF_prob.H similarity index 100% rename from Exec/RegTests/StokesSecondProblem/ERF_prob.H rename to Exec/DryRegTests/StokesSecondProblem/ERF_prob.H diff --git a/Exec/RegTests/StokesSecondProblem/ERF_prob.cpp b/Exec/DryRegTests/StokesSecondProblem/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/StokesSecondProblem/ERF_prob.cpp rename to Exec/DryRegTests/StokesSecondProblem/ERF_prob.cpp diff --git a/Exec/RegTests/StokesSecondProblem/GNUmakefile b/Exec/DryRegTests/StokesSecondProblem/GNUmakefile similarity index 100% rename from Exec/RegTests/StokesSecondProblem/GNUmakefile rename to Exec/DryRegTests/StokesSecondProblem/GNUmakefile diff --git a/Exec/RegTests/StokesSecondProblem/Make.package b/Exec/DryRegTests/StokesSecondProblem/Make.package similarity index 100% rename from Exec/RegTests/StokesSecondProblem/Make.package rename to Exec/DryRegTests/StokesSecondProblem/Make.package diff --git a/Exec/RegTests/StokesSecondProblem/inputs b/Exec/DryRegTests/StokesSecondProblem/inputs similarity index 100% rename from Exec/RegTests/StokesSecondProblem/inputs rename to Exec/DryRegTests/StokesSecondProblem/inputs diff --git a/Exec/RegTests/StokesSecondProblem/inputs_stretched_z_levels b/Exec/DryRegTests/StokesSecondProblem/inputs_stretched_z_levels similarity index 100% rename from Exec/RegTests/StokesSecondProblem/inputs_stretched_z_levels rename to Exec/DryRegTests/StokesSecondProblem/inputs_stretched_z_levels diff --git a/Exec/RegTests/TaylorGreenVortex/CMakeLists.txt b/Exec/DryRegTests/TaylorGreenVortex/CMakeLists.txt similarity index 100% rename from Exec/RegTests/TaylorGreenVortex/CMakeLists.txt rename to Exec/DryRegTests/TaylorGreenVortex/CMakeLists.txt diff --git a/Exec/RegTests/TaylorGreenVortex/ERF_prob.H b/Exec/DryRegTests/TaylorGreenVortex/ERF_prob.H similarity index 100% rename from Exec/RegTests/TaylorGreenVortex/ERF_prob.H rename to Exec/DryRegTests/TaylorGreenVortex/ERF_prob.H diff --git a/Exec/RegTests/TaylorGreenVortex/ERF_prob.cpp b/Exec/DryRegTests/TaylorGreenVortex/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/TaylorGreenVortex/ERF_prob.cpp rename to Exec/DryRegTests/TaylorGreenVortex/ERF_prob.cpp diff --git a/Exec/RegTests/TaylorGreenVortex/GNUmakefile b/Exec/DryRegTests/TaylorGreenVortex/GNUmakefile similarity index 100% rename from Exec/RegTests/TaylorGreenVortex/GNUmakefile rename to Exec/DryRegTests/TaylorGreenVortex/GNUmakefile diff --git a/Exec/RegTests/IsentropicVortex/Make.package b/Exec/DryRegTests/TaylorGreenVortex/Make.package similarity index 100% rename from Exec/RegTests/IsentropicVortex/Make.package rename to Exec/DryRegTests/TaylorGreenVortex/Make.package diff --git a/Exec/RegTests/TaylorGreenVortex/README b/Exec/DryRegTests/TaylorGreenVortex/README similarity index 100% rename from Exec/RegTests/TaylorGreenVortex/README rename to Exec/DryRegTests/TaylorGreenVortex/README diff --git a/Exec/RegTests/TaylorGreenVortex/inputs_advdiff b/Exec/DryRegTests/TaylorGreenVortex/inputs_advdiff similarity index 100% rename from Exec/RegTests/TaylorGreenVortex/inputs_advdiff rename to Exec/DryRegTests/TaylorGreenVortex/inputs_advdiff diff --git a/Exec/RegTests/TaylorGreenVortex/inputs_advonly b/Exec/DryRegTests/TaylorGreenVortex/inputs_advonly similarity index 100% rename from Exec/RegTests/TaylorGreenVortex/inputs_advonly rename to Exec/DryRegTests/TaylorGreenVortex/inputs_advonly diff --git a/Exec/RegTests/TaylorGreenVortex/inputs_multilevel b/Exec/DryRegTests/TaylorGreenVortex/inputs_multilevel similarity index 100% rename from Exec/RegTests/TaylorGreenVortex/inputs_multilevel rename to Exec/DryRegTests/TaylorGreenVortex/inputs_multilevel diff --git a/Exec/RegTests/Terrain2d_Cylinder/CMakeLists.txt b/Exec/DryRegTests/Terrain2d_Cylinder/CMakeLists.txt similarity index 100% rename from Exec/RegTests/Terrain2d_Cylinder/CMakeLists.txt rename to Exec/DryRegTests/Terrain2d_Cylinder/CMakeLists.txt diff --git a/Exec/RegTests/Terrain2d_Cylinder/ERF_prob.H b/Exec/DryRegTests/Terrain2d_Cylinder/ERF_prob.H similarity index 100% rename from Exec/RegTests/Terrain2d_Cylinder/ERF_prob.H rename to Exec/DryRegTests/Terrain2d_Cylinder/ERF_prob.H diff --git a/Exec/RegTests/Terrain2d_Cylinder/ERF_prob.cpp b/Exec/DryRegTests/Terrain2d_Cylinder/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/Terrain2d_Cylinder/ERF_prob.cpp rename to Exec/DryRegTests/Terrain2d_Cylinder/ERF_prob.cpp diff --git a/Exec/RegTests/Terrain2d_Cylinder/GNUmakefile b/Exec/DryRegTests/Terrain2d_Cylinder/GNUmakefile similarity index 100% rename from Exec/RegTests/Terrain2d_Cylinder/GNUmakefile rename to Exec/DryRegTests/Terrain2d_Cylinder/GNUmakefile diff --git a/Exec/RegTests/ParticlesOverWoA/Make.package b/Exec/DryRegTests/Terrain2d_Cylinder/Make.package similarity index 100% rename from Exec/RegTests/ParticlesOverWoA/Make.package rename to Exec/DryRegTests/Terrain2d_Cylinder/Make.package diff --git a/Exec/RegTests/Terrain2d_Cylinder/inputs b/Exec/DryRegTests/Terrain2d_Cylinder/inputs similarity index 100% rename from Exec/RegTests/Terrain2d_Cylinder/inputs rename to Exec/DryRegTests/Terrain2d_Cylinder/inputs diff --git a/Exec/RegTests/Terrain2d_Cylinder/inputs.amr b/Exec/DryRegTests/Terrain2d_Cylinder/inputs.amr similarity index 100% rename from Exec/RegTests/Terrain2d_Cylinder/inputs.amr rename to Exec/DryRegTests/Terrain2d_Cylinder/inputs.amr diff --git a/Exec/RegTests/Terrain2d_Cylinder/inputs_most_test b/Exec/DryRegTests/Terrain2d_Cylinder/inputs_most_test similarity index 100% rename from Exec/RegTests/Terrain2d_Cylinder/inputs_most_test rename to Exec/DryRegTests/Terrain2d_Cylinder/inputs_most_test diff --git a/Exec/RegTests/Terrain2d_Cylinder/inputs_stretched_z_levels b/Exec/DryRegTests/Terrain2d_Cylinder/inputs_stretched_z_levels similarity index 100% rename from Exec/RegTests/Terrain2d_Cylinder/inputs_stretched_z_levels rename to Exec/DryRegTests/Terrain2d_Cylinder/inputs_stretched_z_levels diff --git a/Exec/RegTests/Terrain2d_Cylinder/inputs_verification_final b/Exec/DryRegTests/Terrain2d_Cylinder/inputs_verification_final similarity index 100% rename from Exec/RegTests/Terrain2d_Cylinder/inputs_verification_final rename to Exec/DryRegTests/Terrain2d_Cylinder/inputs_verification_final diff --git a/Exec/RegTests/Terrain3d_Hemisphere/CMakeLists.txt b/Exec/DryRegTests/Terrain3d_Hemisphere/CMakeLists.txt similarity index 100% rename from Exec/RegTests/Terrain3d_Hemisphere/CMakeLists.txt rename to Exec/DryRegTests/Terrain3d_Hemisphere/CMakeLists.txt diff --git a/Exec/RegTests/Terrain3d_Hemisphere/ERF_prob.H b/Exec/DryRegTests/Terrain3d_Hemisphere/ERF_prob.H similarity index 100% rename from Exec/RegTests/Terrain3d_Hemisphere/ERF_prob.H rename to Exec/DryRegTests/Terrain3d_Hemisphere/ERF_prob.H diff --git a/Exec/RegTests/Terrain3d_Hemisphere/ERF_prob.cpp b/Exec/DryRegTests/Terrain3d_Hemisphere/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/Terrain3d_Hemisphere/ERF_prob.cpp rename to Exec/DryRegTests/Terrain3d_Hemisphere/ERF_prob.cpp diff --git a/Exec/RegTests/Terrain3d_Hemisphere/GNUmakefile b/Exec/DryRegTests/Terrain3d_Hemisphere/GNUmakefile similarity index 100% rename from Exec/RegTests/Terrain3d_Hemisphere/GNUmakefile rename to Exec/DryRegTests/Terrain3d_Hemisphere/GNUmakefile diff --git a/Exec/RegTests/ScalarAdvDiff/Make.package b/Exec/DryRegTests/Terrain3d_Hemisphere/Make.package similarity index 100% rename from Exec/RegTests/ScalarAdvDiff/Make.package rename to Exec/DryRegTests/Terrain3d_Hemisphere/Make.package diff --git a/Exec/RegTests/Terrain3d_Hemisphere/inputs b/Exec/DryRegTests/Terrain3d_Hemisphere/inputs similarity index 100% rename from Exec/RegTests/Terrain3d_Hemisphere/inputs rename to Exec/DryRegTests/Terrain3d_Hemisphere/inputs diff --git a/Exec/RegTests/Terrain3d_Hemisphere/inputs.amr b/Exec/DryRegTests/Terrain3d_Hemisphere/inputs.amr similarity index 100% rename from Exec/RegTests/Terrain3d_Hemisphere/inputs.amr rename to Exec/DryRegTests/Terrain3d_Hemisphere/inputs.amr diff --git a/Exec/RegTests/Terrain3d_Hemisphere/inputs_most_test b/Exec/DryRegTests/Terrain3d_Hemisphere/inputs_most_test similarity index 100% rename from Exec/RegTests/Terrain3d_Hemisphere/inputs_most_test rename to Exec/DryRegTests/Terrain3d_Hemisphere/inputs_most_test diff --git a/Exec/RegTests/Terrain3d_Hemisphere/run_3d.sh b/Exec/DryRegTests/Terrain3d_Hemisphere/run_3d.sh similarity index 100% rename from Exec/RegTests/Terrain3d_Hemisphere/run_3d.sh rename to Exec/DryRegTests/Terrain3d_Hemisphere/run_3d.sh diff --git a/Exec/RegTests/TurbulentInflow/CMakeLists.txt b/Exec/DryRegTests/TurbulentInflow/CMakeLists.txt similarity index 100% rename from Exec/RegTests/TurbulentInflow/CMakeLists.txt rename to Exec/DryRegTests/TurbulentInflow/CMakeLists.txt diff --git a/Exec/RegTests/TurbulentInflow/ERF_prob.H b/Exec/DryRegTests/TurbulentInflow/ERF_prob.H similarity index 100% rename from Exec/RegTests/TurbulentInflow/ERF_prob.H rename to Exec/DryRegTests/TurbulentInflow/ERF_prob.H diff --git a/Exec/RegTests/TurbulentInflow/ERF_prob.cpp b/Exec/DryRegTests/TurbulentInflow/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/TurbulentInflow/ERF_prob.cpp rename to Exec/DryRegTests/TurbulentInflow/ERF_prob.cpp diff --git a/Exec/RegTests/TurbulentInflow/GNUmakefile b/Exec/DryRegTests/TurbulentInflow/GNUmakefile similarity index 100% rename from Exec/RegTests/TurbulentInflow/GNUmakefile rename to Exec/DryRegTests/TurbulentInflow/GNUmakefile diff --git a/Exec/RegTests/TurbulentInflow/InflowPerturbationGeneration_HowTo.pdf b/Exec/DryRegTests/TurbulentInflow/InflowPerturbationGeneration_HowTo.pdf similarity index 100% rename from Exec/RegTests/TurbulentInflow/InflowPerturbationGeneration_HowTo.pdf rename to Exec/DryRegTests/TurbulentInflow/InflowPerturbationGeneration_HowTo.pdf diff --git a/Exec/RegTests/TaylorGreenVortex/Make.package b/Exec/DryRegTests/TurbulentInflow/Make.package similarity index 100% rename from Exec/RegTests/TaylorGreenVortex/Make.package rename to Exec/DryRegTests/TurbulentInflow/Make.package diff --git a/Exec/RegTests/TurbulentInflow/README b/Exec/DryRegTests/TurbulentInflow/README similarity index 100% rename from Exec/RegTests/TurbulentInflow/README rename to Exec/DryRegTests/TurbulentInflow/README diff --git a/Exec/RegTests/TurbulentInflow/compressible_direct_inputs b/Exec/DryRegTests/TurbulentInflow/compressible_direct_inputs similarity index 100% rename from Exec/RegTests/TurbulentInflow/compressible_direct_inputs rename to Exec/DryRegTests/TurbulentInflow/compressible_direct_inputs diff --git a/Exec/RegTests/TurbulentInflow/compressible_source_inputs b/Exec/DryRegTests/TurbulentInflow/compressible_source_inputs similarity index 100% rename from Exec/RegTests/TurbulentInflow/compressible_source_inputs rename to Exec/DryRegTests/TurbulentInflow/compressible_source_inputs diff --git a/Exec/RegTests/TurbulentInflow/generateLogLawProfile.py b/Exec/DryRegTests/TurbulentInflow/generateLogLawProfile.py similarity index 100% rename from Exec/RegTests/TurbulentInflow/generateLogLawProfile.py rename to Exec/DryRegTests/TurbulentInflow/generateLogLawProfile.py diff --git a/Exec/RegTests/TurbulentInflow/incompressible_direct_inputs b/Exec/DryRegTests/TurbulentInflow/incompressible_direct_inputs similarity index 100% rename from Exec/RegTests/TurbulentInflow/incompressible_direct_inputs rename to Exec/DryRegTests/TurbulentInflow/incompressible_direct_inputs diff --git a/Exec/RegTests/TurbulentInflow/incompressible_source_inputs b/Exec/DryRegTests/TurbulentInflow/incompressible_source_inputs similarity index 100% rename from Exec/RegTests/TurbulentInflow/incompressible_source_inputs rename to Exec/DryRegTests/TurbulentInflow/incompressible_source_inputs diff --git a/Exec/RegTests/TurbulentInflow/sourceRun.sh b/Exec/DryRegTests/TurbulentInflow/sourceRun.sh similarity index 100% rename from Exec/RegTests/TurbulentInflow/sourceRun.sh rename to Exec/DryRegTests/TurbulentInflow/sourceRun.sh diff --git a/Exec/RegTests/WPS_Test/CMakeLists.txt b/Exec/DryRegTests/WPS_Test/CMakeLists.txt similarity index 100% rename from Exec/RegTests/WPS_Test/CMakeLists.txt rename to Exec/DryRegTests/WPS_Test/CMakeLists.txt diff --git a/Exec/RegTests/WPS_Test/ERF_prob.H b/Exec/DryRegTests/WPS_Test/ERF_prob.H similarity index 100% rename from Exec/RegTests/WPS_Test/ERF_prob.H rename to Exec/DryRegTests/WPS_Test/ERF_prob.H diff --git a/Exec/RegTests/WPS_Test/ERF_prob.cpp b/Exec/DryRegTests/WPS_Test/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/WPS_Test/ERF_prob.cpp rename to Exec/DryRegTests/WPS_Test/ERF_prob.cpp diff --git a/Exec/RegTests/WPS_Test/GNUmakefile b/Exec/DryRegTests/WPS_Test/GNUmakefile similarity index 100% rename from Exec/RegTests/WPS_Test/GNUmakefile rename to Exec/DryRegTests/WPS_Test/GNUmakefile diff --git a/Exec/RegTests/Terrain2d_Cylinder/Make.package b/Exec/DryRegTests/WPS_Test/Make.package similarity index 100% rename from Exec/RegTests/Terrain2d_Cylinder/Make.package rename to Exec/DryRegTests/WPS_Test/Make.package diff --git a/Exec/RegTests/WPS_Test/README b/Exec/DryRegTests/WPS_Test/README similarity index 100% rename from Exec/RegTests/WPS_Test/README rename to Exec/DryRegTests/WPS_Test/README diff --git a/Exec/RegTests/WPS_Test/inputs_real_ChisholmView b/Exec/DryRegTests/WPS_Test/inputs_real_ChisholmView similarity index 100% rename from Exec/RegTests/WPS_Test/inputs_real_ChisholmView rename to Exec/DryRegTests/WPS_Test/inputs_real_ChisholmView diff --git a/Exec/RegTests/WitchOfAgnesi/CMakeLists.txt b/Exec/DryRegTests/WitchOfAgnesi/CMakeLists.txt similarity index 100% rename from Exec/RegTests/WitchOfAgnesi/CMakeLists.txt rename to Exec/DryRegTests/WitchOfAgnesi/CMakeLists.txt diff --git a/Exec/RegTests/WitchOfAgnesi/ERF_prob.H b/Exec/DryRegTests/WitchOfAgnesi/ERF_prob.H similarity index 100% rename from Exec/RegTests/WitchOfAgnesi/ERF_prob.H rename to Exec/DryRegTests/WitchOfAgnesi/ERF_prob.H diff --git a/Exec/RegTests/WitchOfAgnesi/ERF_prob.cpp b/Exec/DryRegTests/WitchOfAgnesi/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/WitchOfAgnesi/ERF_prob.cpp rename to Exec/DryRegTests/WitchOfAgnesi/ERF_prob.cpp diff --git a/Exec/RegTests/WitchOfAgnesi/GNUmakefile b/Exec/DryRegTests/WitchOfAgnesi/GNUmakefile similarity index 100% rename from Exec/RegTests/WitchOfAgnesi/GNUmakefile rename to Exec/DryRegTests/WitchOfAgnesi/GNUmakefile diff --git a/Exec/RegTests/Terrain3d_Hemisphere/Make.package b/Exec/DryRegTests/WitchOfAgnesi/Make.package similarity index 100% rename from Exec/RegTests/Terrain3d_Hemisphere/Make.package rename to Exec/DryRegTests/WitchOfAgnesi/Make.package diff --git a/Exec/RegTests/WitchOfAgnesi/README b/Exec/DryRegTests/WitchOfAgnesi/README similarity index 100% rename from Exec/RegTests/WitchOfAgnesi/README rename to Exec/DryRegTests/WitchOfAgnesi/README diff --git a/Exec/RegTests/WitchOfAgnesi/input_sounding b/Exec/DryRegTests/WitchOfAgnesi/input_sounding similarity index 100% rename from Exec/RegTests/WitchOfAgnesi/input_sounding rename to Exec/DryRegTests/WitchOfAgnesi/input_sounding diff --git a/Exec/RegTests/WitchOfAgnesi/inputs b/Exec/DryRegTests/WitchOfAgnesi/inputs similarity index 100% rename from Exec/RegTests/WitchOfAgnesi/inputs rename to Exec/DryRegTests/WitchOfAgnesi/inputs diff --git a/Exec/RegTests/WitchOfAgnesi/inputs_most_test b/Exec/DryRegTests/WitchOfAgnesi/inputs_most_test similarity index 100% rename from Exec/RegTests/WitchOfAgnesi/inputs_most_test rename to Exec/DryRegTests/WitchOfAgnesi/inputs_most_test diff --git a/Exec/RegTests/WitchOfAgnesi/inputs_static_twolevel b/Exec/DryRegTests/WitchOfAgnesi/inputs_static_twolevel similarity index 100% rename from Exec/RegTests/WitchOfAgnesi/inputs_static_twolevel rename to Exec/DryRegTests/WitchOfAgnesi/inputs_static_twolevel diff --git a/Exec/RegTests/WitchOfAgnesi/inputs_zlevels b/Exec/DryRegTests/WitchOfAgnesi/inputs_zlevels similarity index 100% rename from Exec/RegTests/WitchOfAgnesi/inputs_zlevels rename to Exec/DryRegTests/WitchOfAgnesi/inputs_zlevels diff --git a/Exec/RegTests/Bomex/CMakeLists.txt b/Exec/MoistRegTests/Bomex/CMakeLists.txt similarity index 100% rename from Exec/RegTests/Bomex/CMakeLists.txt rename to Exec/MoistRegTests/Bomex/CMakeLists.txt diff --git a/Exec/RegTests/Bomex/ERF_prob.H b/Exec/MoistRegTests/Bomex/ERF_prob.H similarity index 100% rename from Exec/RegTests/Bomex/ERF_prob.H rename to Exec/MoistRegTests/Bomex/ERF_prob.H diff --git a/Exec/RegTests/Bomex/ERF_prob.cpp b/Exec/MoistRegTests/Bomex/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/Bomex/ERF_prob.cpp rename to Exec/MoistRegTests/Bomex/ERF_prob.cpp diff --git a/Exec/RegTests/Bomex/GNUmakefile b/Exec/MoistRegTests/Bomex/GNUmakefile similarity index 89% rename from Exec/RegTests/Bomex/GNUmakefile rename to Exec/MoistRegTests/Bomex/GNUmakefile index d94c15c2d..23a7b5683 100644 --- a/Exec/RegTests/Bomex/GNUmakefile +++ b/Exec/MoistRegTests/Bomex/GNUmakefile @@ -30,5 +30,5 @@ USE_ASSERTION = TRUE Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/Bomex +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/MoistRegTests/Bomex include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/RegTests/TurbulentInflow/Make.package b/Exec/MoistRegTests/Bomex/Make.package similarity index 100% rename from Exec/RegTests/TurbulentInflow/Make.package rename to Exec/MoistRegTests/Bomex/Make.package diff --git a/Exec/RegTests/Bomex/README b/Exec/MoistRegTests/Bomex/README similarity index 100% rename from Exec/RegTests/Bomex/README rename to Exec/MoistRegTests/Bomex/README diff --git a/Exec/RegTests/Bomex/input_Kessler b/Exec/MoistRegTests/Bomex/input_Kessler similarity index 100% rename from Exec/RegTests/Bomex/input_Kessler rename to Exec/MoistRegTests/Bomex/input_Kessler diff --git a/Exec/RegTests/Bomex/input_SAM b/Exec/MoistRegTests/Bomex/input_SAM similarity index 100% rename from Exec/RegTests/Bomex/input_SAM rename to Exec/MoistRegTests/Bomex/input_SAM diff --git a/Exec/RegTests/Bomex/input_sounding b/Exec/MoistRegTests/Bomex/input_sounding similarity index 100% rename from Exec/RegTests/Bomex/input_sounding rename to Exec/MoistRegTests/Bomex/input_sounding diff --git a/Exec/RegTests/Bubble/CMakeLists.txt b/Exec/MoistRegTests/Bubble/CMakeLists.txt similarity index 100% rename from Exec/RegTests/Bubble/CMakeLists.txt rename to Exec/MoistRegTests/Bubble/CMakeLists.txt diff --git a/Exec/RegTests/Bubble/ERF_prob.H b/Exec/MoistRegTests/Bubble/ERF_prob.H similarity index 100% rename from Exec/RegTests/Bubble/ERF_prob.H rename to Exec/MoistRegTests/Bubble/ERF_prob.H diff --git a/Exec/RegTests/Bubble/ERF_prob.cpp b/Exec/MoistRegTests/Bubble/ERF_prob.cpp similarity index 100% rename from Exec/RegTests/Bubble/ERF_prob.cpp rename to Exec/MoistRegTests/Bubble/ERF_prob.cpp diff --git a/Exec/RegTests/Bubble/GNUmakefile b/Exec/MoistRegTests/Bubble/GNUmakefile similarity index 88% rename from Exec/RegTests/Bubble/GNUmakefile rename to Exec/MoistRegTests/Bubble/GNUmakefile index fef156b43..6f61e4185 100644 --- a/Exec/RegTests/Bubble/GNUmakefile +++ b/Exec/MoistRegTests/Bubble/GNUmakefile @@ -28,5 +28,5 @@ Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/Bubble +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/MoistRegTests/Bubble include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/RegTests/WPS_Test/Make.package b/Exec/MoistRegTests/Bubble/Make.package similarity index 100% rename from Exec/RegTests/WPS_Test/Make.package rename to Exec/MoistRegTests/Bubble/Make.package diff --git a/Exec/RegTests/Bubble/input_sounding_squall2d b/Exec/MoistRegTests/Bubble/input_sounding_squall2d similarity index 100% rename from Exec/RegTests/Bubble/input_sounding_squall2d rename to Exec/MoistRegTests/Bubble/input_sounding_squall2d diff --git a/Exec/RegTests/Bubble/inputs_BF02_dry_bubble b/Exec/MoistRegTests/Bubble/inputs_BF02_dry_bubble similarity index 100% rename from Exec/RegTests/Bubble/inputs_BF02_dry_bubble rename to Exec/MoistRegTests/Bubble/inputs_BF02_dry_bubble diff --git a/Exec/RegTests/Bubble/inputs_BF02_moist_bubble b/Exec/MoistRegTests/Bubble/inputs_BF02_moist_bubble similarity index 100% rename from Exec/RegTests/Bubble/inputs_BF02_moist_bubble rename to Exec/MoistRegTests/Bubble/inputs_BF02_moist_bubble diff --git a/Exec/RegTests/Bubble/inputs_BF02_moist_bubble_Kessler b/Exec/MoistRegTests/Bubble/inputs_BF02_moist_bubble_Kessler similarity index 100% rename from Exec/RegTests/Bubble/inputs_BF02_moist_bubble_Kessler rename to Exec/MoistRegTests/Bubble/inputs_BF02_moist_bubble_Kessler diff --git a/Exec/RegTests/Bubble/inputs_BF02_moist_bubble_OpenBC b/Exec/MoistRegTests/Bubble/inputs_BF02_moist_bubble_OpenBC similarity index 100% rename from Exec/RegTests/Bubble/inputs_BF02_moist_bubble_OpenBC rename to Exec/MoistRegTests/Bubble/inputs_BF02_moist_bubble_OpenBC diff --git a/Exec/RegTests/Bubble/inputs_BF02_moist_bubble_SAM b/Exec/MoistRegTests/Bubble/inputs_BF02_moist_bubble_SAM similarity index 100% rename from Exec/RegTests/Bubble/inputs_BF02_moist_bubble_SAM rename to Exec/MoistRegTests/Bubble/inputs_BF02_moist_bubble_SAM diff --git a/Exec/RegTests/Bubble/inputs_BF02_moist_bubble_SAM_NoIce b/Exec/MoistRegTests/Bubble/inputs_BF02_moist_bubble_SAM_NoIce similarity index 100% rename from Exec/RegTests/Bubble/inputs_BF02_moist_bubble_SAM_NoIce rename to Exec/MoistRegTests/Bubble/inputs_BF02_moist_bubble_SAM_NoIce diff --git a/Exec/RegTests/Bubble/inputs_BF02_moist_bubble_SAM_NoPrecip_NoIce b/Exec/MoistRegTests/Bubble/inputs_BF02_moist_bubble_SAM_NoPrecip_NoIce similarity index 100% rename from Exec/RegTests/Bubble/inputs_BF02_moist_bubble_SAM_NoPrecip_NoIce rename to Exec/MoistRegTests/Bubble/inputs_BF02_moist_bubble_SAM_NoPrecip_NoIce diff --git a/Exec/RegTests/Bubble/inputs_grav2d_x b/Exec/MoistRegTests/Bubble/inputs_grav2d_x similarity index 100% rename from Exec/RegTests/Bubble/inputs_grav2d_x rename to Exec/MoistRegTests/Bubble/inputs_grav2d_x diff --git a/Exec/RegTests/Bubble/inputs_squall2d_x b/Exec/MoistRegTests/Bubble/inputs_squall2d_x similarity index 100% rename from Exec/RegTests/Bubble/inputs_squall2d_x rename to Exec/MoistRegTests/Bubble/inputs_squall2d_x diff --git a/Exec/RegTests/Bubble/inputs_test_outflow b/Exec/MoistRegTests/Bubble/inputs_test_outflow similarity index 100% rename from Exec/RegTests/Bubble/inputs_test_outflow rename to Exec/MoistRegTests/Bubble/inputs_test_outflow diff --git a/Exec/SquallLine_2D/CMakeLists.txt b/Exec/MoistRegTests/SquallLine_2D/CMakeLists.txt similarity index 100% rename from Exec/SquallLine_2D/CMakeLists.txt rename to Exec/MoistRegTests/SquallLine_2D/CMakeLists.txt diff --git a/Exec/SquallLine_2D/ERF_prob.H b/Exec/MoistRegTests/SquallLine_2D/ERF_prob.H similarity index 98% rename from Exec/SquallLine_2D/ERF_prob.H rename to Exec/MoistRegTests/SquallLine_2D/ERF_prob.H index 4cdc03bdb..7fd584299 100644 --- a/Exec/SquallLine_2D/ERF_prob.H +++ b/Exec/MoistRegTests/SquallLine_2D/ERF_prob.H @@ -109,7 +109,7 @@ public: const int& khi); protected: - std::string name () override { return "Supercell"; } + std::string name () override { return "SquallLine"; } private: ProbParm parms; diff --git a/Exec/SquallLine_2D/ERF_prob.cpp b/Exec/MoistRegTests/SquallLine_2D/ERF_prob.cpp similarity index 100% rename from Exec/SquallLine_2D/ERF_prob.cpp rename to Exec/MoistRegTests/SquallLine_2D/ERF_prob.cpp diff --git a/Exec/SquallLine_2D/GNUmakefile b/Exec/MoistRegTests/SquallLine_2D/GNUmakefile similarity index 83% rename from Exec/SquallLine_2D/GNUmakefile rename to Exec/MoistRegTests/SquallLine_2D/GNUmakefile index 5705fc951..f664f464a 100644 --- a/Exec/SquallLine_2D/GNUmakefile +++ b/Exec/MoistRegTests/SquallLine_2D/GNUmakefile @@ -27,6 +27,6 @@ USE_ASSERTION = TRUE # GNU Make Bpack := ./Make.package Blocs := . -ERF_HOME := ../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/SquallLine_2D +ERF_HOME := ../../.. +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/MoistRegTests/SquallLine_2D include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/RegTests/WitchOfAgnesi/Make.package b/Exec/MoistRegTests/SquallLine_2D/Make.package similarity index 100% rename from Exec/RegTests/WitchOfAgnesi/Make.package rename to Exec/MoistRegTests/SquallLine_2D/Make.package diff --git a/Exec/SquallLine_2D/README b/Exec/MoistRegTests/SquallLine_2D/README similarity index 100% rename from Exec/SquallLine_2D/README rename to Exec/MoistRegTests/SquallLine_2D/README diff --git a/Exec/SquallLine_2D/inputs_ml b/Exec/MoistRegTests/SquallLine_2D/inputs_ml similarity index 100% rename from Exec/SquallLine_2D/inputs_ml rename to Exec/MoistRegTests/SquallLine_2D/inputs_ml diff --git a/Exec/SquallLine_2D/inputs_moisture_Gabersek b/Exec/MoistRegTests/SquallLine_2D/inputs_moisture_Gabersek similarity index 100% rename from Exec/SquallLine_2D/inputs_moisture_Gabersek rename to Exec/MoistRegTests/SquallLine_2D/inputs_moisture_Gabersek diff --git a/Exec/SquallLine_2D/inputs_moisture_SAM b/Exec/MoistRegTests/SquallLine_2D/inputs_moisture_SAM similarity index 100% rename from Exec/SquallLine_2D/inputs_moisture_SAM rename to Exec/MoistRegTests/SquallLine_2D/inputs_moisture_SAM diff --git a/Exec/SquallLine_2D/inputs_moisture_WRF b/Exec/MoistRegTests/SquallLine_2D/inputs_moisture_WRF similarity index 100% rename from Exec/SquallLine_2D/inputs_moisture_WRF rename to Exec/MoistRegTests/SquallLine_2D/inputs_moisture_WRF diff --git a/Exec/SuperCell_3D/CMakeLists.txt b/Exec/MoistRegTests/SuperCell_3D/CMakeLists.txt similarity index 100% rename from Exec/SuperCell_3D/CMakeLists.txt rename to Exec/MoistRegTests/SuperCell_3D/CMakeLists.txt diff --git a/Exec/SuperCell_3D/ERF_prob.H b/Exec/MoistRegTests/SuperCell_3D/ERF_prob.H similarity index 100% rename from Exec/SuperCell_3D/ERF_prob.H rename to Exec/MoistRegTests/SuperCell_3D/ERF_prob.H diff --git a/Exec/SuperCell_3D/ERF_prob.cpp b/Exec/MoistRegTests/SuperCell_3D/ERF_prob.cpp similarity index 99% rename from Exec/SuperCell_3D/ERF_prob.cpp rename to Exec/MoistRegTests/SuperCell_3D/ERF_prob.cpp index 164026bcd..1b596b69a 100644 --- a/Exec/SuperCell_3D/ERF_prob.cpp +++ b/Exec/MoistRegTests/SuperCell_3D/ERF_prob.cpp @@ -328,9 +328,6 @@ Problem::init_custom_pert ( const Real x_c = parms.x_c, y_c = parms.y_c, z_c = parms.z_c, x_r = parms.x_r, y_r = parms.y_r, z_r = parms.z_r, theta_c = parms.theta_c, r_c = 1.0; //const Real x_c = 0.0, z_c = 2.0e3, x_r = 10.0e3, z_r = 1.5e3, r_c = 1.0, theta_c = 3.0; - Real Rd_by_Cp = sc.rdOcp; - Rd_by_Cp = Rd_by_Cp; - Real height = parms.height; Real z_tr = parms.z_tr; diff --git a/Exec/SuperCell_3D/GNUmakefile b/Exec/MoistRegTests/SuperCell_3D/GNUmakefile similarity index 83% rename from Exec/SuperCell_3D/GNUmakefile rename to Exec/MoistRegTests/SuperCell_3D/GNUmakefile index c13672992..8a260c0f3 100644 --- a/Exec/SuperCell_3D/GNUmakefile +++ b/Exec/MoistRegTests/SuperCell_3D/GNUmakefile @@ -27,6 +27,6 @@ USE_ASSERTION = TRUE # GNU Make Bpack := ./Make.package Blocs := . -ERF_HOME := ../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/SuperCell_3D +ERF_HOME := ../../.. +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/MoistRegTests/SuperCell_3D include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/SquallLine_2D/Make.package b/Exec/MoistRegTests/SuperCell_3D/Make.package similarity index 100% rename from Exec/SquallLine_2D/Make.package rename to Exec/MoistRegTests/SuperCell_3D/Make.package diff --git a/Exec/SuperCell_3D/README b/Exec/MoistRegTests/SuperCell_3D/README similarity index 100% rename from Exec/SuperCell_3D/README rename to Exec/MoistRegTests/SuperCell_3D/README diff --git a/Exec/SuperCell_3D/inputs_Supercell_3D b/Exec/MoistRegTests/SuperCell_3D/inputs_Supercell_3D similarity index 100% rename from Exec/SuperCell_3D/inputs_Supercell_3D rename to Exec/MoistRegTests/SuperCell_3D/inputs_Supercell_3D diff --git a/Exec/RegTests/DynamicRefinement/CMakeLists.txt b/Exec/RegTests/DynamicRefinement/CMakeLists.txt deleted file mode 100644 index f5e544b89..000000000 --- a/Exec/RegTests/DynamicRefinement/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -set(erf_exe_name erf_dynamic_refinement) - -add_executable(${erf_exe_name} "") -target_sources(${erf_exe_name} - PRIVATE - ERF_prob.cpp -) - -target_include_directories(${erf_exe_name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) - -include(${CMAKE_SOURCE_DIR}/CMake/BuildERFExe.cmake) -build_erf_exe(${erf_exe_name}) diff --git a/Exec/RegTests/DynamicRefinement/ERF_prob.H b/Exec/RegTests/DynamicRefinement/ERF_prob.H deleted file mode 100644 index c759964b8..000000000 --- a/Exec/RegTests/DynamicRefinement/ERF_prob.H +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef ERF_PROB_H_ -#define ERF_PROB_H_ - -#include - -#include "AMReX_REAL.H" - -#include "ERF_prob_common.H" -#include "ERF_Constants.H" - -struct ProbParm : ProbParmDefaults { - amrex::Real p_inf = p_0; //freestream pressure [Pa] - amrex::Real T_inf = 300.0; //freestream temperature [K] - amrex::Real M_inf = 0.2; //freestream Mach number [-] - amrex::Real alpha = 0.0; //inflow angle, 0 --> x-aligned [rad] - amrex::Real gamma = Gamma; //specific heat ratio [-] - amrex::Real beta = 0.01; //non-dimensional max perturbation strength [-] - amrex::Real sigma = 1.0; //Gaussian standard deviation, i.e., spreading parameter [-] - amrex::Real R = 2.0; //characteristic length scale for grid [m] - amrex::Real xc = 0.5; //normalized x-location of vortex center [-] - amrex::Real yc = 0.5; //normalized y-location of vortex center [-] - // calculated quantiites - amrex::Real rho_0; //characteristic density [m/s] - amrex::Real a_inf; //speed of sound [m/s] - amrex::Real inv_gm1; //1/(gamma - 1) [-] -}; // namespace ProbParm - -class Problem : public ProblemBase -{ -public: - Problem(const amrex_real* problo, const amrex_real* probhi); - -#include "Prob/ERF_init_constant_density_hse.H" - - void init_custom_pert ( - const amrex::Box& bx, - const amrex::Box& xbx, - const amrex::Box& ybx, - const amrex::Box& zbx, - amrex::Array4 const& state, - amrex::Array4 const& state_pert, - amrex::Array4 const& x_vel_pert, - amrex::Array4 const& y_vel_pert, - amrex::Array4 const& z_vel_pert, - amrex::Array4 const& r_hse, - amrex::Array4 const& p_hse, - amrex::Array4 const& z_nd, - amrex::Array4 const& z_cc, - amrex::GeometryData const& geomdata, - amrex::Array4 const& mf_m, - amrex::Array4 const& mf_u, - amrex::Array4 const& mf_v, - const SolverChoice& sc) override; - -protected: - std::string name() override { return "Dynamic Refinement"; } - -private: - ProbParm parms; -}; - -#endif diff --git a/Exec/RegTests/DynamicRefinement/ERF_prob.cpp b/Exec/RegTests/DynamicRefinement/ERF_prob.cpp deleted file mode 100644 index 3f6bbd304..000000000 --- a/Exec/RegTests/DynamicRefinement/ERF_prob.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#include "ERF_prob.H" - -using namespace amrex; - -std::unique_ptr -amrex_probinit(const amrex_real* problo, const amrex_real* probhi) -{ - return std::make_unique(problo, probhi); -} - -Problem::Problem(const amrex_real* problo, const amrex_real* probhi) -{ - // Parse params - ParmParse pp("prob"); - pp.query("p_inf", parms.p_inf); - pp.query("T_inf", parms.T_inf); - pp.query("M_inf", parms.M_inf); - pp.query("alpha", parms.alpha); - pp.query("gamma", parms.gamma); - pp.query("beta", parms.beta); - pp.query("sigma", parms.sigma); - pp.query("R", parms.R); - pp.query("xc", parms.xc); - pp.query("yc", parms.yc); - - parms.xc = problo[0] + parms.xc * (probhi[0] - problo[0]); - parms.yc = problo[1] + parms.yc * (probhi[1] - problo[1]); - amrex::Print() << " vortex initialized at (" - << parms.xc << ", " - << parms.yc << ")" - << std::endl; - - parms.inv_gm1 = 1.0 / (parms.gamma - 1.0); - - amrex::Print() << " reference pressure = " << parms.p_inf << " Pa" << std::endl; - amrex::Print() << " reference temperature = " << parms.T_inf << " K" << std::endl; - amrex::Print() << " reference potential temperature (not used) = " << parms.T_0 << " K" << std::endl; - - parms.rho_0 = parms.p_inf / (R_d * parms.T_inf); - amrex::Print() << " calculated freestream air density = " - << parms.rho_0 << " kg/m^3" - << std::endl; - - parms.a_inf = std::sqrt(parms.gamma * R_d * parms.T_inf); - amrex::Print() << " calculated speed of sound, a = " - << parms.a_inf << " m/s" - << std::endl; - - amrex::Print() << " freestream u/a = " - << parms.M_inf * std::cos(parms.alpha) - << std::endl; - amrex::Print() << " freestream v/a = " - << parms.M_inf * std::sin(parms.alpha) - << std::endl; - - init_base_parms(parms.rho_0, parms.T_0); -} - -AMREX_GPU_DEVICE -static -Real -erf_vortex_Gaussian( - Real x, Real y, - Real xc, Real yc, - Real R, Real beta, - Real sigma) -{ - // Evaluate Gaussian function - const Real r2 = ((x-xc)*(x-xc) + (y-yc)*(y-yc)) / (R*R); - return beta * std::exp(-r2/(2.*sigma*sigma)); -} - -void -Problem::init_custom_pert( - const Box& bx, - const Box& xbx, - const Box& ybx, - const Box& zbx, - Array4 const& /*state*/, - Array4 const& state_pert, - Array4 const& x_vel_pert, - Array4 const& y_vel_pert, - Array4 const& z_vel_pert, - Array4 const& /*r_hse*/, - Array4 const& /*p_hse*/, - Array4 const& /*z_nd*/, - Array4 const& /*z_cc*/, - amrex::GeometryData const& geomdata, - Array4 const& /*mf_m*/, - Array4 const& /*mf_u*/, - Array4 const& /*mf_v*/, - const SolverChoice& sc) -{ - const bool use_moisture = (sc.moisture_type != MoistureType::None); - - Real xc = parms.xc; Real yc = parms.yc; - Real R = parms.R ; Real beta = parms.beta; - Real sigma = parms.sigma; - - const Real rdOcp = sc.rdOcp; - - ParallelFor(bx, [=, parms_d=parms] AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - const Real* prob_lo = geomdata.ProbLo(); - const Real* dx = geomdata.CellSize(); - const Real x = prob_lo[0] + (i + 0.5) * dx[0]; // cell center - const Real y = prob_lo[1] + (j + 0.5) * dx[1]; // cell center - - // Calculate perturbation temperature - const Real Omg = erf_vortex_Gaussian(x,y,xc,yc,R,beta,sigma); - const Real deltaT = -(parms_d.gamma - 1.0)/(2.0*sigma*sigma) * Omg*Omg; - - // Set the perturbation density - const Real rho_norm = std::pow(1.0 + deltaT, parms_d.inv_gm1); - state_pert(i, j, k, Rho_comp) = (rho_norm - 1.0) * parms_d.rho_0; - - // Initial _potential_ temperature - const Real T = (1.0 + deltaT) * parms_d.T_inf; - const Real p = std::pow(rho_norm, Gamma) / Gamma // isentropic relation - * parms_d.rho_0*parms_d.a_inf*parms_d.a_inf; - const Real rho_theta = parms_d.rho_0 * rho_norm * (T * std::pow(p_0 / p, rdOcp)); // T --> theta - state_pert(i, j, k, RhoTheta_comp) = rho_theta - parms_d.rho_0 * parms_d.T_0; // Set the perturbation rho*theta - - // Set scalar = 0 -- unused - state_pert(i, j, k, RhoScalar_comp) = 1.0 + Omg; - - if (use_moisture) { - state_pert(i, j, k, RhoQ1_comp) = 0.0; - state_pert(i, j, k, RhoQ2_comp) = 0.0; - } - }); - - // Set the x-velocity - ParallelFor(xbx, [=, parms_d=parms] AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - const Real* prob_lo = geomdata.ProbLo(); - const Real* dx = geomdata.CellSize(); - - const Real x = prob_lo[0] + i * dx[0]; // face center - const Real y = prob_lo[1] + (j + 0.5) * dx[1]; // cell center - const Real Omg = erf_vortex_Gaussian(x,y,xc,yc,R,beta,sigma); - - x_vel_pert(i, j, k) = (parms_d.M_inf * std::cos(parms_d.alpha) - - (y - parms_d.yc)/parms_d.R * Omg) * parms_d.a_inf; - }); - - // Set the y-velocity - ParallelFor(ybx, [=, parms_d=parms] AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - const Real* prob_lo = geomdata.ProbLo(); - const Real* dx = geomdata.CellSize(); - - const Real x = prob_lo[0] + (i + 0.5) * dx[0]; // cell center - const Real y = prob_lo[1] + j * dx[1]; // face center - const Real Omg = erf_vortex_Gaussian(x,y,xc,yc,R,beta,sigma); - - y_vel_pert(i, j, k) = (parms_d.M_inf * std::sin(parms_d.alpha) - + (x - parms_d.xc)/parms_d.R * Omg) * parms_d.a_inf; - }); - - // Set the z-velocity - ParallelFor(zbx, [=] AMREX_GPU_DEVICE(int i, int j, int k) noexcept - { - z_vel_pert(i, j, k) = 0.0; - }); -} - -#if 0 -AMREX_GPU_DEVICE -Real -dhdt(int /*i*/, int /*j*/, - const GpuArray /*dx*/, - const Real /*time_mt*/, const Real /*delta_t*/) -{ - return 0.; -} -#endif diff --git a/Exec/RegTests/DynamicRefinement/GNUmakefile b/Exec/RegTests/DynamicRefinement/GNUmakefile deleted file mode 100644 index 329e9d444..000000000 --- a/Exec/RegTests/DynamicRefinement/GNUmakefile +++ /dev/null @@ -1,33 +0,0 @@ -# AMReX -COMP = gnu -PRECISION = DOUBLE - -# Profiling -PROFILE = FALSE -TINY_PROFILE = FALSE -COMM_PROFILE = FALSE -TRACE_PROFILE = FALSE -MEM_PROFILE = FALSE -USE_GPROF = FALSE - -# Performance -USE_MPI = TRUE -USE_OMP = FALSE - -USE_CUDA = FALSE -USE_HIP = FALSE -USE_SYCL = FALSE - -# Debugging -DEBUG = FALSE - -TEST = TRUE -USE_ASSERTION = TRUE - -# GNU Make -Bpack := ./Make.package -Blocs := . - -ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/DynamicRefinement -include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/RegTests/DynamicRefinement/inputs_threelevel b/Exec/RegTests/DynamicRefinement/inputs_threelevel deleted file mode 100644 index b5dc591e5..000000000 --- a/Exec/RegTests/DynamicRefinement/inputs_threelevel +++ /dev/null @@ -1,83 +0,0 @@ -# ------------------ INPUTS TO MAIN PROGRAM ------------------- -max_step = 2000 - -amrex.fpe_trap_invalid = 1 - -fabarray.mfiter_tile_size = 1024 1024 1024 - -# PROBLEM SIZE & GEOMETRY -geometry.prob_lo = -6 -6 -1 -geometry.prob_hi = 6 6 1 -amr.n_cell = 96 96 4 - -amr.blocking_factor_x = 16 16 16 -amr.blocking_factor_y = 16 16 16 -amr.blocking_factor_z = 1 1 1 - -geometry.is_periodic = 1 1 0 - -zlo.type = "SlipWall" -zhi.type = "SlipWall" - -# TIME STEP CONTROL -erf.substepping_type = Implicit -erf.fixed_dt = 0.000015 - -# DIAGNOSTICS & VERBOSITY -erf.sum_interval = 1 # timesteps between computing mass -erf.v = 1 # verbosity in ERF.cpp -amr.v = 1 # verbosity in Amr.cpp - -# REFINEMENT / REGRIDDING -amr.max_level = 2 # maximum level number allowed -amr.ref_ratio_vect = 2 2 1 4 4 1 -erf.refinement_indicators = hi_scal1 hi_scal2 -erf.hi_scal1.max_level = 1 -erf.hi_scal1.field_name = scalar -erf.hi_scal1.value_greater = 1. -erf.hi_scal2.max_level = 2 -erf.hi_scal2.field_name = scalar -erf.hi_scal2.value_greater = 2. -amr.n_error_buf = 4 -erf.regrid_int = 2 -erf.cf_width = 4 # Internal relaxation (not ready w/ multiple boxes at a level) -erf.cf_set_width = 1 # Internal Dirichlet (not ready w/ multiple boxes at a level) -amr.iterate_grids = true # Prevents level 1 BA decomposition (use true to decompose) - -# CHECKPOINT FILES -erf.check_file = chk # root name of checkpoint file -erf.check_int = -100 # number of timesteps between checkpoints - -# PLOTFILES -erf.plot_file_1 = plt # prefix of plotfile name -erf.plot_int_1 = 1 # number of timesteps between plotfiles -erf.plot_vars_1 = density rhotheta x_velocity y_velocity z_velocity pressure theta temp scalar pres_hse dens_hse pert_pres pert_dens mapfac - -# SOLVER CHOICE -erf.alpha_T = 0.0 -erf.alpha_C = 0.0 -erf.use_gravity = false - -erf.les_type = "None" -erf.molec_diff_type = "None" -erf.dynamicViscosity = 0.0 - -erf.init_type = "uniform" - -# PROBLEM PARAMETERS -prob.p_inf = 1e5 # reference pressure [Pa] -prob.T_inf = 300. # reference temperature [K] -prob.M_inf = 1.1952286093343936 # freestream Mach number [-] -prob.alpha = 0.7853981633974483 # inflow angle, 0 --> x-aligned [rad] -prob.beta = 1.1088514254079065 # non-dimensional max perturbation strength [-] -prob.R = 1.0 # characteristic length scale for grid [m] -prob.sigma = 1.0 # Gaussian standard deviation [-] - -# PROBLEM PARAMETERS - STATIONARY -#prob.M_inf = 0.0 # freestream Mach number [-] -#prob.alpha = 0.0 # inflow angle, 0 --> x-aligned [rad] -#prob.gamma = 1.4 # specific heat ratio [-] -#prob.beta = 0.05 # non-dimensional max perturbation strength [-] - - - diff --git a/Exec/RegTests/DynamicRefinement/inputs_twolevel b/Exec/RegTests/DynamicRefinement/inputs_twolevel deleted file mode 100644 index ab3fe43d2..000000000 --- a/Exec/RegTests/DynamicRefinement/inputs_twolevel +++ /dev/null @@ -1,87 +0,0 @@ -# ------------------ INPUTS TO MAIN PROGRAM ------------------- -max_step = 2000 - -erf.coupling_type = TwoWay -erf.cf_width = 0 # Internal relaxation -erf.cf_set_width = 0 # Internal Dirichlet - -amrex.fpe_trap_invalid = 1 - -fabarray.mfiter_tile_size = 1024 1024 1024 - -# PROBLEM SIZE & GEOMETRY -geometry.prob_lo = -6 -6 -1 -geometry.prob_hi = 6 6 1 -amr.n_cell = 96 96 4 - -amr.max_grid_size_x = 128 128 -amr.max_grid_size_y = 128 128 - -amr.max_grid_size_x = 128 128 -amr.max_grid_size_y = 128 32 - -amr.blocking_factor_z = 1 1 - -geometry.is_periodic = 1 1 0 - -zlo.type = "SlipWall" -zhi.type = "SlipWall" - -# TIME STEP CONTROL -erf.substepping_type = None -erf.fixed_dt = 0.000015 -erf.fixed_fast_dt = 0.000005 - -# DIAGNOSTICS & VERBOSITY -erf.sum_interval = 1 # timesteps between computing mass -erf.v = 1 # verbosity in ERF.cpp -amr.v = 1 # verbosity in Amr.cpp - -# REFINEMENT / REGRIDDING -amr.max_level = 1 # maximum level number allowed -amr.ref_ratio_vect = 3 3 1 -amr.ref_ratio_vect = 2 2 1 -erf.refinement_indicators = hi_scal1 -erf.hi_scal1.max_level = 1 -erf.hi_scal1.field_name = scalar -erf.hi_scal1.value_greater = 1. -amr.n_error_buf = 4 -erf.regrid_int = 2 - -# CHECKPOINT FILES -erf.check_file = chk # root name of checkpoint file -erf.check_int = 200 # number of timesteps between checkpoints - -# PLOTFILES -erf.plot_file_1 = plt # prefix of plotfile name -erf.plot_int_1 = 50 # number of timesteps between plotfiles -erf.plot_vars_1 = density x_velocity y_velocity z_velocity pressure theta temp scalar pres_hse dens_hse pert_pres pert_dens - -# SOLVER CHOICE -erf.alpha_T = 0.0 -erf.alpha_C = 0.0 -erf.use_gravity = false - -erf.les_type = "None" -erf.molec_diff_type = "None" -erf.dynamicViscosity = 0.0 - -erf.init_type = "uniform" - -# PROBLEM PARAMETERS -prob.p_inf = 1e5 # reference pressure [Pa] -prob.T_inf = 300. # reference temperature [K] -prob.M_inf = 1.1952286093343936 # freestream Mach number [-] -prob.alpha = 0.7853981633974483 # inflow angle, 0 --> x-aligned [rad] -prob.beta = 1.1088514254079065 # non-dimensional max perturbation strength [-] -prob.R = 1.0 # characteristic length scale for grid [m] -prob.sigma = 1.0 # Gaussian standard deviation [-] - -# PROBLEM PARAMETERS - STATIONARY -#prob.M_inf = 0.0 # freestream Mach number [-] -#prob.alpha = 0.0 # inflow angle, 0 --> x-aligned [rad] -#prob.gamma = 1.4 # specific heat ratio [-] -#prob.beta = 0.05 # non-dimensional max perturbation strength [-] - - - diff --git a/Exec/SuperCell_3D/Make.package b/Exec/SuperCell_3D/Make.package deleted file mode 100644 index 5fc21f61c..000000000 --- a/Exec/SuperCell_3D/Make.package +++ /dev/null @@ -1,2 +0,0 @@ -CEXE_headers += ERF_prob.H -CEXE_sources += ERF_prob.cpp diff --git a/Tests/CTestList.cmake b/Tests/CTestList.cmake index 231bdf855..e4eb44dd8 100644 --- a/Tests/CTestList.cmake +++ b/Tests/CTestList.cmake @@ -102,86 +102,84 @@ endfunction(add_test_0) # Regression tests #============================================================================= if(WIN32) -#add_test_r(Bubble_DensityCurrent "Bubble/bubble.exe" "plt00010") -add_test_r(CouetteFlow_x "RegTests/Couette_Poiseuille/*/erf_couette_poiseuille.exe" "plt00050") -add_test_r(CouetteFlow_y "RegTests/Couette_Poiseuille/*/erf_couette_poiseuille.exe" "plt00050") -add_test_r(DensityCurrent "RegTests/DensityCurrent/*/erf_density_current.exe" "plt00010") -add_test_r(DensityCurrent_detJ2 "RegTests/DensityCurrent/*/erf_density_current.exe" "plt00010") -add_test_r(DensityCurrent_detJ2_nosub "RegTests/DensityCurrent/*/erf_density_current.exe" "plt00020") -add_test_r(DensityCurrent_detJ2_MT "RegTests/DensityCurrent/*/erf_density_current.exe" "plt00010") -add_test_r(EkmanSpiral "RegTests/EkmanSpiral/*/erf_ekman_spiral.exe" "plt00010") -add_test_r(IsentropicVortexStationary "RegTests/IsentropicVortex/*/erf_isentropic_vortex.exe" "plt00010") -add_test_r(IsentropicVortexAdvecting "RegTests/IsentropicVortex/*/erf_isentropic_vortex.exe" "plt00010") -add_test_r(IVA_NumDiff "RegTests/IsentropicVortex/*/erf_isentropic_vortex.exe" "plt00010") +add_test_r(CouetteFlow_x "DryRegTests/Couette_Poiseuille/*/erf_couette_poiseuille.exe" "plt00050") +add_test_r(CouetteFlow_y "DryRegTests/Couette_Poiseuille/*/erf_couette_poiseuille.exe" "plt00050") +add_test_r(DensityCurrent "DryRegTests/DensityCurrent/*/erf_density_current.exe" "plt00010") +add_test_r(DensityCurrent_detJ2 "DryRegTests/DensityCurrent/*/erf_density_current.exe" "plt00010") +add_test_r(DensityCurrent_detJ2_nosub "DryRegTests/DensityCurrent/*/erf_density_current.exe" "plt00020") +add_test_r(DensityCurrent_detJ2_MT "DryRegTests/DensityCurrent/*/erf_density_current.exe" "plt00010") +add_test_r(EkmanSpiral "DryRegTests/EkmanSpiral/*/erf_ekman_spiral.exe" "plt00010") +add_test_r(IsentropicVortexStationary "DryRegTests/IsentropicVortex/*/erf_isentropic_vortex.exe" "plt00010") +add_test_r(IsentropicVortexAdvecting "DryRegTests/IsentropicVortex/*/erf_isentropic_vortex.exe" "plt00010") +add_test_r(IVA_NumDiff "DryRegTests/IsentropicVortex/*/erf_isentropic_vortex.exe" "plt00010") add_test_r(MovingTerrain_nosub "DevTests/MovingTerrain/*/erf_moving_terrain.exe" "plt00020") add_test_r(MovingTerrain_sub "DevTests/MovingTerrain/*/erf_moving_terrain.exe" "plt00010") -add_test_r(PoiseuilleFlow_x "RegTests/Couette_Poiseuille/*/erf_couette_poiseuille.exe" "plt00010") -add_test_r(PoiseuilleFlow_y "RegTests/Couette_Poiseuille/*/erf_couette_poiseuille.exe" "plt00010") -add_test_r(RayleighDamping "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00100") -add_test_r(ScalarAdvectionUniformU "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") -add_test_r(ScalarAdvectionShearedU "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00080") -add_test_r(ScalarAdvDiff_order2 "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") -add_test_r(ScalarAdvDiff_order3 "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") -add_test_r(ScalarAdvDiff_order4 "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") -add_test_r(ScalarAdvDiff_order5 "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") -add_test_r(ScalarAdvDiff_order6 "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") -add_test_r(ScalarAdvDiff_weno3 "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") -add_test_d(ScalarAdvDiff_weno3z "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") -add_test_r(ScalarAdvDiff_weno5 "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") -add_test_d(ScalarAdvDiff_weno5z "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") -add_test_r(ScalarAdvDiff_wenomzq3 "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") -add_test_r(ScalarDiffusionGaussian "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") -add_test_r(ScalarDiffusionSine "RegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") -add_test_r(TaylorGreenAdvecting "RegTests/TaylorGreenVortex/*/erf_taylor_green.exe" "plt00010") -add_test_r(TaylorGreenAdvectingDiffusing "RegTests/TaylorGreenVortex/*/erf_taylor_green.exe" "plt00010") -add_test_r(MSF_NoSub_IsentropicVortexAdv "RegTests/IsentropicVortex/*/erf_isentropic_vortex.exe" "plt00010") -add_test_r(MSF_Sub_IsentropicVortexAdv "RegTests/IsentropicVortex/*/erf_isentropic_vortex.exe" "plt00010") +add_test_r(PoiseuilleFlow_x "DryRegTests/Couette_Poiseuille/*/erf_couette_poiseuille.exe" "plt00010") +add_test_r(PoiseuilleFlow_y "DryRegTests/Couette_Poiseuille/*/erf_couette_poiseuille.exe" "plt00010") +add_test_r(RayleighDamping "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00100") +add_test_r(ScalarAdvectionUniformU "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") +add_test_r(ScalarAdvectionShearedU "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00080") +add_test_r(ScalarAdvDiff_order2 "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") +add_test_r(ScalarAdvDiff_order3 "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") +add_test_r(ScalarAdvDiff_order4 "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") +add_test_r(ScalarAdvDiff_order5 "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") +add_test_r(ScalarAdvDiff_order6 "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") +add_test_r(ScalarAdvDiff_weno3 "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") +add_test_d(ScalarAdvDiff_weno3z "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") +add_test_r(ScalarAdvDiff_weno5 "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") +add_test_d(ScalarAdvDiff_weno5z "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") +add_test_r(ScalarAdvDiff_wenomzq3 "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") +add_test_r(ScalarDiffusionGaussian "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") +add_test_r(ScalarDiffusionSine "DryRegTests/ScalarAdvDiff/*/erf_scalar_advdiff.exe" "plt00020") +add_test_r(TaylorGreenAdvecting "DryRegTests/TaylorGreenVortex/*/erf_taylor_green.exe" "plt00010") +add_test_r(TaylorGreenAdvectingDiffusing "DryRegTests/TaylorGreenVortex/*/erf_taylor_green.exe" "plt00010") +add_test_r(MSF_NoSub_IsentropicVortexAdv "DryRegTests/IsentropicVortex/*/erf_isentropic_vortex.exe" "plt00010") +add_test_r(MSF_Sub_IsentropicVortexAdv "DryRegTests/IsentropicVortex/*/erf_isentropic_vortex.exe" "plt00010") add_test_r(ABL_MOST "ABL/*/erf_abl.exe" "plt00010") add_test_r(ABL_MYNN_PBL "ABL/*/erf_abl.exe" "plt00100" INPUT_SOUNDING "input_sounding_GABLS1") add_test_r(ABL_InflowFile "ABL/*/erf_abl.exe" "plt00010") -add_test_r(MoistBubble "RegTests/Bubble/*/erf_bubble.exe" "plt00010") +add_test_r(MoistBubble "MoistRegTests/Bubble/*/erf_bubble.exe" "plt00010") add_test_0(Deardorff_stationary "ABL/*/erf_abl.exe" "plt00010") else() -#add_test_r(Bubble_DensityCurrent "Bubble/bubble" "plt00010") -add_test_r(CouetteFlow_x "RegTests/Couette_Poiseuille/erf_couette_poiseuille" "plt00050") -add_test_r(CouetteFlow_y "RegTests/Couette_Poiseuille/erf_couette_poiseuille" "plt00050") -add_test_r(DensityCurrent "RegTests/DensityCurrent/erf_density_current" "plt00010") -add_test_r(DensityCurrent_detJ2 "RegTests/DensityCurrent/erf_density_current" "plt00010") -add_test_r(DensityCurrent_detJ2_nosub "RegTests/DensityCurrent/erf_density_current" "plt00020") -add_test_r(DensityCurrent_detJ2_MT "RegTests/DensityCurrent/erf_density_current" "plt00010") -add_test_r(EkmanSpiral "RegTests/EkmanSpiral/erf_ekman_spiral" "plt00010") -add_test_r(IsentropicVortexStationary "RegTests/IsentropicVortex/erf_isentropic_vortex" "plt00010") -add_test_r(IsentropicVortexAdvecting "RegTests/IsentropicVortex/erf_isentropic_vortex" "plt00010") -add_test_r(IVA_NumDiff "RegTests/IsentropicVortex/erf_isentropic_vortex" "plt00010") +add_test_r(CouetteFlow_x "DryRegTests/Couette_Poiseuille/erf_couette_poiseuille" "plt00050") +add_test_r(CouetteFlow_y "DryRegTests/Couette_Poiseuille/erf_couette_poiseuille" "plt00050") +add_test_r(DensityCurrent "DryRegTests/DensityCurrent/erf_density_current" "plt00010") +add_test_r(DensityCurrent_detJ2 "DryRegTests/DensityCurrent/erf_density_current" "plt00010") +add_test_r(DensityCurrent_detJ2_nosub "DryRegTests/DensityCurrent/erf_density_current" "plt00020") +add_test_r(DensityCurrent_detJ2_MT "DryRegTests/DensityCurrent/erf_density_current" "plt00010") +add_test_r(EkmanSpiral "DryRegTests/EkmanSpiral/erf_ekman_spiral" "plt00010") +add_test_r(IsentropicVortexStationary "DryRegTests/IsentropicVortex/erf_isentropic_vortex" "plt00010") +add_test_r(IsentropicVortexAdvecting "DryRegTests/IsentropicVortex/erf_isentropic_vortex" "plt00010") +add_test_r(IVA_NumDiff "DryRegTests/IsentropicVortex/erf_isentropic_vortex" "plt00010") add_test_r(MovingTerrain_nosub "DevTests/MovingTerrain/erf_moving_terrain" "plt00020") add_test_r(MovingTerrain_sub "DevTests/MovingTerrain/erf_moving_terrain" "plt00010") -add_test_r(PoiseuilleFlow_x "RegTests/Couette_Poiseuille/erf_couette_poiseuille" "plt00010") -add_test_r(PoiseuilleFlow_y "RegTests/Couette_Poiseuille/erf_couette_poiseuille" "plt00010") -add_test_r(RayleighDamping "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00100") -add_test_r(ScalarAdvectionUniformU "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") -add_test_r(ScalarAdvectionShearedU "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00080") -add_test_r(ScalarAdvDiff_order2 "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") -add_test_r(ScalarAdvDiff_order3 "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") -add_test_r(ScalarAdvDiff_order4 "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") -add_test_r(ScalarAdvDiff_order5 "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") -add_test_r(ScalarAdvDiff_order6 "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") -add_test_r(ScalarAdvDiff_weno3 "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") -add_test_d(ScalarAdvDiff_weno3z "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") -add_test_r(ScalarAdvDiff_weno5 "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") -add_test_d(ScalarAdvDiff_weno5z "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") -add_test_r(ScalarAdvDiff_wenomzq3 "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") -add_test_r(ScalarDiffusionGaussian "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") -add_test_r(ScalarDiffusionSine "RegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") -add_test_r(TaylorGreenAdvecting "RegTests/TaylorGreenVortex/erf_taylor_green" "plt00010") -add_test_r(TaylorGreenAdvectingDiffusing "RegTests/TaylorGreenVortex/erf_taylor_green" "plt00010") -add_test_r(MSF_NoSub_IsentropicVortexAdv "RegTests/IsentropicVortex/erf_isentropic_vortex" "plt00010") -add_test_r(MSF_Sub_IsentropicVortexAdv "RegTests/IsentropicVortex/erf_isentropic_vortex" "plt00010") +add_test_r(PoiseuilleFlow_x "DryRegTests/Couette_Poiseuille/erf_couette_poiseuille" "plt00010") +add_test_r(PoiseuilleFlow_y "DryRegTests/Couette_Poiseuille/erf_couette_poiseuille" "plt00010") +add_test_r(RayleighDamping "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00100") +add_test_r(ScalarAdvectionUniformU "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") +add_test_r(ScalarAdvectionShearedU "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00080") +add_test_r(ScalarAdvDiff_order2 "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") +add_test_r(ScalarAdvDiff_order3 "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") +add_test_r(ScalarAdvDiff_order4 "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") +add_test_r(ScalarAdvDiff_order5 "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") +add_test_r(ScalarAdvDiff_order6 "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") +add_test_r(ScalarAdvDiff_weno3 "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") +add_test_d(ScalarAdvDiff_weno3z "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") +add_test_r(ScalarAdvDiff_weno5 "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") +add_test_d(ScalarAdvDiff_weno5z "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") +add_test_r(ScalarAdvDiff_wenomzq3 "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") +add_test_r(ScalarDiffusionGaussian "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") +add_test_r(ScalarDiffusionSine "DryRegTests/ScalarAdvDiff/erf_scalar_advdiff" "plt00020") +add_test_r(TaylorGreenAdvecting "DryRegTests/TaylorGreenVortex/erf_taylor_green" "plt00010") +add_test_r(TaylorGreenAdvectingDiffusing "DryRegTests/TaylorGreenVortex/erf_taylor_green" "plt00010") +add_test_r(MSF_NoSub_IsentropicVortexAdv "DryRegTests/IsentropicVortex/erf_isentropic_vortex" "plt00010") +add_test_r(MSF_Sub_IsentropicVortexAdv "DryRegTests/IsentropicVortex/erf_isentropic_vortex" "plt00010") add_test_r(ABL_MOST "ABL/erf_abl" "plt00010") add_test_r(ABL_MYNN_PBL "ABL/erf_abl" "plt00100" INPUT_SOUNDING "input_sounding_GABLS1") add_test_r(ABL_InflowFile "ABL/erf_abl" "plt00010") -add_test_r(MoistBubble "RegTests/Bubble/erf_bubble" "plt00010") +add_test_r(MoistBubble "MoistRegTests/Bubble/erf_bubble" "plt00010") add_test_0(InitSoundingIdeal_stationary "ABL/erf_abl" "plt00010") add_test_0(Deardorff_stationary "ABL/erf_abl" "plt00010") From 5472f4fa99d908e5b7c5923f38c5c4f3decdf887 Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Mon, 4 Nov 2024 16:11:42 -0800 Subject: [PATCH 20/24] fix GNUmakefiles (#1927) * fix GNUmakefiles * update docs --- Docs/sphinx_doc/RegressionTests.rst | 64 +++++++++---------- Docs/sphinx_doc/building.rst | 12 ++-- Docs/sphinx_doc/testing.rst | 7 +- .../Couette_Poiseuille/GNUmakefile | 2 +- Exec/DryRegTests/DensityCurrent/GNUmakefile | 2 +- Exec/DryRegTests/EkmanSpiral/GNUmakefile | 2 +- Exec/DryRegTests/IsentropicVortex/GNUmakefile | 2 +- Exec/DryRegTests/ParticlesOverWoA/GNUmakefile | 2 +- Exec/DryRegTests/ScalarAdvDiff/GNUmakefile | 2 +- .../StokesSecondProblem/GNUmakefile | 2 +- .../DryRegTests/TaylorGreenVortex/GNUmakefile | 2 +- .../Terrain2d_Cylinder/GNUmakefile | 2 +- .../Terrain3d_Hemisphere/GNUmakefile | 2 +- Exec/DryRegTests/TurbulentInflow/GNUmakefile | 2 +- Exec/DryRegTests/WPS_Test/GNUmakefile | 2 +- Exec/DryRegTests/WitchOfAgnesi/GNUmakefile | 2 +- 16 files changed, 55 insertions(+), 54 deletions(-) diff --git a/Docs/sphinx_doc/RegressionTests.rst b/Docs/sphinx_doc/RegressionTests.rst index 559b41a21..e121ebef7 100644 --- a/Docs/sphinx_doc/RegressionTests.rst +++ b/Docs/sphinx_doc/RegressionTests.rst @@ -247,9 +247,9 @@ Test Location: `Tests/test_files/ScalarAdvectionUniformU`_ .. _`Tests/test_files/ScalarAdvectionUniformU`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/ScalarAdvectionUniformU -Problem Location: `Exec/RegTests/ScalarAdvDiff`_ +Problem Location: `Exec/DryRegTests/ScalarAdvDiff`_ -.. _`Exec/RegTests/ScalarAdvDiff`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/ScalarAdvDiff +.. _`Exec/DryRegTests/ScalarAdvDiff`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/ScalarAdvDiff .. |a2| image:: figures/tests/scalar_advec_uniform_u_start.png :width: 200 @@ -275,9 +275,9 @@ Test Location: `Tests/test_files/ScalarAdvectionShearedU`_ .. _`Tests/test_files/ScalarAdvectionShearedU`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/ScalarAdvectionShearedU -Problem Location: `Exec/RegTests/ScalarAdvDiff`_ +Problem Location: `Exec/DryRegTests/ScalarAdvDiff`_ -.. _`Exec/RegTests/ScalarAdvDiff`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/ScalarAdvDiff +.. _`Exec/DryRegTests/ScalarAdvDiff`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/ScalarAdvDiff .. |a3| image:: figures/tests/scalar_advec_sheared_u_start.png :width: 200 @@ -304,9 +304,9 @@ Test Location: `Tests/test_files/ScalarDiffusionGaussian`_ .. _`Tests/test_files/ScalarDiffusionGaussian`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/ScalarDiffusionGaussian -Problem Location: `Exec/RegTests/ScalarAdvDiff`_ +Problem Location: `Exec/DryRegTests/ScalarAdvDiff`_ -.. _`Exec/RegTests/ScalarAdvDiff`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/ScalarAdvDiff +.. _`Exec/DryRegTests/ScalarAdvDiff`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/ScalarAdvDiff .. |a5| image:: figures/tests/scalar_diff_start.png :width: 300 @@ -332,9 +332,9 @@ Test Location: `Tests/test_files/ScalarDiffusionSine`_ .. _`Tests/test_files/ScalarDiffusionSine`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/ScalarDiffusionSine -Problem Location: `Exec/RegTests/ScalarAdvDiff`_ +Problem Location: `Exec/DryRegTests/ScalarAdvDiff`_ -.. _`Exec/RegTests/ScalarAdvDiff`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/ScalarAdvDiff +.. _`Exec/DryRegTests/ScalarAdvDiff`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/ScalarAdvDiff .. |a6| image:: figures/tests/scalar_diff_sine_start.png :width: 300 @@ -361,9 +361,9 @@ Test Location (for 2nd order): `Tests/test_files/ScalarAdvDiff_order2`_ .. _`Tests/test_files/ScalarAdvDiff_order2`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/ScalarAdvDiff_order2 -Problem Location: `Exec/RegTests/ScalarAdvDiff`_ +Problem Location: `Exec/DryRegTests/ScalarAdvDiff`_ -.. _`Exec/RegTests/ScalarAdvDiff`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/ScalarAdvDiff +.. _`Exec/DryRegTests/ScalarAdvDiff`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/ScalarAdvDiff .. |a7| image:: figures/tests/scalar_advec_diff_start.png :width: 300 @@ -391,9 +391,9 @@ Test Location: `Tests/test_files/RayleighDamping`_ .. _`Tests/test_files/RayleighDamping`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/RayleighDamping -Problem Location: `Exec/RegTests/ScalarAdvDiff`_ +Problem Location: `Exec/DryRegTests/ScalarAdvDiff`_ -.. _`Exec/RegTests/ScalarAdvDiff`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/ScalarAdvDiff +.. _`Exec/DryRegTests/ScalarAdvDiff`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/ScalarAdvDiff Isentropic Vortex: Stationary @@ -404,9 +404,9 @@ Test Location: `Tests/test_files/IsentropicVortexStationary`_ .. _`Tests/test_files/IsentropicVortexStationary`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/IsentropicVortexStationary -Problem Location: `Exec/RegTests/IsentropicVortex`_ +Problem Location: `Exec/DryRegTests/IsentropicVortex`_ -.. _`Exec/RegTests/IsentropicVortex`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/IsentropicVortex +.. _`Exec/DryRegTests/IsentropicVortex`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/IsentropicVortex Isentropic Vortex: Advecting ---------------------------- @@ -416,9 +416,9 @@ Test Location: `Tests/test_files/IsentropicVortexAdvecting`_ .. _`Tests/test_files/IsentropicVortexAdvecting`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/IsentropicVortexAdvecting -Problem Location: `Exec/RegTests/IsentropicVortex`_ +Problem Location: `Exec/DryRegTests/IsentropicVortex`_ -.. _`Exec/RegTests/IsentropicVortex`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/IsentropicVortex +.. _`Exec/DryRegTests/IsentropicVortex`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/IsentropicVortex Taylor Green Vortex: Advection ------------------------------------------------ @@ -428,9 +428,9 @@ Test Location: `Tests/test_files/TaylorGreenAdvecting`_ .. _`Tests/test_files/TaylorGreenAdvecting`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/TaylorGreenAdvecting -Problem Location: `Exec/RegTests/TaylorGreenVortex`_ +Problem Location: `Exec/DryRegTests/TaylorGreenVortex`_ -.. _`Exec/RegTests/TaylorGreenVortex`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/TaylorGreenVortex +.. _`Exec/DryRegTests/TaylorGreenVortex`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/TaylorGreenVortex Taylor Green Vortex: Advection and Diffusion ------------------------------------------------ @@ -440,9 +440,9 @@ Test Location: `Tests/test_files/TaylorGreenAdvectingDiffusing`_ .. _`Tests/test_files/TaylorGreenAdvectingDiffusing`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/TaylorGreenAdvectingDiffusing -Problem Location: `Exec/RegTests/TaylorGreenVortex`_ +Problem Location: `Exec/DryRegTests/TaylorGreenVortex`_ -.. _`Exec/RegTests/TaylorGreenVortex`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/TaylorGreenVortex +.. _`Exec/DryRegTests/TaylorGreenVortex`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/TaylorGreenVortex .. |a8| image:: figures/tests/TGV_start.png :width: 300 @@ -472,9 +472,9 @@ Test Location: `Tests/test_files/CouetteFlow_x`_ .. _`Tests/test_files/CouetteFlow`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/CouetteFlow_x -Problem Location: `Exec/RegTests/CouetteFlow_x`_ +Problem Location: `Exec/DryRegTests/CouetteFlow_x`_ -.. _`Exec/RegTests/Couette_Poiseuille`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/Couette_Poiseuille +.. _`Exec/DryRegTests/Couette_Poiseuille`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/Couette_Poiseuille Couette Flow (y-direction) --------------------------- @@ -488,9 +488,9 @@ Test Location: `Tests/test_files/CouetteFlow_y`_ .. _`Tests/test_files/CouetteFlow`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/CouetteFlow_y -Problem Location: `Exec/RegTests/CouetteFlow_y`_ +Problem Location: `Exec/DryRegTests/CouetteFlow_y`_ -.. _`Exec/RegTests/Couette_Poiseuille`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/Couette_Poiseuille +.. _`Exec/DryRegTests/Couette_Poiseuille`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/Couette_Poiseuille Poiseuille Flow (x-direction) ----------------------------- @@ -504,9 +504,9 @@ Test Location: `Tests/test_files/PoiseuilleFlow_x`_ .. _`Tests/test_files/PoiseuilleFlow_x`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/PoiseuilleFlow_x -Problem Location: `Exec/RegTests/PoiseuilleFlow_x`_ +Problem Location: `Exec/DryRegTests/PoiseuilleFlow_x`_ -.. _`Exec/RegTests/Couette_Poiseuille`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/Couette_Poiseuille +.. _`Exec/DryRegTests/Couette_Poiseuille`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/Couette_Poiseuille Poiseuille Flow (y-direction) ----------------------------- @@ -520,9 +520,9 @@ Test Location: `Tests/test_files/PoiseuilleFlow_y`_ .. _`Tests/test_files/PoiseuilleFlow_y`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/PoiseuilleFlow_y -Problem Location: `Exec/RegTests/PoiseuilleFlow_y`_ +Problem Location: `Exec/DryRegTests/PoiseuilleFlow_y`_ -.. _`Exec/RegTests/Couette_Poiseuille`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/Couette_Poiseuille +.. _`Exec/DryRegTests/Couette_Poiseuille`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/Couette_Poiseuille Nonlinear Density Current --------------------------- @@ -534,9 +534,9 @@ Test Location: `Tests/test_files/DensityCurrent`_ .. _`Tests/test_files/DensityCurrent`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/DensityCurrent -Problem Location: `Exec/RegTests/DensityCurrent`_ +Problem Location: `Exec/DryRegTests/DensityCurrent`_ -.. _`Exec/DensityCurrent`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/DensityCurrent +.. _`Exec/DensityCurrent`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/DensityCurrent Ekman Spiral --------------------------- @@ -548,6 +548,6 @@ Test Location: `Tests/test_files/EkmanSpiral`_ .. _`Tests/test_files/EkmanSpiral`: https://github.com/erf-model/ERF/tree/development/Tests/test_files/EkmanSpiral -Problem Location: `Exec/RegTests/EkmanSpiral`_ +Problem Location: `Exec/DryRegTests/EkmanSpiral`_ -.. _`Exec/RegTests/EkmanSpiral`: https://github.com/erf-model/ERF/tree/development/Exec/RegTests/EkmanSpiral +.. _`Exec/DryRegTests/EkmanSpiral`: https://github.com/erf-model/ERF/tree/development/Exec/DryRegTests/EkmanSpiral diff --git a/Docs/sphinx_doc/building.rst b/Docs/sphinx_doc/building.rst index 1777e9419..c477cde01 100644 --- a/Docs/sphinx_doc/building.rst +++ b/Docs/sphinx_doc/building.rst @@ -33,10 +33,10 @@ ERF uses the paradigm that different executables are built in different subdirec using gmake (see below), the user/developer should build in the directory of the selected problem. When using cmake (see below), separate executables are built for all of the problem directories listed in ``Exec/CMakeLists.txt``. The problem directories within ``Exec`` are sorted into 1) science-relevant setups, such as ``ABL`` for modeling the atmospheric -boundary layer or ``DensityCurrent`` for running the standard density current test case, etc, 2) regression tests in -``Exec/RegTests`` that are used for testing specific known aspects of the code functionality, such as boundary conditions or -Rayleigh damping, and 3) tests for features under development in ``Exec/DevTests``, such as moving terrain. There is a -README in each problem directory that describes the purpose/role of that problem. +boundary layer or ``DensityCurrent`` for running the standard density current test case, etc, 2) dry and moist regression tests in +``Exec/DryRegTests`` and ``Exec/MoistRegTests`` respectively, that are used for testing specific known aspects of the code functionality, +such as boundary conditions or Rayleigh damping, and 3) tests for features under development in ``Exec/DevTests``, such as moving terrain. +There is a README in each problem directory that describes the purpose/role of that problem. GNU Make ~~~~~~~~ @@ -70,7 +70,7 @@ or if using tcsh, setenv AMREX_HOME /path/to/external/amrex -#. ``cd`` to the desired build directory, e.g. ``ERF/Exec/RegTests/IsentropicVortex/`` +#. ``cd`` to the desired build directory, e.g. ``ERF/Exec/DryRegTests/IsentropicVortex/`` #. Edit the ``GNUmakefile``; options include @@ -130,7 +130,7 @@ or if using tcsh, The name of the resulting executable (generated by the GNUmake system) encodes several of the build characteristics, including dimensionality of the problem, compiler name, and whether MPI and/or OpenMP were linked with the executable. Thus, several different build configurations may coexist simultaneously in a problem folder. - For example, the default build in ``ERF/Exec/RegTests/IsentropicVortex`` will look + For example, the default build in ``ERF/Exec/DryRegTests/IsentropicVortex`` will look like ``ERF3d.gnu.MPI.ex``, indicating that this is a 3-d version of the code, made with ``COMP=gnu``, and ``USE_MPI=TRUE``. diff --git a/Docs/sphinx_doc/testing.rst b/Docs/sphinx_doc/testing.rst index e19fc9d3a..f23f04ad9 100644 --- a/Docs/sphinx_doc/testing.rst +++ b/Docs/sphinx_doc/testing.rst @@ -52,10 +52,11 @@ Adding Tests Developers are encouraged to add tests to ERF and in this section we describe how the tests are organized in the CTest framework. The locations (relative to the ERF code base) of the tests are in ``Tests``. To add a test, first -create a problem directory with a name in ``Exec/RegTests/`` (for problems to be used -as regression tests) or ``Exec/DevTests/`` (for problems testing features under development), +create a problem directory with a name in ``Exec/DryRegTests/`` or +``Exec/MoistRegTests/`` (for problems to be used as regression tests) +or ``Exec/DevTests/`` (for problems testing features under development), depending on which type of test is being added. Prepare a suitable input file. -As an example, the ``TaylorGreenVortex`` problem with input file ``Exec/RegTests/TaylorGreenVortex/inputs_ex`` +As an example, the ``TaylorGreenVortex`` problem with input file ``Exec/DryRegTests/TaylorGreenVortex/inputs_ex`` solves a simple advection-diffusion problem. The corresponding regression tests are driven by the input files ``Tests/test_files/TaylorGreenAdvecting/TaylorGreenAdvecting.i`` and ``Tests/test_files/TaylorGreenAdvectingDiffusing/TaylorGreenAdvectingDiffusing.i``. diff --git a/Exec/DryRegTests/Couette_Poiseuille/GNUmakefile b/Exec/DryRegTests/Couette_Poiseuille/GNUmakefile index 1efc87478..86ea62113 100644 --- a/Exec/DryRegTests/Couette_Poiseuille/GNUmakefile +++ b/Exec/DryRegTests/Couette_Poiseuille/GNUmakefile @@ -29,5 +29,5 @@ Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/Couette_Poiseuille +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/DryRegTests/Couette_Poiseuille include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/DryRegTests/DensityCurrent/GNUmakefile b/Exec/DryRegTests/DensityCurrent/GNUmakefile index cda34e9af..f61d2ae0e 100644 --- a/Exec/DryRegTests/DensityCurrent/GNUmakefile +++ b/Exec/DryRegTests/DensityCurrent/GNUmakefile @@ -30,5 +30,5 @@ USE_POISSON_SOLVE = TRUE Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/DensityCurrent +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/DryRegTests/DensityCurrent include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/DryRegTests/EkmanSpiral/GNUmakefile b/Exec/DryRegTests/EkmanSpiral/GNUmakefile index 63e0a52ef..23a64fb3e 100644 --- a/Exec/DryRegTests/EkmanSpiral/GNUmakefile +++ b/Exec/DryRegTests/EkmanSpiral/GNUmakefile @@ -32,5 +32,5 @@ Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/EkmanSpiral +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/DryRegTests/EkmanSpiral include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/DryRegTests/IsentropicVortex/GNUmakefile b/Exec/DryRegTests/IsentropicVortex/GNUmakefile index ff44aa90f..10b5158be 100644 --- a/Exec/DryRegTests/IsentropicVortex/GNUmakefile +++ b/Exec/DryRegTests/IsentropicVortex/GNUmakefile @@ -29,5 +29,5 @@ Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/IsentropicVortex +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/DryRegTests/IsentropicVortex include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/DryRegTests/ParticlesOverWoA/GNUmakefile b/Exec/DryRegTests/ParticlesOverWoA/GNUmakefile index 8bc175ef1..01a7a7dac 100644 --- a/Exec/DryRegTests/ParticlesOverWoA/GNUmakefile +++ b/Exec/DryRegTests/ParticlesOverWoA/GNUmakefile @@ -31,5 +31,5 @@ Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/ParticlesOverWoA +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/DryRegTests/ParticlesOverWoA include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/DryRegTests/ScalarAdvDiff/GNUmakefile b/Exec/DryRegTests/ScalarAdvDiff/GNUmakefile index a81273724..1975a7109 100644 --- a/Exec/DryRegTests/ScalarAdvDiff/GNUmakefile +++ b/Exec/DryRegTests/ScalarAdvDiff/GNUmakefile @@ -29,5 +29,5 @@ Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/ScalarAdvDiff +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/DryRegTests/ScalarAdvDiff include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/DryRegTests/StokesSecondProblem/GNUmakefile b/Exec/DryRegTests/StokesSecondProblem/GNUmakefile index db7266fb0..71e096c63 100644 --- a/Exec/DryRegTests/StokesSecondProblem/GNUmakefile +++ b/Exec/DryRegTests/StokesSecondProblem/GNUmakefile @@ -29,5 +29,5 @@ USE_TERRAIN_VELOCITY = TRUE Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/StokesSecondProblem +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/DryRegTests/StokesSecondProblem include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/DryRegTests/TaylorGreenVortex/GNUmakefile b/Exec/DryRegTests/TaylorGreenVortex/GNUmakefile index 71f0c930a..42fdd8879 100644 --- a/Exec/DryRegTests/TaylorGreenVortex/GNUmakefile +++ b/Exec/DryRegTests/TaylorGreenVortex/GNUmakefile @@ -29,5 +29,5 @@ Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/TaylorGreenVortex +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/DryRegTests/TaylorGreenVortex include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/DryRegTests/Terrain2d_Cylinder/GNUmakefile b/Exec/DryRegTests/Terrain2d_Cylinder/GNUmakefile index 9569d1b2b..1668b3711 100644 --- a/Exec/DryRegTests/Terrain2d_Cylinder/GNUmakefile +++ b/Exec/DryRegTests/Terrain2d_Cylinder/GNUmakefile @@ -28,5 +28,5 @@ USE_ASSERTION = TRUE Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/Terrain2d_Cylinder +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/DryRegTests/Terrain2d_Cylinder include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/DryRegTests/Terrain3d_Hemisphere/GNUmakefile b/Exec/DryRegTests/Terrain3d_Hemisphere/GNUmakefile index 2097f715b..18888b3b1 100644 --- a/Exec/DryRegTests/Terrain3d_Hemisphere/GNUmakefile +++ b/Exec/DryRegTests/Terrain3d_Hemisphere/GNUmakefile @@ -28,5 +28,5 @@ USE_ASSERTION = TRUE Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/Terrain3d_Hemisphere +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/DryRegTests/Terrain3d_Hemisphere include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/DryRegTests/TurbulentInflow/GNUmakefile b/Exec/DryRegTests/TurbulentInflow/GNUmakefile index e1f9ee033..1ab8b7fbb 100644 --- a/Exec/DryRegTests/TurbulentInflow/GNUmakefile +++ b/Exec/DryRegTests/TurbulentInflow/GNUmakefile @@ -31,5 +31,5 @@ USE_POISSON_SOLVE = FALSE Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/TurbulentInflow +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/DryRegTests/TurbulentInflow include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/DryRegTests/WPS_Test/GNUmakefile b/Exec/DryRegTests/WPS_Test/GNUmakefile index 3e501d0a0..83fd3d453 100644 --- a/Exec/DryRegTests/WPS_Test/GNUmakefile +++ b/Exec/DryRegTests/WPS_Test/GNUmakefile @@ -32,5 +32,5 @@ Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/WPS_Test +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/DryRegTests/WPS_Test include $(ERF_HOME)/Exec/Make.ERF diff --git a/Exec/DryRegTests/WitchOfAgnesi/GNUmakefile b/Exec/DryRegTests/WitchOfAgnesi/GNUmakefile index ddc8e0298..78d097d48 100644 --- a/Exec/DryRegTests/WitchOfAgnesi/GNUmakefile +++ b/Exec/DryRegTests/WitchOfAgnesi/GNUmakefile @@ -29,5 +29,5 @@ Bpack := ./Make.package Blocs := . ERF_HOME := ../../.. -ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/RegTests/WitchOfAgnesi +ERF_PROBLEM_DIR = $(ERF_HOME)/Exec/DryRegTests/WitchOfAgnesi include $(ERF_HOME)/Exec/Make.ERF From 9428c70c5c299fd8c11bc0b15634b917e16bdf7b Mon Sep 17 00:00:00 2001 From: "Aaron M. Lattanzi" <103702284+AMLattanzi@users.noreply.github.com> Date: Tue, 5 Nov 2024 07:55:33 -0800 Subject: [PATCH 21/24] fix oops. (#1928) --- Source/SourceTerms/ERF_moist_set_rhs.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Source/SourceTerms/ERF_moist_set_rhs.cpp b/Source/SourceTerms/ERF_moist_set_rhs.cpp index 8a0854d3d..3b63b6a0a 100644 --- a/Source/SourceTerms/ERF_moist_set_rhs.cpp +++ b/Source/SourceTerms/ERF_moist_set_rhs.cpp @@ -160,11 +160,11 @@ moist_set_rhs (const Box& tbx, tbx_xlo, tbx_xhi, tbx_ylo, tbx_yhi, ng_vect, true); - wrfbdy_set_rhs_in_spec_region(dt, RhoQ1_comp, 1, - width, set_width, dom_lo, dom_hi, - tbx_xlo, tbx_xhi, tbx_ylo, tbx_yhi, - arr_xlo, arr_xhi, arr_ylo, arr_yhi, - old_cons, cell_rhs); + realbdy_set_rhs_in_spec_region(dt, RhoQ1_comp, 1, + width, set_width, dom_lo, dom_hi, + tbx_xlo, tbx_xhi, tbx_ylo, tbx_yhi, + arr_xlo, arr_xhi, arr_ylo, arr_yhi, + old_cons, cell_rhs); } @@ -178,11 +178,11 @@ moist_set_rhs (const Box& tbx, compute_interior_ghost_bxs_xy(tbx, domain, width, set_width, tbx_xlo, tbx_xhi, tbx_ylo, tbx_yhi); - wrfbdy_compute_laplacian_relaxation(RhoQ1_comp, 1, - width, set_width, dom_lo, dom_hi, F1, F2, - tbx_xlo, tbx_xhi, tbx_ylo, tbx_yhi, - arr_xlo, arr_xhi, arr_ylo, arr_yhi, - new_cons, cell_rhs); + realbdy_compute_laplacian_relaxation(RhoQ1_comp, 1, + width, set_width, dom_lo, dom_hi, F1, F2, + tbx_xlo, tbx_xhi, tbx_ylo, tbx_yhi, + arr_xlo, arr_xhi, arr_ylo, arr_yhi, + new_cons, cell_rhs); } /* From d55d717a130bc5d9d78066a5d1f5f94c329cc507 Mon Sep 17 00:00:00 2001 From: "Aaron M. Lattanzi" <103702284+AMLattanzi@users.noreply.github.com> Date: Tue, 5 Nov 2024 14:53:21 -0800 Subject: [PATCH 22/24] Make numdiff match WRF docs. (#1929) * Make numdiff match WRF docs. * comment unused vars. * one mapfac multiply. * update ctest. --- Source/SourceTerms/ERF_NumericalDiffusion.H | 59 +++-- Source/SourceTerms/ERF_NumericalDiffusion.cpp | 228 ++++++++++++------ Source/SourceTerms/ERF_Src_headers.H | 1 + Source/SourceTerms/ERF_make_mom_sources.cpp | 31 ++- Source/SourceTerms/ERF_make_sources.cpp | 37 +-- Source/TimeIntegration/ERF_TI_slow_rhs_fun.H | 4 +- Tests/ERFGoldFiles/IVA_NumDiff/Header | 12 +- .../IVA_NumDiff/Level_0/Cell_D_00000 | Bin 129112 -> 258136 bytes .../IVA_NumDiff/Level_0/Cell_D_00001 | Bin 129113 -> 258137 bytes Tests/ERFGoldFiles/IVA_NumDiff/Level_0/Cell_H | 28 +-- 10 files changed, 247 insertions(+), 153 deletions(-) diff --git a/Source/SourceTerms/ERF_NumericalDiffusion.H b/Source/SourceTerms/ERF_NumericalDiffusion.H index 14212e417..03666b002 100644 --- a/Source/SourceTerms/ERF_NumericalDiffusion.H +++ b/Source/SourceTerms/ERF_NumericalDiffusion.H @@ -5,23 +5,46 @@ #include #include -void NumericalDiffusion (const amrex::Box& bx, - const int start_comp, - const int num_comp, - const amrex::Real dt, - const amrex::Real num_diff_coeff, - const amrex::Array4& data, - const amrex::Array4< amrex::Real>& rhs, - const amrex::Array4& mf_x, - const amrex::Array4& mf_y, - const bool avg_mf_x_y, - const bool avg_mf_y_x); -void NumericalDiffusionVert (const amrex::Box& bx, - const int start_comp, - const int num_comp, - const amrex::Real dt, - const amrex::Real num_diff_coeff, - const amrex::Array4& data, - const amrex::Array4< amrex::Real>& rhs); +AMREX_GPU_DEVICE +AMREX_FORCE_INLINE +amrex::Real +calc_fifth_order_deriv (const amrex::Real& dnp2, + const amrex::Real& dnp1, + const amrex::Real& dn, + const amrex::Real& dnm1, + const amrex::Real& dnm2, + const amrex::Real& dnm3) +{ + amrex::Real interp = 10. * (dn - dnm1) + - 5. * (dnp1 - dnm2) + + (dnp2 - dnm3); + return interp; +} + +void NumericalDiffusion_Scal (const amrex::Box& bx, + const int start_comp, + const int num_comp, + const amrex::Real dt, + const amrex::Real num_diff_coeff, + const amrex::Array4& prim_data, + const amrex::Array4& cell_data, + const amrex::Array4< amrex::Real>& rhs, + const amrex::Array4& mf); + +void NumericalDiffusion_Xmom (const amrex::Box& bx, + const amrex::Real dt, + const amrex::Real num_diff_coeff, + const amrex::Array4& prim_data, + const amrex::Array4& cell_data, + const amrex::Array4< amrex::Real>& rhs, + const amrex::Array4& mf); + +void NumericalDiffusion_Ymom (const amrex::Box& bx, + const amrex::Real dt, + const amrex::Real num_diff_coeff, + const amrex::Array4& prim_data, + const amrex::Array4& cell_data, + const amrex::Array4< amrex::Real>& rhs, + const amrex::Array4& mf); #endif diff --git a/Source/SourceTerms/ERF_NumericalDiffusion.cpp b/Source/SourceTerms/ERF_NumericalDiffusion.cpp index e5d287d40..580d2febf 100644 --- a/Source/SourceTerms/ERF_NumericalDiffusion.cpp +++ b/Source/SourceTerms/ERF_NumericalDiffusion.cpp @@ -9,76 +9,130 @@ using namespace amrex; * @param[in] start_comp staring component index * @param[in] num_comp number of total components * @param[in] num_diff_coeff - * @param[in] data variables used to compute RHS + * @param[in] prim_data primitive variables + * @param[in] cell_data cell center variables * @param[out] rhs store the right hand side - * @param[in] mf_x map factor at x-face - * @param[in] mf_y map factor at y-face - * @param[in] avg_mf_x_y flag to average map factor x in y-dir - * @param[in] avg_mf_y_x flag to average map factor y in x-dir + * @param[in] mf map factor */ void -NumericalDiffusion (const Box& bx, - const int start_comp, - const int num_comp, - const Real dt, - const Real num_diff_coeff, - const Array4& data, - const Array4< Real>& rhs, - const Array4& mf_x, - const Array4& mf_y, - const bool avg_mf_x_y, - const bool avg_mf_y_x) +NumericalDiffusion_Scal (const Box& bx, + const int start_comp, + const int num_comp, + const Real dt, + const Real num_diff_coeff, + const Array4& prim_data, + const Array4& cell_data, + const Array4< Real>& rhs, + const Array4& mf_arr) { - BL_PROFILE_VAR("NumericalDiffusion()",NumericalDiffusion); - - // Average map factors to correct locations - Box planebx(bx); planebx.setSmall(2,0); planebx.setBig(2,0); - FArrayBox mf_x_bar; mf_x_bar.resize(planebx,1,The_Async_Arena()); - FArrayBox mf_y_bar; mf_y_bar.resize(planebx,1,The_Async_Arena()); - const Array4& mfx_arr = mf_x_bar.array(); - const Array4& mfy_arr = mf_y_bar.array(); - ParallelFor(planebx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept + BL_PROFILE_VAR("NumericalDiffusion_Scal()",NumericalDiffusion_Scal); + + // Capture diffusion coeff + Real coeff6 = num_diff_coeff / (2.0 * dt); + + // Compute 5th order derivative and augment RHS + ParallelFor(bx, num_comp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int m) noexcept { - if (avg_mf_x_y) { - mfx_arr(i,j,k) = 0.5 * ( mf_x(i,j-1,k) + mf_x(i,j,k) ); - } else { - mfx_arr(i,j,k) = mf_x(i,j,k); - } - if (avg_mf_y_x) { - mfy_arr(i,j,k) = 0.5 * ( mf_y(i-1,j,k) + mf_y(i,j,k) ); - } else { - mfy_arr(i,j,k) = mf_y(i,j,k); - } + int n = start_comp + m; // conserved index + int nm1 = (n==0) ? 0 : n - 1; // prim index + Real rho_x_lo = (n==0) ? 1.0 : 0.5 * ( cell_data(i-1,j,k,Rho_comp) + cell_data(i ,j,k,Rho_comp) ); + Real xflux_lo = rho_x_lo * calc_fifth_order_deriv(prim_data(i+2,j,k,nm1), prim_data(i+1,j,k,nm1), + prim_data(i ,j,k,nm1), prim_data(i-1,j,k,nm1), + prim_data(i-2,j,k,nm1), prim_data(i-3,j,k,nm1)); + if ( (xflux_lo * (prim_data(i,j,k,nm1) - prim_data(i-1,j,k,nm1)) ) < 0.) xflux_lo = 0.; + + + Real rho_x_hi = (n==0) ? 1.0 : 0.5 * ( cell_data(i+1,j,k,Rho_comp) + cell_data(i ,j,k,Rho_comp) ); + Real xflux_hi = rho_x_hi * calc_fifth_order_deriv(prim_data(i+3,j,k,nm1), prim_data(i+2,j,k,nm1), + prim_data(i+1,j,k,nm1), prim_data(i ,j,k,nm1), + prim_data(i-1,j,k,nm1), prim_data(i-2,j,k,nm1)); + if ( (xflux_hi * (prim_data(i+1,j,k,nm1) - prim_data(i,j,k,nm1)) ) < 0.) xflux_hi = 0.; + + + Real rho_y_lo = (n==0) ? 1.0 : 0.5 * ( cell_data(i,j-1,k,Rho_comp) + cell_data(i,j ,k,Rho_comp) ); + Real yflux_lo = rho_y_lo * calc_fifth_order_deriv(prim_data(i,j+2,k,nm1), prim_data(i,j+1,k,nm1), + prim_data(i,j ,k,nm1), prim_data(i,j-1,k,nm1), + prim_data(i,j-2,k,nm1), prim_data(i,j-3,k,nm1)); + if ( (yflux_lo * (prim_data(i,j,k,nm1) - prim_data(i,j-1,k,nm1)) ) < 0.) yflux_lo = 0.; + + + Real rho_y_hi = (n==0) ? 1.0 : 0.5 * ( cell_data(i,j+1,k,Rho_comp) + cell_data(i,j ,k,Rho_comp) ); + Real yflux_hi = rho_y_hi * calc_fifth_order_deriv(prim_data(i,j+3,k,nm1), prim_data(i,j+2,k,nm1), + prim_data(i,j+1,k,nm1), prim_data(i,j ,k,nm1), + prim_data(i,j-1,k,nm1), prim_data(i,j-2,k,nm1)); + if ( (yflux_hi * (prim_data(i,j+1,k,nm1) - prim_data(i,j,k,nm1)) ) < 0.) yflux_hi = 0.; + + + rhs(i,j,k,n) += coeff6 * mf_arr(i,j,0) * ( (xflux_hi - xflux_lo) + + (yflux_hi - yflux_lo) ); }); +} + +/** + * Function to compute 6th order numerical diffusion RHS. + * + * @param[in] bx box to loop over + * @param[in] start_comp staring component index + * @param[in] num_comp number of total components + * @param[in] num_diff_coeff + * @param[in] prim_data primitive variables + * @param[in] cell_data cell center variables + * @param[out] rhs store the right hand side + * @param[in] mf map factor + */ +void +NumericalDiffusion_Xmom (const Box& bx, + const Real dt, + const Real num_diff_coeff, + const Array4& prim_data, + const Array4& cell_data, + const Array4< Real>& rhs, + const Array4& mf_arr) +{ + BL_PROFILE_VAR("NumericalDiffusion_Xmom()",NumericalDiffusion_Xmom); // Capture diffusion coeff Real coeff6 = num_diff_coeff / (2.0 * dt); // Compute 5th order derivative and augment RHS - ParallelFor(bx, num_comp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int m) noexcept + ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - int n = start_comp + m; - Real xflux_lo = 10. * (data(i ,j,k,n) - data(i-1,j,k,n)) - - 5. * (data(i+1,j,k,n) - data(i-2,j,k,n)) - + (data(i+2,j,k,n) - data(i-3,j,k,n)); - if ( (xflux_lo * (data(i,j,k,n) - data(i-1,j,k,n)) ) < 0.) xflux_lo = 0.; - Real xflux_hi = 10. * (data(i+1,j,k,n) - data(i ,j,k,n)) - - 5. * (data(i+2,j,k,n) - data(i-1,j,k,n)) - + (data(i+3,j,k,n) - data(i-2,j,k,n)); - if ( (xflux_hi * (data(i+1,j,k,n) - data(i,j,k,n)) ) < 0.) xflux_hi = 0.; - Real yflux_lo = 10. * (data(i,j ,k,n) - data(i,j-1,k,n)) - - 5. * (data(i,j+1,k,n) - data(i,j-2,k,n)) - + (data(i,j+2,k,n) - data(i,j-3,k,n)); - if ( (yflux_lo * (data(i,j,k,n) - data(i,j-1,k,n)) ) < 0.) yflux_lo = 0.; - Real yflux_hi = 10. * (data(i,j+1,k,n) - data(i,j ,k,n)) - - 5. * (data(i,j+2,k,n) - data(i,j-1,k,n)) - + (data(i,j+3,k,n) - data(i,j-2,k,n)); - if ( (yflux_hi * (data(i,j+1,k,n) - data(i,j,k,n)) ) < 0.) yflux_hi = 0.; - rhs(i,j,k,n) += coeff6 * ( (xflux_hi - xflux_lo) * mfx_arr(i,j,0) - + (yflux_hi - yflux_lo) * mfy_arr(i,j,0) ); + Real rho_x_lo = cell_data(i-1,j,k,Rho_comp); + Real xflux_lo = rho_x_lo * calc_fifth_order_deriv(prim_data(i+2,j,k), prim_data(i+1,j,k), + prim_data(i ,j,k), prim_data(i-1,j,k), + prim_data(i-2,j,k), prim_data(i-3,j,k)); + if ( (xflux_lo * (prim_data(i,j,k) - prim_data(i-1,j,k)) ) < 0.) xflux_lo = 0.; + + + Real rho_x_hi = cell_data(i ,j,k,Rho_comp); + Real xflux_hi = rho_x_hi * calc_fifth_order_deriv(prim_data(i+3,j,k), prim_data(i+2,j,k), + prim_data(i+1,j,k), prim_data(i ,j,k), + prim_data(i-1,j,k), prim_data(i-2,j,k)); + if ( (xflux_hi * (prim_data(i+1,j,k) - prim_data(i,j,k)) ) < 0.) xflux_hi = 0.; + + + Real rho_y_lo = 0.25 * ( cell_data(i ,j ,k,Rho_comp) + cell_data(i-1,j ,k,Rho_comp) + + cell_data(i ,j-1,k,Rho_comp) + cell_data(i-1,j-1,k,Rho_comp) ); + Real yflux_lo = rho_y_lo * calc_fifth_order_deriv(prim_data(i,j+2,k), prim_data(i,j+1,k), + prim_data(i,j ,k), prim_data(i,j-1,k), + prim_data(i,j-2,k), prim_data(i,j-3,k)); + if ( (yflux_lo * (prim_data(i,j,k) - prim_data(i,j-1,k)) ) < 0.) yflux_lo = 0.; + + + Real rho_y_hi = 0.25 * ( cell_data(i ,j ,k,Rho_comp) + cell_data(i-1,j ,k,Rho_comp) + + cell_data(i ,j+1,k,Rho_comp) + cell_data(i-1,j+1,k,Rho_comp) ); + Real yflux_hi = rho_y_hi * calc_fifth_order_deriv(prim_data(i,j+3,k), prim_data(i,j+2,k), + prim_data(i,j+1,k), prim_data(i,j ,k), + prim_data(i,j-1,k), prim_data(i,j-2,k)); + if ( (yflux_hi * (prim_data(i,j+1,k) - prim_data(i,j,k)) ) < 0.) yflux_hi = 0.; + + + rhs(i,j,k) += coeff6 * mf_arr(i,j,0) * ( (xflux_hi - xflux_lo) + + (yflux_hi - yflux_lo) ); }); } + /** * Function to compute 6th order numerical diffusion RHS. * @@ -86,35 +140,59 @@ NumericalDiffusion (const Box& bx, * @param[in] start_comp staring component index * @param[in] num_comp number of total components * @param[in] num_diff_coeff - * @param[in] data variables used to compute RHS + * @param[in] prim_data primitive variables + * @param[in] cell_data cell center variables * @param[out] rhs store the right hand side + * @param[in] mf map factor */ void -NumericalDiffusionVert (const Box& bx, - const int start_comp, - const int num_comp, - const Real dt, - const Real num_diff_coeff, - const Array4& data, - const Array4< Real>& rhs) +NumericalDiffusion_Ymom (const Box& bx, + const Real dt, + const Real num_diff_coeff, + const Array4& prim_data, + const Array4& cell_data, + const Array4< Real>& rhs, + const Array4& mf_arr) { - BL_PROFILE_VAR("NumericalDiffusionVert()",NumericalDiffusionVert); + BL_PROFILE_VAR("NumericalDiffusion_Ymom()",NumericalDiffusion_Ymom); // Capture diffusion coeff Real coeff6 = num_diff_coeff / (2.0 * dt); // Compute 5th order derivative and augment RHS - ParallelFor(bx, num_comp, [=] AMREX_GPU_DEVICE (int i, int j, int k, int m) noexcept + ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept { - int n = start_comp + m; - Real zflux_lo = 10. * (data(i,j,k ,n) - data(i,j,k-1,n)) - - 5. * (data(i,j,k+1,n) - data(i,j,k-2,n)) - + (data(i,j,k+2,n) - data(i,j,k-3,n)); - if ( (zflux_lo * (data(i,j,k,n) - data(i,j,k-1,n)) ) < 0.) zflux_lo = 0.; - Real zflux_hi = 10. * (data(i,j,k+1,n) - data(i,j,k ,n)) - - 5. * (data(i,j,k+2,n) - data(i,j,k-1,n)) - + (data(i,j,k+3,n) - data(i,j,k-2,n)); - if ( (zflux_hi * (data(i,j,k+1,n) - data(i,j,k,n)) ) < 0.) zflux_hi = 0.; - rhs(i,j,k,n) += coeff6 * ( (zflux_hi - zflux_lo) ); + Real rho_x_lo = 0.25 * ( cell_data(i ,j ,k,Rho_comp) + cell_data(i ,j-1,k,Rho_comp) + + cell_data(i-1,j ,k,Rho_comp) + cell_data(i-1,j-1,k,Rho_comp) ); + Real xflux_lo = rho_x_lo * calc_fifth_order_deriv(prim_data(i+2,j,k), prim_data(i+1,j,k), + prim_data(i ,j,k), prim_data(i-1,j,k), + prim_data(i-2,j,k), prim_data(i-3,j,k)); + if ( (xflux_lo * (prim_data(i,j,k) - prim_data(i-1,j,k)) ) < 0.) xflux_lo = 0.; + + + Real rho_x_hi = 0.25 * ( cell_data(i ,j ,k,Rho_comp) + cell_data(i ,j-1,k,Rho_comp) + + cell_data(i+1,j ,k,Rho_comp) + cell_data(i+1,j-1,k,Rho_comp) ); + Real xflux_hi = rho_x_hi * calc_fifth_order_deriv(prim_data(i+3,j,k), prim_data(i+2,j,k), + prim_data(i+1,j,k), prim_data(i ,j,k), + prim_data(i-1,j,k), prim_data(i-2,j,k)); + if ( (xflux_hi * (prim_data(i+1,j,k) - prim_data(i,j,k)) ) < 0.) xflux_hi = 0.; + + + Real rho_y_lo = cell_data(i,j-1,k,Rho_comp); + Real yflux_lo = rho_y_lo * calc_fifth_order_deriv(prim_data(i,j+2,k), prim_data(i,j+1,k), + prim_data(i,j ,k), prim_data(i,j-1,k), + prim_data(i,j-2,k), prim_data(i,j-3,k)); + if ( (yflux_lo * (prim_data(i,j,k) - prim_data(i,j-1,k)) ) < 0.) yflux_lo = 0.; + + + Real rho_y_hi = cell_data(i,j ,k,Rho_comp); + Real yflux_hi = rho_y_hi * calc_fifth_order_deriv(prim_data(i,j+3,k), prim_data(i,j+2,k), + prim_data(i,j+1,k), prim_data(i,j ,k), + prim_data(i,j-1,k), prim_data(i,j-2,k)); + if ( (yflux_hi * (prim_data(i,j ,k) - prim_data(i,j,k)) ) < 0.) yflux_hi = 0.; + + + rhs(i,j,k) += coeff6 * mf_arr(i,j,0) * ( (xflux_hi - xflux_lo) + + (yflux_hi - yflux_lo) ); }); } diff --git a/Source/SourceTerms/ERF_Src_headers.H b/Source/SourceTerms/ERF_Src_headers.H index 7d19eeb0f..667a9dfe7 100644 --- a/Source/SourceTerms/ERF_Src_headers.H +++ b/Source/SourceTerms/ERF_Src_headers.H @@ -37,6 +37,7 @@ void make_sources (int level, int nrk, const SolverChoice& solverChoice, std::unique_ptr& mapfac_u, std::unique_ptr& mapfac_v, + std::unique_ptr& mapfac_m, const amrex::Real* dptr_rhotheta_src, const amrex::Real* dptr_rhoqt_src, const amrex::Real* dptr_wbar_sub, diff --git a/Source/SourceTerms/ERF_make_mom_sources.cpp b/Source/SourceTerms/ERF_make_mom_sources.cpp index 2e9a4d31f..44c4ccb46 100644 --- a/Source/SourceTerms/ERF_make_mom_sources.cpp +++ b/Source/SourceTerms/ERF_make_mom_sources.cpp @@ -38,7 +38,9 @@ using namespace amrex; */ void make_mom_sources (int level, - int /*nrk*/, Real dt, Real time, + int /*nrk*/, + Real /*dt*/, + Real time, Vector& S_data, const MultiFab & S_prim, std::unique_ptr& z_phys_nd, @@ -51,9 +53,9 @@ void make_mom_sources (int level, const MultiFab& base_state, const Geometry geom, const SolverChoice& solverChoice, - std::unique_ptr& mapfac_m, - std::unique_ptr& mapfac_u, - std::unique_ptr& mapfac_v, + std::unique_ptr& /*mapfac_m*/, + std::unique_ptr& /*mapfac_u*/, + std::unique_ptr& /*mapfac_v*/, const Real* dptr_u_geos, const Real* dptr_v_geos, const Real* dptr_wbar_sub, @@ -208,14 +210,17 @@ void make_mom_sources (int level, const Array4& rho_v = S_data[IntVars::ymom].array(mfi); const Array4& rho_w = S_data[IntVars::zmom].array(mfi); + //const Array4& u = xvel.array(mfi); + //const Array4& v = yvel.array(mfi); + const Array4< Real>& xmom_src_arr = xmom_src.array(mfi); const Array4< Real>& ymom_src_arr = ymom_src.array(mfi); const Array4< Real>& zmom_src_arr = zmom_src.array(mfi); // Map factors - const Array4& mf_m = mapfac_m->const_array(mfi); - const Array4& mf_u = mapfac_u->const_array(mfi); - const Array4& mf_v = mapfac_v->const_array(mfi); + //const Array4& mf_m = mapfac_m->const_array(mfi); + //const Array4& mf_u = mapfac_u->const_array(mfi); + //const Array4& mf_v = mapfac_v->const_array(mfi); const Array4& z_nd_arr = (use_terrain) ? z_phys_nd->const_array(mfi) : Array4{}; const Array4& z_cc_arr = (use_terrain) ? z_phys_cc->const_array(mfi) : Array4{}; @@ -424,12 +429,12 @@ void make_mom_sources (int level, // 7. Add NUMERICAL DIFFUSION terms // ***************************************************************************** if (l_use_ndiff) { - NumericalDiffusion(tbx, 0, 1, dt, solverChoice.NumDiffCoeff, - rho_u, xmom_src_arr, mf_m, mf_v, false, true); - NumericalDiffusion(tby, 0, 1, dt, solverChoice.NumDiffCoeff, - rho_v, ymom_src_arr, mf_u, mf_m, true, false); - NumericalDiffusion(tbz, 0, 1, dt, solverChoice.NumDiffCoeff, - rho_w, zmom_src_arr, mf_u, mf_v, false, false); + /* + NumericalDiffusion_Xmom(tbx, dt, solverChoice.NumDiffCoeff, + u, cell_data, xmom_src_arr, mf_u); + NumericalDiffusion_Ymom(tby, dt, solverChoice.NumDiffCoeff, + v, cell_data, ymom_src_arr, mf_v); + */ } // ***************************************************************************** diff --git a/Source/SourceTerms/ERF_make_sources.cpp b/Source/SourceTerms/ERF_make_sources.cpp index 2612849c2..d97cd41c1 100644 --- a/Source/SourceTerms/ERF_make_sources.cpp +++ b/Source/SourceTerms/ERF_make_sources.cpp @@ -40,8 +40,9 @@ void make_sources (int level, #endif const Geometry geom, const SolverChoice& solverChoice, - std::unique_ptr& mapfac_u, - std::unique_ptr& mapfac_v, + std::unique_ptr& /*mapfac_u*/, + std::unique_ptr& /*mapfac_v*/, + std::unique_ptr& mapfac_m, const Real* dptr_rhotheta_src, const Real* dptr_rhoqt_src, const Real* dptr_wbar_sub, @@ -330,27 +331,27 @@ void make_sources (int level, // 6. Add numerical diffuion for rho and (rho theta) // ************************************************************************************* if (l_use_ndiff) { - int start_comp = 0; - int num_comp = 2; + int sc; + int nc; - const Array4& mf_u = mapfac_u->const_array(mfi); - const Array4& mf_v = mapfac_v->const_array(mfi); + const Array4& mf_m = mapfac_m->const_array(mfi); + + // Rho is a special case + NumericalDiffusion_Scal(bx, sc=0, nc=1, dt, solverChoice.NumDiffCoeff, + cell_data, cell_data, cell_src, mf_m); + + // Other scalars proceed as normal + NumericalDiffusion_Scal(bx, sc=1, nc=1, dt, solverChoice.NumDiffCoeff, + cell_prim, cell_data, cell_src, mf_m); - NumericalDiffusion(bx, start_comp, num_comp, dt, solverChoice.NumDiffCoeff, - cell_data, cell_src, mf_u, mf_v, false, false); if (l_use_KE && l_diff_KE) { - int sc = RhoKE_comp; - int nc = 1; - NumericalDiffusion(bx, sc, nc, dt, solverChoice.NumDiffCoeff, - cell_data, cell_src, mf_u, mf_v, false, false); - } - { - int sc = RhoScalar_comp; - int nc = NSCALARS; - NumericalDiffusion(bx, sc, nc, dt, solverChoice.NumDiffCoeff, - cell_data, cell_src, mf_u, mf_v, false, false); + NumericalDiffusion_Scal(bx, sc=RhoKE_comp, nc=1, dt, solverChoice.NumDiffCoeff, + cell_prim, cell_data, cell_src, mf_m); } + + NumericalDiffusion_Scal(bx, sc=RhoScalar_comp, nc=NSCALARS, dt, solverChoice.NumDiffCoeff, + cell_prim, cell_data, cell_src, mf_m); } // ************************************************************************************* diff --git a/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H b/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H index af489069c..d26784ad7 100644 --- a/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H +++ b/Source/TimeIntegration/ERF_TI_slow_rhs_fun.H @@ -53,7 +53,7 @@ qheating_rates[level].get(), #endif fine_geom, solverChoice, - mapfac_u[level], mapfac_v[level], + mapfac_u[level], mapfac_v[level], mapfac_m[level], dptr_rhotheta_src, dptr_rhoqt_src, dptr_wbar_sub, d_rayleigh_ptrs_at_lev, input_sounding_data, turbPert); @@ -433,7 +433,7 @@ qheating_rates[level], #endif fine_geom, solverChoice, - mapfac_u[level], mapfac_v[level], + mapfac_u[level], mapfac_v[level], mapfac_m[level], dptr_rhotheta_src, dptr_rhoqt_src, dptr_wbar_sub, d_rayleigh_ptrs_at_lev, input_sounding_data, turbPert); diff --git a/Tests/ERFGoldFiles/IVA_NumDiff/Header b/Tests/ERFGoldFiles/IVA_NumDiff/Header index 17ab11925..d75438415 100644 --- a/Tests/ERFGoldFiles/IVA_NumDiff/Header +++ b/Tests/ERFGoldFiles/IVA_NumDiff/Header @@ -18,18 +18,12 @@ pressure 0.5 0.5 0.5 0 0 -0 4 0.005000000000000001 +0 2 0.005000000000000001 10 --12 0 --12 0 --1 1 -0 12 +-12 12 -12 0 -1 1 --12 0 -0 12 --1 1 -0 12 +-12 12 0 12 -1 1 Level_0/Cell diff --git a/Tests/ERFGoldFiles/IVA_NumDiff/Level_0/Cell_D_00000 b/Tests/ERFGoldFiles/IVA_NumDiff/Level_0/Cell_D_00000 index 4cf93a1a39468dff9c0fe0861c99435ed20654b6..789d45751d2571644efff535fa13e8b08c599d39 100644 GIT binary patch literal 258136 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 WC%peBy#FV>|0jI^>(}-Dum1t>N3whX literal 129112 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 AO8@`> diff --git a/Tests/ERFGoldFiles/IVA_NumDiff/Level_0/Cell_D_00001 b/Tests/ERFGoldFiles/IVA_NumDiff/Level_0/Cell_D_00001 index ef53c36599d6470961e33041eb85a70100508c10..10e4c91b9cdb9054fb7e86d2fc95e646e2e9fbf5 100644 GIT binary patch literal 258137 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

{KS#j<{imaX_^l{?U$pD$VSmSM4FA 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 Bk1+rM diff --git a/Tests/ERFGoldFiles/IVA_NumDiff/Level_0/Cell_H b/Tests/ERFGoldFiles/IVA_NumDiff/Level_0/Cell_H index efb9a8d3d..89dc2b9c9 100644 --- a/Tests/ERFGoldFiles/IVA_NumDiff/Level_0/Cell_H +++ b/Tests/ERFGoldFiles/IVA_NumDiff/Level_0/Cell_H @@ -2,27 +2,19 @@ 1 7 0 -(4 0 -((0,0,0) (23,23,3) (0,0,0)) -((24,0,0) (47,23,3) (0,0,0)) -((0,24,0) (23,47,3) (0,0,0)) -((24,24,0) (47,47,3) (0,0,0)) +(2 0 +((0,0,0) (47,23,3) (0,0,0)) +((0,24,0) (47,47,3) (0,0,0)) ) -4 +2 FabOnDisk: Cell_D_00000 0 FabOnDisk: Cell_D_00001 0 -FabOnDisk: Cell_D_00002 0 -FabOnDisk: Cell_D_00003 0 -4,7 -1.1508066720086045e+00,2.9304939255617569e+02,2.5272927470640192e+02,0.0000000000000000e+00,2.9889831292387811e+02,2.9999999999999983e+02,9.8720587583530491e+04, -1.0999769859575013e+00,2.9312815840001815e+02,2.3942933114150043e+02,0.0000000000000000e+00,2.9354585669301952e+02,2.9999999999999989e+02,9.2670488078738548e+04, -1.0989702618831949e+00,2.4281464598114090e+02,1.3971517233403904e+02,0.0000000000000000e+00,2.9343836322209842e+02,2.9999999999999983e+02,9.2551770009631713e+04, -6.7267281853664840e-01,9.8985671404306828e+01,8.2922251084239434e+01,0.0000000000000000e+00,2.4112601395574711e+02,2.9999999999999983e+02,4.6551088728444331e+04, +2,7 +1.09998311200565024e+00,2.93049359375847871e+02,2.39429342203333533e+02,0.00000000000000000e+00,2.93546342981243754e+02,2.99999471208575528e+02,9.26711577028009197e+04, +6.72705062982049462e-01,9.89835916836365328e+01,8.29183612143245483e+01,0.00000000000000000e+00,2.41116530931248263e+02,2.99987464049565176e+02,4.65514892931960494e+04, -4,7 -1.1658895079646976e+00,3.3570958010749922e+02,2.9360350865676918e+02,0.0000000000000000e+00,3.0045917672032266e+02,3.0000000000000017e+02,1.0053673189075137e+05, -1.1654120069094225e+00,4.4005067884988495e+02,3.5146580220748069e+02,0.0000000000000000e+00,3.0040994831415992e+02,3.0000000000000017e+02,1.0047909053822359e+05, -1.1656645868467823e+00,3.5574961605285102e+02,2.9371771689681793e+02,0.0000000000000000e+00,3.0043598978020367e+02,3.0000000000000017e+02,1.0050957944959997e+05, -1.1631889438662057e+00,4.9220112212460123e+02,4.7707727843213706e+02,0.0000000000000000e+00,3.0018060013105736e+02,3.0000000000000017e+02,1.0021085875260815e+05, +2,7 +1.16588949797919716e+00,4.40051889512429284e+02,3.51466161252507618e+02,0.00000000000000000e+00,3.00459146875921590e+02,3.00000797593949358e+02,1.00536721043440295e+05, +1.16566457380817878e+00,4.92208769971793572e+02,4.77083602499372148e+02,0.00000000000000000e+00,3.00436213487944030e+02,3.00002718967787814e+02,1.00509653165814598e+05, From 72bf21232d655e574176043b5e608cea90adad24 Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Tue, 5 Nov 2024 16:51:46 -0800 Subject: [PATCH 23/24] more cleanup; no change in functionality expected (#1930) --- CMakeLists.txt | 2 +- Exec/MoistRegTests/Bubble/ERF_prob.cpp | 40 ++----- Exec/MoistRegTests/SquallLine_2D/ERF_prob.cpp | 46 ++------ Exec/MoistRegTests/SuperCell_3D/ERF_prob.cpp | 42 ++----- Source/ERF_make_new_level.cpp | 6 - ...TI_fast_rhs_fun.H => ERF_TI_substep_fun.H} | 0 Source/TimeIntegration/ERF_advance_dycore.cpp | 2 +- Source/TimeIntegration/Make.package | 2 +- Source/Utils/ERF_EOS.H | 103 ++++++++++++------ 9 files changed, 104 insertions(+), 139 deletions(-) rename Source/TimeIntegration/{ERF_TI_fast_rhs_fun.H => ERF_TI_substep_fun.H} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index e045d2eb6..3b8d6b340 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,7 +247,7 @@ target_link_libraries(erf_api PUBLIC erf_srclib) add_library(${PROJECT_NAME}::erf_api ALIAS erf_srclib) # Collect all headers and make them installable with the target -set(ERF_INCLUDES "Source/ERF.H;Source/ERF_Constants.H;Source/WindFarmParametrization/SimpleActuatorDisk/ERF_SimpleAD.H;Source/WindFarmParametrization/EWP/ERF_EWP.H;Source/WindFarmParametrization/Null/ERF_NullWindFarm.H;Source/WindFarmParametrization/ERF_WindFarm.H;Source/WindFarmParametrization/Fitch/ERF_Fitch.H;Source/BoundaryConditions/ERF_PhysBCFunct.H;Source/BoundaryConditions/ERF_MOSTAverage.H;Source/BoundaryConditions/ERF_MOSTRoughness.H;Source/BoundaryConditions/ERF_ABLMost.H;Source/BoundaryConditions/ERF_FillPatcher.H;Source/BoundaryConditions/ERF_MOSTStress.H;Source/BoundaryConditions/ERF_TimeInterpolatedData.H;Source/Utils/ERF_Interpolation.H;Source/Utils/ERF_TileNoZ.H;Source/Utils/ERF_PlaneAverage.H;Source/Utils/ERF_Interpolation_WENO.H;Source/Utils/ERF_DirectionSelector.H;Source/Utils/ERF_ParFunctions.H;Source/Utils/ERF_Wstar.H;Source/Utils/ERF_Microphysics_Utils.H;Source/Utils/ERF_Sat_methods.H;Source/Utils/ERF_Interpolation_1D.H;Source/Utils/ERF_Interpolation_UPW.H;Source/Utils/ERF_TerrainMetrics.H;Source/Utils/ERF_Interpolation_WENO_Z.H;Source/Utils/ERF_Thetav.H;Source/Utils/ERF_Water_vapor_saturation.H;Source/Utils/ERF_Utils.H;Source/Utils/ERF_Orbit.H;Source/Utils/ERF_EOS.H;Source/Utils/ERF_HSE_utils.H;Source/EB/ERF_TerrainIF.H;Source/EB/ERF_FlowerIF.H;Source/EB/ERF_eb_if.H;Source/Particles/ERFPC.H;Source/Particles/ERF_ParticleData.H;Source/Prob/ERF_init_density_hse_dry.H;Source/Prob/ERF_init_rayleigh_damping.H;Source/Prob/ERF_init_constant_density_hse.H;Source/ERF_prob_common.H;Source/ERF_Derive.H;Source/Radiation/ERF_Mam4_constituents.H;Source/Radiation/ERF_Mam4_aero.H;Source/Radiation/ERF_Optics.H;Source/Radiation/ERF_Modal_aero_wateruptake.H;Source/Radiation/ERF_Cloud_rad_props.H;Source/Radiation/ERF_Phys_prop.H;Source/Radiation/ERF_Radiation.H;Source/Radiation/ERF_Albedo.H;Source/Radiation/ERF_Parameterizations.H;Source/Radiation/ERF_Rad_constants.H;Source/Radiation/ERF_Aero_rad_props.H;Source/Radiation/ERF_m2005_effradius.H;Source/Radiation/ERF_Linear_interpolate.H;Source/Radiation/ERF_Slingo.H;Source/Radiation/ERF_Rrtmgp.H;Source/Radiation/ERF_Ebert_curry.H;Source/SourceTerms/ERF_NumericalDiffusion.H;Source/SourceTerms/ERF_Src_headers.H;Source/IO/ERF_NCInterface.H;Source/IO/ERF_NCWpsFile.H;Source/IO/ERF_NCPlotFile.H;Source/IO/ERF_ReadBndryPlanes.H;Source/IO/ERF_WriteBndryPlanes.H;Source/PBL/ERF_MYNNStruct.H;Source/PBL/ERF_PBLModels.H;Source/PBL/ERF_PBLHeight.H;Source/TimeIntegration/ERF_TI_fast_rhs_fun.H;Source/TimeIntegration/ERF_TI_slow_headers.H;Source/TimeIntegration/ERF_TI_slow_rhs_fun.H;Source/TimeIntegration/ERF_TI_fast_headers.H;Source/TimeIntegration/ERF_TI_utils.H;Source/TimeIntegration/ERF_MRI.H;Source/TimeIntegration/ERF_TI_no_substep_fun.H;Source/LandSurfaceModel/Null/ERF_NullSurf.H;Source/LandSurfaceModel/ERF_LandSurface.H;Source/LandSurfaceModel/MM5/ERF_MM5.H;Source/LandSurfaceModel/SLM/ERF_SLM.H;Source/ERF_IndexDefines.H;Source/Advection/ERF_AdvectionSrcForMom_N.H;Source/Advection/ERF_AdvectionSrcForScalars.H;Source/Advection/ERF_AdvectionSrcForMom_T.H;Source/Advection/ERF_Advection.H;Source/MultiBlock/ERF_MultiBlockContainer.H;Source/Initialization/ERF_Metgrid_utils.H;Source/Diffusion/ERF_EddyViscosity.H;Source/Diffusion/ERF_Diffusion.H;Source/Microphysics/Null/ERF_NullMoistLagrangian.H;Source/Microphysics/Null/ERF_NullMoist.H;Source/Microphysics/ERF_Microphysics.H;Source/Microphysics/ERF_LagrangianMicrophysics.H;Source/Microphysics/ERF_EulerianMicrophysics.H;Source/Microphysics/Kessler/ERF_Kessler.H;Source/Microphysics/SAM/ERF_SAM.H;Source/DataStructs/ERF_InputSpongeData.H;Source/DataStructs/ERF_TurbPertStruct.H;Source/DataStructs/ERF_SpongeStruct.H;Source/DataStructs/ERF_AdvStruct.H;Source/DataStructs/ERF_DataStruct.H;Source/DataStructs/ERF_InputSoundingData.H;Source/DataStructs/ERF_DiffStruct.H;Source/DataStructs/ERF_TurbStruct.H") +set(ERF_INCLUDES "Source/ERF.H;Source/ERF_Constants.H;Source/WindFarmParametrization/SimpleActuatorDisk/ERF_SimpleAD.H;Source/WindFarmParametrization/EWP/ERF_EWP.H;Source/WindFarmParametrization/Null/ERF_NullWindFarm.H;Source/WindFarmParametrization/ERF_WindFarm.H;Source/WindFarmParametrization/Fitch/ERF_Fitch.H;Source/BoundaryConditions/ERF_PhysBCFunct.H;Source/BoundaryConditions/ERF_MOSTAverage.H;Source/BoundaryConditions/ERF_MOSTRoughness.H;Source/BoundaryConditions/ERF_ABLMost.H;Source/BoundaryConditions/ERF_FillPatcher.H;Source/BoundaryConditions/ERF_MOSTStress.H;Source/BoundaryConditions/ERF_TimeInterpolatedData.H;Source/Utils/ERF_Interpolation.H;Source/Utils/ERF_TileNoZ.H;Source/Utils/ERF_PlaneAverage.H;Source/Utils/ERF_Interpolation_WENO.H;Source/Utils/ERF_DirectionSelector.H;Source/Utils/ERF_ParFunctions.H;Source/Utils/ERF_Wstar.H;Source/Utils/ERF_Microphysics_Utils.H;Source/Utils/ERF_Sat_methods.H;Source/Utils/ERF_Interpolation_1D.H;Source/Utils/ERF_Interpolation_UPW.H;Source/Utils/ERF_TerrainMetrics.H;Source/Utils/ERF_Interpolation_WENO_Z.H;Source/Utils/ERF_Thetav.H;Source/Utils/ERF_Water_vapor_saturation.H;Source/Utils/ERF_Utils.H;Source/Utils/ERF_Orbit.H;Source/Utils/ERF_EOS.H;Source/Utils/ERF_HSE_utils.H;Source/EB/ERF_TerrainIF.H;Source/EB/ERF_FlowerIF.H;Source/EB/ERF_eb_if.H;Source/Particles/ERFPC.H;Source/Particles/ERF_ParticleData.H;Source/Prob/ERF_init_density_hse_dry.H;Source/Prob/ERF_init_rayleigh_damping.H;Source/Prob/ERF_init_constant_density_hse.H;Source/ERF_prob_common.H;Source/ERF_Derive.H;Source/Radiation/ERF_Mam4_constituents.H;Source/Radiation/ERF_Mam4_aero.H;Source/Radiation/ERF_Optics.H;Source/Radiation/ERF_Modal_aero_wateruptake.H;Source/Radiation/ERF_Cloud_rad_props.H;Source/Radiation/ERF_Phys_prop.H;Source/Radiation/ERF_Radiation.H;Source/Radiation/ERF_Albedo.H;Source/Radiation/ERF_Parameterizations.H;Source/Radiation/ERF_Rad_constants.H;Source/Radiation/ERF_Aero_rad_props.H;Source/Radiation/ERF_m2005_effradius.H;Source/Radiation/ERF_Linear_interpolate.H;Source/Radiation/ERF_Slingo.H;Source/Radiation/ERF_Rrtmgp.H;Source/Radiation/ERF_Ebert_curry.H;Source/SourceTerms/ERF_NumericalDiffusion.H;Source/SourceTerms/ERF_Src_headers.H;Source/IO/ERF_NCInterface.H;Source/IO/ERF_NCWpsFile.H;Source/IO/ERF_NCPlotFile.H;Source/IO/ERF_ReadBndryPlanes.H;Source/IO/ERF_WriteBndryPlanes.H;Source/PBL/ERF_MYNNStruct.H;Source/PBL/ERF_PBLModels.H;Source/PBL/ERF_PBLHeight.H;Source/TimeIntegration/ERF_TI_substep_fun.H;Source/TimeIntegration/ERF_TI_slow_headers.H;Source/TimeIntegration/ERF_TI_slow_rhs_fun.H;Source/TimeIntegration/ERF_TI_fast_headers.H;Source/TimeIntegration/ERF_TI_utils.H;Source/TimeIntegration/ERF_MRI.H;Source/TimeIntegration/ERF_TI_no_substep_fun.H;Source/LandSurfaceModel/Null/ERF_NullSurf.H;Source/LandSurfaceModel/ERF_LandSurface.H;Source/LandSurfaceModel/MM5/ERF_MM5.H;Source/LandSurfaceModel/SLM/ERF_SLM.H;Source/ERF_IndexDefines.H;Source/Advection/ERF_AdvectionSrcForMom_N.H;Source/Advection/ERF_AdvectionSrcForScalars.H;Source/Advection/ERF_AdvectionSrcForMom_T.H;Source/Advection/ERF_Advection.H;Source/MultiBlock/ERF_MultiBlockContainer.H;Source/Initialization/ERF_Metgrid_utils.H;Source/Diffusion/ERF_EddyViscosity.H;Source/Diffusion/ERF_Diffusion.H;Source/Microphysics/Null/ERF_NullMoistLagrangian.H;Source/Microphysics/Null/ERF_NullMoist.H;Source/Microphysics/ERF_Microphysics.H;Source/Microphysics/ERF_LagrangianMicrophysics.H;Source/Microphysics/ERF_EulerianMicrophysics.H;Source/Microphysics/Kessler/ERF_Kessler.H;Source/Microphysics/SAM/ERF_SAM.H;Source/DataStructs/ERF_InputSpongeData.H;Source/DataStructs/ERF_TurbPertStruct.H;Source/DataStructs/ERF_SpongeStruct.H;Source/DataStructs/ERF_AdvStruct.H;Source/DataStructs/ERF_DataStruct.H;Source/DataStructs/ERF_InputSoundingData.H;Source/DataStructs/ERF_DiffStruct.H;Source/DataStructs/ERF_TurbStruct.H") set_target_properties( erf_srclib PROPERTIES PUBLIC_HEADER "${ERF_INCLUDES}") diff --git a/Exec/MoistRegTests/Bubble/ERF_prob.cpp b/Exec/MoistRegTests/Bubble/ERF_prob.cpp index 87f12a7c0..5edf0e671 100644 --- a/Exec/MoistRegTests/Bubble/ERF_prob.cpp +++ b/Exec/MoistRegTests/Bubble/ERF_prob.cpp @@ -1,6 +1,7 @@ #include "ERF_prob.H" #include "ERF_Microphysics_Utils.H" #include "ERF_Constants.H" +#include "ERF_EOS.H" using namespace amrex; @@ -52,13 +53,6 @@ Real compute_relative_humidity () return 1.0; } -AMREX_FORCE_INLINE -AMREX_GPU_HOST_DEVICE -Real compute_vapor_pressure (const Real p_s, const Real RH) -{ - return p_s*RH; -} - AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real vapor_mixing_ratio (const Real p_b, const Real T_b, const Real RH) @@ -118,30 +112,20 @@ Real compute_dewpoint_temperature (const Real T_b, const Real RH) return T_dp; } -AMREX_FORCE_INLINE -AMREX_GPU_HOST_DEVICE -Real Problem::compute_theta(const Real T_b, const Real p_b) -{ - return T_b*std::pow(p_0/p_b, R_d/Cp_d); -} - -AMREX_FORCE_INLINE -AMREX_GPU_HOST_DEVICE -Real compute_temperature_from_theta(const Real theta, const Real p) -{ - return theta*std::pow(p/p_0, R_d/Cp_d); -} - AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE void Problem::compute_rho (const Real& pressure, Real& theta, Real& rho, Real& q_v, Real& T_dp, Real& T_b) { T_b = compute_temperature(pressure); - theta = compute_theta(T_b, pressure); + + theta = getThgivenPandT(T_b, pressure, (R_d/Cp_d)); + Real RH = compute_relative_humidity(); q_v = vapor_mixing_ratio(pressure, T_b, RH); - rho = pressure/(R_d*T_b*(1.0 + (R_v/R_d)*q_v)); + + rho = getRhogivenTandPress(T_b, pressure, q_v); rho = rho*(1.0 + parms.qt_init); // q_t = 0.02 a given constant for this test case + T_dp = compute_dewpoint_temperature(T_b, RH); } @@ -228,16 +212,10 @@ Problem::erf_init_dens_hse_moist (MultiFab& rho_hse, Vector h_q_v(khi+2); Gpu::DeviceVector d_r(khi+2); - Gpu::DeviceVector d_p(khi+2); - Gpu::DeviceVector d_t(khi+2); - Gpu::DeviceVector d_q_v(khi+2); init_isentropic_hse_no_terrain(h_t.data(), h_r.data(),h_p.data(), h_q_v.data(), dz, khi); Gpu::copyAsync(Gpu::hostToDevice, h_r.begin(), h_r.end(), d_r.begin()); - Gpu::copyAsync(Gpu::hostToDevice, h_p.begin(), h_p.end(), d_p.begin()); - Gpu::copyAsync(Gpu::hostToDevice, h_t.begin(), h_t.end(), d_t.begin()); - Gpu::copyAsync(Gpu::hostToDevice, h_q_v.begin(), h_q_v.end(), d_q_v.begin()); Real* r = d_r.data(); @@ -392,13 +370,13 @@ Problem::init_custom_pert( } theta_total = theta_back[k]*(delta_theta/300.0 + 1); - Real T = compute_temperature_from_theta(theta_total, p_back[k]); + Real T = getTgivenPandTh(theta_total, p_back[k], (R_d/Cp_d)); rho = p_back[k]/(R_d*T*(1.0 + (R_v/R_d)*q_v_back[k])); RH = compute_relative_humidity(); Real q_v_hot = vapor_mixing_ratio(p_back[k], T, RH); // Compute background quantities - Real T_back = compute_temperature_from_theta(theta_back[k], p_back[k]); + Real T_back = getTgivenPandTh(theta_back[k], p_back[k], (R_d/Cp_d)); Real rho_back = p_back[k]/(R_d*T_back*(1.0 + (R_v/R_d)*q_v_back[k])); // This version perturbs rho but not p diff --git a/Exec/MoistRegTests/SquallLine_2D/ERF_prob.cpp b/Exec/MoistRegTests/SquallLine_2D/ERF_prob.cpp index a0d555625..01a96d0b2 100644 --- a/Exec/MoistRegTests/SquallLine_2D/ERF_prob.cpp +++ b/Exec/MoistRegTests/SquallLine_2D/ERF_prob.cpp @@ -69,13 +69,6 @@ Real compute_relative_humidity (const Real z, const Real height, const Real z_tr } } -AMREX_FORCE_INLINE -AMREX_GPU_HOST_DEVICE -Real compute_vapor_pressure (const Real p_s, const Real RH) -{ - return p_s*RH; -} - AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real vapor_mixing_ratio (const Real z, const Real height, const Real p_b, const Real T_b, const Real RH) @@ -92,13 +85,6 @@ Real vapor_mixing_ratio (const Real z, const Real height, const Real p_b, const } } -AMREX_FORCE_INLINE -AMREX_GPU_HOST_DEVICE -Real compute_temperature (const Real p_b, const Real theta_b) -{ - return theta_b*std::pow(p_b/p_0,R_d/Cp_d); -} - AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real compute_dewpoint_temperature (const Real T_b, const Real RH) @@ -119,10 +105,10 @@ void Problem::compute_rho (const Real& z, const Real& pressure, Real& theta, Rea { theta = compute_theta(z); - T_b = compute_temperature(pressure, theta); + T_b = getTgivenPandTh(theta, pressure, (R_d/Cp_d)); Real RH = compute_relative_humidity(z, parms.height, parms.z_tr, pressure, T_b); q_v = vapor_mixing_ratio(z, parms.height, pressure, T_b, RH); - rho = pressure/(R_d*T_b*(1.0 + (R_v/R_d)*q_v)); + rho = getRhogivenTandPress(T_b, pressure, q_v); rho = rho*(1.0 + q_v); T_dp = compute_dewpoint_temperature(T_b, RH); } @@ -168,26 +154,19 @@ Problem::init_isentropic_hse_no_terrain(Real *theta, Real* r, Real* p, Real *q_v const Real& dz, const Real& prob_lo_z, const int& khi) { - - //FILE *file_IC; - //file_IC = fopen("input_sounding_probcpp.txt","w"); Real z, T_b, T_dp; // Compute the quantities at z = 0.5*dz (first cell center) z = prob_lo_z + 0.5*dz; p[0] = p_0; compute_p_k(p[0], p_0, theta[0], r[0], q_v[0], T_dp, T_b, dz, z, 0.0); - //fprintf(file_IC, "%0.15g %0.15g %0.15g %0.15g %0.15g %0.15g %0.15g\n", z, T_b-273.15, T_dp, p[0], r[0], theta[0], q_v[0]); for (int k=1;k<=khi;k++){ z = prob_lo_z + (k+0.5)*dz; p[k] = p[k-1]; compute_p_k(p[k], p[k-1], theta[k], r[k], q_v[k], T_dp, T_b, dz, z, r[k-1]); - //fprintf(file_IC, "%0.15g %0.15g %0.15g %0.15g %0.15g %0.15g %0.15g\n", z, T_b-273.15, T_dp, p[k], r[k], theta[k], q_v[k]); } - //fclose(file_IC); - r[khi+1] = r[khi]; } @@ -239,17 +218,11 @@ Problem::erf_init_dens_hse_moist (MultiFab& rho_hse, Vector h_t(khi+2); Vector h_q_v(khi+2); - amrex::Gpu::DeviceVector d_r(khi+2); - amrex::Gpu::DeviceVector d_p(khi+2); - amrex::Gpu::DeviceVector d_t(khi+2); - amrex::Gpu::DeviceVector d_q_v(khi+2); - init_isentropic_hse_no_terrain(h_t.data(), h_r.data(),h_p.data(), h_q_v.data(), dz,prob_lo_z,khi); + amrex::Gpu::DeviceVector d_r(khi+2); + amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, h_r.begin(), h_r.end(), d_r.begin()); - amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, h_p.begin(), h_p.end(), d_p.begin()); - amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, h_t.begin(), h_t.end(), d_t.begin()); - amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, h_q_v.begin(), h_q_v.end(), d_q_v.begin()); Real* r = d_r.data(); @@ -352,15 +325,18 @@ Problem::init_custom_pert ( } theta_total = t[k] + delta_theta; - temperature = compute_temperature(p[k], theta_total); - Real T_b = compute_temperature(p[k], t[k]); + + temperature = getTgivenPandTh(theta_total, p[k], (R_d/Cp_d)); + Real T_b = getTgivenPandTh(t[k] , p[k], (R_d/Cp_d)); + RH = compute_relative_humidity(z, height, z_tr, p[k], T_b); Real q_v_hot = vapor_mixing_ratio(z, height, p[k], T_b, RH); rho = p[k]/(R_d*temperature*(1.0 + (R_v/R_d)*q_v_hot)); // Compute background quantities - Real temperature_back = compute_temperature(p[k], t[k]); - Real T_back = compute_temperature(p[k], t[k]); + Real temperature_back = getTgivenPandTh(t[k], p[k], (R_d/Cp_d)); + Real T_back = getTgivenPandTh(t[k], p[k], (R_d/Cp_d)); + Real RH_back = compute_relative_humidity(z, height, z_tr, p[k], T_back); Real q_v_back = vapor_mixing_ratio(z, height, p[k], T_back, RH_back); Real rho_back = p[k]/(R_d*temperature_back*(1.0 + (R_v/R_d)*q_v_back)); diff --git a/Exec/MoistRegTests/SuperCell_3D/ERF_prob.cpp b/Exec/MoistRegTests/SuperCell_3D/ERF_prob.cpp index 1b596b69a..2aaff6787 100644 --- a/Exec/MoistRegTests/SuperCell_3D/ERF_prob.cpp +++ b/Exec/MoistRegTests/SuperCell_3D/ERF_prob.cpp @@ -71,13 +71,6 @@ Real compute_relative_humidity (const Real z, const Real height, const Real z_tr } } -AMREX_FORCE_INLINE -AMREX_GPU_HOST_DEVICE -Real compute_vapor_pressure (const Real p_s, const Real RH) -{ - return p_s*RH; -} - AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE Real vapor_mixing_ratio (const Real z, const Real height, const Real p_b, const Real T_b, const Real RH) @@ -121,11 +114,13 @@ void Problem::compute_rho (const Real& z, const Real& pressure, Real& theta, Rea { theta = compute_theta(z); - T_b = compute_temperature(pressure, theta); + T_b = getTgivenPandTh(theta, pressure, (R_d/Cp_d)); Real RH = compute_relative_humidity(z, parms.height, parms.z_tr, pressure, T_b); q_v = vapor_mixing_ratio(z, parms.height, pressure, T_b, RH); - rho = pressure/(R_d*T_b*(1.0 + (R_v/R_d)*q_v)); + + rho = getRhogivenTandPress(T_b, pressure, q_v); rho = rho*(1.0 + q_v); + T_dp = compute_dewpoint_temperature(T_b, RH); } @@ -170,26 +165,19 @@ Problem::init_isentropic_hse_no_terrain(Real *theta, Real* r, Real* p, Real *q_v const Real& dz, const Real& prob_lo_z, const int& khi) { - - //FILE *file_IC; - //file_IC = fopen("input_sounding_probcpp.txt","w"); Real z, T_b, T_dp; // Compute the quantities at z = 0.5*dz (first cell center) z = prob_lo_z + 0.5*dz; p[0] = p_0; compute_p_k(p[0], p_0, theta[0], r[0], q_v[0], T_dp, T_b, dz, z, 0.0); - //fprintf(file_IC, "%0.15g %0.15g %0.15g %0.15g %0.15g %0.15g %0.15g\n", z, T_b-273.15, T_dp, p[0], r[0], theta[0], q_v[0]); for (int k=1;k<=khi;k++){ z = prob_lo_z + (k+0.5)*dz; p[k] = p[k-1]; compute_p_k(p[k], p[k-1], theta[k], r[k], q_v[k], T_dp, T_b, dz, z, r[k-1]); - //fprintf(file_IC, "%0.15g %0.15g %0.15g %0.15g %0.15g %0.15g %0.15g\n", z, T_b-273.15, T_dp, p[k], r[k], theta[k], q_v[k]); } - //fclose(file_IC); - r[khi+1] = r[khi]; } @@ -199,8 +187,6 @@ Problem::erf_init_dens_hse_moist (MultiFab& rho_hse, std::unique_ptr& z_phys_nd, Geometry const& geom) { - - const Real prob_lo_z = geom.ProbLo()[2]; const Real dz = geom.CellSize()[2]; const int khi = geom.Domain().bigEnd()[2]; @@ -241,17 +227,11 @@ Problem::erf_init_dens_hse_moist (MultiFab& rho_hse, Vector h_t(khi+2); Vector h_q_v(khi+2); - amrex::Gpu::DeviceVector d_r(khi+2); - amrex::Gpu::DeviceVector d_p(khi+2); - amrex::Gpu::DeviceVector d_t(khi+2); - amrex::Gpu::DeviceVector d_q_v(khi+2); - init_isentropic_hse_no_terrain(h_t.data(), h_r.data(),h_p.data(), h_q_v.data(), dz,prob_lo_z,khi); + amrex::Gpu::DeviceVector d_r(khi+2); + amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, h_r.begin(), h_r.end(), d_r.begin()); - amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, h_p.begin(), h_p.end(), d_p.begin()); - amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, h_t.begin(), h_t.end(), d_t.begin()); - amrex::Gpu::copyAsync(amrex::Gpu::hostToDevice, h_q_v.begin(), h_q_v.end(), d_q_v.begin()); Real* r = d_r.data(); @@ -355,18 +335,18 @@ Problem::init_custom_pert ( } theta_total = t[k] + delta_theta; - temperature = compute_temperature(p[k], theta_total); - Real T_b = compute_temperature(p[k], t[k]); + temperature = getTgivenPandTh(theta_total, p[k], (R_d/Cp_d)); + Real T_b = getTgivenPandTh(t[k] , p[k], (R_d/Cp_d)); RH = compute_relative_humidity(z, height, z_tr, p[k], T_b); Real q_v_hot = vapor_mixing_ratio(z, height, p[k], T_b, RH); rho = p[k]/(R_d*temperature*(1.0 + (R_v/R_d)*q_v_hot)); // Compute background quantities - Real temperature_back = compute_temperature(p[k], t[k]); - Real T_back = compute_temperature(p[k], t[k]); + Real temperature_back = getTgivenPandTh(t[k], p[k], (R_d/Cp_d)); + Real T_back = getTgivenPandTh(t[k], p[k], (R_d/Cp_d)); Real RH_back = compute_relative_humidity(z, height, z_tr, p[k], T_back); Real q_v_back = vapor_mixing_ratio(z, height, p[k], T_back, RH_back); - Real rho_back = p[k]/(R_d*temperature_back*(1.0 + (R_v/R_d)*q_v_back)); + Real rho_back = getRhogivenTandPress(temperature_back, p[k], q_v_back); // This version perturbs rho but not p state_pert(i, j, k, RhoTheta_comp) = rho*theta_total - rho_back*t[k]*(1.0 + (R_v/R_d)*q_v_back);// rho*d_t[k]*(1.0 + R_v_by_R_d*q_v_hot); diff --git a/Source/ERF_make_new_level.cpp b/Source/ERF_make_new_level.cpp index f9d29ce2b..dbe285ec8 100644 --- a/Source/ERF_make_new_level.cpp +++ b/Source/ERF_make_new_level.cpp @@ -63,11 +63,6 @@ void ERF::MakeNewLevelFromScratch (int lev, Real time, const BoxArray& ba_in, m_factory[lev] = std::make_unique(); #endif - // The number of ghost cells for density must be 1 greater than that for velocity - // so that we can go back in forth between velocity and momentum on all faces - // int ngrow_state = ComputeGhostCells(solverChoice.advChoice, solverChoice.use_NumDiff) + 1; - // int ngrow_vels = ComputeGhostCells(solverChoice.advChoice, solverChoice.use_NumDiff); - auto& lev_new = vars_new[lev]; auto& lev_old = vars_old[lev]; @@ -304,7 +299,6 @@ ERF::RemakeLevel (int lev, Real time, const BoxArray& ba, const DistributionMapp int ncomp_cons = vars_new[lev][Vars::cons].nComp(); IntVect ngrow_state = vars_new[lev][Vars::cons].nGrowVect(); - // int ngrow_state = ComputeGhostCells(solverChoice.advChoice, solverChoice.use_NumDiff) + 1; int ngrow_vels = ComputeGhostCells(solverChoice.advChoice, solverChoice.use_NumDiff); Vector temp_lev_new(Vars::NumTypes); diff --git a/Source/TimeIntegration/ERF_TI_fast_rhs_fun.H b/Source/TimeIntegration/ERF_TI_substep_fun.H similarity index 100% rename from Source/TimeIntegration/ERF_TI_fast_rhs_fun.H rename to Source/TimeIntegration/ERF_TI_substep_fun.H diff --git a/Source/TimeIntegration/ERF_advance_dycore.cpp b/Source/TimeIntegration/ERF_advance_dycore.cpp index 64313e133..e211ff464 100644 --- a/Source/TimeIntegration/ERF_advance_dycore.cpp +++ b/Source/TimeIntegration/ERF_advance_dycore.cpp @@ -276,8 +276,8 @@ void ERF::advance_dycore(int level, cons_to_prim(state_old[IntVars::cons], state_old[IntVars::cons].nGrow()); #include "ERF_TI_no_substep_fun.H" +#include "ERF_TI_substep_fun.H" #include "ERF_TI_slow_rhs_fun.H" -#include "ERF_TI_fast_rhs_fun.H" // *************************************************************************************** // Setup the integrator and integrate for a single timestep diff --git a/Source/TimeIntegration/Make.package b/Source/TimeIntegration/Make.package index d117f5e87..7333d3676 100644 --- a/Source/TimeIntegration/Make.package +++ b/Source/TimeIntegration/Make.package @@ -12,9 +12,9 @@ CEXE_sources += ERF_fast_rhs_N.cpp CEXE_sources += ERF_fast_rhs_T.cpp CEXE_sources += ERF_fast_rhs_MT.cpp -CEXE_headers += ERF_TI_fast_rhs_fun.H CEXE_headers += ERF_TI_slow_rhs_fun.H CEXE_headers += ERF_TI_no_substep_fun.H +CEXE_headers += ERF_TI_substep_fun.H CEXE_headers += ERF_TI_fast_headers.H CEXE_headers += ERF_TI_slow_headers.H CEXE_headers += ERF_TI_utils.H diff --git a/Source/Utils/ERF_EOS.H b/Source/Utils/ERF_EOS.H index 3d47639b8..dcae76733 100644 --- a/Source/Utils/ERF_EOS.H +++ b/Source/Utils/ERF_EOS.H @@ -9,34 +9,38 @@ /** * Function to return potential temperature given pressure and temperature * - * @params[in] pressure - * @params[in] temperature - * @params[in] rdOcp ratio of R_d to c_p + * @params[in ] P pressure + * @params[in ] T temperature + * @params[in ] rdOcp ratio of R_d to c_p + * @params[ out] potential temperature */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getThgivenPandT(const amrex::Real T, const amrex::Real P, const amrex::Real rdOcp) { - return T*std::pow(p_0/P, rdOcp); + return T * std::pow(p_0/P, rdOcp); } /** * Function to return temperature given pressure and potential temperature * - * @params[in] pressure - * @params[in] potential temperature - * @params[in] rdOcp ratio of R_d to c_p + * @params[in ] P pressure + * @params[in ] th potential temperature + * @params[in ] rdOcp ratio of R_d to c_p + * @params[ out] temperature */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE -amrex::Real getTgivenPandTh(const amrex::Real P, const amrex::Real Th, const amrex::Real rdOcp) +amrex::Real getTgivenPandTh(const amrex::Real th, const amrex::Real P, const amrex::Real rdOcp) { - return Th / std::pow(p_0/P, rdOcp); + return th / std::pow(p_0/P, rdOcp); } /** * Function to return temperature given density and potential temperature * - * @params[in] rho density - * @params[in] rhotheta density times potential temperature theta + * @params[in ] rho density + * @params[in ] rhotheta (density times potential temperature) + * @params[in ] qv water vapor + * @params[ out] temperature */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getTgivenRandRTh(const amrex::Real rho, const amrex::Real rhotheta, const amrex::Real qv=0.0) @@ -53,15 +57,18 @@ amrex::Real getTgivenRandRTh(const amrex::Real rho, const amrex::Real rhotheta, /** * Function to return potential temperature given density and temperature * - * @params[in] rho density - * @params[in] T temperature - * @params[in] rdOcp ratio of R_d to c_p + * @params[in ] rho density + * @params[in ] T temperature + * @params[in ] rdOcp ratio of R_d to c_p + * @params[in ] qv water vapor + * @params[ out] potential temperature */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getThgivenRandT(const amrex::Real rho, const amrex::Real T, const amrex::Real rdOcp, const amrex::Real qv=0.0) { // p = rho_d * R_d * T_moist amrex::Real p_loc = rho * R_d * T * (1.0 + R_v/R_d*qv); + // theta_d = T * (p0/p)^(R_d/C_p) return T * std::pow((p_0/p_loc),rdOcp); } @@ -69,49 +76,69 @@ amrex::Real getThgivenRandT(const amrex::Real rho, const amrex::Real T, const am /** * Function to return pressure given density times theta * - * @params[in] rhotheta density times potential temperature - * @params[in] qv water vapor + * @params[in ] rhotheta density times potential temperature + * @params[in ] qv water vapor + * @params[ out] pressure */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getPgivenRTh(const amrex::Real rhotheta, const amrex::Real qv = 0.) { - return p_0 * std::pow(R_d * rhotheta * (1.0+(R_v/R_d)*qv) * ip_0, Gamma); + return p_0 * std::pow(R_d * rhotheta * ( amrex::Real(1.0) + (R_v/R_d)*qv) * ip_0, Gamma); } /** * Function to return density given theta and pressure * - * @params[in] theta potential temperature - * @params[in] p pressure - * @params[in] rdOcp ratio of R_d to c_p + * @params[in ] theta potential temperature + * @params[in ] p pressure + * @params[in ] rdOcp ratio of R_d to c_p + * @params[in ] qv water vapor + * @params[ out] density */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE -amrex::Real getRhogivenThetaPress (const amrex::Real theta, const amrex::Real p, const amrex::Real rdOcp, const amrex::Real qv=0.0) +amrex::Real getRhogivenThetaPress (const amrex::Real th, const amrex::Real p, const amrex::Real rdOcp, const amrex::Real qv=0.0) { // We should be using moist value of theta when using moisture // theta_m = theta * (1 + R_v/R_d*qv) - return std::pow(p_0, rdOcp) * std::pow(p, iGamma) / (R_d * theta * (1.0 + R_v/R_d*qv) ); + return std::pow(p_0, rdOcp) * std::pow(p, iGamma) / (R_d * th * (amrex::Real(1.0) + R_v/R_d*qv) ); +} + +/** + * Function to return density given temperature and pressure + * + * @params[in ] theta potential temperature + * @params[in ] p pressure + * @params[in ] rdOcp ratio of R_d to c_p + * @params[in ] qv water vapor + * @params[ out] density +*/ +AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE +amrex::Real getRhogivenTandPress (const amrex::Real T, const amrex::Real p, const amrex::Real qv=0.0) +{ + return p / ( R_d * T * (amrex::Real(1.0) + (R_v/R_d)*qv) ); } /** * Function to return dP/drho at constant theta * - * @params[in] theta potential temperature - * @params[in] p pressure - * @params[in] rdOcp ratio of R_d to c_p + * @params[in ] rho density + * @params[in ] theta potential temperature + * @params[in ] qv water vapor + * @params[ out] pressure */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getdPdRgivenConstantTheta(const amrex::Real rho, const amrex::Real theta, const amrex::Real qv=0.0) { // We should be using moist value of theta when using moisture // theta_m = theta * (1 + R_v/R_d*qv) - return Gamma * p_0 * std::pow( (R_d * theta * (1.0 + R_v/R_d*qv) * ip_0), Gamma) * std::pow(rho, Gamma-1.0) ; + return Gamma * p_0 * std::pow( (R_d * theta * (amrex::Real(1.0) + R_v/R_d*qv) * ip_0), Gamma) * std::pow(rho, Gamma-1.0) ; } /** * Function to return the Exner function pi given pressure - * @params[in] p pressure - * @params[in] rdOcp ratio of R_d to c_p + * @params[in ] p pressure + * @params[in ] rdOcp ratio of R_d to c_p + * @params[ out] Exner function */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getExnergivenP(const amrex::Real P, const amrex::Real rdOcp) @@ -121,10 +148,12 @@ amrex::Real getExnergivenP(const amrex::Real P, const amrex::Real rdOcp) } /** - * Function to return the Exner function pi given densith times potential temperature + * Function to return the Exner function pi given density times potential temperature * - * @params[in] rhotheta density times potential temperature - * @params[in] rdOcp ratio of R_d to c_p + * @params[in ] rhotheta density times potential temperature + * @params[in ] rdOcp ratio of R_d to c_p + * @params[in ] qv water vapor + * @params[ out] Exner function */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getExnergivenRTh(const amrex::Real rhotheta, const amrex::Real rdOcp, const amrex::Real qv=0.0 ) @@ -136,9 +165,11 @@ amrex::Real getExnergivenRTh(const amrex::Real rhotheta, const amrex::Real rdOcp } /** - * Function to return the density given pressure + * Function to return (rho theta) given pressure * - * @params[in] p pressure + * @params[in ] p pressure + * @params[in ] qv water vapor + * @params[ out] density times potential temperature */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real getRhoThetagivenP(const amrex::Real p, const amrex::Real qv=0.0) @@ -149,5 +180,11 @@ amrex::Real getRhoThetagivenP(const amrex::Real p, const amrex::Real qv=0.0) return std::pow(p*std::pow(p_0, Gamma-1), iGamma) * iR_d / (1.0 + R_v/R_d*qv) ; } +AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE +amrex::Real compute_vapor_pressure (const amrex::Real p_s, const amrex::Real RH) +{ + return p_s*RH; +} + #endif From 4bc4950d90737b122d9b717218514576b44f7baf Mon Sep 17 00:00:00 2001 From: Ann Almgren Date: Wed, 6 Nov 2024 08:45:50 -0800 Subject: [PATCH 24/24] fix typo in EOS (#1931) --- Source/Utils/ERF_EOS.H | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Utils/ERF_EOS.H b/Source/Utils/ERF_EOS.H index dcae76733..978926a19 100644 --- a/Source/Utils/ERF_EOS.H +++ b/Source/Utils/ERF_EOS.H @@ -29,7 +29,7 @@ amrex::Real getThgivenPandT(const amrex::Real T, const amrex::Real P, const amre * @params[ out] temperature */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE -amrex::Real getTgivenPandTh(const amrex::Real th, const amrex::Real P, const amrex::Real rdOcp) +amrex::Real getTgivenPandTh(const amrex::Real P, const amrex::Real th, const amrex::Real rdOcp) { return th / std::pow(p_0/P, rdOcp); }