DESC
DESC copied to clipboard
Dp/signed distance
- Adds
PlasmaVesselDistanceCircularas an objective, which is a simpler way to calculate the plasma-vessel separation when the vessel is a circular axisymmetric torus - Add
use_signed_distanceflag toPlasmaVesselDistancewhich will use a signed distance as the target, which is positive when the plasma is inside of the vessel surface and negative if the plasma is outside of the vessel surface
use_signed_distance does not work with use_softmin, as the current method of checking the sign of the distance (dotting the unit normal of the surface with the vector $x_{plasma} - x_{surface}$ will give the incorrect sign for a point on the plasma at $\phi=0$ and a point on the surface at $\phi=\pi$)
Using the hard min does not have this issue as the sign is only applied after the closest point to the surface for each point on the plasma is found, and these plasma and surface points will typically be in the same (or very nearly the same) toroidal plane, avoiding this aforementioned issue and yielding the correct sign.
| benchmark_name | dt(%) | dt(s) | t_new(s) | t_old(s) |
| -------------------------------------- | ---------------------- | ---------------------- | ---------------------- | ---------------------- |
test_build_transform_fft_lowres | +0.27 +/- 1.45 | +3.35e-05 +/- 1.80e-04 | 1.25e-02 +/- 1.5e-04 | 1.25e-02 +/- 1.1e-04 |
test_build_transform_fft_midres | +0.29 +/- 0.73 | +2.66e-04 +/- 6.68e-04 | 9.18e-02 +/- 4.1e-04 | 9.15e-02 +/- 5.2e-04 |
test_build_transform_fft_highres | +2.73 +/- 2.00 | +1.23e-02 +/- 9.02e-03 | 4.63e-01 +/- 4.2e-03 | 4.51e-01 +/- 8.0e-03 |
test_equilibrium_init_lowres | +0.92 +/- 2.44 | +7.19e-03 +/- 1.91e-02 | 7.91e-01 +/- 1.7e-02 | 7.84e-01 +/- 8.1e-03 |
test_equilibrium_init_medres | -0.00 +/- 2.40 | -2.97e-05 +/- 3.36e-02 | 1.40e+00 +/- 3.1e-02 | 1.40e+00 +/- 1.3e-02 |
test_equilibrium_init_highres | -0.04 +/- 3.23 | -1.77e-03 +/- 1.35e-01 | 4.19e+00 +/- 8.9e-02 | 4.19e+00 +/- 1.0e-01 |
test_objective_compile_dshape_current | +1.12 +/- 7.22 | +4.73e-02 +/- 3.04e-01 | 4.26e+00 +/- 2.3e-01 | 4.21e+00 +/- 1.9e-01 |
test_objective_compile_atf | +0.15 +/- 7.34 | +1.35e-02 +/- 6.66e-01 | 9.09e+00 +/- 3.8e-01 | 9.08e+00 +/- 5.5e-01 |
test_objective_compute_dshape_current | -2.41 +/- 5.12 | -5.07e-05 +/- 1.08e-04 | 2.05e-03 +/- 1.0e-04 | 2.10e-03 +/- 3.2e-05 |
test_objective_compute_atf | -1.64 +/- 0.95 | -1.24e-04 +/- 7.20e-05 | 7.44e-03 +/- 5.5e-05 | 7.56e-03 +/- 4.6e-05 |
test_objective_jac_dshape_current | -2.80 +/- 8.20 | -1.32e-03 +/- 3.87e-03 | 4.59e-02 +/- 2.7e-03 | 4.72e-02 +/- 2.7e-03 |
test_objective_jac_atf | +5.90 +/- 6.44 | +1.23e-01 +/- 1.35e-01 | 2.22e+00 +/- 9.9e-02 | 2.09e+00 +/- 9.1e-02 |
test_perturb_1 | +0.05 +/- 13.98 | +4.41e-03 +/- 1.18e+00 | 8.46e+00 +/- 8.8e-01 | 8.46e+00 +/- 7.9e-01 |
test_perturb_2 | -0.23 +/- 4.45 | -3.25e-02 +/- 6.40e-01 | 1.43e+01 +/- 2.8e-01 | 1.44e+01 +/- 5.8e-01 |
| benchmark_name | dt(%) | dt(s) | t_new(s) | t_old(s) |
| -------------------------------------- | ---------------------- | ---------------------- | ---------------------- | ---------------------- |
test_build_transform_fft_lowres | +4.66 +/- 4.66 | +5.82e-04 +/- 5.82e-04 | 1.31e-02 +/- 5.7e-04 | 1.25e-02 +/- 1.0e-04 |
test_build_transform_fft_midres | +0.11 +/- 0.73 | +1.03e-04 +/- 6.68e-04 | 9.12e-02 +/- 4.5e-04 | 9.11e-02 +/- 4.9e-04 |
test_build_transform_fft_highres | +0.47 +/- 0.73 | +2.13e-03 +/- 3.35e-03 | 4.59e-01 +/- 1.7e-03 | 4.57e-01 +/- 2.9e-03 |
test_equilibrium_init_lowres | +1.98 +/- 1.83 | +1.59e-02 +/- 1.47e-02 | 8.20e-01 +/- 8.7e-03 | 8.04e-01 +/- 1.2e-02 |
test_equilibrium_init_medres | -0.02 +/- 1.39 | -2.40e-04 +/- 2.01e-02 | 1.44e+00 +/- 1.6e-02 | 1.44e+00 +/- 1.3e-02 |
test_equilibrium_init_highres | +0.21 +/- 0.72 | +8.71e-03 +/- 3.01e-02 | 4.17e+00 +/- 2.0e-02 | 4.16e+00 +/- 2.2e-02 |
test_objective_compile_dshape_current | +1.13 +/- 9.24 | +4.85e-02 +/- 3.97e-01 | 4.34e+00 +/- 3.1e-01 | 4.30e+00 +/- 2.5e-01 |
test_objective_compile_atf | +1.39 +/- 5.99 | +1.27e-01 +/- 5.45e-01 | 9.22e+00 +/- 4.0e-01 | 9.09e+00 +/- 3.7e-01 |
test_objective_compute_dshape_current | +1.63 +/- 1.43 | +3.42e-05 +/- 2.99e-05 | 2.13e-03 +/- 2.1e-05 | 2.10e-03 +/- 2.2e-05 |
test_objective_compute_atf | -0.65 +/- 1.23 | -4.89e-05 +/- 9.21e-05 | 7.45e-03 +/- 4.8e-05 | 7.50e-03 +/- 7.8e-05 |
test_objective_jac_dshape_current | -5.01 +/- 8.60 | -2.42e-03 +/- 4.15e-03 | 4.59e-02 +/- 3.6e-03 | 4.83e-02 +/- 2.1e-03 |
test_objective_jac_atf | +3.84 +/- 7.46 | +8.18e-02 +/- 1.59e-01 | 2.21e+00 +/- 1.3e-01 | 2.13e+00 +/- 9.6e-02 |
test_perturb_1 | -1.60 +/- 11.86 | -1.40e-01 +/- 1.04e+00 | 8.60e+00 +/- 7.9e-01 | 8.74e+00 +/- 6.7e-01 |
test_perturb_2 | -6.21 +/- 5.05 | -9.70e-01 +/- 7.88e-01 | 1.46e+01 +/- 3.4e-01 | 1.56e+01 +/- 7.1e-01 |
| benchmark_name | dt(%) | dt(s) | t_new(s) | t_old(s) |
| -------------------------------------- | ---------------------- | ---------------------- | ---------------------- | ---------------------- |
test_build_transform_fft_lowres | -0.71 +/- 1.21 | -8.72e-05 +/- 1.49e-04 | 1.23e-02 +/- 1.1e-04 | 1.24e-02 +/- 1.0e-04 |
test_build_transform_fft_midres | +0.08 +/- 0.89 | +6.77e-05 +/- 8.06e-04 | 9.03e-02 +/- 6.5e-04 | 9.02e-02 +/- 4.8e-04 |
test_build_transform_fft_highres | +1.40 +/- 0.70 | +6.36e-03 +/- 3.17e-03 | 4.60e-01 +/- 2.1e-03 | 4.54e-01 +/- 2.4e-03 |
test_equilibrium_init_lowres | -0.20 +/- 1.32 | -1.55e-03 +/- 1.05e-02 | 7.91e-01 +/- 8.3e-03 | 7.93e-01 +/- 6.4e-03 |
test_equilibrium_init_medres | +0.22 +/- 1.14 | +3.15e-03 +/- 1.60e-02 | 1.40e+00 +/- 1.2e-02 | 1.40e+00 +/- 1.1e-02 |
test_equilibrium_init_highres | -0.56 +/- 0.62 | -2.33e-02 +/- 2.58e-02 | 4.14e+00 +/- 2.1e-02 | 4.16e+00 +/- 1.5e-02 |
test_objective_compile_dshape_current | -1.63 +/- 8.07 | -7.11e-02 +/- 3.52e-01 | 4.29e+00 +/- 2.5e-01 | 4.36e+00 +/- 2.5e-01 |
test_objective_compile_atf | +0.09 +/- 7.16 | +8.03e-03 +/- 6.50e-01 | 9.09e+00 +/- 4.6e-01 | 9.08e+00 +/- 4.6e-01 |
test_objective_compute_dshape_current | -0.81 +/- 2.69 | -1.72e-05 +/- 5.74e-05 | 2.11e-03 +/- 4.1e-05 | 2.13e-03 +/- 4.0e-05 |
test_objective_compute_atf | -2.57 +/- 0.87 | -1.99e-04 +/- 6.73e-05 | 7.54e-03 +/- 5.1e-05 | 7.74e-03 +/- 4.3e-05 |
test_objective_jac_dshape_current | -0.73 +/- 10.17 | -3.36e-04 +/- 4.71e-03 | 4.60e-02 +/- 3.2e-03 | 4.63e-02 +/- 3.4e-03 |
test_objective_jac_atf | -0.69 +/- 7.93 | -1.49e-02 +/- 1.70e-01 | 2.12e+00 +/- 1.4e-01 | 2.14e+00 +/- 1.0e-01 |
test_perturb_1 | +0.44 +/- 14.91 | +3.74e-02 +/- 1.26e+00 | 8.48e+00 +/- 8.9e-01 | 8.44e+00 +/- 8.9e-01 |
test_perturb_2 | -0.18 +/- 4.01 | -2.65e-02 +/- 5.80e-01 | 1.44e+01 +/- 3.8e-01 | 1.45e+01 +/- 4.4e-01 |
Codecov Report
All modified and coverable lines are covered by tests :white_check_mark:
Project coverage is 95.46%. Comparing base (
b622eae) to head (b52728a). Report is 1752 commits behind head on master.
Additional details and impacted files
@@ Coverage Diff @@
## master #817 +/- ##
==========================================
+ Coverage 95.45% 95.46% +0.01%
==========================================
Files 87 87
Lines 22243 22297 +54
==========================================
+ Hits 21232 21286 +54
Misses 1011 1011
| Files with missing lines | Coverage Δ | |
|---|---|---|
| desc/objectives/_geometry.py | 96.94% <100.00%> (+0.36%) |
:arrow_up: |
| desc/objectives/utils.py | 100.00% <100.00%> (ø) |
| benchmark_name | dt(%) | dt(s) | t_new(s) | t_old(s) |
| -------------------------------------- | ---------------------- | ---------------------- | ---------------------- | ---------------------- |
test_build_transform_fft_lowres | -0.69 +/- 1.97 | -8.72e-05 +/- 2.49e-04 | 1.26e-02 +/- 2.2e-04 | 1.27e-02 +/- 1.2e-04 |
test_build_transform_fft_midres | -0.11 +/- 1.10 | -1.02e-04 +/- 1.03e-03 | 9.32e-02 +/- 8.5e-04 | 9.33e-02 +/- 5.7e-04 |
test_build_transform_fft_highres | -0.22 +/- 0.65 | -1.04e-03 +/- 3.03e-03 | 4.64e-01 +/- 2.5e-03 | 4.65e-01 +/- 1.7e-03 |
test_equilibrium_init_lowres | +0.88 +/- 1.30 | +7.13e-03 +/- 1.05e-02 | 8.20e-01 +/- 6.7e-03 | 8.12e-01 +/- 8.1e-03 |
test_equilibrium_init_medres | -0.36 +/- 0.99 | -5.23e-03 +/- 1.44e-02 | 1.44e+00 +/- 9.7e-03 | 1.45e+00 +/- 1.1e-02 |
test_equilibrium_init_highres | -1.43 +/- 0.70 | -6.10e-02 +/- 2.98e-02 | 4.20e+00 +/- 2.5e-02 | 4.26e+00 +/- 1.6e-02 |
test_objective_compile_dshape_current | +0.07 +/- 7.84 | +3.02e-03 +/- 3.59e-01 | 4.58e+00 +/- 2.5e-01 | 4.58e+00 +/- 2.5e-01 |
test_objective_compile_atf | +0.25 +/- 5.96 | +2.34e-02 +/- 5.66e-01 | 9.52e+00 +/- 3.7e-01 | 9.49e+00 +/- 4.3e-01 |
test_objective_compute_dshape_current | -2.49 +/- 3.55 | -5.56e-05 +/- 7.95e-05 | 2.18e-03 +/- 5.5e-05 | 2.24e-03 +/- 5.7e-05 |
test_objective_compute_atf | -4.19 +/- 2.55 | -3.28e-04 +/- 2.00e-04 | 7.50e-03 +/- 6.4e-05 | 7.83e-03 +/- 1.9e-04 |
test_objective_jac_dshape_current | +3.45 +/- 7.51 | +1.61e-03 +/- 3.50e-03 | 4.82e-02 +/- 2.6e-03 | 4.65e-02 +/- 2.3e-03 |
test_objective_jac_atf | -2.59 +/- 6.43 | -5.97e-02 +/- 1.48e-01 | 2.24e+00 +/- 1.3e-01 | 2.30e+00 +/- 7.5e-02 |
test_perturb_1 | +0.55 +/- 13.24 | +4.93e-02 +/- 1.18e+00 | 8.96e+00 +/- 8.6e-01 | 8.91e+00 +/- 8.1e-01 |
test_perturb_2 | -0.10 +/- 4.67 | -1.60e-02 +/- 7.12e-01 | 1.52e+01 +/- 5.2e-01 | 1.53e+01 +/- 4.9e-01 |
| benchmark_name | dt(%) | dt(s) | t_new(s) | t_old(s) |
| -------------------------------------- | ---------------------- | ---------------------- | ---------------------- | ---------------------- |
test_build_transform_fft_lowres | +3.55 +/- 5.73 | +4.43e-04 +/- 7.15e-04 | 1.29e-02 +/- 5.8e-04 | 1.25e-02 +/- 4.2e-04 |
test_build_transform_fft_midres | -0.47 +/- 1.39 | -4.33e-04 +/- 1.28e-03 | 9.16e-02 +/- 7.9e-04 | 9.20e-02 +/- 1.0e-03 |
test_build_transform_fft_highres | -0.49 +/- 1.06 | -2.25e-03 +/- 4.89e-03 | 4.61e-01 +/- 3.7e-03 | 4.63e-01 +/- 3.2e-03 |
test_equilibrium_init_lowres | +0.96 +/- 2.24 | +7.74e-03 +/- 1.80e-02 | 8.12e-01 +/- 1.3e-02 | 8.04e-01 +/- 1.3e-02 |
test_equilibrium_init_medres | +0.63 +/- 1.82 | +8.96e-03 +/- 2.58e-02 | 1.43e+00 +/- 2.0e-02 | 1.42e+00 +/- 1.7e-02 |
test_equilibrium_init_highres | +0.28 +/- 0.92 | +1.19e-02 +/- 3.87e-02 | 4.21e+00 +/- 2.8e-02 | 4.20e+00 +/- 2.6e-02 |
test_objective_compile_dshape_current | -0.39 +/- 10.41 | -1.70e-02 +/- 4.56e-01 | 4.37e+00 +/- 3.6e-01 | 4.38e+00 +/- 2.8e-01 |
test_objective_compile_atf | +1.14 +/- 7.02 | +1.05e-01 +/- 6.46e-01 | 9.30e+00 +/- 4.4e-01 | 9.20e+00 +/- 4.8e-01 |
test_objective_compute_dshape_current | +1.23 +/- 8.21 | +2.67e-05 +/- 1.79e-04 | 2.21e-03 +/- 1.7e-04 | 2.18e-03 +/- 5.0e-05 |
test_objective_compute_atf | +1.82 +/- 2.74 | +1.39e-04 +/- 2.09e-04 | 7.79e-03 +/- 1.8e-04 | 7.65e-03 +/- 1.1e-04 |
test_objective_jac_dshape_current | -5.31 +/- 10.41 | -2.55e-03 +/- 5.00e-03 | 4.55e-02 +/- 3.0e-03 | 4.81e-02 +/- 4.0e-03 |
test_objective_jac_atf | +3.96 +/- 9.37 | +8.45e-02 +/- 2.00e-01 | 2.22e+00 +/- 1.3e-01 | 2.14e+00 +/- 1.6e-01 |
test_perturb_1 | -0.91 +/- 10.84 | -8.10e-02 +/- 9.61e-01 | 8.78e+00 +/- 7.3e-01 | 8.86e+00 +/- 6.3e-01 |
test_perturb_2 | -0.40 +/- 2.98 | -6.06e-02 +/- 4.46e-01 | 1.49e+01 +/- 2.4e-01 | 1.50e+01 +/- 3.8e-01 |
Or just change to force grids to be the same toroidal angle, then look at things plane by plane and check distances like in the circular objective (find dist to magnetic axis at that phi, and then compare those...)
| benchmark_name | dt(%) | dt(s) | t_new(s) | t_old(s) |
| -------------------------------------- | ---------------------- | ---------------------- | ---------------------- | ---------------------- |
test_build_transform_fft_lowres | -5.82 +/- 8.30 | -3.20e-02 +/- 4.57e-02 | 5.19e-01 +/- 2.2e-02 | 5.51e-01 +/- 4.0e-02 |
test_build_transform_fft_midres | -5.66 +/- 4.69 | -3.62e-02 +/- 3.00e-02 | 6.04e-01 +/- 1.8e-02 | 6.40e-01 +/- 2.4e-02 |
test_build_transform_fft_highres | -0.96 +/- 4.65 | -9.59e-03 +/- 4.66e-02 | 9.92e-01 +/- 1.8e-02 | 1.00e+00 +/- 4.3e-02 |
test_equilibrium_init_lowres | -0.96 +/- 6.52 | -3.66e-02 +/- 2.47e-01 | 3.76e+00 +/- 7.2e-02 | 3.79e+00 +/- 2.4e-01 |
test_equilibrium_init_medres | -0.30 +/- 3.81 | -1.26e-02 +/- 1.61e-01 | 4.21e+00 +/- 1.2e-01 | 4.22e+00 +/- 1.1e-01 |
test_equilibrium_init_highres | +1.51 +/- 4.58 | +8.46e-02 +/- 2.57e-01 | 5.70e+00 +/- 2.4e-01 | 5.62e+00 +/- 8.7e-02 |
test_objective_compile_dshape_current | +1.04 +/- 1.35 | +4.06e-02 +/- 5.25e-02 | 3.94e+00 +/- 3.2e-02 | 3.90e+00 +/- 4.1e-02 |
test_objective_compile_atf | +0.20 +/- 3.11 | +1.64e-02 +/- 2.61e-01 | 8.40e+00 +/- 2.5e-01 | 8.39e+00 +/- 8.5e-02 |
test_objective_compute_dshape_current | -1.97 +/- 3.84 | -2.51e-05 +/- 4.90e-05 | 1.25e-03 +/- 3.0e-05 | 1.27e-03 +/- 3.8e-05 |
test_objective_compute_atf | -1.01 +/- 6.43 | -4.32e-05 +/- 2.76e-04 | 4.24e-03 +/- 2.1e-04 | 4.29e-03 +/- 1.8e-04 |
test_objective_jac_dshape_current | -5.74 +/- 6.38 | -2.19e-03 +/- 2.43e-03 | 3.59e-02 +/- 2.2e-03 | 3.81e-02 +/- 1.1e-03 |
test_objective_jac_atf | +0.54 +/- 2.65 | +1.02e-02 +/- 4.97e-02 | 1.88e+00 +/- 3.7e-02 | 1.87e+00 +/- 3.3e-02 |
test_perturb_1 | -0.29 +/- 3.16 | -4.09e-02 +/- 4.39e-01 | 1.39e+01 +/- 2.2e-01 | 1.39e+01 +/- 3.8e-01 |
test_perturb_2 | +1.15 +/- 3.35 | +2.17e-01 +/- 6.33e-01 | 1.91e+01 +/- 6.3e-01 | 1.89e+01 +/- 9.2e-02 |
test_proximal_jac_atf | +0.10 +/- 1.37 | +7.26e-03 +/- 1.01e-01 | 7.35e+00 +/- 5.0e-02 | 7.35e+00 +/- 8.8e-02 |
test_proximal_freeb_compute | +1.14 +/- 0.96 | +2.04e-03 +/- 1.71e-03 | 1.81e-01 +/- 1.2e-03 | 1.79e-01 +/- 1.2e-03 |
test_proximal_freeb_jac | +1.82 +/- 1.26 | +1.34e-01 +/- 9.32e-02 | 7.50e+00 +/- 7.6e-02 | 7.37e+00 +/- 5.4e-02 |
test_solve_fixed_iter | +0.63 +/- 5.75 | +1.14e-01 +/- 1.05e+00 | 1.83e+01 +/- 8.2e-01 | 1.82e+01 +/- 6.4e-01 |
Algorithm implementing the winding number approach to find if a point is inside a surface can use this to assign signs to the min distancesof each point on the plasma, if we restrict the plasma and surf grids to use the same zeta values
based off of https://www.sciencedirect.com/science/article/abs/pii/B9780123361561500124?via%3Dihub
from desc.geometry import FourierRZToroidalSurface
import numpy as np
import matplotlib.pyplot as plt
from desc.backend import jnp
from desc.grid import LinearGrid
def find_angle_vec(R,Z,Rtest,Ztest):
"""R Z and surf points, Rtest Ztest are the point we wanna check is inside or not"""
# R Z can be vecs for sure
Rbool = R>Rtest
Zbool = Z>Ztest
return_data = np.zeros_like(R)
return_data = np.where(np.logical_and(Rbool, Zbool),
0,
return_data)
return_data = np.where(np.logical_and(np.logical_not( Rbool), Zbool),
1,
return_data)
return_data = np.where(np.logical_and(np.logical_not( Rbool) , np.logical_not( Zbool)),
2,
return_data)
return_data = np.where(np.logical_and(Rbool , np.logical_not( Zbool)),
3,
return_data)
return return_data
circ = FourierRZToroidalSurface()
pt_in_R = np.array([10])
pt_in_Z = np.array([0])
data_circ = circ.compute(["R","Z"],grid=LinearGrid(M=10,L=0,N=0,endpoint=True))
# vectorized over the surf pts
# NOTE: you loop over every VERTEX, so the last vertex you consider is the last point to the first point, so here we must add a ghost last point to account
# for that
R_circ = np.append(data_circ["R"],data_circ["R"][0])
Z_circ=np.append(data_circ["Z"],data_circ["Z"][0])
R=R_circ
Z=Z_circ
quads = find_angle_vec(R_circ,Z_circ,pt_in_R[0],pt_in_Z[0])
deltas = quads[1:] - quads[0:-1]
deltas = np.where(deltas==3,-1,deltas)
deltas = np.where(deltas==-3,1,deltas)
# then flip sign if the R intercept is > Rtest and the
# quadrant flipped over a diagonal
b = (Z[1:]/R[1:] - Z[0:-1]/R[0:-1]) / (Z[1:]-Z[0:-1])
Rint = pt_in_Z[0] - b*(R[1:]-R[0:-1])/(Z[1:]-Z[0:-1])
deltas = np.where(np.logical_and(np.abs(deltas)==2, Rint>pt_in_R[0]),-deltas,deltas)
theta = np.sum(deltas)
print(theta) # this is +/- 4 if inside the shape, and 0 if outside