Skip to content

Commit 7520da3

Browse files
pgreteBenWibkingpar-hermes
authored
Add reflecting boundary conditions (#140)
* bump Parthenon * Bump Parth to include restart ghost fix * update parthenon to openpmd branch * Bump Parthenon and Kokkos * Bump Kokkos 4.4.0 and Parthenon 24.08 * Add LW implosion problem * Fix history filename * Update interface (cleanup and workaround) * cpp-py-formatter * Fix typo * Remove unused vars * Add hydro bvals and LW implosion pgen * Add more details on outflow bound. conditions * Add reflection symmetry regression test --------- Co-authored-by: Ben Wibking <ben@wibking.com> Co-authored-by: par-hermes <par-hermes@automation.bot>
1 parent e7da245 commit 7520da3

14 files changed

Lines changed: 359 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ In between a subtle bug was introduced that resulted in inconsistent divergence
1010
refinement.
1111

1212
### Added (new features/APIs/variables/...)
13+
- [[PR 140]](https://github.com/parthenon-hpc-lab/athenapk/pull/140) Add hydro reflecting boundary conditions
1314
- [[PR102]](https://github.com/parthenon-hpc-lab/athenapk/pull/102) Add support for tracer particles
1415
- [[PR 89]](https://github.com/parthenon-hpc-lab/athenapk/pull/89) Add viscosity and resistivity
1516
- [[PR 1]](https://github.com/parthenon-hpc-lab/athenapk/pull/1) Add isotropic thermal conduction and RKL2 supertimestepping

docs/input.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,4 +407,24 @@ Following "restrictions" apply to the current tracer implementation:
407407
- Default tracer values (such as the primitive fields) are only updated right before writing an output file.
408408
- Ids are only unique if tracers are seeded at the beginning at the simulations and no new tracer particles are added dynamically while the simulation is running.
409409

410-
Please get in touch, if you interested in running simulations that require lifting one (or more) of those restrictions.
410+
Please get in touch, if you interested in running simulations that require lifting one (or more) of those restrictions.
411+
412+
## Boundary conditions
413+
414+
In addition to enrolling custom boundary conditions, three general options are currently supported by default:
415+
416+
- `periodic`: Work without restrictions (implemented in upstream Parthenon)
417+
- `outflow`: Last layer of active cells is copied into ghost cells. Work (technicaly) without restrictions (implemented in upstream Parthenon). Physically care must be taken when using outflow conditions in subsonic flows (as characteristics can travel into the domain, which is not properly handled by copying the active cell data).
418+
It is recommended to implement custom, problem specific boundary conditions for subsonic outflows, see large body of engineering literature.
419+
For supersonic outflows there is no issue as the flow itself is faster than the fastest characteristic.
420+
- `reflecting`: Work only for cell-centered *hydro* fluid variables
421+
(implemented in AthenaPK currently without support for particles or `Metadata::Fine` fields,
422+
where the latter are currently not being used in AthenaPK).
423+
Note, that we specifically do *not* provide "reflecting" boundary conditions for the magnetic
424+
fields as these kind of configurations are typically highly problem dependent and, thus,
425+
require manual treatment.
426+
427+
They are being used by specifying the name as parameter value for the
428+
`ix1_bc`, `ox1_bc`, `ix2_bc`, `ox2_bc`, `ix3_bc`, and `ox3_bc` paraemters
429+
in the `<parthenon/mesh>` block of the input file for the inner and outer
430+
(say left and right in x1 direction) in each coordinate direction, respectively.

inputs/lw_implode.in

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# AthenaPK - a performance portable block structured AMR MHD code
2+
# Copyright (c) 2024-2025, Athena Parthenon Collaboration. All rights reserved.
3+
# Licensed under the BSD 3-Clause License (the "LICENSE");
4+
5+
# Problem generator for square implosion problem
6+
# REFERENCE: R. Liska & B. Wendroff, SIAM J. Sci. Comput., 25, 995 (2003)
7+
<comment>
8+
problem = Liska Wendroff implosion
9+
10+
<job>
11+
problem_id = lw_implode
12+
13+
<problem/lw_implode>
14+
# Interior Conditions
15+
d_in = 0.125 # density
16+
p_in = 0.14 # pressure
17+
18+
# Exterior Conditions
19+
d_out = 1.0 # density
20+
p_out = 1.0 # pressure
21+
22+
<parthenon/mesh>
23+
refinement = none
24+
nghost = 3
25+
26+
nx1 = 256
27+
x1min = 0.0
28+
x1max = 0.3
29+
ix1_bc = reflecting
30+
ox1_bc = reflecting
31+
32+
nx2 = 256
33+
x2min = 0.0
34+
x2max = 0.3
35+
ix2_bc = reflecting
36+
ox2_bc = reflecting
37+
38+
nx3 = 1
39+
x3min = -0.5
40+
x3max = 0.5
41+
ix3_bc = periodic
42+
ox3_bc = periodic
43+
44+
<parthenon/meshblock>
45+
nx1 = 256
46+
nx2 = 256
47+
nx3 = 1
48+
49+
<parthenon/output0>
50+
file_type = hdf5
51+
dt = 0.1
52+
#dn = 1
53+
variables = prim
54+
id = prim
55+
56+
<parthenon/output1>
57+
file_type = hst
58+
dt = 0.1
59+
60+
<parthenon/time>
61+
integrator = vl2
62+
cfl = 0.4
63+
tlim = 2.5
64+
nlim = -1
65+
66+
<hydro>
67+
fluid = euler
68+
eos = adiabatic
69+
riemann = hllc
70+
reconstruction = plm
71+
gamma = 1.4

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ add_executable(
66
main.cpp
77
eos/adiabatic_glmmhd.cpp
88
units.hpp
9+
bvals/boundary_conditions_apk.hpp
910
eos/adiabatic_hydro.cpp
1011
hydro/diffusion/conduction.cpp
1112
hydro/diffusion/diffusion.cpp
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//========================================================================================
2+
// AthenaPK - a performance portable block structured AMR astrophysical MHD code.
3+
// Copyright (c) 2025, Athena-Parthenon Collaboration. All rights reserved.
4+
// Licensed under the 3-clause BSD License, see LICENSE file for details
5+
//========================================================================================
6+
//! \file boundary_conditions_apk.chpp
7+
// \brief AthenaPK specific boundary conditions
8+
//
9+
10+
#ifndef BVALS_BOUNDARY_CONDITIONS_APK_HPP_
11+
#define BVALS_BOUNDARY_CONDITIONS_APK_HPP_
12+
13+
#include <memory>
14+
#include <string>
15+
#include <vector>
16+
17+
// Parthenon headers
18+
#include <parthenon/package.hpp>
19+
20+
#include "basic_types.hpp"
21+
#include "bvals/boundary_conditions_generic.hpp"
22+
#include "mesh/domain.hpp"
23+
#include "mesh/mesh.hpp"
24+
#include "mesh/meshblock.hpp"
25+
#include "utils/error_checking.hpp"
26+
27+
#include "../main.hpp"
28+
29+
namespace Hydro {
30+
namespace BoundaryFunction {
31+
32+
using namespace parthenon::package::prelude;
33+
using parthenon::CoordinateDirection;
34+
// using parthenon::MeshBlockData;
35+
// using parthenon::Real;
36+
using parthenon::BoundaryFunction::BCSide;
37+
38+
template <CoordinateDirection DIR, BCSide SIDE>
39+
void ReflectBC(std::shared_ptr<MeshBlockData<Real>> &mbd, bool coarse) {
40+
// make sure DIR is X[123]DIR so we don't have to check again
41+
static_assert(DIR == X1DIR || DIR == X2DIR || DIR == X3DIR, "DIR must be X[123]DIR");
42+
43+
MeshBlock *pmb = mbd->GetBlockPointer();
44+
45+
auto hydro_pkg = pmb->packages.Get("Hydro");
46+
auto fluid = hydro_pkg->Param<Fluid>("fluid");
47+
PARTHENON_REQUIRE_THROWS(
48+
fluid == Fluid::euler,
49+
"Reflecting boundary conditions for MHD need special treatment.");
50+
51+
// convenient shorthands
52+
constexpr bool X1 = (DIR == X1DIR);
53+
constexpr bool X2 = (DIR == X2DIR);
54+
constexpr bool X3 = (DIR == X3DIR);
55+
constexpr bool INNER = (SIDE == BCSide::Inner);
56+
57+
const auto &bounds = coarse ? pmb->c_cellbounds : pmb->cellbounds;
58+
59+
const auto &range = X1 ? bounds.GetBoundsI(IndexDomain::interior)
60+
: (X2 ? bounds.GetBoundsJ(IndexDomain::interior)
61+
: bounds.GetBoundsK(IndexDomain::interior));
62+
const int ref = INNER ? range.s : range.e;
63+
64+
constexpr IndexDomain domain =
65+
INNER ? (X1 ? IndexDomain::inner_x1
66+
: (X2 ? IndexDomain::inner_x2 : IndexDomain::inner_x3))
67+
: (X1 ? IndexDomain::outer_x1
68+
: (X2 ? IndexDomain::outer_x2 : IndexDomain::outer_x3));
69+
70+
// used for reflections
71+
const int offset = (2 * ref) + (INNER ? -1 : 1);
72+
73+
auto cons = mbd->PackVariables(std::vector<std::string>{"cons"}, coarse);
74+
const bool fine = false; // no usage of fine fields in AthenaPK for now
75+
76+
const auto nv = IndexRange{0, cons.GetDim(4) - 1};
77+
pmb->par_for_bndry(
78+
"ReflectBC", nv, domain, parthenon::TopologicalElement::CC, coarse, fine,
79+
KOKKOS_LAMBDA(const int &v, const int &k, const int &j, const int &i) {
80+
const bool reflect = v == DIR;
81+
cons(v, k, j, i) =
82+
(reflect ? -1.0 : 1.0) *
83+
cons(v, X3 ? offset - k : k, X2 ? offset - j : j, X1 ? offset - i : i);
84+
});
85+
}
86+
87+
} // namespace BoundaryFunction
88+
} // namespace Hydro
89+
90+
#endif // BVALS_BOUNDARY_CONDITIONS_APK_HPP_

src/hydro/hydro_driver.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ TaskStatus RKL2StepFirst(MeshData<Real> *md_Y0, MeshData<Real> *md_Yjm1,
111111
auto Yjm2 = md_Yjm2->PackVariablesAndFluxes(flags_ind);
112112
auto MY0 = md_MY0->PackVariablesAndFluxes(flags_ind);
113113

114-
const int ndim = pmb->pmy_mesh->ndim;
115114
// Using separate loops for each dim as the launch overhead should be hidden
116115
// by enough work over the entire pack and it allows to not use any conditionals.
117116
parthenon::par_for(

src/main.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
#include <sstream>
66

77
// Parthenon headers
8+
#include "bvals/boundary_conditions_generic.hpp"
9+
#include "defs.hpp"
810
#include "globals.hpp"
911
#include "parthenon_manager.hpp"
1012

1113
// AthenaPK headers
14+
#include "bvals/boundary_conditions_apk.hpp"
1215
#include "hydro/hydro.hpp"
1316
#include "hydro/hydro_driver.hpp"
1417
#include "main.hpp"
@@ -89,6 +92,8 @@ int main(int argc, char *argv[]) {
8992
Hydro::ProblemInitPackageData = field_loop::ProblemInitPackageData;
9093
} else if (problem == "kh") {
9194
pman.app_input->MeshProblemGenerator = kh::ProblemGenerator;
95+
} else if (problem == "lw_implode") {
96+
pman.app_input->ProblemGenerator = lw_implode::ProblemGenerator;
9297
} else if (problem == "rand_blast") {
9398
pman.app_input->ProblemGenerator = rand_blast::ProblemGenerator;
9499
Hydro::ProblemInitPackageData = rand_blast::ProblemInitPackageData;
@@ -117,6 +122,23 @@ int main(int argc, char *argv[]) {
117122
PARTHENON_THROW(msg);
118123
}
119124

125+
const std::string REFLECTING = "reflecting";
126+
using BF = parthenon::BoundaryFace;
127+
using Hydro::BoundaryFunction::ReflectBC;
128+
using parthenon::BoundaryFunction::BCSide;
129+
pman.app_input->RegisterBoundaryCondition(BF::inner_x1, REFLECTING,
130+
ReflectBC<X1DIR, BCSide::Inner>);
131+
pman.app_input->RegisterBoundaryCondition(BF::outer_x1, REFLECTING,
132+
ReflectBC<X1DIR, BCSide::Outer>);
133+
pman.app_input->RegisterBoundaryCondition(BF::inner_x2, REFLECTING,
134+
ReflectBC<X2DIR, BCSide::Inner>);
135+
pman.app_input->RegisterBoundaryCondition(BF::outer_x2, REFLECTING,
136+
ReflectBC<X2DIR, BCSide::Outer>);
137+
pman.app_input->RegisterBoundaryCondition(BF::inner_x3, REFLECTING,
138+
ReflectBC<X3DIR, BCSide::Inner>);
139+
pman.app_input->RegisterBoundaryCondition(BF::outer_x3, REFLECTING,
140+
ReflectBC<X3DIR, BCSide::Outer>);
141+
120142
pman.ParthenonInitPackagesAndMesh();
121143

122144
// Startup the corresponding driver for the integrator

src/pgen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ target_sources(athenaPK PRIVATE
2020
kh.cpp
2121
linear_wave.cpp
2222
linear_wave_mhd.cpp
23+
lw_implode.cpp
2324
orszag_tang.cpp
2425
rand_blast.cpp
2526
sod.cpp

src/pgen/cluster/agn_feedback.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,6 @@ void AGNFeedback::FeedbackSrcTerm(parthenon::MeshData<parthenon::Real> *md,
290290

291291
// Velocity of added gas
292292
const Real jet_velocity = kinetic_jet_velocity_;
293-
const Real jet_specific_internal_e = kinetic_jet_e_;
294293

295294
// Amount of momentum density ( density * velocity) to dump in each cell
296295
const Real jet_momentum = jet_density * jet_velocity;

src/pgen/lw_implode.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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

Comments
 (0)