Skip to content

chc.transport

Stability tier: experimental.

Continuum mean-field control: the density transport PDE rho_t + (rho v)_x = s.

The continuous-space sibling of chc.meanfield.MeanFieldControl (which lives on a finite zone graph). Agents are a density rho(x, t) on a periodic 1-D domain; a velocity field v advects them and a source s injects/removes mass. Two pieces, both honest and validated:

  • a conservative finite-volume solver (upwind flux) that conserves total mass to machine precision -- the physical invariant of a continuity equation -- advanced by Strang-Marchuk operator splitting (advection & reaction), reusing chc.splitting.strang_marchuk_step. This is where the Marchuk framing earns its keep on a genuine PDE; the split is 2nd-order in time;
  • MeanFieldTransport, which picks the velocity field steering rho from an initial to a target profile at least transport effort sum rho v^2 -- a discretised dynamic optimal transport / mean-field game, differentiable straight through the conservative solver.

The discrete zone graph stays the primary model, with most of the value at a fraction of the cost; this continuum model is built as its elegant limit, with the mass-conservation and splitting-order gates that make it trustworthy rather than merely elegant.

MeanFieldTransport dataclass

Steer a density rho(x,t) to a target by choosing the velocity field (continuum MFC).

Minimises terminal mismatch ||rho_T - target||^2 plus transport effort sum rho v^2 over a time-varying velocity field, advecting mass with the conservative solver. The velocity is CFL-capped so the explicit scheme stays stable no matter what the optimiser proposes.

rollout_cost(v_seq)

Terminal mismatch + transport effort for a velocity plan v_seq (horizon, n).

plan(steps=300, lr=0.05)

Adam on the velocity field through the conservative solver; keep the best-seen plan.

mismatches(steps=300)

Terminal mismatch with no control vs the planned velocity field (lower is better).

transport_step(rho, v, k, s, dx, dt)

One Strang-Marchuk step of rho_t + (rho v)_x = -k rho + s (reaction & advection).

solve_transport(rho0, v, k, s, dx, dt, steps)

Roll the Strang-Marchuk step steps times; return (final_density, trajectory).

periodic_wavenumbers(n, length)

Real-FFT wavenumbers k_m = 2*pi*m/length for m = 0 .. n//2.

advection_diffusion_symbol(n, length, *, speed, viscosity)

Symbol of the translation-invariant vector field -c u_x + nu u_xx: -i c k - nu k^2.

Derived in validation/spectral_circulant.mac STEP 5: substituting exp(i(kx - wt)) gives w(k) = c k - i nu k^2, so the phase speed is c at every wavenumber -- the advection is NON-dispersive and all the k-dependence sits in the exp(-nu k^2 t) decay.

On an even grid the Nyquist bin is set to zero for the advection part, and that is the correct discrete answer rather than a patch: the Nyquist mode is cos(pi j) = (-1)^j, whose exact derivative -pi sin(pi j) vanishes at every grid point, so the sampled first derivative of that mode is identically zero (STEP 7). It is also what keeps the operator a REAL circulant -- a real first column forces a real eigenvalue at Nyquist, which -i c k is not.

advection_diffusion_kernel(n, length, *, speed, viscosity)

First column of the circulant realising that vector field -- the truth to be recovered.

A chc.residual.SpectralResidual parameterises exactly this vector, so on this plant the truth lies IN the hypothesis class. That is deliberate: it makes a failure to recover it a failure of the fit rather than of the model, which is what the comparison against an MLP is supposed to isolate.

advection_diffusion_field(u, length, *, speed, viscosity)

Apply -c d_x + nu d_xx to a periodic field, spectrally and therefore exactly.

advection_diffusion_propagator(u, length, *, speed, viscosity, dt)

The EXACT solution operator over dt: exp(-i c k dt - nu k^2 dt) applied spectrally.

Exact in time as well as in space, so it introduces no discretisation error of its own -- unlike transport_step, whose upwind flux and Strang split are second-order at best. The price is that it only exists because the operator is linear and translation-invariant, which is precisely the structure chc.residual.SpectralResidual is built to exploit.

periodic_smoothing_kernel(n, length, width)

A periodic Gaussian convolution kernel, unit gain at k = 0 -- a NONLOCAL actuator.

Control applied in one cell spreads to its neighbours. A diagonal control matrix cannot express that and a circulant can, which is why the certificate gives the control channel its own kernel rather than a scalar.