|
| 1 | +//======================================================================================== |
| 2 | +// AthenaPK - a performance portable block structured AMR MHD code |
| 3 | +// Copyright (c) 2024, Athena Parthenon Collaboration. All rights reserved. |
| 4 | +// Licensed under the 3-Clause License (the "LICENSE") |
| 5 | +//======================================================================================== |
| 6 | +//! \file lw_implode.cpp |
| 7 | +//! \brief Problem generator for square implosion problem |
| 8 | +//! |
| 9 | +//! REFERENCE: R. Liska & B. Wendroff, SIAM J. Sci. Comput., 25, 995 (2003) |
| 10 | +//======================================================================================== |
| 11 | + |
| 12 | +// Parthenon headers |
| 13 | +#include "mesh/mesh.hpp" |
| 14 | +#include <parthenon/driver.hpp> |
| 15 | +#include <parthenon/package.hpp> |
| 16 | + |
| 17 | +// Athena headers |
| 18 | +#include "../main.hpp" |
| 19 | +#include "utils/error_checking.hpp" |
| 20 | + |
| 21 | +namespace lw_implode { |
| 22 | +using namespace parthenon::driver::prelude; |
| 23 | + |
| 24 | +void ProblemGenerator(MeshBlock *pmb, parthenon::ParameterInput *pin) { |
| 25 | + auto hydro_pkg = pmb->packages.Get("Hydro"); |
| 26 | + auto ib = pmb->cellbounds.GetBoundsI(IndexDomain::interior); |
| 27 | + auto jb = pmb->cellbounds.GetBoundsJ(IndexDomain::interior); |
| 28 | + auto kb = pmb->cellbounds.GetBoundsK(IndexDomain::interior); |
| 29 | + |
| 30 | + PARTHENON_REQUIRE_THROWS( |
| 31 | + hydro_pkg->Param<Fluid>("fluid") == Fluid::euler, |
| 32 | + "Only hydro runs are supported for LW implosion problem generator."); |
| 33 | + |
| 34 | + auto d_in = pin->GetReal("problem/lw_implode", "d_in"); |
| 35 | + auto p_in = pin->GetReal("problem/lw_implode", "p_in"); |
| 36 | + |
| 37 | + auto d_out = pin->GetReal("problem/lw_implode", "d_out"); |
| 38 | + auto p_out = pin->GetReal("problem/lw_implode", "p_out"); |
| 39 | + |
| 40 | + auto gm1 = pin->GetReal("hydro", "gamma") - 1.0; |
| 41 | + |
| 42 | + // initialize conserved variables |
| 43 | + auto &mbd = pmb->meshblock_data.Get(); |
| 44 | + auto &cons = mbd->Get("cons").data; |
| 45 | + auto &coords = pmb->coords; |
| 46 | + |
| 47 | + // Following Athena++ |
| 48 | + // https://github.com/PrincetonUniversity/athena/blob/1591aab84ba7055e5b356a8f069695ea451af8a0/src/pgen/lw_implode.cpp#L43 |
| 49 | + // to make sure the ICs are symmetric, set y0 to be in between cell centers |
| 50 | + const auto x2min = pin->GetReal("parthenon/mesh", "x2min"); |
| 51 | + const auto x2max = pin->GetReal("parthenon/mesh", "x2max"); |
| 52 | + Real y0 = 0.5 * (x2max + x2min); |
| 53 | + for (int j = jb.s; j <= jb.e; j++) { |
| 54 | + if (coords.Xc<2>(j) > y0) { |
| 55 | + // TODO(felker): check this condition for multi-meshblock setups |
| 56 | + // further adjust y0 to be between cell center and lower x2 face |
| 57 | + y0 = coords.Xf<2>(j) + 0.5 * coords.Dxf<2>(j); |
| 58 | + break; |
| 59 | + } |
| 60 | + } |
| 61 | + |
| 62 | + pmb->par_for( |
| 63 | + "Init lw_implode", kb.s, kb.e, jb.s, jb.e, ib.s, ib.e, |
| 64 | + KOKKOS_LAMBDA(const int k, const int j, const int i) { |
| 65 | + cons(IM1, k, j, i) = 0.0; |
| 66 | + cons(IM2, k, j, i) = 0.0; |
| 67 | + cons(IM3, k, j, i) = 0.0; |
| 68 | + if (coords.Xc<2>(j) > (y0 - coords.Xc<1>(i))) { |
| 69 | + cons(IDN, k, j, i) = d_out; |
| 70 | + cons(IEN, k, j, i) = p_out / gm1; |
| 71 | + } else { |
| 72 | + cons(IDN, k, j, i) = d_in; |
| 73 | + cons(IEN, k, j, i) = p_in / gm1; |
| 74 | + } |
| 75 | + }); |
| 76 | +} |
| 77 | +} // namespace lw_implode |
0 commit comments