Vlasov-Fokker-Planck 1D Solver

Example decks live in configs/vfp-1d/. To run one:

uv run run.py --cfg configs/vfp-1d/epp-short

This solver models electron transport over hydrodynamic / collisional time-scales using a spherical harmonic expansion of the distribution function. It is based on the OSHUN algorithm described in Tzoufras et al. (2011, 2013).

Equations and Quantities

The electron distribution function is expanded in spherical harmonics:

\[ f(t, x, v, \theta) = \sum_{l=0}^{l_{\max}} f_{l0}(t, x, v) P_l(\cos\theta) \]

where \(P_l\) are Legendre polynomials, \(v = |\mathbf{v}|\) is the speed (positive-only grid), and \(\theta\) is the angle between \(\mathbf{v}\) and \(\hat{x}\).

The isotropic component \(f_0\) and the first anisotropic component \(f_{10}\) satisfy:

\[ \frac{\partial f_0}{\partial t} = -\frac{v}{3} \frac{\partial f_{10}}{\partial x} + \frac{E}{3}\left(\frac{2}{v} f_{10} + \frac{\partial f_{10}}{\partial v}\right) + C_{00}[f_0] \]
\[ \frac{\partial f_{10}}{\partial t} = -v \frac{\partial f_0}{\partial x} + E \frac{\partial f_0}{\partial v} + C_{10}[f_{10}, f_0] \]

where \(E\) is the electric field, \(C_{00}\) is the isotropic collision operator, and \(C_{10}\) is the anisotropic (FLM) collision operator.

Staggered Spatial Grid

The solver uses a staggered (Yee-like) spatial grid:

  • Cell centers: \(f_0\) (scalar, isotropic distribution) and ion quantities (\(Z\), \(n_i\))

  • Cell edges: \(f_{10}\) (vector, anisotropic distribution), \(E\), \(B\), \(j\)

edges:   x_0       x_1       x_2              x_{nx}
          |         |         |                  |
centers:     x_1/2     x_3/2     ...   x_{nx-1/2}

f0:        [0]       [1]       ...     [nx-1]         (nx cells)
f10:     [0]      [1]      [2]    ... [nx-1]   [nx]   (nx+1 edges)
E:       [0]      [1]      [2]    ... [nx-1]   [nx]   (nx+1 edges)

Spatial derivatives naturally map between grids: \(\partial f_0 / \partial x\) (centers \(\to\) edges) and \(\partial f_{10} / \partial x\) (edges \(\to\) centers).

Boundary Conditions

Configurable via grid.boundary:

  • periodic (default): Wrapping ghost cells. \(f_{10}[0] = f_{10}[n_x]\).

  • reflective: \(f_{10} = 0\) and \(E = 0\) at boundary edges. \(f_0\) ghost cells use mirror reflection.

Collision Operators

Isotropic (\(f_0\)): Lenard-Bernstein / Dougherty

The \(f_0\) collision operator is a drift-diffusion operator in velocity space, solved implicitly via a tridiagonal system. Configurable model and differencing scheme.

Anisotropic (\(f_{10}\)): FLM

The FLM collision operator (Tzoufras 2013) includes:

  • Electron-ion: Pitch-angle scattering diagonal term \(\propto Z^2 n_i / v^3\)

  • Electron-electron (optional): Rosenbluth potential integrals for diagonal and off-diagonal contributions. When disabled, the electron-ion collision frequency is boosted by the “collision fix”: \((Z+4.2)/(Z+0.24)\).

Electric Field Solver

  • oshun: Implicit E-field via a Taylor expansion of \(J(E)\) (Tzoufras 2013). Computes \(\Delta J / \Delta E\) by perturbation and solves \(E = -J_0 \cdot \Delta E / (J(E + \Delta E) - J_0)\).

  • ampere: Explicit Ampere update \(E^{n+1} = E^n + \Delta t \cdot J\).

Solver Algorithm

Each timestep:

  1. Explicit spatial streaming: \(v \partial f / \partial x\) (Tsit5 integrator)

  2. Implicit \(f_0\) collision solve (Lenard-Bernstein)

  3. Implicit E-field solve (OSHUN method)

  4. Explicit \(E \partial f / \partial v\) push (Tsit5 integrator)

  5. Implicit \(f_{10}\) collision solve (FLM)

Boundary Conditions

Set with grid.boundary and grid.geometry:

Axis / quantity

Condition

Notes

\(x\)

periodic or reflective

The default is periodic for geometry: cartesian. The spatial grid is staggered — cell centers for \(f_0\), cell edges for \(f_1\) and \(E\).

\(r\) (geometry: spherical)

Reflective, required

Spherical geometry requires boundary: reflective and xmin >= 0. \(f_{10}\) and \(E\) vanish at the inner boundary — by symmetry when xmin = 0 — and at the outer wall. xmin > 0 gives an annular domain with a reflecting inner wall.

\(v\)

Positive-only with a reflecting axis

The velocity grid runs from 0 to vmax, since the spherical-harmonic expansion carries the angular dependence.

\(v\) (collisions)

Zero-flux

At both ends of the speed grid.

Forcing and Drivers

The physics here is transport over collisional timescales, so the forcing is heating rather than a coherent wave driver:

Block

What it does

drivers.ib

Inverse-bremsstrahlung heating from a laser of wavelength units.laser_wavelength.

drivers.maxwellian_heating

A heating operator that drives the distribution toward a hotter Maxwellian, used to set up a temperature profile without resolving the absorption physics.

drivers.ex, ey

Present in the schema and normally left empty ({}) — the example decks drive the system through heating and the initial temperature profile, not through a field.

Initial conditions carry most of the setup: a hotspot or a temperature ramp relaxes and you measure the resulting heat flow.

What Gets Saved

binary/:

File

Contents

scalars-t=<t>.nc

Scalar time series

<prefix>-t=<t>.nc

Field and moment quantities on the requested grids

dist.nc

The distribution function, i.e. the Legendre harmonics \(f_{lm}(x, v)\)

heat-flux-comparison.nc

The kinetic heat flux alongside the Spitzer-Härm and SNB predictions

plots/: plots/fields/, plots/scalars/, plots/dist/, plus heat-flux-comparison.png.

That heat-flux comparison is the headline diagnostic — it is the direct read on nonlocal transport, which is what the solver exists to compute.

Configuration Reference

See the Configuration Reference for complete YAML schema documentation.