Fitting a field grid to generalized gradients¶
The central operation is gg_fit, which fits a 3D magnetic field grid to
generalized-gradient functions a_n(s), b_n(s), b_s(s) and their
s-derivatives, plane by plane.
1. Read a field grid¶
A field grid is held in a FieldGridTable. Read one from a Bmad openPMD
field_grid HDF5 file with read_field_grid_hdf5:
using GeneralizedGradients
field = read_field_grid_hdf5("examples/wsnk_fieldmap_reduced.h5")
In a FieldGridTable, field.magnetic[ix, iy, iz] is the [Bx, By, Bz]
3-vector at the grid point whose position is
(x, y, z) = field.r0 .+ field.dr .* (ix, iy, iz)
A non-zero field.g_ref (= 1 / bending_radius) marks a curved (curvilinear)
reference frame.
2. Set the fit parameters¶
Fit controls live in a GGFitInputParams struct:
params = GGFitInputParams()
params.origin = [0.0, 0.0] # (x, y) axis the GGs are expanded about
params.n_planes_add = 1 # z-planes added either side of the base plane
params.core_weight = 1 # up-weight near-axis points (1 = uniform)
params.outer_plane_weight = 1 # weight of the outer z-planes (1 = uniform)
params.output_file = "gg_fit_result.h5"
If field.g_ref is non-zero, origin must be [0, 0]. The maximum derivative
order resolved is m_max = 2 * n_planes_add. See Theory for what
the weights do.
3. Run the fit¶
results = gg_fit(field, params)
results is a GGCoefs holding the fitted coefficient functions
(a, b, bs) sampled at every base plane (z_base), along with
the per-plane weighted-RMS residuals (rms_plane), m_max, and the
reference-frame bending strength g_ref.
4. Inspect and save¶
Print a human-readable summary (fit settings, per-plane residuals, leading multipoles at the central plane):
gg_fit_show_results(results, field, params)
Write the result to an HDF5 file (readable later by read_gg_fit, and the input
to the Bmad exporters):
write_gg_fit(results, field, params) # writes params.output_file
Putting it together¶
The complete script lives at examples/run_gg_fit.jl:
using GeneralizedGradients
field = read_field_grid_hdf5("wsnk_fieldmap_reduced.h5")
params = GGFitInputParams()
params.n_planes_add = 1
params.output_file = "gg_fit_result.h5"
results = gg_fit(field, params)
gg_fit_show_results(results, field, params)
write_gg_fit(results, field, params)
Tip
The fit does not strictly require a rectangular, evenly spaced grid — the merit
function is a sum over field points — but the current gg_fit assumes the GG
functions are sampled on the grid’s own z-planes.
Next: evaluate the fitted field or export it to Bmad.