Benchmarks
Published cases at their published resolution. Each has a driver in
benchmarks/: edit the settings at its top and run it on a GPU node. CI runs
the same discretization at a small resolution in tests/.
| case | driver | resolution | reference gamma^2 |
solver | wall time | hardware | agnimhd |
|---|---|---|---|---|---|---|---|
| DSHAPE tokamak | benchmarks/dshape.py |
Zernike 96x96x1, MPOL = 4 n, penalty 0.08 (n = 1) and 0.01 (n = 2 ... 5), Gamma = 5/3 |
n = 2: 2.770639e-4, 3: 2.791126e-4, 4: 1.785811e-4, 5: 6.459412e-5 |
shift-invert Lanczos, dense LU | about 265 s per mode (driver, n = 1, 2), mostly the penalty projector's SVD |
one 80 GB A100 | n = 2 ... 5 equal; n = 1: 5.31e-6, the paper's point is not reproduced |
DSHAPE tokamak
AGNI paper, arXiv:2608.01750v3, section 5.2 and figure 5. The equilibrium is
tests/data/dshape_imax0.98_1608.h5: a DESC DSHAPE tokamak with major radius
4.0 m, minor radius 1.198 m, volume-averaged beta 2.5 %, and rotational
transform from 0.978 on the axis (low shear inside rho = 0.5) to 0.359 at the
edge. Each toroidal mode n is solved on its own (one plane, d/dphi = i n),
with no mass density profile. The paper does not state the Zernike penalty;
its runs used 0.01 for every n. The benchmark uses 0.08 for n = 1, where
0.01 leaves a spurious unstable mode (below), and 0.01 for n = 2 ... 5.
The reference values are those runs. With B_N = Psi / (pi a^2), ion density
2.2e20 m^-3 and the proton mass they give the plotted AGNI growth rates, 2.24e4,
2.25e4, 1.80e4 and 1.08e4 rad/s for n = 2 ... 5 (n = 1: about 5e2 rad/s,
gamma^2 about 1.5e-7, read off the plot). The NIMSTELL points of the same
figure are 2.48e4, 2.40e4, 1.91e4 and 1.09e4 rad/s, and n = 1 stable.
Measured with benchmarks/dshape.py's settings on one A100 (n = 1 and n = 2
by the driver itself, n = 3, 4, 5 by the same discretization and solver in a
separate script):
n |
penalty | gamma^2 |
rad/s | paper |
|---|---|---|---|---|
| 1 | 0.08 | 5.310873e-6 | 3.10e3 | about 1.5e-7 (5.1e2 rad/s): not reproduced |
| 2 | 0.01 | 2.770639e-4 | 2.24e4 | 2.770639e-4 |
| 3 | 0.01 | 2.791125e-4 | 2.25e4 | 2.791126e-4 |
| 4 | 0.01 | 1.785811e-4 | 1.80e4 | 1.785811e-4 |
| 5 | 0.01 | 6.459412e-5 | 1.08e4 | 6.459412e-5 |
The eigenpair residuals are large, 4e2 to 3e3 for n = 2 ... 5 and 1.1e6 for
n = 1, because the whitened penalty makes the matrix stiff; the n = 2 ... 5
values still equal the paper's ARPACK values to seven digits, and the n = 1
value lies between those at penalty 0.05 and 0.1 (table below).
The penalty
The Zernike derivative matrices annihilate the nodal content the basis does not
represent, so that content has no field-line bending energy; the penalty
(zernike_penalty times the projector onto it) is all that holds it against
the pressure drive. gamma^2 therefore falls as the penalty grows, toward the
limit where that content is excluded, the displacement restricted to the
Zernike space. Only that limit is independent of the penalty.
The penalty is added to the energy matrix before the whitening, without the
quadrature weights, so the strength a mode sees varies over the nodes and grows
with the node count. Per unit penalty, the diagonal of the whitened penalty
ranges from 0.16 to 8.8e6 at 16x48 and from 0.42 to 2.3e9 at 32x64. At 16x48 the
paper's 0.01 is far too weak: n = 1 has 23 unstable modes up to
gamma^2 = 7.0e-2, and the most unstable one lies 99.4 % outside the Zernike
space. They disappear as the penalty grows (n = 1, MPOL = 4, lowest
eigenvalue of the dense matrix):
| penalty | 0.01 | 0.03 | 0.05 | 0.1 | 0.3 | 1 | 10 | limit |
|---|---|---|---|---|---|---|---|---|
| unstable modes | 23 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
gamma^2 |
7.0e-2 | 1.2e-4 | 5.9e-5 | 1.6e-5 | -1.32e-6 | -1.351e-6 | -1.357e-6 | -1.361e-6 |
At 96x96, MPOL = 4 n, shift-invert Lanczos on an A100 (the dense GPU
eigensolver returned wrong small eigenvalues there, already at penalty 0.01;
the whitened matrix is too stiff for it):
n |
paper (penalty 0.01) | agnimhd, 0.01 | agnimhd, 0.05 | limit (penalty-free) |
|---|---|---|---|---|
| 1 | about 1.5e-7 | 3.708e-5 | 8.488e-6 | -3.90e-7 |
| 2 | 2.770639e-4 | 2.770639e-4 | 2.282387e-4 | 1.948e-4 |
| 3 | 2.791126e-4 | 2.791125e-4 | 2.513169e-4 | 2.245e-4 |
| 4 | 1.785811e-4 | 1.785811e-4 | 1.665235e-4 | 1.503e-4 |
| 5 | 6.459412e-5 | 6.459412e-5 | 5.970116e-5 | 5.091e-5 |
n = 1 at 96x96 with more penalty: 5.31e-6 (0.08), 4.18e-6 (0.1), 8.85e-7
(0.3), -2.0e-7 (1).
With all poloidal modes (MPOL = 47): 2.99e-5 (0.01), 1.44e-5 (0.05), 5.68e-6
(limit).
The penalty-free limit against resolution (MPOL = 4 n; Zernike radial degree
L = 2 (n_rho // 2 - 1) in brackets):
n |
16x48 (14) | 24x48 (22) | 32x64 (30) | 48x96 (46) | 64x96 (62) | 96x96 (94) |
|---|---|---|---|---|---|---|
| 1 | -1.36e-6 | -9.5e-7 | -1.17e-6 | -5.2e-7 | -5.5e-7 | -3.9e-7 |
| 2 | -5.4e-6 | -4.2e-6 | 8.9e-6 | 9.23e-5 | 1.433e-4 | 1.948e-4 |
| 3 | -1.27e-5 | -6.1e-6 | -2.3e-6 | 1.130e-4 | 2.245e-4 | |
| 4 | -2.11e-5 | -1.71e-5 | -6.5e-6 | 7.29e-5 | 1.503e-4 | |
| 5 | -2.80e-5 | -2.24e-5 | -1.15e-5 | -3.7e-6 | 5.09e-5 |
In this limit n = 1 is near marginal at every resolution, n = 2 ... 5 become
unstable as the radial degree grows and keep growing at 96x96, and the paper's
ordering (3 and 2, then 4, then 5) holds at 96x96. The limit was computed by
restricting the displacement to the Zernike space with a script outside the
package.
What CI checks (tests/test_dshape.py, 16x48, about 25 s): at this resolution
every unstable eigenvalue at the benchmark's penalties is a penalty artifact
(the limit is stable for every n; n = 1 at 0.08 gives 2.65e-5). So it checks
- code agreement, not physics:
n = 2 ... 5at penalty 0.01 equal DESC's AGNI on the same nodes and settings (measured to 2e-11); n = 1with penalty 1 and 10: near marginal, the same to 1 %, within 1 % of the limit.
The paper's verdict, n = 2 ... 5 unstable, holds in the limit only from 48x96
for n = 2, 3, 4 and only at 96x96 for n = 5 (-3.7e-6 at 48x96). A 48x96 solve
is already a 13,632-row complex dense matrix (3 GB); its time on a CI runner was
not measured. The verdict is left to the benchmark.