-
Couldn't load subscription status.
- Fork 71
Passive Arrays Branch PR Part 1: Force and torque overhaul #509
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
akaptano
wants to merge
350
commits into
master
Choose a base branch
from
force_and_torque_overhaul
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 250 commits
Commits
Show all changes
350 commits
Select commit
Hold shift + click to select a range
d36ef4b
Tests passing nicely. Trying to get a version of stage_two_optimizati…
akaptano 9384734
Seems I have gotten the stage two example working with all Jax object…
akaptano 6f499b9
got force minimization working to some extent.
akaptano af2d133
Playing with the force min example.
akaptano 75c082b
Started attempt at torques.
akaptano efd3d5b
First attempt at getting a full planar coil optimization working with…
akaptano 6316ef8
After lots of debugging, believe I have gotten the torques and total …
akaptano 2792427
Attempted to get the self force working and immediately find issue th…
akaptano 5a42a44
Added some more examples for scanning and baselining. Added optimizat…
akaptano e78b247
Did some more fiddling with the QA example to see improvements. With …
akaptano cf9a995
Didnt do much beyond mess around a bit trying to find what the issue …
akaptano 78c86f0
Scans are too slow on laptop so saving current status and going to tr…
akaptano c18c648
Some more fiddling with the examples. Saving to try this on a gpu on …
akaptano 2de04a3
Tried speeding up some of the biotsavart stuff but no luck with jax s…
akaptano 4dc12b4
Merge branch 'master' into planar_coil_arrays
akaptano 34cf164
Merged with coil_forces branch
akaptano 1d3fa27
Added some of my metrics. Comparing pointwise and net force minimizat…
akaptano 1194dba
Saving example for running at home on laptop to generate the figures …
akaptano b3885f6
Added reactor scale examples and new speedup python code for gamma ca…
akaptano 5fbf636
Performed a lot of debugging, including trying to speed up Sienas for…
akaptano fcd3dff
Merged with recent coil_forces branch changes.
akaptano 426cf6b
Merged with laptop changes
akaptano 8eb1b6b
prepping to try pareto scans with net force and torques.
akaptano 31a1d92
Getting ready to merge with laptop changes, minimal changes to exampl…
akaptano 1089ac9
Merge branch 'planar_coil_arrays' of https://github.com/hiddenSymmetr…
akaptano 76319eb
Made a bunch of fixes in the direct force and torque calculations. Tr…
akaptano 92cc378
Tweaked the examples a tiny bit.
akaptano 68219b4
Some more tweaks to the examples to get rid of interlocking coils and…
akaptano 97d9acb
More example tweaking.
akaptano 9801fe5
Added updated examples.
akaptano bf3dab0
Trying to get the fixed surface dipole example working better.
akaptano 02473f8
Added poincare plotting and example updates.
akaptano 09f4aaa
Merge branch 'planar_coil_arrays' of https://github.com/hiddenSymmetr…
akaptano c57a07e
Added new example updates.
akaptano 3bdf169
Merge branch 'planar_coil_arrays' of https://github.com/hiddenSymmetr…
akaptano 16bb776
Rerunning the fixed orientations one to remove the interlinking coils…
akaptano 8a2e57b
Made some example changes. Need to increase the force weighting on th…
akaptano aea2f37
Updated the torques to be computed with respect to the coil barycente…
akaptano beb74ec
More example tweaking. QA example essentially there with params QA_fi…
akaptano b3d7ac4
Merge branch 'master' of https://github.com/hiddenSymmetries/simsopt
akaptano 4802d6e
Merge branch 'master' into planar_coil_arrays
akaptano 5ae14c0
Made some more useful changes. Got the MixedLpCurve class running fas…
akaptano b08061a
Isolated the weak reference spawning in the jacobian calculation of J…
akaptano 45dd058
Updating laptop branch.
akaptano cc527f7
Merge branch 'planar_coil_arrays' of https://github.com/hiddenSymmetr…
akaptano 3f19636
Still struggling to find out why JaxCurves seem to spawn so many opti…
akaptano b0243bf
Fixed a bug from when i added openmp loops in the c++ files for curve…
akaptano ff70274
Did nothing beyond tune the QH example a bit.
akaptano ec33cdd
Trying to finalize examples.
akaptano cefa722
Got the QA example working well, including getting QFMs working and s…
akaptano c7ef948
Merge branch 'master' of https://github.com/hiddenSymmetries/simsopt
akaptano ddc1e16
Merge branch 'master' into planar_coil_arrays
akaptano 4c4048c
Added continuation script for QH.
akaptano 7727f8f
Merged with desktop changes.
akaptano ae98781
Cleaned up the post processing plots. Going to reorganize and delete …
akaptano 318b993
Moved all the planar coil files into separate folder.
akaptano c2ab3eb
Got the self field unit tests working again, just some normalization …
akaptano a53d85a
Merge branch 'master' of https://github.com/hiddenSymmetries/simsopt
akaptano 6e1e6d9
Merge branch 'master' into planar_coil_arrays
akaptano 2606407
QH example tweaks but mostly just merging ith desktop code.
akaptano f1fb5f7
Merge branch 'planar_coil_arrays' of https://github.com/hiddenSymmetr…
akaptano b47a168
Removing some more files. Adding henneberg example.
akaptano be71b5e
Okay now adding henneberg example
akaptano 525c170
Added henneberg example.
akaptano a2e278d
Tweaked all the examples. Tried to rename some stuff. Got the hennebe…
akaptano b9c7fc4
Updating pareto script. Going to try running it on greene.
akaptano 6fc842d
Adding pareto updates to run on greene in parallel.
akaptano 810a42e
Additional tweaking, switching to laptop.
akaptano e608730
Merging with desktop changes.
akaptano 3286f1f
Merge branch 'planar_coil_arrays' of https://github.com/hiddenSymmetr…
akaptano a80b167
Testing merging.
akaptano 9e629e1
Merge branch 'master' into planar_coil_arrays
akaptano 6746873
Tweaking examples so they reproduce the results in the paper.
akaptano 664ef77
Getting all the eamples reproducing the paper results.
akaptano b5f2bee
Autopepped all the files, which seems hasnt been done in a while on m…
akaptano d84735e
Fixed the force tests with downsampling.
akaptano fa54c27
Did some linting with ruff.
akaptano 18a8c6f
Cleaning up code and writing up tve calculation with my current metho…
akaptano d05ccfe
Still linting. Added henneberg example without dipoles.
akaptano b8933f5
Got linting fully working. Added some tests of the self and mutual in…
akaptano 329d266
Working on getting all unit tests running properly on the github CI a…
akaptano 6cc7cfb
Got the TVE working
akaptano 742954c
Adding pareto change from greene runs.
akaptano a4c3be8
Removed omp functionality from dipoles to check for a race condition …
akaptano a9158f1
Moved all the coil force stuff to single folder inside 3_Advanced.
akaptano 28a0b4b
Deleting old files.
akaptano b19ad46
Tweaked pareto runs to do the same for TVE.
akaptano 4f3aea5
Merge branch 'planar_coil_arrays' of https://github.com/hiddenSymmetr…
akaptano 8cd3ef7
Put back the omp, didnt seem to fix the unit test.
akaptano c6e5c1b
Merged with laptop changes that moved coil force examples.
akaptano 2ef63db
Fixed the input file in the pareto scan.
akaptano dcd1a50
played with the tve a bit more in the coil force scan.
akaptano 2793011
Still trying to get unit tests working on github CI, but cannot repro…
akaptano a9e1378
Did tiny bit of linting.
akaptano 3ec484c
Got the examples running better.
akaptano a7571fa
Removed some old stuff from RotatedCurve related to previous optimiza…
akaptano 2cea459
Did some TVE runs but results look a big strange so going to debug a …
akaptano d6327e8
Merge branch 'planar_coil_arrays' of https://github.com/hiddenSymmetr…
akaptano 88ee6ad
Downsampled tve calculation looks quite accurate still and speeds up …
akaptano d0d729f
Fixed a dumb bug in the TVE where the magnitude of the currents were …
akaptano 220c0d6
Finished up the TVE scan.
akaptano 0f97eae
Took first stab at redoing the passive coil terms.
akaptano 965500c
Merge branch 'planar_coil_arrays' of https://github.com/hiddenSymmetr…
akaptano 2fc5da8
Added psc example test.
akaptano 18540a0
Amazingly, example seems to be running properly but its too slow beca…
akaptano bc80c68
Still working on getting the PSC jacobian integrated properly. Is tri…
akaptano 31ead00
Think I went down a wrong road trying to combine the biotsavart objec…
akaptano 5eb4f4f
Got the PSC array working much more effectively by avoiding a call to…
akaptano f154608
Made the jacobian calculation much faster by swapping jacfwd with jac…
akaptano d08042b
Debugging. Added a test to see if I can even get dI_dgammas through j…
akaptano 15df425
I tentatively may have fixed the jacobian calculation by just directl…
akaptano c6cc816
Fixed some lingering bugs. Seems the jacobian is fully working, inclu…
akaptano af29321
Continuing to clean up the code and speed up the jacobian calculation…
akaptano 3a9997d
Fixed a bug in the A() calculation where I wasnt dividing by the numb…
akaptano 9143cff
Moved the passive coil example files. Fixed lingering bug that the ja…
akaptano f7907d4
Working on getting a final solution for the schuett-henneberg configu…
akaptano 90ea154
Got the henneberg example finalized. Working on a QH example now. Sav…
akaptano bfc20a7
Finalizing poincare plots and other postprocessing thngs.
akaptano 6786968
Added CSX files.
akaptano f3c7ff4
Saving final status of the psc branch before cleaning it up.
akaptano ec870e4
Committing last changes from desktop, will merge with latest changes …
akaptano 4c66b93
Merge branch 'passive_coil_arrays' of https://github.com/hiddenSymmet…
akaptano 25d8c49
Merge branch 'passive_coil_arrays' of https://github.com/hiddenSymmet…
akaptano 07f3c35
Merge branch 'planar_coil_arrays' into passive_coil_arrays
akaptano 036f698
Some small reorganizing and rerunning for setting up the dipole array…
akaptano a019f44
Small changes to compare with florians coils.
akaptano ec84832
small change to coil forces script.
akaptano 3c87248
Merge branch 'master' of https://github.com/hiddenSymmetries/simsopt
akaptano b095f22
Merged with main
akaptano 5a74c3b
Ran ruff, still fixes to make.
akaptano a9e6435
Did some linting and added Taylor test for all the force and dipole r…
akaptano c2f63a0
Linting and added doc files.
akaptano 2487bba
Got CSX passive coil example cleaned up, and only requiring one scrip…
akaptano 3330e6f
Made some renaming changes and tried to get both the initial optimiza…
akaptano 9262a73
Still in the process of dipole array script clean up and linting and …
akaptano 2c984c7
Almost got the dipole array examples fully in order. Need to get the …
akaptano fd39c9f
Tweaking and cleaning the examples. QH example with continuation not …
akaptano 3c199fd
Moved all the postprocessing into a single script. Got the examples w…
akaptano cb42ed7
Combined the nodipole scripts.
akaptano 9cc8c3d
Added in Jakes tokamak stellarator hybrid example.
akaptano 4953de8
Fixed SchuettHenneberg example to include the bootstrap current contr…
akaptano b2bc210
Added some linting and improvements on Jakes script, including use th…
akaptano b8163fd
Added Jakes grid setup to a LP QA reactor scale example. Got it runni…
akaptano b68e493
Did some linting
akaptano c5cc698
Merge with wireframe update
akaptano 185567f
Minor fix in the import file.
akaptano 202c1ba
Edited the muse examples.
akaptano f377670
Cleaned up the passive coil scripts in anticipation for making a Zeno…
akaptano b5382ef
Did a round of autopep
akaptano 07a2e1e
Linted a bit more. Ran ruff and recommit. Cleaned up the SchuettHenne…
akaptano ebe5029
Renamed the folder.
akaptano 36eeb25
Added a detailed dipole array tutorial example, as well as renamed so…
akaptano 2617435
Did some linting.
akaptano 9477c09
Deleted old file from Jake.
akaptano 16d6ece
Fixed a bug from a conflict between an initialize_coils function from…
akaptano 57f8c8b
Reorganizing and renaming files while I debug the tests.
akaptano a19dbc1
Renamed dipole array reproducing files.
akaptano c45aafa
Made a bunch of files executable to run all the example scripts. Fixe…
akaptano 210a3a2
Fixed some lingering issues running the serial examples.
akaptano 764c06e
Added the zenodo links for both papers.
akaptano 2905a8a
Added all the dipole scripts to run at low resolution if CI is going.
akaptano 704b356
Finalized linting.
akaptano 9930aee
Fixed the CI I think.
akaptano 3612d57
Think I fixed an error in running the coil force examples.
akaptano 94b15de
Merge branch 'master' into passive_coil_arrays
akaptano fa889c6
Linted and added a lot coverage.
akaptano caf4ce8
Attempting to rerun code coverage on pull request updates.
akaptano 8501859
Fixed some little bugs in the tests, including a factor of two missin…
akaptano 6123079
Attempted to fix the planar curve test failure in the CI, which appea…
akaptano fcd7f35
Started fixing a substantial bug I found in the course of checking ou…
akaptano abd0b4f
Got rid of the pyplot show.
akaptano 760a768
Think I fixed the test error. Going to try and see if the tests pass …
akaptano 3bb65ff
Tiny change to get the Taylor test working on CI.
akaptano b79f48e
Got the passive coil jacobians looking good with the mixed force and …
akaptano ca2e826
Linted and fixed the Taylor test.
akaptano 55bd042
Fixed a small error introduced in the inductance calculation when ref…
akaptano c82ee22
Added some wireframe tests missing from coverage. Wireframe optimizat…
akaptano e245139
Got the QFM with nontrivial Bnormal_plasma working in the jacobian ca…
akaptano 6322a44
Fix wireframe optimization test with target bnormal
kchammond 8960f04
Finalized the passive coil example scripts and debugged a little erro…
akaptano e3dce55
Merge branch 'passive_coil_arrays' of https://github.com/hiddenSymmet…
akaptano f413dec
Did tiny linting on change from Ken.
akaptano 678c23a
Think I fixed the issue with the force and torque and other objective…
akaptano 4862fde
Added comments about the optimizable graph blow up issue. Will open a…
akaptano 734fe08
Added much more rigorous taylor tests for the force terms. Still seei…
akaptano 9315d34
Attempting a major overhaul of the force and torque calculations. Dep…
akaptano ba4fabb
slow work trying to get the new force objectives into shape.
akaptano b336ba7
Finally got something decent working in the new coil coil force and t…
akaptano cde8bf9
Changed all the dipole and other example files to use the new force a…
akaptano 2e1d3bb
Linted the code.
akaptano 432a4fa
Tried fixing the Taylor tests. It looks like the issue that the jacob…
akaptano 785d407
Merge branch 'master' of https://github.com/hiddenSymmetries/simsopt
akaptano 7e5c606
Resolved merge conflicts with main branch with autopep pull request m…
akaptano b8ea42d
Merge branch 'master' into passive_coil_arrays
akaptano 8202f24
Linted after merge with main.
akaptano 6970841
Added some little fixes from Misha review. Deleted 3_Advanced/inputs/…
akaptano 87f936f
Deleted all the changes to non-relevant example files. deleted all th…
akaptano 5bcaaec
Deleted a lot more files. Revert a few other changes related to the Q…
akaptano 535f376
Fixed the init files which I had accidentally swapped.
akaptano c7dc84c
Reverted the name change in coil_initialization in the permanent magn…
akaptano 5b274e8
Readded some files that shouldnt have been deleted, and reverted some…
akaptano d70cd33
Fixed the CI error. Did some linting and documentation, responding to…
akaptano 0a8bae2
Made the fixes initially from Matt. Cleaned up the coil_force_optimiz…
akaptano 003b4e6
Making a number of simplifications along the lines of Matt Landremans…
akaptano 578e59b
Think I polished off lingering failing unit tests from all the change…
akaptano 799f5fe
Fixed a few more unit tests that were perturbed by the changes to the…
akaptano 0ebb93b
Fixed the ruff check and added coverage, which had decreased because …
akaptano 37ca7bc
Fixed coils_to_vtk working.
akaptano 420c44a
Deprecated functions still making the Taylor test fail, so removed th…
akaptano 3e3374d
added some documentation. got the self force functions to also use th…
akaptano 18b8319
Forgot to rename the coils in the last commit.
akaptano f8188df
1. The CurvePlanarFourier class now is initialized without the stells…
akaptano 9953db6
Made the recommended fixes from Andrew G. Cleaned up the coil force p…
akaptano 55f53fb
Few more small changes from Andrews suggestion, fixed a lot of docstr…
akaptano c5e3f49
Fix the tests, which failed because optimization_tools.py in examples…
akaptano 1cbdb5b
Finished off remaining test failures and other comments from Andrew. …
akaptano d772aa5
Merged with master branch changes.
akaptano 02a019d
Merged with curve helical changes from master branch. Added curveheli…
akaptano 4f3787d
Merge branch 'master' into force_and_torque_overhaul
akaptano 8aca047
Added a tiny bit of coverage. Checks now that shortest_distance still…
akaptano ef96aad
Merge branch 'master' into force_and_torque_overhaul
akaptano fc16454
Made a bunch of docstring and other changes along the lines of Mishas…
akaptano 1eae0b2
Finished off lingering import issues from renaming some parameters.
akaptano b2c66c2
Merge branch 'master' into force_and_torque_overhaul
akaptano 26de6e7
Fixed some docstrings and other things.
akaptano e496823
Added tiny amount of coverage. Fixed the setup_uniform_grid function …
akaptano 066a004
Removed deprecated force objectives, curveplanarellipticalcylindrical…
akaptano 42e81db
Got the tests running again after all the deletions.
akaptano a931cf9
Merge branch 'master' into force_and_torque_overhaul
akaptano 725c153
Merge branch 'master' of https://github.com/hiddenSymmetries/simsopt
akaptano 2d05b76
Merge branch 'master' of https://github.com/hiddenSymmetries/simsopt
akaptano 8f07751
Merge branch 'jax_curve_PR' into force_and_torque_overhaul
akaptano d1954bf
Fixed testing issues from merging with jax_curve_PR.
akaptano 9e69e12
Merge branch 'master' into force_and_torque_overhaul
akaptano e39413d
Corrected the example files to use the new jax curve flag.
akaptano 2612630
Made a new util file with the coil pareto scans and other coil optimi…
akaptano be428e7
Fixed some unit test and example issues coming from moving all the pa…
akaptano 77e926d
Think I fixed the example failures.
akaptano 0aeb369
Tried to get the unit test folders created correctly.
akaptano 9bb1ffc
Trying to remove the unit test issue.
akaptano 900c7c0
Trying a different way to save the files.
akaptano ec10885
Improved the code coverage, which had depreciated since the migration…
akaptano af1545a
Hopefully fixed remaining unit test issues.
akaptano 3cd4aaf
Added paretoset package to be downloaded for unit tests.
akaptano 161ff15
Merge branch 'master' of https://github.com/hiddenSymmetries/simsopt
akaptano 8051df9
Merge branch 'master' of https://github.com/hiddenSymmetries/simsopt
akaptano 6d239fa
Merge branch 'master' into force_and_torque_overhaul
akaptano dbc53f3
Added small fix from merge.
akaptano e9e5b4e
Merge branch 'master' of https://github.com/hiddenSymmetries/simsopt
akaptano b80af5d
Merge branch 'master' into force_and_torque_overhaul
akaptano File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
akaptano marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
284 changes: 284 additions & 0 deletions
284
examples/3_Advanced/coil_force_optimization/coil_force_objectives_scan.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,284 @@ | ||
| #!/usr/bin/env python | ||
|
|
||
| """ | ||
| coil_force_objectives_scan.py | ||
| ---------------------------- | ||
|
|
||
| This script scans and compares different force and torque objective terms in stage-two coil optimization | ||
| for stellarator design using SIMSOPT. It sets up an optimization problem for magnetic | ||
| coils, with selectable force/torque objectives and engineering constraints, and solves it using | ||
| SciPy's L-BFGS-B optimizer. The script outputs VTK files for visualization and prints diagnostic | ||
| information about the optimization process. The goal is to see how different force/torque/magnetic energy | ||
| terms affect the optimization and the various trade-offs. This scan we used to generate the results in the paper: | ||
|
|
||
| Kaptanoglu, A.A., Wiedman, A., Halpern, J., Hurwitz, S., Paul, E.J. and Landreman, M., 2025. | ||
| Reactor-scale stellarators with force and torque minimized dipole coils. | ||
| Nuclear Fusion, 65(4), p.046029. | ||
| https://iopscience.iop.org/article/10.1088/1741-4326/adc318/meta | ||
|
|
||
akaptano marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Main steps: | ||
| - Parse command-line arguments to select the force/torque objective and its weight. | ||
| - Define input parameters for coil geometry, penalties, and weights. | ||
| - Set up the magnetic surface and initial coil configuration. | ||
| - Construct the objective function as a weighted sum of physics and engineering terms, with the selected force/torque objective. | ||
| - Perform a Taylor test to verify gradient correctness. | ||
| - Run the optimization and save results. | ||
|
|
||
| Usage: | ||
| python coil_force_objectives_scan.py <ObjectiveType> <ForceWeight> [<Threshold>] | ||
| where <ObjectiveType> is one of: SquaredMeanForce, SquaredMeanTorque, LpCurveForce, LpCurveTorque, B2_Energy, NetFluxes | ||
| and <ForceWeight> is the weight for the force/torque term. | ||
| <Threshold> is optional for LpCurveForce/LpCurveTorque. | ||
|
|
||
| """ | ||
| import os | ||
| import sys | ||
| from pathlib import Path | ||
| import shutil | ||
| from scipy.optimize import minimize | ||
| import numpy as np | ||
| from simsopt.geo import create_equally_spaced_curves | ||
| from simsopt.geo import SurfaceRZFourier | ||
| from simsopt.field import Current, coils_via_symmetries, coils_to_vtk | ||
| from simsopt.objectives import SquaredFlux, Weight, QuadraticPenalty | ||
| from simsopt.geo import (CurveLength, CurveCurveDistance, CurveSurfaceDistance, | ||
| MeanSquaredCurvature, LpCurveCurvature) | ||
| from simsopt.field import BiotSavart | ||
| from simsopt.field.force import LpCurveForce, \ | ||
| SquaredMeanForce, SquaredMeanTorque, LpCurveTorque, B2_Energy, NetFluxes | ||
| from simsopt.field.selffield import regularization_circ | ||
| from simsopt.util import in_github_actions | ||
|
|
||
| # --- Argument check and usage warning --- | ||
| if len(sys.argv) < 3: | ||
| print("\nUsage: python coil_force_objectives_scan.py <ObjectiveType> <ForceWeight> [<Threshold>]") | ||
| print(" <ObjectiveType>: SquaredMeanForce, SquaredMeanTorque, LpCurveForce, LpCurveTorque, B2_Energy, NetFluxes") | ||
| print(" <ForceWeight>: weight for the force/torque term (float)") | ||
| print(" <Threshold>: (optional) threshold for LpCurveForce/LpCurveTorque (float)") | ||
| print("\nExample: python coil_force_objectives_scan.py LpCurveForce 1e-3 0.0\n") | ||
| sys.exit(1) | ||
|
|
||
| ############################################################################### | ||
| # INPUT PARAMETERS | ||
| ############################################################################### | ||
|
|
||
| # Number of unique coil shapes, i.e. the number of coils per half field period: | ||
| # (Since the configuration has nfp = 2, multiply by 4 to get the total number of coils.) | ||
| ncoils = 4 | ||
|
|
||
| # Major radius for the initial circular coils: | ||
| R0 = 1.0 | ||
|
|
||
| # Minor radius for the initial circular coils: | ||
| R1 = 0.5 | ||
|
|
||
| # Number of Fourier modes describing each Cartesian component of each coil: | ||
| order = 5 | ||
|
|
||
| # Weight on the curve lengths in the objective function. We use the `Weight` | ||
| # class here to later easily adjust the scalar value and rerun the optimization | ||
| # without having to rebuild the objective. | ||
| LENGTH_WEIGHT = Weight(1e-1) | ||
| LENGTH_TARGET = 15.0 | ||
|
|
||
| # Threshold and weight for the coil-to-coil distance penalty in the objective function: | ||
| CC_THRESHOLD = 0.1 | ||
| CC_WEIGHT = 1e3 | ||
|
|
||
| # Threshold and weight for the coil-to-surface distance penalty in the objective function: | ||
| CS_THRESHOLD = 0.3 | ||
| CS_WEIGHT = 1e2 | ||
|
|
||
| # Threshold and weight for the curvature penalty in the objective function: | ||
| CURVATURE_THRESHOLD = 5. | ||
| CURVATURE_WEIGHT = 1e-6 | ||
|
|
||
| # Threshold and weight for the mean squared curvature penalty in the objective function: | ||
| MSC_THRESHOLD = 5 | ||
| MSC_WEIGHT = 1e-6 | ||
|
|
||
| # Number of iterations to perform: | ||
| MAXITER = 200 if not in_github_actions else 10 | ||
|
|
||
| # File for the desired boundary magnetic surface: | ||
| TEST_DIR = (Path(__file__).parent / ".." / ".." / ".." / "tests" / "test_files").resolve() | ||
| filename = TEST_DIR / 'input.LandremanPaul2021_QA' | ||
|
|
||
| # Directory for output | ||
| OUT_DIR = "./coil_forces_scan_" + sys.argv[1] + '_Weight' + sys.argv[2] + '/' | ||
| if os.path.exists(OUT_DIR): | ||
| shutil.rmtree(OUT_DIR) | ||
| os.makedirs(OUT_DIR, exist_ok=True) | ||
|
|
||
| ############################################################################### | ||
| # SET UP OBJECTIVE FUNCTION | ||
| ############################################################################### | ||
|
|
||
| # Initialize the boundary magnetic surface: | ||
| nphi = 32 if not in_github_actions else 8 | ||
| ntheta = 32 if not in_github_actions else 8 | ||
| s = SurfaceRZFourier.from_vmec_input(filename, range="half period", nphi=nphi, ntheta=ntheta) | ||
|
|
||
| qphi = nphi * 2 | ||
| qtheta = ntheta * 2 | ||
| quadpoints_phi = np.linspace(0, 1, qphi, endpoint=True) | ||
| quadpoints_theta = np.linspace(0, 1, qtheta, endpoint=True) | ||
| # Make high resolution, full torus version of the plasma boundary for plotting | ||
| s_plot = SurfaceRZFourier.from_vmec_input( | ||
| filename, | ||
| quadpoints_phi=quadpoints_phi, | ||
| quadpoints_theta=quadpoints_theta | ||
| ) | ||
|
|
||
| # Create the initial coils: | ||
| base_curves = create_equally_spaced_curves( | ||
| ncoils, s.nfp, stellsym=True, R0=R0, R1=R1, order=order, jax_flag=False) | ||
| base_currents = [Current(1e5) for i in range(ncoils)] | ||
| # Since the target field is zero, one possible solution is just to set all | ||
| # currents to 0. To avoid the minimizer finding that solution, we fix one | ||
| # of the currents: | ||
| base_currents[0].fix_all() | ||
|
|
||
| coils = coils_via_symmetries(base_curves, base_currents, s.nfp, True) | ||
| base_coils = coils[:ncoils] | ||
| bs = BiotSavart(coils) | ||
| bs.set_points(s.gamma().reshape((-1, 3))) | ||
|
|
||
| a = 0.02 | ||
| a_list = np.ones(len(coils)) * a | ||
| nturns = 100 | ||
| curves = [c.curve for c in coils] | ||
| coils_to_vtk(coils, OUT_DIR + "coils_init", close=True) | ||
| pointData = {"B_N": np.sum(bs.B().reshape((nphi, ntheta, 3)) * s.unitnormal(), axis=2)[:, :, None]} | ||
| s.to_vtk(OUT_DIR + "surf_init", extra_data=pointData) | ||
| bs.set_points(s_plot.gamma().reshape((-1, 3))) | ||
| pointData = {"B_N": np.sum(bs.B().reshape((qphi, qtheta, 3)) * s_plot.unitnormal(), axis=2)[:, :, None]} | ||
| s_plot.to_vtk(OUT_DIR + "surf_full_init", extra_data=pointData) | ||
| bs.set_points(s.gamma().reshape((-1, 3))) | ||
|
|
||
| # Define the individual terms objective function: | ||
| Jf = SquaredFlux(s, bs) | ||
| Jls = [CurveLength(c) for c in base_curves] | ||
| Jccdist = CurveCurveDistance(curves, CC_THRESHOLD, num_basecurves=ncoils) | ||
| Jcsdist = CurveSurfaceDistance(curves, s, CS_THRESHOLD) | ||
| Jcs = [LpCurveCurvature(c, 2, CURVATURE_THRESHOLD) for c in base_curves] | ||
| Jmscs = [MeanSquaredCurvature(c) for c in base_curves] | ||
| Jlength = QuadraticPenalty(sum(Jls), LENGTH_TARGET) | ||
| for c in coils: | ||
| c.regularization = regularization_circ(0.05) | ||
|
|
||
| if sys.argv[1] == 'SquaredMeanForce': | ||
| Jforce = SquaredMeanForce(base_coils, coils) | ||
| elif sys.argv[1] == 'SquaredMeanTorque': | ||
| Jforce = SquaredMeanTorque(base_coils, coils) | ||
| elif sys.argv[1] == 'LpCurveForce': | ||
| print('If user did not specify the threshold as the third command line argument, it will be set to zero ') | ||
| try: | ||
| Jforce = LpCurveForce(base_coils, coils, p=2, threshold=float(sys.argv[3])) | ||
| except: | ||
| Jforce = LpCurveForce(base_coils, coils, p=2, threshold=0.0) | ||
| elif sys.argv[1] == 'LpCurveTorque': | ||
| print('If user did not specify the threshold as the third command line argument, it will be set to zero ') | ||
| try: | ||
| Jforce = LpCurveTorque(base_coils, coils, p=2, threshold=float(sys.argv[3])) | ||
| except: | ||
| Jforce = LpCurveTorque(base_coils, coils, p=2, threshold=0.0) | ||
| elif sys.argv[1] == 'B2_Energy': | ||
| Jforce = B2_Energy(coils) | ||
| elif sys.argv[1] == 'NetFluxes': | ||
| Jforce = sum([NetFluxes(c, coils) for c in base_coils]) | ||
| else: | ||
| print('User did not input a valid Force/Torque objective. Defaulting to no force term') | ||
| FORCE_WEIGHT = 1e-100 | ||
|
|
||
| # Weight on the mean squared force penalty in the objective function | ||
| try: | ||
| FORCE_WEIGHT = Weight(sys.argv[2]) | ||
| except: | ||
| FORCE_WEIGHT = Weight(1e-100) | ||
|
|
||
| JF = Jf \ | ||
| + LENGTH_WEIGHT * Jlength \ | ||
| + CC_WEIGHT * Jccdist \ | ||
| + CS_WEIGHT * Jcsdist \ | ||
| + CURVATURE_WEIGHT * sum(Jcs) \ | ||
| + MSC_WEIGHT * sum(QuadraticPenalty(J, MSC_THRESHOLD, "max") for J in Jmscs) \ | ||
| + FORCE_WEIGHT * Jforce | ||
|
|
||
| # We don't have a general interface in SIMSOPT for optimisation problems that | ||
| # are not in least-squares form, so we write a little wrapper function that we | ||
| # pass directly to scipy.optimize.minimize | ||
|
|
||
|
|
||
| def fun(dofs): | ||
| """ | ||
| Wrapper for the total objective function and its gradient for use with SciPy's optimizer. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| dofs : np.ndarray | ||
| Array of degrees of freedom (optimization variables). | ||
|
|
||
| Returns | ||
| ------- | ||
| J : float | ||
| Value of the total objective function. | ||
| grad : np.ndarray | ||
| Gradient of the objective function with respect to dofs. | ||
| """ | ||
| JF.x = dofs | ||
| J = JF.J() | ||
| grad = JF.dJ() | ||
| BdotN = np.mean(np.abs(np.sum(bs.B().reshape((nphi, ntheta, 3)) * s.unitnormal(), axis=2))) | ||
| BdotN_over_B = BdotN / np.mean(bs.AbsB()) | ||
| outstr = f"J={J:.1e}, Jf={Jf.J():.1e}, ⟨B·n⟩={BdotN:.1e}, ⟨B·n⟩/⟨B⟩={BdotN_over_B:.1e}" | ||
| cl_string = ", ".join([f"{J.J():.1f}" for J in Jls]) | ||
| outstr += f", Len=sum([{cl_string}])={sum(J.J() for J in Jls):.2f}" | ||
| outstr += f", C-C-Sep={Jccdist.shortest_distance():.2f}, C-S-Sep={Jcsdist.shortest_distance():.2f}" | ||
| length_val = LENGTH_WEIGHT.value * Jlength.J() | ||
| cc_val = CC_WEIGHT * Jccdist.J() | ||
| cs_val = CS_WEIGHT * Jcsdist.J() | ||
| forces_val = FORCE_WEIGHT.value * Jforce.J() | ||
| valuestr = f"J={J:.2e}, Jf={Jf.J():.2e}" | ||
| valuestr += f", LenObj={length_val:.2e}" | ||
| valuestr += f", ccObj={cc_val:.2e}" | ||
| valuestr += f", csObj={cs_val:.2e}" | ||
| valuestr += f", forceObj={forces_val:.2e}" | ||
| outstr += f", F={Jforce.J():.2e}" | ||
| outstr += f", ║∇J║={np.linalg.norm(grad):.1e}" | ||
| print(outstr) | ||
| print(valuestr) | ||
| return J, grad | ||
|
|
||
|
|
||
| print(""" | ||
| ############################################################################### | ||
| # Perform a Taylor test | ||
| ############################################################################### | ||
| """) | ||
| print("(It make take jax several minutes to compile the objective for the first evaluation.)") | ||
| f = fun | ||
| dofs = JF.x | ||
| np.random.seed(1) | ||
| h = np.random.uniform(size=dofs.shape) | ||
| J0, dJ0 = f(dofs) | ||
| dJh = sum(dJ0 * h) | ||
| for eps in [1e-3, 1e-4, 1e-5, 1e-6, 1e-7]: | ||
| J1, _ = f(dofs + eps*h) | ||
| J2, _ = f(dofs - eps*h) | ||
| print("err", (J1-J2)/(2*eps) - dJh) | ||
|
|
||
| ############################################################################### | ||
| # RUN THE OPTIMIZATION | ||
| ############################################################################### | ||
|
|
||
| dofs = JF.x | ||
| print(f"Optimization with FORCE_WEIGHT={FORCE_WEIGHT.value} and LENGTH_WEIGHT={LENGTH_WEIGHT.value}") | ||
| res = minimize(fun, dofs, jac=True, method='L-BFGS-B', options={'maxiter': MAXITER, 'maxcor': MAXITER}, tol=1e-12) | ||
| coils_to_vtk(coils, OUT_DIR + "coils_opt", close=True) | ||
|
|
||
| pointData_surf = {"B_N": np.sum(bs.B().reshape((nphi, ntheta, 3)) * s.unitnormal(), axis=2)[:, :, None]} | ||
| s.to_vtk(OUT_DIR + "surf_opt", extra_data=pointData_surf) | ||
| bs.set_points(s_plot.gamma().reshape((-1, 3))) | ||
| pointData = {"B_N": np.sum(bs.B().reshape((qphi, qtheta, 3)) * s_plot.unitnormal(), axis=2)[:, :, None]} | ||
| s_plot.to_vtk(OUT_DIR + "surf_full_opt", extra_data=pointData) | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is pandas necessary? Curious why we need this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's for doing database querying in the pareto scans (see optimization_tools.py in the examples)