Grid Unit
Kamayan is built on parthenon's grid, which can support uniform, static
and adaptively refined meshes as a runtime option. The domain is initialized
as a uniform grid of nx1
xnx2
xnx3
cells. These can then be
partitioned onto an initial grid of MeshBlocks
, which can be further
refined based on various conditions. See Parameters for more
details on the runtime parameters that control this behavior.
Fields
Kamayan strongly prefers to reference field data stored on the MeshBlock
s through
the type based interface. Fields are associated with a struct
, and instantiations
of that type can be used to reference a desired element of that field if it
is declared with some tensor shape. Kamayan exports all possible fields in
kamayan/fields.hpp
, but which fields have been registered to the simulation
will depend on the configuration of the various units. Here fields are declared
with the VARIABLE
macro, which takes in the type name in all capital letters,
which also serves as the string label associated with the field, and optionally
a list of int
s that will become the tensor shape of the field when registered
with the kamayan::AddField[s]
interfaces.
// conserved variables
VARIABLE(DENS);
VARIABLE(MOMENTUM, 3); // will register with shape=std::vector<int>{3}
VARIABLE(ENER);
VARIABLE(MAG);
Note
KamayanUnit
s will register fields through the Initialize
callback interface
that returns a StateDescriptor
.
Packs
Field data can be accessed through the SparsePack
s
provided by parthenon that will pack variables by type into a single data structure
that can be used to index into cell level data on MeshBlock
s and MeshData
partitions. Kamayan provides an interface to directly get these packs, either
directly through listing explicitly the desired variables or by passing a
TypeList
of the variable structs you wish to access.
physics/hydro/hydro_add_flux_tasks.cpp:pack
// explicitly specify the fields we want
auto pack = grid::GetPack<DENS, VELOCITY, PRES>(mb);
// packing with a decl'ed `TypeList` from the HydroTraits
auto pack_recon = grid::GetPack(reconstruct_vars(), md);
auto pack_flux = grid::GetPack(conserved_vars(), md, {PDOpt::WithFluxes});
Note
Additional pack options can be specified. In this example the PDOpt::WithFluxes
option means that the associated fluxes if any for the packed variables will
also be accessible with the pack_flux.flux
interface.
Packs can then be indexed by block, variable and (k,j,i) index
pack(0, DENS(), k, j, i) = state(DENS());
pack(0, PRES(), k, j, i) = state(PRES());
pack(0, VELOCITY(0), k, j, i) = state(VELOCITY(0));
pack(0, VELOCITY(1), k, j, i) = state(VELOCITY(1));
Subpack
s
Often we don't need full access to all block, and cell indices of the pack. Rather it is advantageous only worry about a relative offset along the dimensions of interest for a particular function. Some examples are the conversion of primitive to conservative variables, which only cares about indexing into different fields at the same cell, or the reconstruction of Riemann states, which need only to index into the same field at neighboring zones along a one dimensional stencil.
Kamayan provides the SubPack
abstractions to wrap packs and
Kokkos::View
s to do just that.
auto U = SubPack(pack, b, k, j, i);
Prim2Cons<hydro_traits>(U, U);
U(DENS()) = V(DENS());
Real emag = 0.;
Real ekin = 0.;
for (int dir = 0; dir < 3; dir++) {
U(MOMENTUM(dir)) = V(DENS()) * V(VELOCITY(dir));
ekin += V(VELOCITY(dir)) * V(VELOCITY(dir));
if constexpr (hydro_traits::MHD != Mhd::off) {
U(MAGC(dir)) = V(MAGC(dir));
emag += V(MAGC(dir)) * V(MAGC(dir));
}
}
auto stencil = SubPack<Axis::IAXIS>(pack_recon, b, var, k, j, i);
Reconstruct<reconstruction_traits>(stencil, vM(var, i), vP(var, i));
const Real dvL = stencil(0) - stencil(-1);
const Real dvR = stencil(1) - stencil(0);
Parameters
Paramter | Type | Default | Allowed | Description |
---|---|---|---|---|
<parthenon/mesh> | ||||
ix1_bc | String | outflow | [ periodic, outflow, reflect, user, ] | Inner boundary condition along x1. |
ix2_bc | String | outflow | [ periodic, outflow, reflect, user, ] | Inner boundary condition along x2. |
ix3_bc | String | outflow | [ periodic, outflow, reflect, user, ] | Inner boundary condition along x3. |
nghost | Integer | 3 | Number of ghost zones to use on each block. | |
numlevel | Integer | 1 | Number of refinement levels. | |
nx1 | Integer | 32 | Number of cells across the domain at level 0. | |
nx2 | Integer | 32 | Number of cells across the domain at level 0. Set to 1 for 1D. | |
nx3 | Integer | 32 | Number of cells across the domain at level 0. Set to 1 for 2D. | |
ox1_bc | String | outflow | [ periodic, outflow, reflect, user, ] | Outer boundary condition along x1. |
ox2_bc | String | outflow | [ periodic, outflow, reflect, user, ] | Outer boundary condition along x2. |
ox3_bc | String | outflow | [ periodic, outflow, reflect, user, ] | Outer boundary condition along x3. |
refinement | String | adaptive | [ adaptive, static, none, ] | Mesh refinement startegy. |
x1max | Real | 1.00000e+00 | Maximum x1 value of domain. | |
x1min | Real | 0.00000e+00 | Minimum x1 value of domain. | |
x2max | Real | 1.00000e+00 | Maximum x2 value of domain. | |
x2min | Real | 0.00000e+00 | Minimum x2 value of domain. | |
x3max | Real | 1.00000e+00 | Maximum x3 value of domain. | |
x3min | Real | 0.00000e+00 | Minimum x3 value of domain. | |
<parthenon/meshblock> | ||||
nx1 | Integer | 16 | Size of meshblocks in x1. | |
nx2 | Integer | 16 | Size of meshblocks in x2. | |
nx3 | Integer | 16 | Size of meshblocks in x3. |