Setting up a Simulation
This guide covers how to create and configure Kamayan simulations using either C++ or Python.
C++
int main(int argc, char *argv[]) {
auto pman = kamayan::InitEnv(argc, argv);
auto units = std::make_shared<kamayan::UnitCollection>(kamayan::ProcessUnits());
auto simulation = std::make_shared<kamayan::KamayanUnit>("isentropic_vortex");
simulation->SetupParams = kamayan::isentropic_vortex::Setup;
simulation->InitializeData = kamayan::isentropic_vortex::Initialize;
simulation->ProblemGeneratorMeshBlock = kamayan::isentropic_vortex::ProblemGenerator;
units->Add(simulation);
auto driver = kamayan::InitPackages(pman, units);
auto driver_status = driver.Execute();
pman->ParthenonFinalize();
}
Kamayan itself is more of a library of KamayanUnits and a driver that is
steered by user code. Simulations must provide their own main function,
which will initialize kamayan, build a driver and execute the evolution
loop. The main work of creating a new simulation is in building the
driver from a UnitCollection. Kamayan provides a kamayan::ProcessUnits()
function that will build the default set of units, which can be modified
however one wishes. Additionally, units may be added into the UnitCollection,
which can hook into any of the interfaces described in Kamayan Infrastructure.
Most importantly a unit that provides a ProblemGenerator should be added
to set the initial conditions.
Finally the new problem can be added to the build with a provided cmake function.
Python
Introduction
The design of kamayan as a library of component units that can be used to build a standalone C++ program to run a simulation allows for a very similar program to be constructed using the provided Python bindings (pyKamayan).
API Reference
For detailed documentation of all Python classes and functions, see the API Reference.
Building a Simulation with pyKamayan
@kamayan_app(description="Sedov blast wave simulation")
def sedov() -> KamayanManager:
"""Build the KamayanManager for Sedov."""
units = kman.process_units(
"sedov", setup_params=setup, initialize=initialize, pgen=pgen
)
km = KamayanManager("sedov", units)
nxb = 32 # zones per block
nblocks = int(128 / 32) # number of blocks to get 128 zones at coarsest resolution
km.grid = AdaptiveGrid(
xbnd1=(-0.5, 0.5), # xmin/max
xbnd2=(-0.5, 0.5), # ymin/max
nxb1=nxb, # zones per block along x
nxb2=nxb,
num_levels=3, # 3 levels of refinement
nblocks1=nblocks, # number of root blocks in each direction
nblocks2=nblocks,
)
km.grid.refinement_fields.add("pres")
km.grid.boundary_conditions = gr.outflow_box()
km.driver = driver.Driver(integrator="rk2", tlim=0.05)
km.outputs.add("restarts", "rst", dt=0.01)
km.physics.hydro = Hydro(reconstruction="wenoz", riemann="hllc")
km.physics.eos = eos.GammaEos(gamma=5.0 / 3.0, mode_init="dens_pres")
km.params["sedov"] = {"density": 1.0, "pressure": 1.0e-5, "energy": 1.0}
return km
In complete analogy to the C++ approach, a UnitCollection is made using
kamayan_manager.process_units to construct a "sedov" unit using the provided
Python callbacks and taking the default unit collection provided by kamayan.
This is used to build the KamayanManager object that is used to set
input parameters and run the simulation. The KamayanManager owns a set of
properties that can be set with the various objects provided by the kamayan.code_units
module to set various input parameters in common combinations. Finally,
any arbitrary input parameter can be set through the KamayanManager.params property.
See the Simulation Manager and Core Module in the API reference for detailed documentation.
KamayanManager
kamayan.kamayan_manager.KamayanManager
Manages the an instance of the kamayan simulation.
write_input
Write out all the params owned by the unit data collection.
Format as a parthenon input file.
process_units
kamayan.kamayan_manager.process_units
process_units(
name: str,
setup_params: SetupInterface | None = None,
initialize: InitializeInterface | None = None,
pgen: ProblemGeneratorInterface | None = None,
) -> pk.UnitCollection
Build a default UnitCollection with a user provided KamayanUnit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name for user generated KamayanUnit |
required |
setup_params
|
SetupInterface | None
|
hook into parameter setup |
None
|
initialize
|
InitializeInterface | None
|
hook into package initialization |
None
|
pgen
|
ProblemGeneratorInterface | None
|
problem generator |
None
|
For details on UnitData, callbacks, and component architecture, see Kamayan Infrastructure.
Adding the CLI Interface
The @kamayan_app decorator automatically generates a command-line interface with common commands
for running, testing, and inspecting your simulation. See the CLI Interface
module in the API reference for detailed documentation.
kamayan_app Decorator
kamayan.cli.app.kamayan_app
Decorator to create a Kamayan simulation CLI.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
Optional[str]
|
Optional name for the simulation |
None
|
description
|
Optional[str]
|
Optional description for the CLI help |
None
|
Usage
@kamayan_app def my_simulation() -> KamayanManager: km = KamayanManager(...) # configure ... return km
if name == "main": my_simulation.app()
The decorated function can also be used directly
km = my_simulation()
Add the decorator and entry point to your simulation:
from kamayan import kamayan_app
@kamayan_app(description="Sedov blast wave simulation")
def sedov() -> KamayanManager:
# ... (simulation setup as shown above)
return km
if __name__ == "__main__":
sedov.app()
Running Your Simulation
We provide an entry point script kamayan that will launch a simulation from a script that has a function
decorated with the @kamayan_app decorator.
Single process:
Parallel (MPI):
MPI Command Order
Always put mpirun before uv run:
✓ mpirun -np 4 uv run kamayan ...
✗ uv run mpirun -np 4 kamayan ... (broken pipe error)
Dry run (generate input only):
Available Commands
The @kamayan_app decorator provides these commands:
| Command | Description |
|---|---|
run |
Execute simulation (default) |
run --dry-run |
Generate input file only |
generate-input |
Generate input file |
info |
Show configuration |
version |
Show Kamayan version |
Parthenon Arguments
Additional arguments are forwarded to Parthenon's argument parser. Kamayan
automatically generates its own input file, so the -i flag is not used.
| Argument | Description | Example |
|---|---|---|
-r <file> |
Restart from checkpoint | -r sedov.out0.00500.rhdf |
-a <file> |
Analyze/postprocess | -a output.phdf |
-d <dir> |
Run directory | -d /scratch/run |
-t hh:mm:ss |
Wall time limit | -t 01:30:00 |
-n |
Parse and quit | -n |
-m <n> |
Output mesh structure | -m 4 |
-c |
Show config | -c |
block/par=val |
Override parameters | sedov/density=2.0 |
Example: