DESC
DESC copied to clipboard
Robust Coil Optimization (Wechsung)
Check out this pull request on ![]()
See visual diffs & provide feedback on Jupyter Notebooks.
Powered by ReviewNB
| benchmark_name | dt(%) | dt(s) | t_new(s) | t_old(s) |
| -------------------------------------- | ---------------------- | ---------------------- | ---------------------- | ---------------------- |
test_build_transform_fft_midres | -0.46 +/- 5.83 | -3.04e-03 +/- 3.84e-02 | 6.56e-01 +/- 2.7e-02 | 6.59e-01 +/- 2.8e-02 |
test_build_transform_fft_highres | -0.43 +/- 5.94 | -4.09e-03 +/- 5.66e-02 | 9.48e-01 +/- 5.0e-02 | 9.52e-01 +/- 2.6e-02 |
test_equilibrium_init_lowres | -3.66 +/- 4.19 | -1.58e-01 +/- 1.81e-01 | 4.15e+00 +/- 1.2e-01 | 4.30e+00 +/- 1.3e-01 |
test_objective_compile_atf | -1.80 +/- 1.78 | -1.57e-01 +/- 1.56e-01 | 8.58e+00 +/- 1.1e-01 | 8.74e+00 +/- 1.1e-01 |
test_objective_compute_atf | -8.66 +/- 4.21 | -1.57e-03 +/- 7.64e-04 | 1.66e-02 +/- 3.5e-04 | 1.82e-02 +/- 6.8e-04 |
test_objective_jac_atf | -0.25 +/- 1.85 | -4.99e-03 +/- 3.70e-02 | 2.00e+00 +/- 3.2e-02 | 2.00e+00 +/- 1.9e-02 |
test_perturb_1 | -4.37 +/- 3.93 | -7.13e-01 +/- 6.42e-01 | 1.56e+01 +/- 5.0e-01 | 1.63e+01 +/- 4.0e-01 |
test_proximal_jac_atf | +0.27 +/- 1.53 | +2.19e-02 +/- 1.25e-01 | 8.18e+00 +/- 1.1e-01 | 8.16e+00 +/- 5.2e-02 |
test_proximal_freeb_compute | +1.39 +/- 1.46 | +2.56e-03 +/- 2.68e-03 | 1.87e-01 +/- 2.1e-03 | 1.84e-01 +/- 1.7e-03 |
test_solve_fixed_iter_compiled | -0.62 +/- 1.41 | -1.30e-01 +/- 2.95e-01 | 2.08e+01 +/- 4.8e-02 | 2.10e+01 +/- 2.9e-01 |
test_objective_compute_ripple | -0.92 +/- 2.28 | -5.98e-03 +/- 1.49e-02 | 6.47e-01 +/- 1.4e-02 | 6.53e-01 +/- 5.9e-03 |
test_objective_grad_ripple | -1.25 +/- 1.73 | -3.47e-02 +/- 4.79e-02 | 2.74e+00 +/- 3.7e-02 | 2.78e+00 +/- 3.0e-02 |
test_build_transform_fft_lowres | -2.75 +/- 3.46 | -1.88e-02 +/- 2.36e-02 | 6.64e-01 +/- 1.6e-02 | 6.82e-01 +/- 1.7e-02 |
test_equilibrium_init_medres | -3.02 +/- 3.68 | -1.48e-01 +/- 1.80e-01 | 4.74e+00 +/- 1.7e-01 | 4.89e+00 +/- 7.2e-02 |
test_equilibrium_init_highres | +0.36 +/- 2.86 | +2.06e-02 +/- 1.63e-01 | 5.71e+00 +/- 1.2e-01 | 5.69e+00 +/- 1.1e-01 |
test_objective_compile_dshape_current | +1.88 +/- 5.93 | +8.15e-02 +/- 2.58e-01 | 4.43e+00 +/- 1.7e-01 | 4.34e+00 +/- 1.9e-01 |
test_objective_compute_dshape_current | +1.34 +/- 2.69 | +7.36e-05 +/- 1.48e-04 | 5.57e-03 +/- 8.2e-05 | 5.50e-03 +/- 1.2e-04 |
test_objective_jac_dshape_current | +2.03 +/- 7.84 | +9.15e-04 +/- 3.53e-03 | 4.59e-02 +/- 2.5e-03 | 4.50e-02 +/- 2.5e-03 |
test_perturb_2 | -1.45 +/- 2.22 | -3.19e-01 +/- 4.88e-01 | 2.17e+01 +/- 1.8e-01 | 2.20e+01 +/- 4.5e-01 |
test_proximal_freeb_jac | -1.19 +/- 2.86 | -8.71e-02 +/- 2.09e-01 | 7.21e+00 +/- 6.5e-02 | 7.29e+00 +/- 2.0e-01 |
test_solve_fixed_iter | +1.09 +/- 5.58 | +3.75e-01 +/- 1.92e+00 | 3.49e+01 +/- 1.0e+00 | 3.45e+01 +/- 1.6e+00 |
test_LinearConstraintProjection_build | +0.41 +/- 2.50 | +4.62e-02 +/- 2.81e-01 | 1.13e+01 +/- 2.3e-01 | 1.12e+01 +/- 1.6e-01 |
test_objective_compute_ripple_spline | +0.44 +/- 1.09 | +1.36e-03 +/- 3.36e-03 | 3.10e-01 +/- 1.4e-03 | 3.09e-01 +/- 3.0e-03 |
test_objective_grad_ripple_spline | +0.18 +/- 2.17 | +2.92e-03 +/- 3.45e-02 | 1.59e+00 +/- 2.4e-02 | 1.59e+00 +/- 2.4e-02 |
unscented transform as an option?
Is perturbation the same in each step during optimization? It would be better if it was the same.
Perturbations seems to be working:
| X | Y | Z |
|---|---|---|
- The blue line represents the position perturbation as a function of $\theta$ (ranging from $0$ to $2\pi$, covering a complete revolution of the coil).
- The orange and green lines show the derivatives of the position perturbation with respect to $\theta$, which will be used to perturb the tangent at each point.
- The orange line corresponds to samples drawn from a normal distribution using the covariance matrix (which is what we are going to use for the optimization)
- The green line computed numerically through finite differences, for validation.
The perturbation is periodic (position perturbation at $\theta=0$ and perturbation at $\theta=2\pi$ is the same), a crucial aspect since the coil’s position must be identical at $\theta$ = 0 and $\theta = 2\pi$.
Here is an example of a coil and its perturbed version (large standard deviation is used for illustration):
Here is an optimization example (black one is the result of the regular optimization, red one is the result of the stochastic optimization):
Here is what the API will look like:
QuadraticFlux(
eq,
field=coilset,
eval_grid=plasma_grid,
field_grid=coil_grid,
vacuum=True,
weight=weights_dict["quadratic flux"],
stochastic_optimization_settings={
"number_of_samples": 1,
"length_scale": 0.2,
"standard_deviation": 0.01,
},
)
Some questions:
- Do we want to add
stochastic_optimization_settingskey to all the coil objectives?
Memory benchmark result
| Test Name | %Δ | Master (MB) | PR (MB) | Δ (MB) | Time PR (s) | Time Master (s) |
| -------------------------------------- | ------------ | ------------------ | ------------------ | ------------ | ------------------ | ------------------ |
test_objective_jac_w7x | 3.23 % | 3.955e+03 | 4.082e+03 | 127.55 | 40.67 | 36.77 |
test_proximal_jac_w7x_with_eq_update | 2.29 % | 6.465e+03 | 6.613e+03 | 148.27 | 163.60 | 163.22 |
test_proximal_freeb_jac | -0.15 % | 1.321e+04 | 1.319e+04 | -19.91 | 85.75 | 85.24 |
test_proximal_freeb_jac_blocked | -0.73 % | 7.575e+03 | 7.520e+03 | -55.20 | 73.40 | 73.82 |
test_proximal_freeb_jac_batched | -0.25 % | 7.447e+03 | 7.429e+03 | -18.32 | 73.51 | 73.91 |
test_proximal_jac_ripple | -4.08 % | 3.588e+03 | 3.442e+03 | -146.40 | 65.60 | 68.11 |
test_proximal_jac_ripple_bounce1d | 3.34 % | 3.478e+03 | 3.594e+03 | 116.32 | 77.27 | 76.95 |
test_eq_solve | -2.76 % | 2.028e+03 | 1.972e+03 | -55.93 | 93.98 | 94.39 |
For the memory plots, go to the summary of Memory Benchmarks workflow and download the artifact.
Perturbations seems to be working:
X Y Z
![]()
![]()
The blue line represents the position perturbation as a function of θ (ranging from 0 to 2 π , covering a complete revolution of the coil).
The orange and green lines show the derivatives of the position perturbation with respect to θ , which will be used to perturb the tangent at each point.
- The orange line corresponds to samples drawn from a normal distribution using the covariance matrix (which is what we are going to use for the optimization)
- The green line computed numerically through finite differences, for validation.
The perturbation is periodic (position perturbation at θ = 0 and perturbation at θ = 2 π is the same), a crucial aspect since the coil’s position must be identical at θ = 0 and θ = 2 π .
Here is an example of a coil and its perturbed version (large standard deviation is used for illustration):
Here is an optimization example (black one is the result of the regular optimization, red one is the result of the stochastic optimization):
Here is what the API will look like:
QuadraticFlux( eq, field=coilset, eval_grid=plasma_grid, field_grid=coil_grid, vacuum=True, weight=weights_dict["quadratic flux"], stochastic_optimization_settings={ "number_of_samples": 1, "length_scale": 0.2, "standard_deviation": 0.01, }, )Some questions:
- Do we want to add
stochastic_optimization_settingskey to all the coil objectives?
@sinaatalay how were these figures made?
An issue I noticed: right now this computes a single perturbation which is applied to every coil in the coilset, i.e. every coil in the coilset has the exact same perturbation, described by displacements in x,z,z at each point along the coil.
I am pretty sure we want this to be a different perturbation per unique coil in the coilset, at the very least, if not also allowing for field-period-symmetry-breaking errors (which I think if we allow perturbations per unique coil, we could accomdate this by just changing from a CoilSet with NFP>1 to a CoilSet with NFP=1, maybe)
@sinaatalay how were these figures made?
It's been a while, I don’t remember exactly, but it should be in here:
https://github.com/sinaatalay/desc-projects/tree/main/finals/01_stochastic_coil_optimization
Maybe instead of current API make a "perturbed coilset" class which would have perturbations or something related to that as its params (though it would NOT be optimizable... or just force use of MixedCoilset?)


