Optimization

This repository contains two main optimization “stories”:

  1. Electrode optimization: optimize discrete source/sink currents (and optionally positions) that drive a surface potential solve.

  2. Current-potential optimization: optimize Fourier coefficients of a REGCOIL-like current potential \(\Phi\).

Both are differentiable end-to-end with JAX.

Objectives: always use normalized \(B_n/|B|\)

When targeting a surface \(S\) with unit normal \(\hat{\mathbf n}\), define:

\[ \mathrm{BnOverB}(\theta,\phi) = \frac{\mathbf B(\theta,\phi)\cdot \hat{\mathbf n}(\theta,\phi)}{|\mathbf B(\theta,\phi)|}. \]

Most scripts report both:

  • area-weighted rms(Bn/B)

  • max|Bn/B|

and aim for max|Bn/B| < 5e-3 (0.5%).

Current-potential model (REGCOIL-like)

examples/inverse_design/optimize_vmec_surface_Bn.py --model current-potential solves:

  • parameterization: \(\Phi_{\mathrm{sv}}\) as a Fourier series in \((\theta,\phi)\)

  • net currents: \((I_\mathrm{pol}, I_\mathrm{tor})\)

  • objective: weighted \(p\)-norm (default \(p=8\)) of \(\mathrm{BnOverB}\) plus regularization on \(\langle|K|^2\rangle\)

Why a \(p\)-norm?

The \(p\)-norm interpolates between RMS (\(p=2\)) and max-norm (\(p\to\infty\)):

\[ \|x\|_{p,w} = \left(\frac{\sum_i w_i |x_i|^p}{\sum_i w_i}\right)^{1/p}. \]

This is a smooth proxy for “make the worst-case points small”.

Mode aliasing and resolution

If the winding-surface grid has \(N_\theta\times N_\phi\) points and the device has \(N_\mathrm{fp}\) field periods, then toroidal Fourier modes are effectively limited by:

\[ |n| N_\mathrm{fp} \le \frac{N_\phi}{2}-1, \]

and poloidal modes by:

\[ m \le \frac{N_\theta}{2}-1. \]

The VMEC optimization script automatically clips requested modes to avoid aliasing.

Electrode model

The electrode model is conceptually closer to “voltage/current injection hardware”, but it is typically harder to hit stringent \(B_n/|B|\) targets than a flexible current-potential representation.

It is still valuable for:

  • building intuition

  • prototyping GUI workflows

  • exploring regularization and constraints on discrete drivers

In this repository:

  • torus_solver.optimize.optimize_sources(...) uses Adam (Optax).

  • torus_solver.optimize.optimize_sources_lbfgs(...) uses L-BFGS (JAXopt), which can converge in fewer steps for small/medium problems.

  • examples/inverse_design/optimize_helical_axis_field.py --optimizer lbfgs demonstrates the L-BFGS path.

Practical tuning knobs

If an optimization stalls or gives poor results, the most common levers are:

  • Fit margin: scaling the target surface deeper inside the winding surface can dramatically improve the attainable \(B_n/|B|\) and reduce field-line drift.

  • Resolution: increase --surf-n-theta/--surf-n-phi and check convergence.

  • Degrees of freedom:

    • increase Fourier modes in the current-potential model

    • increase number of electrodes and/or optimize positions in the electrode model

  • Regularization: adjust reg_K (current-potential) or reg_currents (electrodes).

Regularization scan (L-curve) workflow

In current-potential coil design literature (including REGCOIL-style formulations), it is common to scan the regularization weight that penalizes current magnitude and then choose a compromise point on a tradeoff curve (often called an “L-curve”):

  • smaller regularization → smaller Bn/B, but larger |K|

  • larger regularization → smaller |K|, but worse Bn/B

examples/inverse_design/scan_vmec_surface_regularization.py performs this scan in a way that is friendly to research:

  • runs a series of optimizations for a geometric sequence of reg_K

  • uses continuation / warm-starting (each run initializes from the previous result)

  • produces a log–log tradeoff plot of max|Bn/B| and rms(Bn/B) versus K_rms

The script accepts --vmec-input examples/data/vmec/input.QA_nfp2 (from the repo root).