diff --git a/Exec/science/flame_wave/ci-benchmarks/job_info_params.txt b/Exec/science/flame_wave/ci-benchmarks/job_info_params.txt index 4425286077..48571d7864 100644 --- a/Exec/science/flame_wave/ci-benchmarks/job_info_params.txt +++ b/Exec/science/flame_wave/ci-benchmarks/job_info_params.txt @@ -49,6 +49,7 @@ castro.hybrid_hydro = 0 castro.ppm_type = 1 castro.ppm_do_limiting = 1 + castro.ppm_one_sided_stencils = 0 castro.mhd_limit_characteristic = 1 castro.ppm_temp_fix = 0 castro.plm_iorder = 2 diff --git a/Source/driver/_cpp_parameters b/Source/driver/_cpp_parameters index 7d7ccaaf88..e7bd13120c 100644 --- a/Source/driver/_cpp_parameters +++ b/Source/driver/_cpp_parameters @@ -89,6 +89,9 @@ ppm_type int 1 # do we limit the ppm parabola? ppm_do_limiting bool 1 +# do we use one-sided stencils at reflecting boundaries? +ppm_one_sided_stencils bool 0 + # For MHD + PLM, do we limit on characteristic or primitive variables mhd_limit_characteristic bool 1 diff --git a/Source/hydro/Castro_mol.cpp b/Source/hydro/Castro_mol.cpp index 0d819107b7..9c1f62e70c 100644 --- a/Source/hydro/Castro_mol.cpp +++ b/Source/hydro/Castro_mol.cpp @@ -55,7 +55,7 @@ Castro::mol_plm_reconstruct(const Box& bx, Real s[nslp]; Real flat = flatn_arr(i,j,k); - load_stencil(q_arr, idir, i, j, k, n, s); + load_stencil(q_arr, reconstruction::Centering::zone_centered, idir, i, j, k, n, s); // normal velocity? bool vtest = n == QU+idir; @@ -83,9 +83,9 @@ Castro::mol_plm_reconstruct(const Box& bx, (idir == 1 && j == domhi[1]) || (idir == 2 && k == domhi[2])); - load_stencil(q_arr, idir, i, j, k, QPRES, s); - load_stencil(q_arr, idir, i, j, k, QRHO, trho); - load_stencil(src_q_arr, idir, i, j, k, QU+idir, src); + load_stencil(q_arr, reconstruction::Centering::zone_centered, idir, i, j, k, QPRES, s); + load_stencil(q_arr, reconstruction::Centering::zone_centered, idir, i, j, k, QRHO, trho); + load_stencil(src_q_arr, reconstruction::Centering::zone_centered, idir, i, j, k, QU+idir, src); Real dp = dq(i,j,k,QPRES); pslope(trho, s, src, flat, lo_bc_test, hi_bc_test, dx[idir], dp); @@ -164,8 +164,9 @@ Castro::mol_ppm_reconstruct(const Box& bx, Real sm; Real sp; - load_stencil(q_arr, idir, i, j, k, n, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(q_arr, reconstruction::Centering::zone_centered, idir, i, j, k, n, s); + ppm_reconstruct(s, reconstruction::Centering::zone_centered, + flat, sm, sp); if (idir == 0) { // right state at i-1/2 @@ -351,7 +352,7 @@ Castro::compute_flux_from_q(const Box& bx, // int iu, iv1, iv2; - int im1, im2, im3; + int imx1, imx2, imx3; auto coord = geom.Coord(); auto mom_check = mom_flux_has_p(idir, idir, coord); @@ -360,25 +361,25 @@ Castro::compute_flux_from_q(const Box& bx, iu = QU; iv1 = QV; iv2 = QW; - im1 = UMX; - im2 = UMY; - im3 = UMZ; + imx1 = UMX; + imx2 = UMY; + imx3 = UMZ; } else if (idir == 1) { iu = QV; iv1 = QU; iv2 = QW; - im1 = UMY; - im2 = UMX; - im3 = UMZ; + imx1 = UMY; + imx2 = UMX; + imx3 = UMZ; } else { iu = QW; iv1 = QU; iv2 = QV; - im1 = UMZ; - im2 = UMX; - im3 = UMY; + imx1 = UMZ; + imx2 = UMX; + imx3 = UMY; } #ifdef HYBRID_MOMENTUM @@ -395,12 +396,12 @@ Castro::compute_flux_from_q(const Box& bx, // Compute fluxes, order as conserved state (not q) F(i,j,k,URHO) = qint(i,j,k,QRHO)*u_adv; - F(i,j,k,im1) = F(i,j,k,URHO)*qint(i,j,k,iu); + F(i,j,k,imx1) = F(i,j,k,URHO)*qint(i,j,k,iu); if (mom_check) { - F(i,j,k,im1) += qint(i,j,k,QPRES); + F(i,j,k,imx1) += qint(i,j,k,QPRES); } - F(i,j,k,im2) = F(i,j,k,URHO)*qint(i,j,k,iv1); - F(i,j,k,im3) = F(i,j,k,URHO)*qint(i,j,k,iv2); + F(i,j,k,imx2) = F(i,j,k,URHO)*qint(i,j,k,iv1); + F(i,j,k,imx3) = F(i,j,k,URHO)*qint(i,j,k,iv2); Real rhoetot = rhoeint + 0.5_rt * qint(i,j,k,QRHO)* (qint(i,j,k,iu)*qint(i,j,k,iu) + diff --git a/Source/hydro/ppm.H b/Source/hydro/ppm.H index de67432033..0cdb1c171a 100644 --- a/Source/hydro/ppm.H +++ b/Source/hydro/ppm.H @@ -48,7 +48,7 @@ check_trace_source(amrex::Array4 const& srcQ, const int idir, /// Compute the coefficients of a parabolic reconstruction of the data in a zone. /// This uses the standard PPM limiters described in Colella & Woodward (1984) /// -/// @param s Real[nslp] the state to be reconstructed in zones i-2, i-1, i, i+1, i+2 +/// @param s Real[nslp] the state to be reconstructed in zones i-3, i-2, i-1, i, i+1, i+2, i+3 /// @param flatn The flattening coefficient /// @param sm The value of the parabola on the left edge of the zone /// @param sp The value of the parabola on the right edge of the zone @@ -56,67 +56,148 @@ check_trace_source(amrex::Array4 const& srcQ, const int idir, AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void ppm_reconstruct(const amrex::Real* s, + reconstruction::Centering centering, const amrex::Real flatn, amrex::Real& sm, amrex::Real& sp) { + // first we compute s_{i-1/2} -- the left interface value for zone i if (ppm_do_limiting) { - // Compute van Leer slopes + if (centering == reconstruction::Centering::zone_on_left_bndry) { - amrex::Real dsl = 2.0_rt * (s[im1] - s[im2]); - amrex::Real dsr = 2.0_rt * (s[i0] - s[im1]); + // use a stencil for when the current zone is on the left + // physical boundary. Then the left interface is on the + // physical boundary, MC Eq. 21 - amrex::Real dsvl_l = 0.0_rt; - if (dsl*dsr > 0.0_rt) { - amrex::Real dsc = 0.5_rt * (s[i0] - s[im2]); - dsvl_l = std::copysign(1.0_rt, dsc) * amrex::min(std::abs(dsc), std::abs(dsl), std::abs(dsr)); - } + sm = (1.0_rt/12.0_rt)*(25.0_rt*s[i0] - 23.0_rt*s[ip1] + + 13.0_rt*s[ip2] - 3.0_rt*s[ip3]); - dsl = 2.0_rt * (s[i0] - s[im1]); - dsr = 2.0_rt * (s[ip1] - s[i0]); + } else if (centering == reconstruction::Centering::zone_one_from_left_bndry) { - amrex::Real dsvl_r = 0.0_rt; - if (dsl*dsr > 0.0_rt) { - amrex::Real dsc = 0.5_rt * (s[ip1] - s[im1]); - dsvl_r = std::copysign(1.0_rt, dsc) * amrex::min(std::abs(dsc), std::abs(dsl),std::abs(dsr)); - } + // use a stencil for when the current zone is one zone + // away from the left physical boundary, and then the left + // interface is one zone away from the boundary, MC Eq. 22 - // Interpolate s to edges + sm = (1.0_rt/12.0_rt)*(3.0_rt*s[im1] + 13.0_rt*s[i0] - + 5.0_rt*s[ip1] + s[ip2]); - sm = 0.5_rt * (s[i0] + s[im1]) - (1.0_rt/6.0_rt) * (dsvl_r - dsvl_l); + // Make sure sedge lies in between adjacent cell-centered values - // Make sure sedge lies in between adjacent cell-centered values + sm = amrex::Clamp(sm, amrex::min(s[i0], s[im1]), amrex::max(s[i0], s[im1])); - sm = amrex::Clamp(sm, std::min(s[i0], s[im1]), std::max(s[i0], s[im1])); + } else if (centering == reconstruction::Centering::zone_on_right_bndry) { - // Compute van Leer slopes + // use a stencil for when the current zone is on the right + // physical boundary then the left interface is one zone + // away from the physical boundary - dsl = 2.0_rt * (s[i0] - s[im1]); - dsr = 2.0_rt * (s[ip1] - s[i0]); + sm = (1.0_rt/12.0_rt)*(3.0_rt*s[i0] + 13.0_rt*s[im1] - + 5.0_rt*s[im2] + s[im3]); - dsvl_l = 0.0_rt; - if (dsl*dsr > 0.0_rt) { - amrex::Real dsc = 0.5_rt * (s[ip1] - s[im1]); - dsvl_l = std::copysign(1.0_rt, dsc) * amrex::min(std::abs(dsc), std::abs(dsl), std::abs(dsr)); - } + // Make sure sedge lies in between adjacent cell-centered values + + sm = amrex::Clamp(sm, amrex::min(s[i0], s[im1]), amrex::max(s[i0], s[im1])); + + } else { + + + // Compute van Leer slopes + + amrex::Real dsl = 2.0_rt * (s[im1] - s[im2]); + amrex::Real dsr = 2.0_rt * (s[i0] - s[im1]); + + amrex::Real dsvl_l = 0.0_rt; + if (dsl*dsr > 0.0_rt) { + amrex::Real dsc = 0.5_rt * (s[i0] - s[im2]); + dsvl_l = std::copysign(1.0_rt, dsc) * amrex::min(std::abs(dsc), std::abs(dsl), std::abs(dsr)); + } + + dsl = 2.0_rt * (s[i0] - s[im1]); + dsr = 2.0_rt * (s[ip1] - s[i0]); + + amrex::Real dsvl_r = 0.0_rt; + if (dsl*dsr > 0.0_rt) { + amrex::Real dsc = 0.5_rt * (s[ip1] - s[im1]); + dsvl_r = std::copysign(1.0_rt, dsc) * amrex::min(std::abs(dsc), std::abs(dsl), std::abs(dsr)); + } + + // Interpolate s to edges + + sm = 0.5_rt * (s[i0] + s[im1]) - (1.0_rt/6.0_rt) * (dsvl_r - dsvl_l); - dsl = 2.0_rt * (s[ip1] - s[i0]); - dsr = 2.0_rt * (s[ip2] - s[ip1]); + // Make sure sedge lies in between adjacent cell-centered values + + sm = amrex::Clamp(sm, std::min(s[i0], s[im1]), std::max(s[i0], s[im1])); - dsvl_r = 0.0_rt; - if (dsl*dsr > 0.0_rt) { - amrex::Real dsc = 0.5_rt * (s[ip2] - s[i0]); - dsvl_r = std::copysign(1.0_rt, dsc) * amrex::min(std::abs(dsc), std::abs(dsl), std::abs(dsr)); } - // Interpolate s to edges + // now we compute s_{i+1/2} -- the right interface value for zone i + + if (centering == reconstruction::Centering::zone_on_left_bndry) { + + // use a stencil for when the current zone is on the left physical + // boundary. Then the right interface is one zone away from the + // physical boundary, + + sp = (1.0_rt/12.0_rt)*(3.0_rt*s[i0] + 13.0_rt*s[ip1] - + 5.0_rt*s[ip2] + s[ip3]); + + // Make sure sedge lies in between adjacent cell-centered values + + sp = amrex::Clamp(sp, amrex::min(s[ip1], s[i0]), amrex::max(s[ip1], s[i0])); + + } else if (centering == reconstruction::Centering::zone_on_right_bndry) { + + // use a stencil for when the current zone is on the right physical boundary + // then the right interface is on the physical boundary + + sp = (1.0_rt/12.0_rt)*(25.0_rt*s[i0] - 23.0_rt*s[im1] + + 13.0_rt*s[im2] - 3.0_rt*s[im3]); - sp = 0.5_rt * (s[ip1] + s[i0]) - (1.0_rt/6.0_rt) * (dsvl_r - dsvl_l); + } else if (centering == reconstruction::Centering::zone_one_from_right_bndry) { - // Make sure sedge lies in between adjacent cell-centered values + // use a stencil for when the current zone is one zone away from + // the right physical boundary, and then the right interface is one + // zone away from the boundary - sp = amrex::Clamp(sp, std::min(s[ip1], s[i0]), std::max(s[ip1], s[i0])); + sp = (1.0_rt/12.0_rt)*(3.0_rt*s[ip1] + 13.0_rt*s[i0] - + 5.0_rt*s[im1] + s[im2]); + // Make sure sedge lies in between adjacent cell-centered values + + sp = amrex::Clamp(sp, amrex::min(s[ip1], s[i0]), amrex::max(s[ip1], s[i0])); + + } else { + + // Compute van Leer slopes + + amrex::Real dsl = 2.0_rt * (s[i0] - s[im1]); + amrex::Real dsr = 2.0_rt * (s[ip1] - s[i0]); + + amrex::Real dsvl_l = 0.0_rt; + if (dsl*dsr > 0.0_rt) { + amrex::Real dsc = 0.5_rt * (s[ip1] - s[im1]); + dsvl_l = std::copysign(1.0_rt, dsc) * amrex::min(std::abs(dsc), std::abs(dsl), std::abs(dsr)); + } + + dsl = 2.0_rt * (s[ip1] - s[i0]); + dsr = 2.0_rt * (s[ip2] - s[ip1]); + + amrex::Real dsvl_r = 0.0_rt; + if (dsl*dsr > 0.0_rt) { + amrex::Real dsc = 0.5_rt * (s[ip2] - s[i0]); + dsvl_r = std::copysign(1.0_rt, dsc) * amrex::min(std::abs(dsc), std::abs(dsl), std::abs(dsr)); + } + + // Interpolate s to edges + + sp = 0.5_rt * (s[ip1] + s[i0]) - (1.0_rt/6.0_rt) * (dsvl_r - dsvl_l); + + // Make sure sedge lies in between adjacent cell-centered values + + sp = amrex::Clamp(sp, std::min(s[ip1], s[i0]), std::max(s[ip1], s[i0])); + + } // Flatten the parabola @@ -127,14 +208,14 @@ ppm_reconstruct(const amrex::Real* s, // from Colella and Sekora (2008), not the original PPM paper. if ((sp - s[i0]) * (s[i0] - sm) <= 0.0_rt) { - sp = s[i0]; - sm = s[i0]; + sp = s[i0]; + sm = s[i0]; } else if (std::abs(sp - s[i0]) >= 2.0_rt * std::abs(sm - s[i0])) { - sp = 3.0_rt * s[i0] - 2.0_rt * sm; + sp = 3.0_rt * s[i0] - 2.0_rt * sm; } else if (std::abs(sm - s[i0]) >= 2.0_rt * std::abs(sp - s[i0])) { - sm = 3.0_rt * s[i0] - 2.0_rt * sp; + sm = 3.0_rt * s[i0] - 2.0_rt * sp; } } else { @@ -170,8 +251,10 @@ ppm_reconstruct(const amrex::Real* s, /// AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE bool -ppm_reconstruct_pslope(const amrex::Real* rho, const amrex::Real* p, const amrex::Real* src, const amrex::Real flatn, +ppm_reconstruct_pslope(const amrex::Real* rho, const amrex::Real* p, const amrex::Real* src, const amrex::Real dx, + reconstruction::Centering centering, + const amrex::Real flatn, amrex::Real& sm, amrex::Real& sp) { amrex::Real tp[nslp]; @@ -182,9 +265,17 @@ ppm_reconstruct_pslope(const amrex::Real* rho, const amrex::Real* p, const amrex amrex::Real pp1_hse = p0_hse + 0.25_rt*dx * (rho[i0] + rho[ip1]) * (src[i0] + src[ip1]); amrex::Real pp2_hse = pp1_hse + 0.25_rt*dx * (rho[ip1] + rho[ip2]) * (src[ip1] + src[ip2]); + amrex::Real pp3_hse{}; + if (centering == reconstruction::Centering::zone_on_left_bndry) { + pp3_hse = pp2_hse + 0.25_rt*dx * (rho[ip2] + rho[ip3]) * (src[ip2] + src[ip3]); + } amrex::Real pm1_hse = p0_hse - 0.25_rt*dx * (rho[i0] + rho[im1]) * (src[i0] + src[im1]); amrex::Real pm2_hse = pm1_hse - 0.25_rt*dx * (rho[im1] + rho[im2]) * (src[im1] + src[im2]); + amrex::Real pm3_hse{}; + if (centering == reconstruction::Centering::zone_on_right_bndry) { + pm3_hse = pm2_hse - 0.25_rt*dx * (rho[im2] + rho[im3]) * (src[im2] + src[im3]); + } // this only makes sense if the pressures are positive bool ptest = p0_hse < 0.0 || @@ -193,6 +284,13 @@ ppm_reconstruct_pslope(const amrex::Real* rho, const amrex::Real* p, const amrex pm1_hse < 0.0 || pm2_hse < 0.0; + if (centering == reconstruction::Centering::zone_on_left_bndry) { + ptest = ptest || (pp3_hse < 0.0); + } + + if (centering == reconstruction::Centering::zone_on_right_bndry) { + ptest = ptest || (pm3_hse < 0.0); + } bool do_hse = !ptest && rho[i0] >= pslope_cutoff_density; @@ -204,22 +302,34 @@ ppm_reconstruct_pslope(const amrex::Real* rho, const amrex::Real* p, const amrex tp[ip1] = p[ip1] - pp1_hse; tp[ip2] = p[ip2] - pp2_hse; + if (centering == reconstruction::Centering::zone_on_left_bndry) { + tp[ip3] = p[ip3] - pp3_hse; + } tp[im1] = p[im1] - pm1_hse; tp[im2] = p[im2] - pm2_hse; + if (centering == reconstruction::Centering::zone_on_right_bndry) { + tp[im3] = p[im3] - pm3_hse; + } } else { // don't subtract off HSE + if (centering == reconstruction::Centering::zone_on_right_bndry) { + tp[im3] = p[im3]; + } tp[im2] = p[im2]; tp[im1] = p[im1]; tp[i0] = p[i0]; tp[ip1]= p[ip1]; tp[ip2] = p[ip2]; + if (centering == reconstruction::Centering::zone_on_left_bndry) { + tp[ip3] = p[ip3]; + } } - ppm_reconstruct(tp, flatn, sm, sp); + ppm_reconstruct(tp, centering, flatn, sm, sp); // now correct sm and sp to be back to the full pressure by @@ -262,7 +372,7 @@ ppm_int_profile(const amrex::Real sm, const amrex::Real sp, const amrex::Real sc // compute x-component of Ip and Im - Real s6 = 6.0_rt * sc - 3.0_rt * (sm + sp); + amrex::Real s6 = 6.0_rt * sc - 3.0_rt * (sm + sp); // Ip/m is the integral under the parabola for the extent // that a wave can travel over a timestep @@ -271,8 +381,8 @@ ppm_int_profile(const amrex::Real sm, const amrex::Real sp, const amrex::Real sc // Im integrates to the left edge of a cell // u-c wave - Real speed = u - c; - Real sigma = std::abs(speed) * dtdx; + amrex::Real speed = u - c; + amrex::Real sigma = std::abs(speed) * dtdx; // if speed == ZERO, then either branch is the same if (speed <= 0.0_rt) { @@ -323,15 +433,15 @@ ppm_int_profile(const amrex::Real sm, const amrex::Real sp, const amrex::Real sc /// AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void -ppm_int_profile_single(const Real sm, const Real sp, const Real sc, - const Real lam, const Real dtdx, - Real& Ip, Real& Im) { +ppm_int_profile_single(const amrex::Real sm, const amrex::Real sp, const amrex::Real sc, + const amrex::Real lam, const amrex::Real dtdx, + amrex::Real& Ip, amrex::Real& Im) { // Integrate the parabolic profile to the edge of the cell. // This is the MHD version. We come in already with the eigenvalues. // compute x-component of Ip and Im - Real s6 = 6.0_rt * sc - 3.0_rt * (sm + sp); + amrex::Real s6 = 6.0_rt * sc - 3.0_rt * (sm + sp); // Ip/m is the integral under the parabola for the extent // that a wave can travel over a timestep @@ -339,7 +449,7 @@ ppm_int_profile_single(const Real sm, const Real sp, const Real sc, // Ip integrates to the right edge of a cell // Im integrates to the left edge of a cell - Real sigma = std::abs(lam) * dtdx; + amrex::Real sigma = std::abs(lam) * dtdx; if (lam <= 0.0_rt) { Ip = sp; diff --git a/Source/hydro/reconstruction.H b/Source/hydro/reconstruction.H index 94a0f1b71f..f6e3d040e6 100644 --- a/Source/hydro/reconstruction.H +++ b/Source/hydro/reconstruction.H @@ -4,46 +4,220 @@ #include namespace reconstruction { - enum slope_indices { - im2 = 0, - im1, - i0, - ip1, - ip2, - nslp - }; + enum slope_indices : std::uint8_t { + im3 = 0, + im2, + im1, + i0, + ip1, + ip2, + ip3, + nslp + }; + + enum class Centering : std::uint8_t { + zone_on_left_bndry=0, + zone_one_from_left_bndry, + zone_centered, + zone_one_from_right_bndry, + zone_on_right_bndry + }; + +} + +AMREX_GPU_HOST_DEVICE AMREX_INLINE +reconstruction::Centering +get_centering(const int i, const int j, const int k, const int idir, + const amrex::GpuArray& domlo, const amrex::GpuArray& domhi, + const bool lo_bc_test, const bool hi_bc_test) { + + reconstruction::Centering centering{reconstruction::Centering::zone_centered}; + + if (ppm_one_sided_stencils && lo_bc_test && + ((idir == 0 && i == domlo[0]) || + (idir == 1 && j == domlo[1]) || + (idir == 2 && k == domlo[2]))) { + centering = reconstruction::Centering::zone_on_left_bndry; + + } else if (ppm_one_sided_stencils && lo_bc_test && + ((idir == 0 && i == domlo[0]+1) || + (idir == 1 && j == domlo[1]+1) || + (idir == 2 && k == domlo[2]+1))) { + centering = reconstruction::Centering::zone_one_from_left_bndry; + + } else if (ppm_one_sided_stencils && hi_bc_test && + ((idir == 0 && i == domhi[0]-1) || + (idir == 1 && j == domhi[1]-1) || + (idir == 2 && k == domhi[2]-1))) { + centering = reconstruction::Centering::zone_one_from_right_bndry; + + } else if (ppm_one_sided_stencils && hi_bc_test && + ((idir == 0 && i == domhi[0]) || + (idir == 1 && j == domhi[1]) || + (idir == 2 && k == domhi[2]))) { + centering = reconstruction::Centering::zone_on_right_bndry; + } + + return centering; + } + AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void -load_stencil(amrex::Array4 const& q_arr, const int idir, +load_stencil(amrex::Array4 const& q_arr, + reconstruction::Centering centering, const int idir, const int i, const int j, const int k, const int ncomp, amrex::Real* s) { using namespace reconstruction; - if (idir == 0) { - s[im2] = q_arr(i-2,j,k,ncomp); - s[im1] = q_arr(i-1,j,k,ncomp); - s[i0] = q_arr(i,j,k,ncomp); - s[ip1] = q_arr(i+1,j,k,ncomp); - s[ip2] = q_arr(i+2,j,k,ncomp); - - } else if (idir == 1) { - s[im2] = q_arr(i,j-2,k,ncomp); - s[im1] = q_arr(i,j-1,k,ncomp); - s[i0] = q_arr(i,j,k,ncomp); - s[ip1] = q_arr(i,j+1,k,ncomp); - s[ip2] = q_arr(i,j+2,k,ncomp); - - } else { - s[im2] = q_arr(i,j,k-2,ncomp); - s[im1] = q_arr(i,j,k-1,ncomp); - s[i0] = q_arr(i,j,k,ncomp); - s[ip1] = q_arr(i,j,k+1,ncomp); - s[ip2] = q_arr(i,j,k+2,ncomp); - - } + // care needs to be done when filling the stencil here, since we + // might be passing in the source for q_arr, which has + // NUM_GROW_SRC < NUM_GROW ghost cells. But we know that we only + // need the one-sided stencils when we are at a physical boundary, + // and we also know that extra zones are all inside the domain, so + // we don't access any cells we shouldn't if we fill according to + // the centering. + + switch (centering) { + case Centering::zone_on_left_bndry: + + // --- | --- | --- | --- | --- | --- | --- | + // i-3 i-2 i-1 ^ i i+1 i+2 i+3 + // ^ + // boundary + + if (idir == 0) { + s[i0] = q_arr(i,j,k,ncomp); + s[ip1] = q_arr(i+1,j,k,ncomp); + s[ip2] = q_arr(i+2,j,k,ncomp); + s[ip3] = q_arr(i+3,j,k,ncomp); + + } else if (idir == 1) { + s[i0] = q_arr(i,j,k,ncomp); + s[ip1] = q_arr(i,j+1,k,ncomp); + s[ip2] = q_arr(i,j+2,k,ncomp); + s[ip3] = q_arr(i,j+3,k,ncomp); + + } else { + s[i0] = q_arr(i,j,k,ncomp); + s[ip1] = q_arr(i,j,k+1,ncomp); + s[ip2] = q_arr(i,j,k+2,ncomp); + s[ip3] = q_arr(i,j,k+3,ncomp); + + } + break; + + case Centering::zone_one_from_left_bndry: + + // --- | --- | --- | --- | --- | --- | --- | + // i-3 i-2 ^ i-1 i i+1 i+2 i+3 + // ^ + // boundary + + if (idir == 0) { + s[im1] = q_arr(i-1,j,k,ncomp); + s[i0] = q_arr(i,j,k,ncomp); + s[ip1] = q_arr(i+1,j,k,ncomp); + s[ip2] = q_arr(i+2,j,k,ncomp); + + } else if (idir == 1) { + s[im1] = q_arr(i,j-1,k,ncomp); + s[i0] = q_arr(i,j,k,ncomp); + s[ip1] = q_arr(i,j+1,k,ncomp); + s[ip2] = q_arr(i,j+2,k,ncomp); + + } else { + s[im1] = q_arr(i,j,k-1,ncomp); + s[i0] = q_arr(i,j,k,ncomp); + s[ip1] = q_arr(i,j,k+1,ncomp); + s[ip2] = q_arr(i,j,k+2,ncomp); + + } + break; + + case Centering::zone_centered: + if (idir == 0) { + s[im2] = q_arr(i-2,j,k,ncomp); + s[im1] = q_arr(i-1,j,k,ncomp); + s[i0] = q_arr(i,j,k,ncomp); + s[ip1] = q_arr(i+1,j,k,ncomp); + s[ip2] = q_arr(i+2,j,k,ncomp); + + } else if (idir == 1) { + s[im2] = q_arr(i,j-2,k,ncomp); + s[im1] = q_arr(i,j-1,k,ncomp); + s[i0] = q_arr(i,j,k,ncomp); + s[ip1] = q_arr(i,j+1,k,ncomp); + s[ip2] = q_arr(i,j+2,k,ncomp); + + } else { + s[im2] = q_arr(i,j,k-2,ncomp); + s[im1] = q_arr(i,j,k-1,ncomp); + s[i0] = q_arr(i,j,k,ncomp); + s[ip1] = q_arr(i,j,k+1,ncomp); + s[ip2] = q_arr(i,j,k+2,ncomp); + + } + break; + + case Centering::zone_one_from_right_bndry: + + // --- | --- | --- | --- | --- | --- | --- | + // i-3 i-2 i-1 i i+1 ^ i+2 i+3 + // ^ + // boundary + + if (idir == 0) { + s[im2] = q_arr(i-2,j,k,ncomp); + s[im1] = q_arr(i-1,j,k,ncomp); + s[i0] = q_arr(i,j,k,ncomp); + s[ip1] = q_arr(i+1,j,k,ncomp); + + } else if (idir == 1) { + s[im2] = q_arr(i,j-2,k,ncomp); + s[im1] = q_arr(i,j-1,k,ncomp); + s[i0] = q_arr(i,j,k,ncomp); + s[ip1] = q_arr(i,j+1,k,ncomp); + + } else { + s[im2] = q_arr(i,j,k-2,ncomp); + s[im1] = q_arr(i,j,k-1,ncomp); + s[i0] = q_arr(i,j,k,ncomp); + s[ip1] = q_arr(i,j,k+1,ncomp); + + } + break; + + case Centering::zone_on_right_bndry: + + // --- | --- | --- | --- | --- | --- | --- | + // i-3 i-2 i-1 i ^ i+1 i+2 i+3 + // ^ + // boundary + + if (idir == 0) { + s[im3] = q_arr(i-3,j,k,ncomp); + s[im2] = q_arr(i-2,j,k,ncomp); + s[im1] = q_arr(i-1,j,k,ncomp); + s[i0] = q_arr(i,j,k,ncomp); + + } else if (idir == 1) { + s[im3] = q_arr(i,j-3,k,ncomp); + s[im2] = q_arr(i,j-2,k,ncomp); + s[im1] = q_arr(i,j-1,k,ncomp); + s[i0] = q_arr(i,j,k,ncomp); + + } else { + s[im3] = q_arr(i,j,k-3,ncomp); + s[im2] = q_arr(i,j,k-2,ncomp); + s[im1] = q_arr(i,j,k-1,ncomp); + s[i0] = q_arr(i,j,k,ncomp); + + } + break; + } } @@ -51,34 +225,131 @@ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void load_passive_stencil(amrex::Array4 const& U_arr, amrex::Array4 const& rho_inv_arr, - const int idir, + reconstruction::Centering centering, const int idir, const int i, const int j, const int k, const int ncomp, amrex::Real* s) { using namespace reconstruction; - if (idir == 0) { - s[im2] = U_arr(i-2,j,k,ncomp) * rho_inv_arr(i-2,j,k); - s[im1] = U_arr(i-1,j,k,ncomp) * rho_inv_arr(i-1,j,k); - s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); - s[ip1] = U_arr(i+1,j,k,ncomp) * rho_inv_arr(i+1,j,k); - s[ip2] = U_arr(i+2,j,k,ncomp) * rho_inv_arr(i+2,j,k); - - } else if (idir == 1) { - s[im2] = U_arr(i,j-2,k,ncomp) * rho_inv_arr(i,j-2,k); - s[im1] = U_arr(i,j-1,k,ncomp) * rho_inv_arr(i,j-1,k); - s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); - s[ip1] = U_arr(i,j+1,k,ncomp) * rho_inv_arr(i,j+1,k); - s[ip2] = U_arr(i,j+2,k,ncomp) * rho_inv_arr(i,j+2,k); - - } else { - s[im2] = U_arr(i,j,k-2,ncomp) * rho_inv_arr(i,j,k-2); - s[im1] = U_arr(i,j,k-1,ncomp) * rho_inv_arr(i,j,k-1); - s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); - s[ip1] = U_arr(i,j,k+1,ncomp) * rho_inv_arr(i,j,k+1); - s[ip2] = U_arr(i,j,k+2,ncomp) * rho_inv_arr(i,j,k+2); - - } + switch (centering) { + case Centering::zone_on_left_bndry: + + if (idir == 0) { + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + s[ip1] = U_arr(i+1,j,k,ncomp) * rho_inv_arr(i+1,j,k); + s[ip2] = U_arr(i+2,j,k,ncomp) * rho_inv_arr(i+2,j,k); + s[ip3] = U_arr(i+3,j,k,ncomp) * rho_inv_arr(i+3,j,k); + + } else if (idir == 1) { + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + s[ip1] = U_arr(i,j+1,k,ncomp) * rho_inv_arr(i,j+1,k); + s[ip2] = U_arr(i,j+2,k,ncomp) * rho_inv_arr(i,j+2,k); + s[ip3] = U_arr(i,j+3,k,ncomp) * rho_inv_arr(i,j+3,k); + + } else { + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + s[ip1] = U_arr(i,j,k+1,ncomp) * rho_inv_arr(i,j,k+1); + s[ip2] = U_arr(i,j,k+2,ncomp) * rho_inv_arr(i,j,k+2); + s[ip3] = U_arr(i,j,k+3,ncomp) * rho_inv_arr(i,j,k+3); + + } + break; + + case Centering::zone_one_from_left_bndry: + + if (idir == 0) { + s[im1] = U_arr(i-1,j,k,ncomp) * rho_inv_arr(i-1,j,k); + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + s[ip1] = U_arr(i+1,j,k,ncomp) * rho_inv_arr(i+1,j,k); + s[ip2] = U_arr(i+2,j,k,ncomp) * rho_inv_arr(i+2,j,k); + + } else if (idir == 1) { + s[im1] = U_arr(i,j-1,k,ncomp) * rho_inv_arr(i,j-1,k); + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + s[ip1] = U_arr(i,j+1,k,ncomp) * rho_inv_arr(i,j+1,k); + s[ip2] = U_arr(i,j+2,k,ncomp) * rho_inv_arr(i,j+2,k); + + } else { + s[im1] = U_arr(i,j,k-1,ncomp) * rho_inv_arr(i,j,k-1); + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + s[ip1] = U_arr(i,j,k+1,ncomp) * rho_inv_arr(i,j,k+1); + s[ip2] = U_arr(i,j,k+2,ncomp) * rho_inv_arr(i,j,k+2); + + } + break; + + case Centering::zone_centered: + + if (idir == 0) { + s[im2] = U_arr(i-2,j,k,ncomp) * rho_inv_arr(i-2,j,k); + s[im1] = U_arr(i-1,j,k,ncomp) * rho_inv_arr(i-1,j,k); + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + s[ip1] = U_arr(i+1,j,k,ncomp) * rho_inv_arr(i+1,j,k); + s[ip2] = U_arr(i+2,j,k,ncomp) * rho_inv_arr(i+2,j,k); + + } else if (idir == 1) { + s[im2] = U_arr(i,j-2,k,ncomp) * rho_inv_arr(i,j-2,k); + s[im1] = U_arr(i,j-1,k,ncomp) * rho_inv_arr(i,j-1,k); + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + s[ip1] = U_arr(i,j+1,k,ncomp) * rho_inv_arr(i,j+1,k); + s[ip2] = U_arr(i,j+2,k,ncomp) * rho_inv_arr(i,j+2,k); + + } else { + s[im2] = U_arr(i,j,k-2,ncomp) * rho_inv_arr(i,j,k-2); + s[im1] = U_arr(i,j,k-1,ncomp) * rho_inv_arr(i,j,k-1); + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + s[ip1] = U_arr(i,j,k+1,ncomp) * rho_inv_arr(i,j,k+1); + s[ip2] = U_arr(i,j,k+2,ncomp) * rho_inv_arr(i,j,k+2); + + } + break; + + case Centering::zone_one_from_right_bndry: + + if (idir == 0) { + s[im2] = U_arr(i-2,j,k,ncomp) * rho_inv_arr(i-2,j,k); + s[im1] = U_arr(i-1,j,k,ncomp) * rho_inv_arr(i-1,j,k); + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + s[ip1] = U_arr(i+1,j,k,ncomp) * rho_inv_arr(i+1,j,k); + + } else if (idir == 1) { + s[im2] = U_arr(i,j-2,k,ncomp) * rho_inv_arr(i,j-2,k); + s[im1] = U_arr(i,j-1,k,ncomp) * rho_inv_arr(i,j-1,k); + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + s[ip1] = U_arr(i,j+1,k,ncomp) * rho_inv_arr(i,j+1,k); + + } else { + s[im2] = U_arr(i,j,k-2,ncomp) * rho_inv_arr(i,j,k-2); + s[im1] = U_arr(i,j,k-1,ncomp) * rho_inv_arr(i,j,k-1); + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + s[ip1] = U_arr(i,j,k+1,ncomp) * rho_inv_arr(i,j,k+1); + + } + break; + + case Centering::zone_on_right_bndry: + + if (idir == 0) { + s[im3] = U_arr(i-3,j,k,ncomp) * rho_inv_arr(i-3,j,k); + s[im2] = U_arr(i-2,j,k,ncomp) * rho_inv_arr(i-2,j,k); + s[im1] = U_arr(i-1,j,k,ncomp) * rho_inv_arr(i-1,j,k); + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + + } else if (idir == 1) { + s[im3] = U_arr(i,j-3,k,ncomp) * rho_inv_arr(i,j-3,k); + s[im2] = U_arr(i,j-2,k,ncomp) * rho_inv_arr(i,j-2,k); + s[im1] = U_arr(i,j-1,k,ncomp) * rho_inv_arr(i,j-1,k); + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + + } else { + s[im3] = U_arr(i,j,k-3,ncomp) * rho_inv_arr(i,j,k-3); + s[im2] = U_arr(i,j,k-2,ncomp) * rho_inv_arr(i,j,k-2); + s[im1] = U_arr(i,j,k-1,ncomp) * rho_inv_arr(i,j,k-1); + s[i0] = U_arr(i,j,k,ncomp) * rho_inv_arr(i,j,k); + + } + break; + } } @@ -103,21 +374,29 @@ add_geometric_rho_source(amrex::Array4 const& q_arr, // ncomp should be QU for idir == 0 and QV for idir == 1 + // note, we know that dloga and q_arr all have NUM_GROW ghost + // cells, so we can fill the entire stencil and not worry about + // the centering. + if (ncomp == QU) { + s[im3] += -dloga(i-3,j,k) * q_arr(i-3,j,k,QRHO) * q_arr(i-3,j,k,ncomp); s[im2] += -dloga(i-2,j,k) * q_arr(i-2,j,k,QRHO) * q_arr(i-2,j,k,ncomp); s[im1] += -dloga(i-1,j,k) * q_arr(i-1,j,k,QRHO) * q_arr(i-1,j,k,ncomp); s[i0] += -dloga(i,j,k) * q_arr(i,j,k,QRHO) * q_arr(i,j,k,ncomp); s[ip1] += -dloga(i+1,j,k) * q_arr(i+1,j,k,QRHO) * q_arr(i+1,j,k,ncomp); s[ip2] += -dloga(i+2,j,k) * q_arr(i+2,j,k,QRHO) * q_arr(i+2,j,k,ncomp); + s[ip3] += -dloga(i+3,j,k) * q_arr(i+3,j,k,QRHO) * q_arr(i+3,j,k,ncomp); } else if (ncomp == QV) { + s[im3] += -dloga(i,j-3,k) * q_arr(i,j-3,k,QRHO) * q_arr(i,j-3,k,ncomp); s[im2] += -dloga(i,j-2,k) * q_arr(i,j-2,k,QRHO) * q_arr(i,j-2,k,ncomp); s[im1] += -dloga(i,j-1,k) * q_arr(i,j-1,k,QRHO) * q_arr(i,j-1,k,ncomp); s[i0] += -dloga(i,j,k) * q_arr(i,j,k,QRHO) * q_arr(i,j,k,ncomp); s[ip1] += -dloga(i,j+1,k) * q_arr(i,j+1,k,QRHO) * q_arr(i,j+1,k,ncomp); s[ip2] += -dloga(i,j+2,k) * q_arr(i,j+2,k,QRHO) * q_arr(i,j+2,k,ncomp); + s[ip3] += -dloga(i,j+3,k) * q_arr(i,j+3,k,QRHO) * q_arr(i,j+3,k,ncomp); } @@ -144,21 +423,29 @@ add_geometric_rhoe_source(amrex::Array4 const& q_arr, // ncomp should be QU for idir == 0 and QV for idir == 1 + // note, we know that dloga and q_arr all have NUM_GROW ghost + // cells, so we can fill the entire stencil and not worry about + // the centering. + if (ncomp == QU) { + s[im3] += -dloga(i-3,j,k) * (q_arr(i-3,j,k,QREINT) + q_arr(i-3,j,k,QPRES)) * q_arr(i-3,j,k,ncomp); s[im2] += -dloga(i-2,j,k) * (q_arr(i-2,j,k,QREINT) + q_arr(i-2,j,k,QPRES)) * q_arr(i-2,j,k,ncomp); s[im1] += -dloga(i-1,j,k) * (q_arr(i-1,j,k,QREINT) + q_arr(i-1,j,k,QPRES)) * q_arr(i-1,j,k,ncomp); s[i0] += -dloga(i,j,k) * (q_arr(i,j,k,QREINT) + q_arr(i,j,k,QPRES)) * q_arr(i,j,k,ncomp); s[ip1] += -dloga(i+1,j,k) * (q_arr(i+1,j,k,QREINT) + q_arr(i+1,j,k,QPRES)) * q_arr(i+1,j,k,ncomp); s[ip2] += -dloga(i+2,j,k) * (q_arr(i+2,j,k,QREINT) + q_arr(i+2,j,k,QPRES)) * q_arr(i+2,j,k,ncomp); + s[ip3] += -dloga(i+3,j,k) * (q_arr(i+3,j,k,QREINT) + q_arr(i+3,j,k,QPRES)) * q_arr(i+3,j,k,ncomp); } else if (ncomp == QV) { + s[im3] += -dloga(i,j-3,k) * (q_arr(i,j-3,k,QREINT) + q_arr(i,j-3,k,QPRES)) * q_arr(i,j-3,k,ncomp); s[im2] += -dloga(i,j-2,k) * (q_arr(i,j-2,k,QREINT) + q_arr(i,j-2,k,QPRES)) * q_arr(i,j-2,k,ncomp); s[im1] += -dloga(i,j-1,k) * (q_arr(i,j-1,k,QREINT) + q_arr(i,j-1,k,QPRES)) * q_arr(i,j-1,k,ncomp); s[i0] += -dloga(i,j,k) * (q_arr(i,j,k,QREINT) + q_arr(i,j,k,QPRES)) * q_arr(i,j,k,ncomp); s[ip1] += -dloga(i,j+1,k) * (q_arr(i,j+1,k,QREINT) + q_arr(i,j+1,k,QPRES)) * q_arr(i,j+1,k,ncomp); s[ip2] += -dloga(i,j+2,k) * (q_arr(i,j+2,k,QREINT) + q_arr(i,j+2,k,QPRES)) * q_arr(i,j+2,k,ncomp); + s[ip3] += -dloga(i,j+3,k) * (q_arr(i,j+3,k,QREINT) + q_arr(i,j+3,k,QPRES)) * q_arr(i,j+3,k,ncomp); } @@ -186,22 +473,29 @@ add_geometric_p_source(amrex::Array4 const& q_arr, // ncomp should be QU for idir == 0 and QV for idir == 1 + // note, we know that dloga, q_arr, and qaux_arr all have NUM_GROW + // ghost cells, so we can fill the entire stencil and not worry + // about the centering. if (ncomp == QU) { + s[im3] += -dloga(i-3,j,k) * q_arr(i-3,j,k,QPRES) * qaux_arr(i-3,j,k,QGAMC) * q_arr(i-3,j,k,ncomp); s[im2] += -dloga(i-2,j,k) * q_arr(i-2,j,k,QPRES) * qaux_arr(i-2,j,k,QGAMC) * q_arr(i-2,j,k,ncomp); s[im1] += -dloga(i-1,j,k) * q_arr(i-1,j,k,QPRES) * qaux_arr(i-1,j,k,QGAMC) * q_arr(i-1,j,k,ncomp); s[i0] += -dloga(i,j,k) * q_arr(i,j,k,QPRES) * qaux_arr(i,j,k,QGAMC) * q_arr(i,j,k,ncomp); s[ip1] += -dloga(i+1,j,k) * q_arr(i+1,j,k,QPRES) * qaux_arr(i+1,j,k,QGAMC) * q_arr(i+1,j,k,ncomp); s[ip2] += -dloga(i+2,j,k) * q_arr(i+2,j,k,QPRES) * qaux_arr(i+2,j,k,QGAMC) * q_arr(i+2,j,k,ncomp); + s[ip3] += -dloga(i+3,j,k) * q_arr(i+3,j,k,QPRES) * qaux_arr(i+3,j,k,QGAMC) * q_arr(i+3,j,k,ncomp); } else if (ncomp == QV) { + s[im2] += -dloga(i,j-3,k) * q_arr(i,j-3,k,QPRES) * qaux_arr(i,j-3,k,QGAMC) * q_arr(i,j-3,k,ncomp); s[im2] += -dloga(i,j-2,k) * q_arr(i,j-2,k,QPRES) * qaux_arr(i,j-2,k,QGAMC) * q_arr(i,j-2,k,ncomp); s[im1] += -dloga(i,j-1,k) * q_arr(i,j-1,k,QPRES) * qaux_arr(i,j-1,k,QGAMC) * q_arr(i,j-1,k,ncomp); s[i0] += -dloga(i,j,k) * q_arr(i,j,k,QPRES) * qaux_arr(i,j,k,QGAMC) * q_arr(i,j,k,ncomp); s[ip1] += -dloga(i,j+1,k) * q_arr(i,j+1,k,QPRES) * qaux_arr(i,j+1,k,QGAMC) * q_arr(i,j+1,k,ncomp); s[ip2] += -dloga(i,j+2,k) * q_arr(i,j+2,k,QPRES) * qaux_arr(i,j+2,k,QGAMC) * q_arr(i,j+2,k,ncomp); + s[ip3] += -dloga(i,j+3,k) * q_arr(i,j+3,k,QPRES) * qaux_arr(i,j+3,k,QGAMC) * q_arr(i,j+3,k,ncomp); } } diff --git a/Source/hydro/riemann_solvers.H b/Source/hydro/riemann_solvers.H index 19b93287a7..899675ec4c 100644 --- a/Source/hydro/riemann_solvers.H +++ b/Source/hydro/riemann_solvers.H @@ -26,37 +26,37 @@ compute_flux_q(const int i, const int j, const int k, const int idir, // given a primitive state, compute the flux in direction idir // - int im1, im2, im3; + int imx1, imx2, imx3; auto coord = geomdata.Coord(); auto mom_check = mom_flux_has_p(idir, idir, coord); if (idir == 0) { - im1 = UMX; - im2 = UMY; - im3 = UMZ; + imx1 = UMX; + imx2 = UMY; + imx3 = UMZ; } else if (idir == 1) { - im1 = UMY; - im2 = UMX; - im3 = UMZ; + imx1 = UMY; + imx2 = UMX; + imx3 = UMZ; } else { - im1 = UMZ; - im2 = UMX; - im3 = UMY; + imx1 = UMZ; + imx2 = UMX; + imx3 = UMY; } // Compute fluxes, order as conserved state (not q) F(i,j,k,URHO) = qint.rho * qint.un; - F(i,j,k,im1) = F(i,j,k,URHO) * qint.un; - F(i,j,k,im2) = F(i,j,k,URHO) * qint.ut; - F(i,j,k,im3) = F(i,j,k,URHO) * qint.utt; + F(i,j,k,imx1) = F(i,j,k,URHO) * qint.un; + F(i,j,k,imx2) = F(i,j,k,URHO) * qint.ut; + F(i,j,k,imx3) = F(i,j,k,URHO) * qint.utt; #ifndef RADIATION if (mom_check) { - F(i,j,k,im1) += qint.p; + F(i,j,k,imx1) += qint.p; } Real rhoetot = qint.rhoe + 0.5_rt * qint.rho * @@ -68,7 +68,7 @@ compute_flux_q(const int i, const int j, const int k, const int idir, F(i,j,k,UEINT) = qint.un * qint.rhoe; #else if (mom_check) { - F(i,j,k,im1) += qint.p_g; + F(i,j,k,imx1) += qint.p_g; } Real rhoetot = qint.rhoe_g + 0.5_rt * qint.rho * diff --git a/Source/hydro/trace_plm.cpp b/Source/hydro/trace_plm.cpp index 20e75ba02c..00c9bd3fd5 100644 --- a/Source/hydro/trace_plm.cpp +++ b/Source/hydro/trace_plm.cpp @@ -159,7 +159,7 @@ Castro::trace_plm(const Box& bx, const int idir, for (int n = 0; n < NEIGN; n++) { int v = cvars[n]; - load_stencil(q_arr, idir, i, j, k, v, s); + load_stencil(q_arr, reconstruction::Centering::zone_centered, idir, i, j, k, v, s); bool vtest = v == QUN; dq[n] = uslope(s, flat, lo_bc_test && vtest, hi_bc_test && vtest); @@ -171,9 +171,9 @@ Castro::trace_plm(const Box& bx, const int idir, Real trho[nslp]; Real src[nslp]; - load_stencil(q_arr, idir, i, j, k, QPRES, s); - load_stencil(q_arr, idir, i, j, k, QRHO, trho); - load_stencil(srcQ, idir, i, j, k, QUN, src); + load_stencil(q_arr, reconstruction::Centering::zone_centered, idir, i, j, k, QPRES, s); + load_stencil(q_arr, reconstruction::Centering::zone_centered, idir, i, j, k, QRHO, trho); + load_stencil(srcQ, reconstruction::Centering::zone_centered, idir, i, j, k, QUN, src); Real dp = dq[IEIGN_P]; pslope(trho, s, src, flat, lo_bc_test, hi_bc_test, dL, dp); @@ -355,7 +355,7 @@ Castro::trace_plm(const Box& bx, const int idir, // get the slope - load_passive_stencil(U_arr, rho_inv_arr, idir, i, j, k, nc, s); + load_passive_stencil(U_arr, rho_inv_arr, reconstruction::Centering::zone_centered, idir, i, j, k, nc, s); Real dX = uslope(s, flat, false, false); // Right state diff --git a/Source/hydro/trace_ppm.cpp b/Source/hydro/trace_ppm.cpp index 823c6ec726..3a3ec9bb6d 100644 --- a/Source/hydro/trace_ppm.cpp +++ b/Source/hydro/trace_ppm.cpp @@ -152,6 +152,17 @@ Castro::trace_ppm(const Box& bx, Real lsmall_dens = small_dens; Real lsmall_pres = small_pres; + // special care for reflecting BCs + const int* lo_bc = phys_bc.lo(); + const int* hi_bc = phys_bc.hi(); + + const auto domlo = geom.Domain().loVect3d(); + const auto domhi = geom.Domain().hiVect3d(); + + bool lo_symm = lo_bc[idir] == amrex::PhysBCType::symmetry; + bool hi_symm = hi_bc[idir] == amrex::PhysBCType::symmetry; + + // Trace to left and right edges using upwind PPM amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE (int i, int j, int k) noexcept @@ -159,6 +170,10 @@ Castro::trace_ppm(const Box& bx, Real dtdL = dt / dx[idir]; Real dL = dx[idir]; + // we might be using a one-sided stencil in some places, so get + // the centering + auto centering = get_centering(i, j, k, idir, domlo, domhi, lo_symm, hi_symm); + // Want dt/(rdtheta) instead of dt/dtheta for 2d Spherical if (coord == 2 && idir == 1) { Real r = problo[0] + static_cast(i + 0.5_rt) * dx[0]; @@ -199,14 +214,15 @@ Castro::trace_ppm(const Box& bx, Real sm; Real sp; - // reconstruct density Real Ip_rho[3]; Real Im_rho[3]; - load_stencil(q_arr, idir, i, j, k, QRHO, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(q_arr, centering, idir, i, j, k, QRHO, s); + ppm_reconstruct(s, centering, flat, sm, sp); + //sm = amrex::max(lsmall_dens, sm); + //sp = amrex::max(lsmall_dens, sp); ppm_int_profile(sm, sp, s[i0], un, cc, dtdL, Ip_rho, Im_rho); // reconstruct normal velocity @@ -216,8 +232,8 @@ Castro::trace_ppm(const Box& bx, Real Ip_un_2; Real Im_un_2; - load_stencil(q_arr, idir, i, j, k, QUN, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(q_arr, centering, idir, i, j, k, QUN, s); + ppm_reconstruct(s, centering, flat, sm, sp); ppm_int_profile_single(sm, sp, s[i0], un-cc, dtdL, Ip_un_0, Im_un_0); ppm_int_profile_single(sm, sp, s[i0], un+cc, dtdL, Ip_un_2, Im_un_2); @@ -226,7 +242,7 @@ Castro::trace_ppm(const Box& bx, Real Ip_p[3]; Real Im_p[3]; - load_stencil(q_arr, idir, i, j, k, QPRES, s); + load_stencil(q_arr, centering, idir, i, j, k, QPRES, s); bool in_hse{}; @@ -240,10 +256,10 @@ Castro::trace_ppm(const Box& bx, Real trho[nslp]; Real src[nslp]; - load_stencil(q_arr, idir, i, j, k, QRHO, trho); - load_stencil(srcQ, idir, i, j, k, QUN, src); + load_stencil(q_arr, centering, idir, i, j, k, QRHO, trho); + load_stencil(srcQ, centering, idir, i, j, k, QUN, src); - in_hse = ppm_reconstruct_pslope(trho, s, src, flat, dL, sm, sp); + in_hse = ppm_reconstruct_pslope(trho, s, src, dL, centering, flat, sm, sp); if (in_hse && castro::ppm_well_balanced) { // we are working with the perturbational pressure @@ -256,7 +272,7 @@ Castro::trace_ppm(const Box& bx, } } else { - ppm_reconstruct(s, flat, sm, sp); + ppm_reconstruct(s, centering, flat, sm, sp); ppm_int_profile(sm, sp, s[i0], un, cc, dtdL, Ip_p, Im_p); } @@ -265,8 +281,8 @@ Castro::trace_ppm(const Box& bx, Real Ip_rhoe[3]; Real Im_rhoe[3]; - load_stencil(q_arr, idir, i, j, k, QREINT, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(q_arr, centering, idir, i, j, k, QREINT, s); + ppm_reconstruct(s, centering, flat, sm, sp); ppm_int_profile(sm, sp, s[i0], un, cc, dtdL, Ip_rhoe, Im_rhoe); // reconstruct transverse velocities @@ -276,12 +292,12 @@ Castro::trace_ppm(const Box& bx, Real Ip_utt_1; Real Im_utt_1; - load_stencil(q_arr, idir, i, j, k, QUT, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(q_arr, centering, idir, i, j, k, QUT, s); + ppm_reconstruct(s, centering, flat, sm, sp); ppm_int_profile_single(sm, sp, s[i0], un, dtdL, Ip_ut_1, Im_ut_1); - load_stencil(q_arr, idir, i, j, k, QUTT, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(q_arr, centering, idir, i, j, k, QUTT, s); + ppm_reconstruct(s, centering, flat, sm, sp); ppm_int_profile_single(sm, sp, s[i0], un, dtdL, Ip_utt_1, Im_utt_1); // gamma_c @@ -291,8 +307,8 @@ Castro::trace_ppm(const Box& bx, Real Ip_gc_2; Real Im_gc_2; - load_stencil(qaux_arr, idir, i, j, k, QGAMC, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(qaux_arr, centering, idir, i, j, k, QGAMC, s); + ppm_reconstruct(s, centering, flat, sm, sp); ppm_int_profile_single(sm, sp, s[i0], un-cc, dtdL, Ip_gc_0, Im_gc_0); ppm_int_profile_single(sm, sp, s[i0], un+cc, dtdL, Ip_gc_2, Im_gc_2); @@ -316,13 +332,13 @@ Castro::trace_ppm(const Box& bx, #endif if (do_trace) { - load_stencil(srcQ, idir, i, j, k, QRHO, s); + load_stencil(srcQ, centering, idir, i, j, k, QRHO, s); #if AMREX_SPACEDIM <= 2 if (coord == 2 || (idir == 0 && coord == 1)) { add_geometric_rho_source(q_arr, dloga, i, j, k, QUN, s); } #endif - ppm_reconstruct(s, flat, sm, sp); + ppm_reconstruct(s, centering, flat, sm, sp); ppm_int_profile(sm, sp, s[i0], un, cc, dtdL, Ip_src_rho, Im_src_rho); } @@ -340,8 +356,8 @@ Castro::trace_ppm(const Box& bx, #endif if (do_trace) { - load_stencil(srcQ, idir, i, j, k, QUN, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(srcQ, centering, idir, i, j, k, QUN, s); + ppm_reconstruct(s, centering, flat, sm, sp); ppm_int_profile_single(sm, sp, s[i0], un-cc, dtdL, Ip_src_un_0, Im_src_un_0); ppm_int_profile_single(sm, sp, s[i0], un+cc, dtdL, Ip_src_un_2, Im_src_un_2); } @@ -362,13 +378,13 @@ Castro::trace_ppm(const Box& bx, #endif if (do_trace) { - load_stencil(srcQ, idir, i, j, k, QPRES, s); + load_stencil(srcQ, centering, idir, i, j, k, QPRES, s); #if AMREX_SPACEDIM <= 2 if (coord == 2 || (idir == 0 && coord == 1)) { add_geometric_p_source(q_arr, qaux_arr, dloga, i, j, k, QUN, s); } #endif - ppm_reconstruct(s, flat, sm, sp); + ppm_reconstruct(s, centering, flat, sm, sp); ppm_int_profile(sm, sp, s[i0], un, cc, dtdL, Ip_src_p, Im_src_p); } @@ -388,13 +404,13 @@ Castro::trace_ppm(const Box& bx, #endif if (do_trace) { - load_stencil(srcQ, idir, i, j, k, QREINT, s); + load_stencil(srcQ, centering, idir, i, j, k, QREINT, s); #if AMREX_SPACEDIM <= 2 if (coord == 2 || (idir == 0 && coord == 1)) { add_geometric_rhoe_source(q_arr, dloga, i, j, k, QUN, s); } #endif - ppm_reconstruct(s, flat, sm, sp); + ppm_reconstruct(s, centering, flat, sm, sp); ppm_int_profile(sm, sp, s[i0], un, cc, dtdL, Ip_src_rhoe, Im_src_rhoe); } @@ -410,8 +426,8 @@ Castro::trace_ppm(const Box& bx, #endif if (do_trace) { - load_stencil(srcQ, idir, i, j, k, QUT, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(srcQ, centering, idir, i, j, k, QUT, s); + ppm_reconstruct(s, centering, flat, sm, sp); ppm_int_profile_single(sm, sp, s[i0], un, dtdL, Ip_src_ut_1, Im_src_ut_1); } @@ -425,8 +441,8 @@ Castro::trace_ppm(const Box& bx, #endif if (do_trace) { - load_stencil(srcQ, idir, i, j, k, QUTT, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(srcQ, centering, idir, i, j, k, QUTT, s); + ppm_reconstruct(s, centering, flat, sm, sp); ppm_int_profile_single(sm, sp, s[i0], un, dtdL, Ip_src_utt_1, Im_src_utt_1); } @@ -443,8 +459,8 @@ Castro::trace_ppm(const Box& bx, const int nc = upassmap(ipassive); const int n = qpassmap(ipassive); - load_passive_stencil(U_arr, rho_inv_arr, idir, i, j, k, nc, s); - ppm_reconstruct(s, flat, sm, sp); + load_passive_stencil(U_arr, rho_inv_arr, centering, idir, i, j, k, nc, s); + ppm_reconstruct(s, centering, flat, sm, sp); ppm_int_profile_single(sm, sp, s[i0], un, dtdL, Ip_passive, Im_passive); // Plus state on face i diff --git a/Source/mhd/mhd_plm.cpp b/Source/mhd/mhd_plm.cpp index f86c255f53..9bfe20793e 100644 --- a/Source/mhd/mhd_plm.cpp +++ b/Source/mhd/mhd_plm.cpp @@ -57,34 +57,34 @@ Castro::plm(const Box& bx, // the velocity is int QUN; - load_stencil(s, idir, i, j, k, QRHO, Q[IEIGN_RHO]); - load_stencil(s, idir, i, j, k, QU, Q[IEIGN_U]); - load_stencil(s, idir, i, j, k, QV, Q[IEIGN_V]); - load_stencil(s, idir, i, j, k, QW, Q[IEIGN_W]); - load_stencil(s, idir, i, j, k, QPRES, Q[IEIGN_P]); + load_stencil(s, reconstruction::Centering::zone_centered, idir, i, j, k, QRHO, Q[IEIGN_RHO]); + load_stencil(s, reconstruction::Centering::zone_centered, idir, i, j, k, QU, Q[IEIGN_U]); + load_stencil(s, reconstruction::Centering::zone_centered, idir, i, j, k, QV, Q[IEIGN_V]); + load_stencil(s, reconstruction::Centering::zone_centered, idir, i, j, k, QW, Q[IEIGN_W]); + load_stencil(s, reconstruction::Centering::zone_centered, idir, i, j, k, QPRES, Q[IEIGN_P]); if (idir == 0) { QUN = IEIGN_U; // component (Bx) is omitted - load_stencil(s, idir, i, j, k, QMAGY, Q[IEIGN_BT]); - load_stencil(s, idir, i, j, k, QMAGZ, Q[IEIGN_BTT]); + load_stencil(s, reconstruction::Centering::zone_centered, idir, i, j, k, QMAGY, Q[IEIGN_BT]); + load_stencil(s, reconstruction::Centering::zone_centered, idir, i, j, k, QMAGZ, Q[IEIGN_BTT]); } else if (idir == 1) { QUN = IEIGN_V; // component (By) is omitted - load_stencil(s, idir, i, j, k, QMAGX, Q[IEIGN_BT]); - load_stencil(s, idir, i, j, k, QMAGZ, Q[IEIGN_BTT]); + load_stencil(s, reconstruction::Centering::zone_centered, idir, i, j, k, QMAGX, Q[IEIGN_BT]); + load_stencil(s, reconstruction::Centering::zone_centered, idir, i, j, k, QMAGZ, Q[IEIGN_BTT]); } else { QUN = IEIGN_W; // component (Bz) is omitted - load_stencil(s, idir, i, j, k, QMAGX, Q[IEIGN_BT]); - load_stencil(s, idir, i, j, k, QMAGY, Q[IEIGN_BTT]); + load_stencil(s, reconstruction::Centering::zone_centered, idir, i, j, k, QMAGX, Q[IEIGN_BT]); + load_stencil(s, reconstruction::Centering::zone_centered, idir, i, j, k, QMAGY, Q[IEIGN_BTT]); } @@ -281,7 +281,7 @@ Castro::plm(const Box& bx, Real un{}; Real X[nslp]; - load_stencil(s, idir, i, j, k, QFS+n, X); + load_stencil(s, reconstruction::Centering::zone_centered, idir, i, j, k, QFS+n, X); if (idir == 0) { un = s(i,j,k,QU); diff --git a/Source/mhd/mhd_ppm.cpp b/Source/mhd/mhd_ppm.cpp index 3221e1561c..151f555eb5 100644 --- a/Source/mhd/mhd_ppm.cpp +++ b/Source/mhd/mhd_ppm.cpp @@ -117,8 +117,8 @@ Castro::ppm_mhd(const Box& bx, int v = cvars[n]; - load_stencil(q_arr, idir, i, j, k, v, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(q_arr, reconstruction::Centering::zone_centered, idir, i, j, k, v, s); + ppm_reconstruct(s, reconstruction::Centering::zone_centered, flat, sm, sp); Real Ipt = 0.0; Real Imt = 0.0; @@ -347,8 +347,8 @@ Castro::ppm_mhd(const Box& bx, un = q_arr(i,j,k,QW); } - load_stencil(q_arr, idir, i, j, k, v, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(q_arr, reconstruction::Centering::zone_centered, idir, i, j, k, v, s); + ppm_reconstruct(s, reconstruction::Centering::zone_centered, flat, sm, sp); ppm_int_profile_single(sm, sp, s[i0], un, dtdx, Ips, Ims); if (idir == 0) { diff --git a/Source/radiation/trace_ppm_rad.cpp b/Source/radiation/trace_ppm_rad.cpp index e78180c6a0..07619e9c8e 100644 --- a/Source/radiation/trace_ppm_rad.cpp +++ b/Source/radiation/trace_ppm_rad.cpp @@ -206,8 +206,8 @@ Castro::trace_ppm_rad(const Box& bx, for (int n = 0; n < NQTHERM; n++) { if (n == QTEMP) continue; - load_stencil(q_arr, idir, i, j, k, n, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(q_arr, reconstruction::Centering::zone_centered, idir, i, j, k, n, s); + ppm_reconstruct(s, reconstruction::Centering::zone_centered, flat, sm, sp); ppm_int_profile(sm, sp, s[i0], un, cc, dtdx, Ip[n], Im[n]); } @@ -219,8 +219,8 @@ Castro::trace_ppm_rad(const Box& bx, const int n = qpassmap(ipassive); const int nc = upassmap(ipassive); - load_passive_stencil(U_arr, rho_inv_arr, idir, i, j, k, nc, s); - ppm_reconstruct(s, flat, sm, sp); + load_passive_stencil(U_arr, rho_inv_arr, reconstruction::Centering::zone_centered, idir, i, j, k, nc, s); + ppm_reconstruct(s, reconstruction::Centering::zone_centered, flat, sm, sp); ppm_int_profile(sm, sp, s[i0], un, cc, dtdx, Ip[n], Im[n]); } @@ -263,8 +263,8 @@ Castro::trace_ppm_rad(const Box& bx, if (do_trace) { - load_stencil(srcQ, idir, i, j, k, n, s); - ppm_reconstruct(s, flat, sm, sp); + load_stencil(srcQ, reconstruction::Centering::zone_centered, idir, i, j, k, n, s); + ppm_reconstruct(s, reconstruction::Centering::zone_centered, flat, sm, sp); ppm_int_profile(sm, sp, s[i0], un, cc, dtdx, Ip_src[n], Im_src[n]); } else {