Dynamics and remnant

Two products that are not a waveform, served by their own methods. Written 2026-09-02; the numbers were measured that day through the consumer route on the released NRHJSur3dq8_AA_v3, NumPy backend, OMP_NUM_THREADS=1.

Orbital dynamics

dynamics = model.get_orbital_dynamics(mass_ratio, spin1z, spin2z)

One parameter point, geometric units, on the model's own orbital-phase grid. Measured at (4, 0.3, -0.2):

key what measured
"phi" the orbital-phase grid, radians, 4000 points -113.650 to -0.024
"tau" the fitted clock, M, peak aligned -3819.08 to -0.135
"omega" orbital frequency 1 / tau', a spectral derivative of the fitted clock 0.01983 to 0.1754, positive and rising on every sample
"x" the FITTED post-Newtonian variable 0.0733 to 0.3133
"eps" -tau'' / tau', how far from adiabatic 4.2e-3 to 0.158
"k" the scalar plunge coefficient 0.24872

nrhjsurrogate/driver/aa_api.py:926-949. It costs 75 ms warm, almost all of it the same predict_pieces call a waveform pays, and model.dynamics is the superseded name, forwarding, measured bitwise. It also works on a model loaded with backend="kokkos", because it is host-side arithmetic.

x is fitted, not derived, and it is load-bearing. The consistency check |x - omega^(2/3)| / x reaches 2.5e-4 across the grid, which is the size of the statement that x is its own variable. At serving time v = sqrt(x) builds the post-Newtonian normaliser that the ratio route is multiplied back by (aa_api.py:830-831, _predict_pieces_in_arm), so the paper sentence calling it "only diagnostic" was refuted by the 2026-09-02 review. It is diagnostic for the timing only.

What this method does not return: J and E. Both are fitted variables of the artifact (predict_pieces serves E, J, k, tau, x and the seven modes, measured), both have stored variances reachable through get_dynamics_error_estimate (keys E, J, tau, x, k), and neither is in this dictionary. They are served by the waveform call instead: with dynamics=True, result["dynamics"] is {Phi, J, E, omega, t}. On a native call that is the native orbital-phase grid (4000 points); with f_low below reach it is the extended domain (1354 points at f_low = 0.004), see hybridisation.md. One key set for both, since 1.1; in 1.0.0 the native call returned None under that key.

On the derived routes the clock is derived. timing_mode="aa-int" and "aa-int-pn" obtain the clock from the stored action and energy through the first law rather than from the fitted tau; they are reference models, inspiral only, one point at a time (docs/USAGE.md section 5). The released default route is the fitted clock, so for it the waveform is not derived from J.

Remnant

mass_over_total, spin = model.get_remnant_properties_geometric(mass_ratio, spin1z, spin2z)
mass_solar, spin      = model.get_remnant_properties(mass1, mass2, spin1z, spin2z)

Measured: at (4, 0.3, -0.2) M_f / M = 0.973603, chi_f = 0.624352, in 0.30 ms; for 50 + 12.5 solar masses M_f = 60.8502. Passing the bodies the other way round, (12.5, 50, -0.2, 0.3), is bitwise the same, because the physical method sorts the pair and each spin follows its body (aa_api.py:2328-2346). The map is exchange-even by construction and that is exact: rho(1/q, chi2, chi1) == rho(q, chi1, chi2) bitwise, measured. Array inputs broadcast to (B,). At (1, 0, 0) it returns (0.951588, 0.686433). remnant and remnant_physical are the superseded names.

Where it comes from. The map ships INSIDE the merger-ringdown arm and is the same object the ringdown detrend uses (self.mr.X.rho, nrhjsurrogate/physics/spin_weighted_angular_harmonics.py:207 RemnantMap, :457 remnant), so one artifact has exactly one source of remnant truth and no sidecar file. Two Gaussian process maps on the same trend-plus-kernel construction as the waveform fits, read off the released MR_v3: M_f with a degree-4 trend, nugget 1e-9, fitted on 259 simulations (SXS:BBH:1124 excluded as a catalogue outlier), and chi_f with a degree-3 trend, nugget 1e-10, on all 260. A model must carry the arm to answer, and on a released artifact it always does, see artifacts-and-resolution.md.

Accuracy, 260-fold leave-one-out against the training catalogue, measured 2026-08-23:

quantity median abs error, all 260 inside q <= 8, abs(chi) <= 0.8 (201)
chi_f 1.63e-5 1.44e-5
M_f / M 4.48e-5 4.25e-5

RMS forms of the same errors, 1.1987e-4 on M_f (2.696e-4 if 1124 is kept) and 5.306e-5 on chi_f, are what the error estimate carries as remnant_sigma = (1.2e-4, 5.3e-5) (spin_weighted_angular_harmonics.py:802).

Against the shipped surfinBH fits, same catalogue, paired medians, ratio above 1 meaning this map is more accurate: on chi_f 1.80x over NRSur3dq8_RD on all 260 and 1.64x inside its own box; on M_f 1.21x on all 260 but 1.01x, parity, inside the box, the whole lead coming from the 59 simulations outside abs(chi) <= 0.8 where that fit extrapolates. About 23 percent of the catalogue coincides with the other fit's training points, and on that subset it marginally wins chi_f (0.89x); the numbers above survive the out-of-training cut. Do not claim more than parity on M_f.

Limits, next to the capability

Where the code is

what where
dynamics method nrhjsurrogate/driver/aa_api.py:926
remnant methods nrhjsurrogate/driver/aa_api.py:2300-2356
the remnant map and its clamp nrhjsurrogate/physics/spin_weighted_angular_harmonics.py:207, :457
dynamics uncertainties nrhjsurrogate/driver/aa_api.py:1123
derived routes nrhjsurrogate/driver/nrpn.py, driver/aaintpn.py
user documentation docs/USAGE.md sections 5 and 11