DESC icon indicating copy to clipboard operation
DESC copied to clipboard

Robust Coil Optimization (Wechsung)

Open dpanici opened this issue 10 months ago • 10 comments

dpanici avatar Jan 16 '25 17:01 dpanici

Check out this pull request on  ReviewNB

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  |

github-actions[bot] avatar Jan 16 '25 18:01 github-actions[bot]

unscented transform as an option?

dpanici avatar Jan 22 '25 20:01 dpanici

Is perturbation the same in each step during optimization? It would be better if it was the same.

sinaatalay avatar Jan 22 '25 20:01 sinaatalay

Perturbations seems to be working:

X Y Z
image image image
  • 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):

image

Here is an optimization example (black one is the result of the regular optimization, red one is the result of the stochastic optimization):

image

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:

  1. Do we want to add stochastic_optimization_settings key to all the coil objectives?

sinaatalay avatar Feb 03 '25 23:02 sinaatalay

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.

github-actions[bot] avatar Aug 21 '25 18:08 github-actions[bot]

Perturbations seems to be working:

X Y Z image image image

  • 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):

image

Here is an optimization example (black one is the result of the regular optimization, red one is the result of the stochastic optimization):

image

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:

  1. Do we want to add stochastic_optimization_settings key to all the coil objectives?

@sinaatalay how were these figures made?

dpanici avatar Aug 24 '25 20:08 dpanici

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)

dpanici avatar Aug 25 '25 01:08 dpanici

@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

sinaatalay avatar Aug 25 '25 13:08 sinaatalay

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?)

dpanici avatar Aug 25 '25 19:08 dpanici