N₂ vibrationally-elastic/inelastic cross section: time-dependent (Crank-Nicolson) route to the exact 2-D solution¶
Location: qscat.evolution.make_sparse_cn_stepper (the general sparse propagator),
projects/n2_2d_td_cross_section/ (wavepacket.py, td_propagation.py, correlation.py,
td_cross_section.py, convergence.py), validation/n2/td_exact2d.py
(the harness’s Group F wiring), validation/n2/experiment.py (Group F).
Origin: the same 2-D (electronic r × nuclear R) electron-N₂ ²Π_g shape-resonance
model as docs/physics/n2-2d-cross-section.md (sub-project #6) — same potential surface
(projects/n2_resonance/potential.py), same grids/Hamiltonian machinery
(projects/n2_2d_cross_section/electronic_grid.py, hamiltonian2d.py), same
l = 2 partial wave and nuclear reduced mass MU. This sub-project (#7) does not
introduce new potential physics or a new energy-domain solver; it is a second,
independent numerical route — time propagation instead of a direct linear solve — to
the identical exact cross section.
Units: atomic units throughout (energy in Hartree, length in Bohr, time in
hbar/Hartree, cross section in bohr²).
Framing (read this before the numbers)¶
docs/physics/n2-2d-cross-section.md solves \((E_\mathrm{tot}\mathbb{1} - H_\mathrm{2D})^{-1} V_\mathrm{int} \Psi_i\) directly
— one sparse LU factorization per collision energy — and calls that the exact 2-D
result. This document computes the same exact S-matrix a different way: prepare an
incident wavepacket at t=0, propagate it forward under the full 2-D Hamiltonian with a
sparse Crank-Nicolson stepper, record its correlation with an outgoing test function over
time, and Fourier-transform (Tannor-Weeks) that correlation function into the energy
domain. This is the time-domain twin of #6: two structurally unrelated computations
(one direct linear solve per energy vs. one propagation covering every energy) converging
to the same number is a strong, non-trivial cross-check — not a restatement of #6, and not
a new physical model. Concretely, nothing here introduces new potential physics, a new
partial wave, or a new grid convention: every physical input — the potential surface, the
reduced mass, l=2, the FEM-DVR-ECS grids — is carried over from #6 unchanged, and the
two routes are validated against each other as an exact differential oracle.
in the long-propagation-time limit — the Laplace transform of the propagator is exactly the resolvent #6 computes directly.
Method¶
Incident wavepacket. \(\Psi(0) = g(r)\,\chi_0(R)\): a Gaussian in the electronic coordinate,
g(r) = exp(-(r-r0)^2/(2 sigma^2)) exp(i p0 r)(wavepacket.py), tensored with the neutral-N₂ ground vibrational eigenvectorchi_0(R)(the samevibrational_statesoutput #6 uses), masked to the real (unscaled) grid region. Unlike #6’s static incident channel functionF_{E,l}(r) chi_v(R)(one fixed energy), the wavepacket carries a spread of energies set byp0/sigma— this is what lets one propagation cover a wholesigma(E)curve at once (see below).Order-3 Padé propagation (
qscat.evolution.make_pade_stepper(H, dt, order=3)): the diagonal [3,3] Padé approximant ofexp(-i H dt),exp(-iHdt) ~ prod_i (I - iHdt/r_i) (I + iHdt/r_i)^{-1}over the Padé rootsr_i, accurate toO(dt^7)per step. Order 1 is ordinary Crank-Nicolson (make_sparse_cn_stepper, \(O(\mathrm{d}t^3)\)) — and order-1 CN under-converges catastrophically over a multi-thousand-step run: ~100% accumulated propagation error atdt = 0.5-1.0(verified againstscipy.linalg.expm), which capped the earliersigma_TD/sigma_TIat ~0.93/1.10 and left the boomerang oscillations unresolved. The order-3 operator (eMoScat’s setting,dt = 1.0) removes it:sigma_TDmatches the TI oracle to ~1-2% median across 0.04-0.18 Ha for all channels (elastic + excitations), tracking the boomerang peaks point-by-point. Each of the 3 denominators(I + iHdt/r_i)is LU-factored once (viaSparseLU) and reused for every step — the same “factor once, reuse many times” structure #6 uses per-energy, applied across time.H = H_2D(built once viahamiltonian2d.build_h2d) is time-independent.H_2D’s absorbing ECS tail makes \(\lVert\psi(t)\rVert\) genuinely decay: this is the mechanism by which the transient N₂⁻ resonance “leaks away” into the numerically absorbed continuum, exactly mirroring the physical autodetachment/dissociative- attachment decay.Correlation function. \(c_{v'}(t_n) = \langle \Phi_{v'} \vert \psi(t_n) \rangle\) (the DVR c-product, no conjugation — matching #6’s and
docs/physics/n2-td-cross-section.md’s convention under exterior complex scaling), recorded at every time step against an energy-independent outgoing test functionPhi_{v'} = g_out(r) chi_{v'}(R)(correlation.outgoing_channel).Tannor-Weeks energy transform (
td_cross_section.sigma_from_correlations/td_ve_cross_section_2d):\[\begin{split} \begin{aligned} S_{v \to v'}(E) &= \left[2\pi\, \overline{\eta^\mathrm{out}_{v'}(E)}\;\eta^\mathrm{in}_v(E)\right]^{-1} \sum_n w_n\, e^{\,i E_\mathrm{tot} t_n}\, c_{v'}(t_n)\,\mathrm{d}t \\ \sigma_{v \to v'}(E) &= \frac{\pi\,|S - S_\mathrm{ref}|^2}{2E} &&\text{bohr}^2,\ =\ \text{\#6's } 4\pi^3|T|^2/2E \end{aligned} \end{split}\]\(E_\mathrm{tot} = E + \varepsilon_{v_\mathrm{init}}\), \(w_n\) composite Simpson weights (trapezoid fallback), and
eta_in/eta_outdeconvolve the wavepacket’s own spectral content, leaving the pure single-energy \(S\)-matrix element. Because \(c_{v'}(t)\) does not depend on \(E\), this transform can be evaluated at any number of energies from one stored trajectory — the wholesigma(E)“boomerang” curve is free once the single ~3.5-minute propagation is done (convergence.sigma_curve).The unscattered reference
S_ref(the elastic subtraction). For an inelastic channel (v' != v_init)S_ref = 0andsigma = pi|S|^2/(2E). For the elastic/diagonal channel the standard convention isS_ref = 1(the Kronecker delta) — but that is only correct if the transform normalizes the free/unscattered S-matrix to exactly 1, which THIS transform does not. The outgoing normalization factorC(E)multiplies every channel’sSequally, so the inelastic \(|S|^2\) silently absorbs it (that is why the excitation channels matched the TI oracle all along); but a free-particle (V_int = 0) propagation gives \(|S_\mathrm{free}(E)| = C(E) \sim 2\pi^2\), NOT 1, so the diagonal \(|S - 1|^2\) leaves a ~500x spurious elastic background. The fix is to subtract the actual unscattered value:S_ref = S_free(E), the S-matrix of aV_int = 0reference propagation run with the same wavepacket and grid (td_ve_cross_section_2d(..., subtract_free_reference= True), the default, runs it;_propagate(..., free=True)builds the reference;sigma_from_correlations(..., free_result=...)consumes it). This also cancels, to leading order, the small already-outgoing tail any displaced Gaussian carries (it evolves identically in the free reference). With the reference subtracted, the elastic channel matches the exact TI solver to a few percent (measured elastic TD/TI ≈ 1.01 at E = 0.14 and ≈ 0.99 at E = 0.15, gated atrel=0.08bytest_v2c_td_elastic_matches_ti_with_free_reference— from ~500× wrong before the reference was subtracted). The residual near-threshold elastic degradation (the1/eta_outdeconvolution grows ill-conditioned ask -> 0:sqrt(2k/pi) -> 0and the outgoing Hankel’s \(y_l(kr) \sim (kr)^{-(l+1)}\) diverges) is a documented low-E limit, not this bug — see thetd-elastic-wavepacket-normalizationnote.
The two physics facts settled by the exact-oracle gate¶
1. F_out must be the outgoing Hankel half, not the regular free function — a
structural, five-order-of-magnitude discriminator, not a fit. eta_out projects the
outgoing test wavepacket onto an energy-normalized free radial function; there were two
candidates, the regular Riccati-Bessel function (F = sqrt(2k/pi) r j_l(kr), the same one
eta_in correctly uses for the incident channel) and the outgoing Hankel half
(F^out = sqrt(2k/pi) r h_l^{(1)}(kr) / 2, since j_l = (h_l^{(1)}+h_l^{(2)})/2).
Measured directly against the exact-TI oracle:
the regular choice gives sigma_TD/sigma_TI of order 1e-5 — five to six orders of
magnitude too small — at every (T, E) tried, while the Hankel half brings it to O(1)
immediately, with no further normalization factor needed beyond the /2.
A discriminator this large cannot be produced by tuning Gaussian wavepacket parameters, so it settles a genuine physics question (which free function represents “outgoing flux”) structurally, before any fitting could occur — and, being a five-order-of-magnitude effect, it is entirely independent of propagator accuracy.
(The specific O(1)-column ratios once tabulated here — 1.101/1.144/1.113/1.234 at
T = 1500/1800 — were order-1 Crank-Nicolson measurements and no longer describe the code;
the current agreement is the few-percent figure measured below. The 1e-5-vs-O(1)
discriminator is unaffected by that correction, which is the whole point of relying on it.)
2. The resonance fully depletes — the literal “observe formation and decay” result.
||Psi(t)|| drops from 1.0 at t=0 to 0.024 by T=1500 (measured profile:
t=0: 1.000, 200: 0.588, 400: 0.347, 600: 0.328, 900: 0.085, 1500: 0.024) — the transient
N₂⁻ anion forms as the wavepacket enters the interaction region, persists briefly as a
quasi-bound state, then decays via the ECS-absorbed continuum, exactly the physical
autodetachment picture the resonance model describes.
The validation ladder¶
Sparse-CN-vs-dense:
make_sparse_cn_steppermatches the densemake_cn_stepper(qscat.evolution, promoted earlier fordocs/physics/n2-td-cross-section.md) to round-off on a small test system — confirms the sparse factorization introduces no new numerics, only performance.TD ≈ TI at the gated anchors — an EXACT differential oracle, not a cross-model comparison. Unlike TD-vs-Houfek (genuinely different implementations, so only loose agreement is expected), TD and TI solve for the same
S-matrix by construction (see “Framing” above), sosigma_TDis checked againstsigma_TIdirectly:E (Ha)
v’
sigma_TD (bohr²)
sigma_TI (bohr²)
ratio
0.10
1
5.9595
6.1228
0.9733
0.15
1
0.6185
0.6258
0.9884
(
test_td_cross_section.py’s@slowV2a tests,rel=0.06at both anchors. Earlier versions of this note quoted 0.9305 / 1.1033 against tolerances of 0.10 / 0.15, with the looser E=0.15 bound explained as a “window-edge loosening” — both the numbers and the explanation were order-1 Crank-Nicolson artefacts and are gone.)The genuineness check: the ratios bracket 1.0. A systematic normalization error (a wrong prefactor, a missing factor of 2, a sign error) would push every ratio the same direction. They do not: across the six measured energies the ratios straddle unity — 0.9733, 1.0013, 0.9884, 0.9932, 1.0087, 1.0132 — three either side, spread 0.973–1.013. That, combined with the independent five-order-of-magnitude
F_outdiscriminator above, is the evidence that the transform is genuinely correct physics rather than a fitted agreement.(Note the two anchors alone now both sit slightly below 1.0, so the older form of this argument — “0.9305 below, 1.1033 above” — no longer holds on the anchors by themselves. The wider measurement is what carries it.)
Finite-T behaviour. A
T-scan table previously appeared here (ratios 0.760–1.204 acrossT = 600…1800) and was read as showing E=0.15 hitting “a floor, not a still-converging transient, diagnostic of the usable-spectral-window effect.” Those numbers were order-1 Crank-Nicolson; the apparent floor was under-convergence of the propagator, not a spectral-window effect. The table has been removed rather than restated, because re-running the scan at order-3 Padé is a measurement nobody has made — and a claim aboutT-convergence should rest on aT-scan, not on inference from a singleT.test_v4_finite_t_stability_and_depletion: transforming the SAME storedc(t)truncated atT=1000vs. the fullT=1500changessigma_TD(E=0.10)by only 2.8% (free — no second propagation needed), andnorm[-1] < 0.05— the resonance has genuinely depleted by the end of the stored trajectory, so truncating the tail does not silently discard un-decayed amplitude.
The honest limits¶
The usable spectral window, (0.06, 0.21) Ha. wp_in’s p0 = -0.5 puts the incident
wavepacket’s spectral peak at p0^2/2 = 0.125 Ha, between the two TI anchors (0.10, 0.15).
|eta_incident(E)| (measured peak 2.844 at E=0.12) falls off away from that peak; the
Tannor-Weeks deconvolution divides by eta_incident, so outside the window where
|eta_incident| drops below half its peak, that division amplifies residual
truncation/discretization noise into something that looks like signal but isn’t.
convergence.usable_window(frac=0.5) computes (E_lo, E_hi) = (0.06, 0.21) directly from
the measured |eta_incident(E)| curve — comfortably bracketing both anchors.
A “finite-T resolution limit” this note used to claim, now withdrawn. Earlier versions
of this note described a second, separate reliability limit: that sigma_TI(E)’s boomerang
sub-features (as narrow as ~0.004 Ha) were comparable to the propagation’s implicit
frequency resolution 2*pi/T ~ 0.0042 Ha at T=1500, so sigma_TD could not resolve them
pointwise even inside the usable window — citing ratios of 0.229/0.575/0.348 at
E=0.06/0.08/0.12. It further claimed the limit was intrinsic: fixable only by a longer T,
“not by re-tuning the wavepacket.”
That was wrong, and it is worth stating plainly because it is the failure mode this note
should have caught first. Those ratios were measured with the order-1 Crank-Nicolson
propagator in use at the time, which under-converges badly over a long propagation. The
error was a solver artefact; the note explained it as a property of the method. With
order-3 Padé (the default since) the same energies track the exact oracle — see the measured
table below, where nothing in the tested range departs by more than a few percent. The
plot_sigma_vs_ti “finite-T unresolved” region that rendered this claim has been removed
along with the validated_anchors mechanism that existed only to except two energies from
it.
The usable spectral window above is real and remains; it is a genuine amplitude/SNR limit. It was the second region that never existed.
observation.py has been retired into qscat_run.artifacts. Every capability it
provided now has a home in the qscat-run config/artifact pipeline, with two losses
accepted along the way:
|
Replacement in |
|---|---|
|
|
|
|
|
|
|
|
The r_max = 50 box caveat. The electronic grid’s ECS pivot r_max = 50 was sized by
physical reasoning (wp_in’s r0=25 and wp_out’s r0_out=35 both fit comfortably
inside the real region with room to spare, and the interaction
V_int = -lambda(R) exp(-alpha_c r^2) vanishes by r ~ 5-6), and is cross-checked only
indirectly, via the TD-vs-TI agreement measured across the usable window above. It was
not subjected to a direct empirical r_max-convergence sweep (e.g. re-running at
r_max = 40/50/60 and confirming sigma_TD is unchanged) — that sweep is documented
future work, out of this sub-project’s scope.
The figures¶

The capstone comparison: sigma_{0->v'}(E) for elastic (v’=0) and the first two
excitations (v’=1, v’=2), with the TD points (order-3 Pade, dt=1.0, elastic
free-reference) overlaid on the exact TI oracle (which itself reproduces Houfek’s
CSVE.V00.J00 data to the plotted precision). TD tracks TI/Houfek to ~1-2%
median across 0.04-0.18 Ha, boomerang oscillations resolved point-by-point.

rho(R,t)/rho(r,t) at t = [0, 200, 400, 600, 900, 1500]: the nuclear density starts
sharply peaked near R ~ 2 bohr (the N₂ equilibrium bond length) and its amplitude
collapses over time as the resonance depletes; the electronic density shows the incoming
wavepacket’s interference lobes collapsing toward zero. The bottom panel, ||Psi(t)||
with the snapshot times marked, is the direct visual of the norm-decay profile above —
formation, a brief quasi-stationary plateau, then decay.

|c_{v'=1}(t)|: rises to a peak near t ~ 220, decays, and rebounds to a smaller
secondary peak near t ~ 780 (a boomerang-like re-crossing) before decaying further — the
sub-project’s stated goal, “observe formation in the correlation function,” directly
visualized. The bottom panel shows the rapid Re/Im oscillation inside that envelope.

sigma_TD overlaid on the exact sigma_TI across E in [0.06, 0.22] Ha, recomputed
2026-08-17 at 161 energies (step 0.001 Ha) from one order-3 Padé propagation — the
transform of a single stored trajectory is free at any energy, so the density costs only the
TI oracle sweep. The usable spectral window (0.060, 0.216) is shaded; the four points
outside it are faded.
Across the 157 in-window points the ratio sigma_TD/sigma_TI has median 0.9984, range
0.868–1.106, with 93% of points inside 5%. The previous version of this figure was
computed with order-1 Crank-Nicolson on 11 energies and drew three “honesty regions”,
including the fictitious finite-T band withdrawn above; the dense curve simply tracks the
oracle, and needs no regions to be honest about.
The numeric-output deliverable (historical record)¶
This section records what the retired observation.py (see the retirement note and
capability→replacement table above) produced for the committed TD_WORKING_GRID run, and
how that output was verified at the time; the module and its test are gone, replaced by
qscat_run.artifacts.
observation.save_numeric_outputs wrote a .npz — the primary “observe formation”
artifact, not the figures (which were drawn from it). Confirmed array keys/shapes from the
committed TD_WORKING_GRID run:
key |
shape |
dtype |
meaning |
|---|---|---|---|
|
|
float64 |
sample times |
|
|
complex128 |
|
|
|
float64 |
` |
|
|
float64 |
snapshot times |
|
|
float64 |
nuclear density per snapshot, stacked |
|
|
float64 |
electronic density per snapshot, stacked |
|
|
float64 |
|
|
|
float64 |
|
rho_R/rho_r were the full axis length, unmasked to the ECS tail (plot_snapshots
masked to the real region itself when given the grid). Self-consistency was checked
directly: the (now-retired) test_v5_saved_c_reproduces_saved_sigma saved a small
propagation’s c(t) and computed sigma_E to .npz, reloaded both, and re-ran the public
transform (sigma_from_correlations) on the reloaded t/c — it reproduced the saved
sigma_E via assert_allclose(rtol=1e-12, atol=1e-14), bit-for-bit, confirming the .npz
round-trip was lossless and the transform deterministic.
The real run: sigma(E) across the boomerang curve¶
TD_WORKING_GRID (N = 47188): electronic r_max=50, order=8, n_complex=6; nuclear
quadrature=10, r_max=22, n_complex=5; wp_in = {r0:25, p0:-0.5, sigma:5.0};
wp_out = {r0_out:35, p0_out:0.5, sigma_out:4.0}; dt=0.5, n_steps=3000 (T=1500).
One propagation, 210.8s; the sigma_TI oracle scan (11 energies, on the same box),
112.9s; the sigma_TD transform of the stored trajectory at all 11 energies is free.
Measured 2026-08-17 at the order-3 Padé default (one propagation, all 11 energies transformed from the same stored trajectory):
E (Ha) |
sigma_TD |
sigma_TI |
ratio |
|---|---|---|---|
0.06 |
0.2864 |
0.2872 |
0.9974 |
0.08 |
5.8958 |
6.1516 |
0.9584 |
0.10 |
5.9595 |
6.1228 |
0.9733 |
0.12 |
3.7078 |
3.6514 |
1.0154 |
0.14 |
1.0601 |
1.0587 |
1.0013 |
0.15 |
0.6185 |
0.6258 |
0.9884 |
0.16 |
0.3999 |
0.4026 |
0.9932 |
0.17 |
0.2817 |
0.2793 |
1.0087 |
0.18 |
0.2084 |
0.2057 |
1.0132 |
0.20 |
0.1236 |
0.1256 |
0.9834 |
0.22 |
0.0866 |
0.0857 |
1.0099 |
Every energy agrees with the exact oracle to within 4.2%, worst case E=0.08; nine of the
eleven are inside 2%. usable_window(frac=0.5) still gives (0.06, 0.21), and the window
remains the honest statement about where the deconvolution is trustworthy — but note that
even E=0.22, just outside it, lands at 1.0099 here.
This table is the clearest evidence for the withdrawal above. In its previous form, the
same three energies read 0.229 / 0.575 / 0.348 at E = 0.06 / 0.08 / 0.12 and were
labelled “finite-T unresolved” — the observation that the whole invented resolution limit was
built on. At order-3 Padé they are 0.9974 / 0.9584 / 1.0154. Nothing about the propagation
time, the wavepacket, or sigma_TI’s fine structure changed; only the propagator did. The
“structure too narrow to resolve” was accumulated Crank-Nicolson error.
A long passage used to sit here reconciling the “well-converged anchor” label at E=0.10
with the finite-T caveat — arguing that E=0.10 was an exception because it “lands near the
resonance peak where the exact TI feature is broad enough to resolve”, while the dense
boomerang curve between the anchors was not trustworthy. There is nothing left to reconcile:
the caveat was an artefact (above), and with order-3 Padé the curve tracks the oracle across
the window without special-casing any energy. The figure no longer draws starred exceptions,
because there is no rule for them to be exceptions to.
Harness Group F: reported, not re-run live¶
validation/n2/td_exact2d.py computes nothing at harness run time. A full propagation at
TD_WORKING_GRID costs ~210-250s wall (measured above); timed directly for this decision,
the sparse LU factorization alone costs ~7.8s and each propagation step ~0.064s, so even a
short T=600 run costs ~7.8 + 1200*0.064 ~ 85s, over the harness’s ~60s-per-group budget.
Going shorter would extrapolate outside the range ever validated (at t=200 the norm has
barely begun to decay — the resonance has hardly formed), which would require a tolerance so
loose it would no longer test anything. Per the sub-project’s decision rule, Group F
therefore emits NOTE rows that report the already-validated numbers as literal, cited
constants — never a live gate, never counted toward PASS/FAIL:
[NOTE] F time-dependent 2-D: F1 sigma_TD(E=0.1 Ha, v=0->1) [recorded] sigma_TD=5.9595e+00, sigma_TI=6.1230e+00,
ratio=0.9733 (validated rtol<=0.06 by test_td_cross_section.py::test_v2a_td_matches_ti_at_e010
(@slow) / order-3 Pade TD_WORKING_GRID run); full TD propagation NOT run in-harness
[NOTE] F time-dependent 2-D: F1 sigma_TD(E=0.15 Ha, v=0->1) [recorded] sigma_TD=6.1850e-01, sigma_TI=6.2576e-01,
ratio=0.9884 (validated rtol<=0.06 by test_td_cross_section.py::test_v2a_td_matches_ti_at_e015
(@slow) / order-3 Pade TD_WORKING_GRID run); full TD propagation NOT run in-harness
(Transcribed from an actual harness run on 2026-08-17. validation/n2/td_exact2d.py already
carried these values; it was only this note’s copy of its output that had gone stale.)
The genuine, live PASS/FAIL gate on this comparison is
projects/n2_2d_td_cross_section/test_td_cross_section.py’s @pytest.mark.slow tests,
run explicitly (uv run pytest projects/n2_2d_td_cross_section -m slow), not as part of
the default harness.
Deferred: the optimize-in-Rust target¶
The sparse LU factorization / back-substitution is the eventual
optimize-in-Rust lifecycle target — explicitly NOT done in this sub-project. eMoScat’s
own production runs report MKL PARDISO completing full N₂/NO/F₂ time-dependent
calculations in under an hour; this sub-project’s ~210s single-energy-equivalent
propagation (using SciPy’s SparseLU, not PARDISO) already validates the method
end-to-end against the exact oracle — performance is a separate lifecycle stage (python- to-rust-kernel), to be taken up only once a hot path is proven and there is a reason
(e.g. wanting the full boomerang curve at a much longer T, or a finer dt) to pay for it.
Validation summary¶
libs/qscat/tests/test_crank_nicolson.py:make_sparse_cn_steppermatchesmake_cn_stepperto round-off; mypy-clean — PASS.projects/n2_2d_td_cross_section/test_td_propagation.py,test_wavepacket.py: propagation engine and wavepacket construction — PASS.projects/n2_2d_td_cross_section/test_td_cross_section.py(@pytest.mark.slowx4 + 1 cheap): V2a (TD ≈ TI, the exact-oracle gate), V2b (closed channel exactly zero), V4 (finite-T stability, free re-transform of a truncated trajectory), shape contract — PASS.projects/n2_2d_td_cross_section/test_td_convergence.py(@pytest.mark.slowx1 + 1 cheap): the fullsigma(E)curve from one propagation matchessigma_TIon the smooth branch — PASS.validation/n2/experiment.pyGroup F: 2 recorded NOTE rows (never gating); harness totals with Group F added: 23 PASS, 0 PENDING, 6 NOTE, 0 FAIL, exit code0— no regression of the pre-existing 23 PASS / 0 PENDING / 4 NOTE / 0 FAIL.
No model parameter was tuned to improve agreement with anything¶
The potential surface, reduced mass, fixed partial wave l=2, and every grid parameter in
TD_WORKING_GRID are carried over unchanged from #6 or chosen from convergence
measurements (the T-scan, the wavepacket-placement reasoning above) — none was adjusted
after seeing a TI-oracle or Houfek comparison. The F_out = Hankel/2 choice was settled by
a five-order-of-magnitude structural discriminator (regular vs. Hankel), not by fitting to
match a target ratio.
Sibling extractors: Dirac (delta) and Flux (flow)¶
The Tannor-Weeks transform documented above is one of THREE energy-extraction routes
eMoScat implements from the same propagated trajectory. A later sub-project
(td-alternative-extractors) promotes the other two — Dirac (a fixed-point delta
projection) and Flux (a fixed-surface Wronskian flux) — as siblings behind a shared
Extractor protocol (qscat.core.time_dependent.propagate(..., extractors=[...])),
selectable via td_ve_cross_section(method="tw"|"delta"|"flow"), plus
td_ve_cross_sections_all (one shared propagation, all three sigma(E) at once — the
honest three-way comparison). On N2 all three converge to the SAME TI oracle this document
gates against, to ~3% at a converged grid. See docs/physics/td-extractors.md for the
full architecture, formulas, and three-way validation.