Dust from MHD turbulence

Can MHD turbulence make dust maps good enough to train a CNN?

The goal is a CNN that removes Galactic dust from CMB polarization maps, trained on simulations instead of on the sky itself. This report covers the upstream half: which simulations reproduce the published dust statistics, which ones actually resemble real dust, and what resolution the training maps need.

Reference: Stalpes, Collins & Huffenberger 2024, arXiv:2404.02874 Codes: own isothermal MHD solver · Enzo · Cho–Lazarian (via The Well) Cluster: FASRC Cannon

Status. The simulation and analysis chain is complete; the CNN is not trained yet, because the training set needs simulations that did not fit in the compute available. A second agent (Codex) reviewed this work and found two blocking defects in the analysis. Both are fixed, the affected results were regenerated, and one headline claim did not survive — it is marked where it appeared, and the last section says what the review changed.

step 1MHD turbulence
step 2Project to Stokes T, Q, U
step 3E/B spectra, compare with Planck & PySM3
step 4 — not reached128×128 maps → CNN

The paper's Table 1, reproduced with an independent code

finding 1

The paper fits every spectral slope as α = a + b·MS + c·MA. We repeated that fit on 100 snapshots streamed from The Well's 256³ boxes, which use the Cho–Lazarian ENO code — unrelated to the paper's Enzo — over its sub-Alfvénic family (MA ≈ 0.8, MS from 0.5 to 8.4).

Fitted coefficients, this work against the published values
slopea (this work)a (paper)b (this work)b (paper)
αρ−3.47−3.610.1520.160
αv−3.85−3.750.0100.020
αH−3.57−3.530.0310.020
αTT−3.64−3.590.1740.150
αEE−3.38−3.410.1640.170
αBB−3.93−4.310.2160.280

what this buys us

Everything matches except B-modes, and our own from-scratch solver misses in the same direction. Two independent codes disagreeing with the published B-mode fit the same way points at the B-mode measurement rather than at either code. The velocity spectrum goes the other way: The Well gives αv = −3.85 to −4.03 against the paper's −3.86, while our solver gives −3.41 — that slope is our solver's own numerical dissipation.

Do simulated maps look like real dust?

finding 2 — revised after review

One estimator, applied identically to simulated maps and to PySM3 dust models at 353 GHz (128×128 patches of 20°, Galactic latitudes 35°–75°, E/B decomposed on the full sphere so nothing leaks at the patch edge, same beam divided out of every spectrum). Simulated maps are whole projected faces binned to 128×128, so that a map wavenumber is a box wavenumber, and the band is k = 3–9 — the range where a 256³ box is still turbulent rather than numerically damped.

Dust statistics over k = 3–9. The polarization fraction of a simulation still needs the intrinsic grain fraction p₀ before it can be compared.
sourceαEEαBBBB/EErTES at 2 pxp/p₀skew ln T
PySM3 d1−2.78−2.700.560.175.6°0.090.27
PySM3 d10−2.81−2.680.580.294.6°0.040.55
PySM3 d12−2.85−3.040.610.303.3°0.060.61
Enzo — MS 5.3, MA 1.5 (1 snapshot)−2.01−2.441.10−0.297.7°0.35−0.11
Well — MS 7, MA ≈ 8−1.90−2.560.960.5111.7°0.17−0.06
Well — MS 7, MA ≈ 0.8−1.92−2.351.170.082.5°0.740.09
Well — MS 2.5, MA ≈ 8−2.26−3.180.970.559.9°0.160.01
Well — MS 2.5, MA ≈ 0.8−2.32−3.091.250.211.7°0.73−0.04
Box plots comparing nine statistics across PySM3 dust models, public MHD boxes and the Enzo run
Every statistic, every map. Boxes span the middle half of the maps in each family; the dashed line is the Planck value where one exists.
How far off, in units of how much one dust patch differs from another (half the 16–84% spread of d10 over its 72 patches)
statisticthe three dust models differ bysimulations sit away by
αEE0.21.4 – 2.6
αBB0.70.2 – 1.0
BB/EE0.21.4 – 2.5
rTE0.80.5 – 3.7
S0.70.6 – 2.2

the honest result

The spectral shapes are reasonable; the E/B asymmetry is not. B-mode slopes land inside the patch-to-patch scatter of the dust models, and so does the angle dispersion for some parameter choices — map by map nobody could tell those apart. What is systematic is that E-mode slopes are too shallow by 0.5–0.9, and that BB/EE is ≈ 1.0 where the dust models sit at ≈ 0.58 and Planck measures 0.53. The sky's 2:1 excess of E over B is the most studied feature of dust polarization and the subject of the paper this project set out to reproduce; a box with BB/EE ≈ 1 has none of it, so a network trained on these maps would learn a foreground with about 70% too much B relative to E — an error in exactly the channel the experiment cares about.

A claim withdrawn. The first version of this report said the Enzo box at MA = 1.5 matched PySM3 on nearly every statistic. That was an artifact. Those numbers came from native-resolution 128² tiles cut from the 512³ face, which sample box wavenumbers 12–52 — mostly the numerically damped range, where slopes steepen and happened to land near the dust values. The reviewer found the inverted conversion; measured on the properly binned face, the same snapshot gives the row above.

Intensity, Q and U maps for a PySM3 patch and a simulated box face
A PySM3 d10 patch (top) beside a simulated face (bottom), same quantities and colour scales.

Why one 512³ box cost more than the rest of the project

finding 3

We ran Enzo at 512³ at the paper's Planck point on one 112-core node. Parallel efficiency was never the problem: 2.8×10⁵ cell-updates per core per second, 62% of the wall time inside the MHD solver, load imbalance 1.04. The time step was.

Measured from the run's own log
dynamical timestime steps neededfastest signal in the box
0 → 13,45829
1 → 247,672250
2 → 2.1364,051900
→ 2.44131,6842,295

The gas itself moves at about 5. The runaway comes from a handful of cells that the turbulence empties to a millionth of the mean density: their magnetic signal speed B/√ρ sets the time step for the whole box, and those cells carry a millionth of the mass and none of the dust emission. Two three-day segments — about 16,000 core-hours — reached 2.44 of the 10 dynamical times requested.

Time steps per dynamical time rising for the uncapped runs and staying flat for the capped one
With no cap on the Alfvén speed, the cost per dynamical time keeps climbing; with the cap it is flat. The 512³ points are the production box, the 64³ pair is a controlled test with the same forcing seed.

The fix, and the test that it changes nothing

Enzo has an Alfvén-speed limiter that raises the density of exactly those cells until their signal speed reaches a cap. Two details are not in the documentation and came from reading the source: the parameter usually recommended for this (SmallRho) is not a general floor for this solver, and the limiter prints one line per capped cell per step, which at 256³ means gigabytes of log. A one-line patch silences it.

The limiter was then tested rather than assumed: two 64³ runs with identical parameters and forcing seed, one capped and one not.

64³, statistics averaged over the seven snapshots after 2 dynamical times
quantityno limiterAlfvén cap 50
cycles for 5 tdyn9,6654,571
MS4.66 ± 0.254.80 ± 0.26
MA1.44 ± 0.061.49 ± 0.07
σ(ln ρ)1.31 ± 0.051.34 ± 0.09
αEE−2.38 ± 0.40−2.02 ± 0.35
BB/EE1.11 ± 0.230.89 ± 0.24
αv−3.90 ± 0.28−4.01 ± 0.18
mass added—1.2 × 10⁻⁴

The two runs are identical to four decimals until the limiter first fires, then drift apart as any two turbulence runs do after a tiny perturbation, so the comparison has to be statistical: no quantity differs by more than its scatter between snapshots. Treating the seven dumps as independent, the 95% intervals on the differences are about [−0.10, +0.84] for αEE and [−0.52, +0.08] for BB/EE — the test excludes a large effect and nothing finer, from one seed at 64³. The cost reduction, by contrast, is measured directly.

cost after the fix

10 dynamical times take about 4 days and 10,000 core-hours at 512³, or about 8 hours and 900 core-hours at 256³. Before the fix, the 512³ box was heading for 40,000–70,000 core-hours with no end in sight.

Is 256³ enough to train the CNN?

finding 4

Three measurements on real 256³ data decide this.

Where the turbulence stops being physical

The local slope of the power spectrum is flat through the cascade and steepens where the scheme's numerical dissipation takes over. That knee sits at k ≈ 9 in a 256³ box: physical over a factor of 3 in scale. How far it sits depends on the criterion — between 7 and 14 as the reference window and tolerance are varied — and that spread is part of the result. The common assumption that the knee scales with resolution is not supported by our own ladder: the same criterion gives k ≈ 8 at 64³ and k ≈ 9 at 128³.

Local spectral slope against wavenumber for density, velocity and magnetic field
Density, velocity and magnetic field in a 256³ box, averaged over ten snapshots. Inside the shaded band the slope is roughly constant — that is the range a training map can use.

What a 128×128 map keeps

Binning a 256² projected face down to 128² costs almost nothing. Cutting a native-resolution quarter tile instead is a mistake, and the reason is the one the review corrected: a half-width tile reaches a given box wavenumber at half its own k, so its band sits at smaller scales, past the knee. Its slopes are steeper by 0.4–0.9 because they are measuring numerical dissipation.

Median over four parameter pairs and ten snapshots each
map productαTTαEEαBBBB/EErTE
native 256² face−2.52−2.09−2.711.080.36
128² binned face−2.54−2.10−2.731.070.36
128² native tile−2.99−2.62−2.780.770.35

What the same band means on the sky

A 128² map of angular size Θ carries k = 3–9 at these multipoles
map sizeℓ at k = 3ℓ at k = 9pixel
20°541629.4′
10°1083244.7′
5°2166482.3′

Planck measures dust over ℓ ≈ 40–600, a factor of 15 in scale. A 256³ box gives a factor of 3. Whether a bigger box buys range in proportion is exactly the scaling our ladder does not support, so the covered range has to be measured per box rather than assumed.

answer

Pixels are not the limitation; scale range is. Binning to 128×128 costs 0.02 in slope, so the CNN's input resolution is free. But a 256³ box is physical over only a factor of 3 in scale — ℓ ≈ 108–324 for 10° maps — so training maps must be binned full faces with a declared angular size, and the network cannot be asked to learn structure outside that band. At 900 core-hours per box against 10,000 for 512³, more seeds still beat one large box. What this does not show is that such training transfers to the sky: after the revision above, that question now outranks resolution.

What the external review changed

cross-agent review

A second agent (Codex, OpenAI) reviewed the code and the result files, with a prompt requiring every finding to point at a file, a line or a number. It returned ten findings; eight were accepted outright and two in part. Two were blocking:

Wrong frame on one projection axis

For one of the three lines of sight, Q was defined in the cyclic sky frame while the E/B transform used the array's own axes, mixing E and B. Half the simulated maps in two result files were affected. Fixed and verified against the same line of sight rotated onto a different axis, to one part in 10¹⁵.

Inverted scale conversion

A half-width tile reaches a given box wavenumber at twice its own k, not half. Native tiles were therefore measured in the numerically damped range — which is what produced the apparent agreement between the MA = 1.5 box and the dust models.

A knee that could not be found

The dissipation-knee search started above its own reference window, so it could not return a value below 11; five of twelve results sat at exactly that bound. Widened, the knee moved from 12 to 9, with a published sensitivity table.

Claims stronger than the data

"Statistics unchanged" by the Alfvén limiter became a bound (nothing finer than ≈0.8 in a slope is excluded by seven snapshots at 64³), and "only MA ≈ 1.5 matches dust" was withdrawn.

The full exchange — prompt, findings verbatim, and a response to each marked fixed, accepted or disputed — is in review/ in the repository. Two earlier attempts produced no review at all: the reviewer's sandbox could not start, and it reported that as a blocking finding rather than inventing results.

What is left

Finish one 256³ box

At the Planck point with the limiter, about 8 hours on one node. Queued as job 47520681.

Build the training set

Several seeds, snapshots every 2 dynamical times (the measured decorrelation time), binned faces, random rotations: about 1,600 maps for roughly 5 × 900 core-hours — worth doing once the E/B mismatch above is understood, since the network would learn it.

Train and stress-test the CNN

Then test it on PySM3 dust models it never saw during training.

Chase the B-mode excess

Every box measured here, from three codes, carries more B relative to E than the dust models do, and the same excess appears against the paper's value. Estimator, projection model or physics — the next test pushes known pure-E realizations through the whole pipeline.