Rummy Input Files
Parthenon supports an extended input file format provided by the Link Rummy <https://github.com/lanl/rummy> library, in addition to the native, Athena++ format. Rummy input files provide expression evaluation, global variables, vector operations, relative block paths, file inclusion, and more.
Rummy is auto-detected — no special build flag is required. Whether a particular input file is parsed by Rummy or the native parser is determined automatically at runtime (see How Parthenon Detects Rummy Files).
Basic Syntax
Rummy input files share the same block/parameter structure as native files:
<blockname>
param = value # optional inline comment
other = 1.23
The key difference is that Rummy compiles the entire file from the top down, so any card defined earlier can be referenced by name in a later expression.
Global Variables
Variables declared before the first <block> header are global variables.
Global variables can be referenced by name anywhere in
the file without a block qualifier:
L = 1.0
rho = 2.5
<mesh>
Lx = L # reference the global variable L
Ly = L
Global variables are the simplest Rummy feature. Their presence (content
before the first <...> line) is one of the markers that causes Parthenon
to choose the Rummy parser automatically.
Expression Evaluation
Parameter values can be arbitrary arithmetic expressions.
Arithmetic
Syntax |
Meaning |
|---|---|
|
Addition / subtraction |
|
Multiplication / division |
|
Integer (floor) division |
|
Power (e.g. |
|
Modulo |
|
Named constant π |
Boolean (operate on true/false values)
Syntax |
Meaning |
|---|---|
|
Logical AND |
|
Logical OR |
|
Logical XOR |
|
Logical NOT (unary) |
Bitwise (operate on integers; also work on booleans)
Syntax |
Meaning |
|---|---|
|
Bitwise AND |
|
Bitwise OR |
|
Bitwise XOR |
|
Bitwise NOT (unary) |
|
Left shift |
|
Right shift |
Comparison: ==, !=, <, <=, >, >=
Examples:
dt = 0.45 * dx
gamma = 5.0/3.0
cv = 1.0/(gamma - 1.0)
vol = L**3
half_nx = nx // 2
use_mhd = hydro and conduction
Values from any previously-defined card (including cards in other blocks) can be referenced by their fully-qualified dotted name:
<eos>
gamma = 5.0/3.0
<gas>
cv = 1.0/(eos.gamma - 1.0)
Math Functions
Almost all <cmath> functions are available as built-in keywords:
Trigonometric — sin, cos, tan, asin, acos, atan,
atan2(y, x)
Exponential / logarithm — exp, log (natural), log10
Power / rounding — sqrt, ceil, floor, abs, sign
Extrema — min(a, b), max(a, b)
theta = pi / 4.0
vx = v * cos(theta)
vy = v * sin(theta)
r = sqrt(vx**2 + vy**2)
lo = min(r, 1.0)
Environment Variables
The special function env("VARIABLE") is available for reading environment variables. The output can be stored into a variable for later use.
Ternary Operator
The C-style ternary condition ? value_if_true : value_if_false is
supported:
nx = 64
ny = (nx > 32) ? nx // 2 : nx # ny = 32
label = (debug) ? "debug" : "production"
String Parameters
String values must be quoted:
<parthenon/job>
problem_id = "advection"
String concatenation uses +:
prefix = "my_"
<outputs>
label = prefix + "run"
Boolean Parameters
Boolean values are written as true or false (case-insensitive):
<physics>
hydro = true
conduction = false
do_work = hydro or conduction
both = hydro and conduction
neither = not hydro and not conduction
Vector Parameters
Vectors are comma-separated lists. Both bare and bracketed syntax work:
L = 1.0, 1.0, 0.5 # bare comma list
n = [10, 10, 1] # bracket syntax
Individual elements are accessed with zero-based indexing:
<mesh>
nx1 = n[0]
nx2 = n[1]
Slice assignments copy a range of elements from a vector into another:
xmin = -L[0]/2., -L[1]/2., -L[2]/2.
xmax[:] = 0.5 * L[:3] # broadcast scalar * slice
The [:] slice on the left-hand side means “all elements”; [:3] means
elements 0, 1, 2.
Relative Block Paths
A block header starting with <../ declares a child of the current block:
<gas>
name = "hydrogen"
<../eos> # expands to <gas/eos>
gamma = 5.0/3.0
<../conductivity> # expands to <gas/conductivity>
kappa = 0.1 / gas.eos.gamma
Relative paths allow logically related sub-blocks to stay near each other in the file without repeating long prefixes.
Including Other Files
The include statement inserts another file into the current compilation
at that point. All variables defined before the include are visible
inside the included file, and all variables defined inside are visible after
it returns:
# main.par
# use rummy
L = 1.0
nx = 64
include "mesh.par" # relative to the directory of main.par
include "/abs/path/eos.par" # absolute path also works
Circular includes are detected and cause a fatal error. Paths are resolved
relative to the directory of the file containing the include statement.
Multiple Input Files
Multiple -i arguments can be passed on the command line. All files are
compiled in the same Rummy compilation space, so variables defined in an
earlier file are available in later ones:
./my-app -i base.par -i overrides.par parthenon.time.nlim=100
# base.par
# use rummy
nx = 64
<parthenon/mesh>
nx1 = nx
# overrides.par — sees nx from base.par
nx = 128 # redefines nx for the higher-resolution run
Files are read in the order they appear on the command line.
Debugging Utilities
Three special statements print the current state of the compiler to standard output and are useful for debugging input decks:
__locals__Print all variables local to the current block (suit).
__globals__Print all globally defined variables (including cards from all previously compiled suits).
__stack__Print the current expression evaluation stack.
__list__The combined output of
__globals__,__locals__, and__stack__.
<mesh>
nx = 64
__globals__ # prints all globals including nx
The print Function
The built-in variadic print function writes any previously compiled card’s value to
standard output when the deck is loaded. It is useful for sanity-checking
derived quantities:
dt = 0.45 * dx
print("dt = ", dt)
Only cards defined before the print call can be printed.
Multiline Expressions
A trailing & continues an expression on the next line:
long_value = 1.0 &
+ 2.0 &
+ 3.0 # = 6.0
How Parthenon Detects Rummy Files
Parthenon auto-detects Rummy format without any explicit flag. A file (or command-line override string) is routed to the Rummy parser if any of the following is true:
The first non-blank line is
# use rummy(case-insensitive) — the explicit opt-in marker.There is non-comment, non-blank content before the first
<block>header (i.e., global variables are present).A block header begins with
<..(relative path syntax).A parameter name contains
.or[(dotted reference or vector index on the LHS).A parameter value contains any of:
**,",[,%,^, or|(expression operators or quoted strings).
To unconditionally use the native (Rummy) parser, place # use native (# use rummy) at the first line of the file:
# use rummy
<parthenon/time>
nlim = 100
tlim = 1.0
A native input file (no Rummy syntax) continues to be parsed by the native parser transparently.
Restart Files and Rummy
When restarting from an HDF5 restart file (-r), Parthenon loads the
parameter snapshot stored in the restart file using the native parser, then
layers any Rummy input file (-i) and command-line overrides on top.
The Rummy deck is seeded with all parameters from the restart before the Rummy file is compiled, so expressions in the Rummy file can reference values that came from the restart. For example:
./my-app -r run.out1.final.rhdf -i params.par parthenon.time.nlim=10
parthenon.time.nlim=10 is itself detected as a Rummy override (native
overrides use block/param=value syntax) and is applied after the restart
parameters are seeded into the deck.
Example
A complete minimal Rummy input file:
# use rummy
# --- Global parameters ---
L = 1.0
nx = 64
include "common_physics.par"
<parthenon/mesh>
nx1 = nx
nx2 = nx
x1min = -L/2.
x1max = L/2.
x2min = -L/2.
x2max = L/2.
<parthenon/time>
tlim = 2.0
nlim = -1
dt = 0.45 * L / nx # CFL-based initial guess
<../output> # relative: expands to parthenon/output
file_type = "hdf5"
dt = 0.1
__globals__ # print all compiled globals for debugging