Skip to content
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

Magnetic axis limits and new variables #556

Merged
merged 142 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
142 commits
Select commit Hold shift + click to select a range
753ee67
Update basis vectors for new toroidal stream function
f0uriest Apr 11, 2023
cc01178
Add compute functions for toroidal stream function
f0uriest Apr 11, 2023
866cfc6
Add toroidal stream function to equilibrium and objectives etc
f0uriest Apr 11, 2023
fec2a53
Add constraint to fix omega at boundary
f0uriest Apr 11, 2023
d2a350e
Add analytic derivatives wrt misc coordinates
f0uriest Apr 26, 2023
00b5646
Add new function for mapping between coordinate systems
f0uriest Apr 26, 2023
bea0d7a
Merge branch 'master' into rc/toroidal_angle
f0uriest Apr 26, 2023
b111d00
Start adding toroidal stream function to surfaces
f0uriest Apr 26, 2023
b7cca7a
Finish adding toroidal stream function to surfaces
f0uriest May 5, 2023
1918075
Merge branch 'master' into rc/toroidal_angle
f0uriest May 29, 2023
77515dd
Fix calculation of alpha, theta_PEST, sqrt(g)_PEST etc
f0uriest May 29, 2023
63a9264
Copy iota compute fun refactor from PR #448
unalmis Jun 1, 2023
8948ee1
Update iota for toroidal stream function
unalmis Jun 1, 2023
7fefcfd
started updating _field.py for toroidal angle
unalmis Jun 1, 2023
34fe673
Merge branch 'master' into rc/toroidal_angle
f0uriest Jun 8, 2023
01c340b
Add new contravariant magnetic field qtys
f0uriest Jun 8, 2023
8bc4bf9
Add Wb_mn to perturbation functions
f0uriest Jun 8, 2023
a9fcd8f
Merge branch 'master' into rc/toroidal_angle
unalmis Jun 16, 2023
a23d44b
Merge branch 'function_integral' into add_all_limits
unalmis Jun 22, 2023
bb4d761
Create checkpoint for axis limit side quest
unalmis Jun 25, 2023
c80a9d7
first pass for adding magnetic field limits
unalmis Jun 26, 2023
39512f5
Merge branch 'master' into add_all_limits
unalmis Jun 26, 2023
d9279de
add more axis limits
unalmis Jun 27, 2023
2c0af13
Merge branch 'master' into add_all_limits
unalmis Jun 27, 2023
0123d39
update axis_limits test
unalmis Jun 28, 2023
7d9a3ca
add limits and update api
unalmis Jul 3, 2023
1b4ca01
Fix norm bug in n_rho computation
unalmis Jul 4, 2023
17bf5cb
update limit api to lambda function
unalmis Jul 4, 2023
3f797ee
add more limtis
unalmis Jul 5, 2023
026348b
make compress and expand grid object methods
unalmis Jul 5, 2023
4f57efd
refactor surface utils tests
unalmis Jul 5, 2023
8dd1293
clean up code, fix bugs in grid.py related to change_resolution
unalmis Jul 6, 2023
c3d67c4
update contravariant metrics with limits
unalmis Jul 7, 2023
4945449
add iota deriv limits
unalmis Jul 9, 2023
6598c48
Note bug in denominator limit
unalmis Jul 10, 2023
17e1561
start detangle process
unalmis Jul 10, 2023
a812ff2
detangle with rc/toroidal_angle
unalmis Jul 10, 2023
733bbce
set omega to dummy variable of 0
unalmis Jul 10, 2023
14e10b0
remove and comment
unalmis Jul 10, 2023
5b7ab09
Merge branch 'master' into add_all_limits
unalmis Jul 10, 2023
cd83609
remove remaining references to omega bdry modes
unalmis Jul 10, 2023
6310993
Merge branch 'master' into add_all_limits
unalmis Jul 10, 2023
55025ee
fix test
unalmis Jul 10, 2023
d577b5a
do black formatting and remove reference to removed function
unalmis Jul 10, 2023
b4a124c
add data deps test
unalmis Jul 11, 2023
e3f2652
fix up stuff
unalmis Jul 11, 2023
ca74912
Fix limit tests and improve speed significantly
unalmis Jul 13, 2023
5a6232f
fix grad(B) test
unalmis Jul 13, 2023
a3bac54
update tests
unalmis Jul 13, 2023
7be37cb
Fix iota derivatives limits
unalmis Jul 16, 2023
de73385
fix return type
unalmis Jul 16, 2023
6a8b626
update axis limit tests
unalmis Jul 16, 2023
bab5ad7
Use boolean and for qs function
unalmis Jul 16, 2023
dadc1cc
Fix up tests for axis limits and plotting
unalmis Jul 16, 2023
9185546
Merge branch 'master' into add_all_limits
unalmis Jul 16, 2023
c3aee53
Remove testing crutch
unalmis Jul 16, 2023
03c23d4
Resolve merge conflicts, fix logic bug in plotting
unalmis Jul 17, 2023
886c262
resolve flake linting comments
unalmis Jul 17, 2023
14835f6
Convert vectors to xyz basis before finite differencing
f0uriest Jul 13, 2023
0cac8c2
Fix boundary conditions on 2d finite differencing
f0uriest Jul 13, 2023
48f54cc
Update tests/test_constrain_current.py
unalmis Jul 17, 2023
b5f4fc1
Update plotting limit
unalmis Jul 17, 2023
c93a5b8
make plotting fsa limit more robust
unalmis Jul 17, 2023
ac7eb79
Revert changes to transform to resolve in different PR
unalmis Jul 17, 2023
0ecfd34
Fix test constrain current test for higher order derivatives
unalmis Jul 18, 2023
4657eb4
Resolve github actions
unalmis Jul 18, 2023
5bb120c
cosmetic change
unalmis Jul 19, 2023
73d436b
Merge branch 'master' into add_all_limits
unalmis Jul 19, 2023
e4d236a
Merge branch 'higher_order_deriv' into add_all_limits
unalmis Jul 19, 2023
5cb82ca
Allow fourth order radial derivs in profiles...
unalmis Jul 19, 2023
3ed6cff
Fix failing tests
unalmis Jul 21, 2023
25df43c
Merge branch 'master' into add_all_limits
unalmis Jul 21, 2023
464a2a4
Ignore division by zero warnings in compute funs
unalmis Jul 21, 2023
9a258f5
Recreate transforms in equilibrium set_up for current...
unalmis Jul 21, 2023
0248ed0
Python 3.8 compatible dict union
unalmis Jul 21, 2023
38df04d
Fix magnetic field derivative and add test...
unalmis Jul 21, 2023
fddc199
Make sure axis limit test can identify dicontinuities
unalmis Jul 21, 2023
780ba18
Decrease tolerance for optimizer test until review
unalmis Jul 21, 2023
248e158
Mark augmented lagrangian test xfail..
unalmis Jul 22, 2023
dbc4331
Vmec test durations, generalize a test_constrain_current
unalmis Jul 22, 2023
c58e610
Add test_toroidal_current test
unalmis Jul 22, 2023
0c80f6d
Merge branch 'higher_order_deriv' into add_all_limits
unalmis Jul 22, 2023
9ba77f0
Fix Heliotron vac usage in TestConstrainCurrent
unalmis Jul 23, 2023
f10e7c3
Reduce tolerance for QIC solve test
unalmis Jul 23, 2023
2ca4454
Update test durations
unalmis Jul 23, 2023
0f77e1c
Revert adding axis to boozer plot functions
unalmis Jul 23, 2023
e7d8c85
Regenerate plotting test baselines
unalmis Jul 23, 2023
44fd582
Pull request review suggestions number 1...
unalmis Jul 25, 2023
e6ea383
Update test durations after renaming test_compute_utils
unalmis Jul 25, 2023
d7f3c04
Make logic to plot axis limit in plot_fsa more clear
unalmis Jul 25, 2023
d138435
Revert unneeded change
unalmis Jul 25, 2023
bf27e10
Update names as requested in PR review
unalmis Jul 25, 2023
ac8113c
sort _core using script to make next merge easier
unalmis Aug 1, 2023
2a1cfb7
Merge branch 'master' into add_all_limits
unalmis Aug 1, 2023
d8821e9
Sort _basis_vectors to prepare for later merge
unalmis Aug 1, 2023
57e2a2e
Prevent registering same function twice
unalmis Aug 1, 2023
1e3a7f8
Implement new limits
unalmis Aug 1, 2023
e5bb5db
Fix calls to data_index in plotting.py
unalmis Aug 1, 2023
1fe56f6
Fix calls to data_index in plotting.py
unalmis Aug 1, 2023
6e5e992
Fix calls to data_index in tests/test_plotting.py
unalmis Aug 1, 2023
55fdde4
Fix e_zeta_rtt
unalmis Aug 1, 2023
5864bf2
tighten limit test tolerance
unalmis Aug 1, 2023
da10561
switch to better fitting method
unalmis Aug 1, 2023
f56dfd0
use dedicated variable in test_axis_limits test
unalmis Aug 1, 2023
256fbb0
Merge branch 'master' into add_all_limits
dpanici Aug 2, 2023
d7dd933
Fix plot_fsa handling of nan in surface average
unalmis Aug 4, 2023
b16400f
Merge branch 'master' into add_all_limits
unalmis Aug 8, 2023
4605ad1
Add new surface quantities needed after merging #583...
unalmis Aug 9, 2023
8987a73
Reduce resolution of map_coordinates test to avoid memory issues on CI
f0uriest Aug 4, 2023
72e49f7
update duration to match rename
unalmis Aug 9, 2023
8e6ebbe
remove tests for older JAX versions, increase test split to 3 to avoi…
dpanici Aug 5, 2023
0176c66
Change vmec save to regression to try avoid OOM issue
unalmis Aug 9, 2023
47428a1
Merge branch 'master' into add_all_limits...
unalmis Aug 10, 2023
766ffc6
Merge branch 'master' into add_all_limits...
unalmis Aug 10, 2023
88c18c9
switch docstring to cdots instead of ldots
unalmis Aug 10, 2023
a56cd54
Consolidate tests per Rory's suggestion
unalmis Aug 11, 2023
8feb914
Merge branch 'basis_vectors' into add_all_limits
unalmis Aug 11, 2023
c91ed8f
Merge branch 'master' into add_all_limits
dpanici Aug 11, 2023
2546383
Merge remote-tracking branch 'refs/remotes/origin/add_all_limits' int…
unalmis Aug 11, 2023
a34cebf
Merge branch 'master' into add_all_limits
unalmis Aug 11, 2023
8b1902c
Correct comments in curvature limit computation
unalmis Aug 11, 2023
e2850b8
sort .test_durations to reduce diff size
unalmis Aug 12, 2023
42e6358
Merge branch 'master' into add_all_limits
unalmis Aug 14, 2023
6f469e8
fix conflict from old cherry-pick
unalmis Aug 14, 2023
6e15796
Merge branch 'master' into add_all_limits...
unalmis Aug 15, 2023
fe56f4d
Merge branch 'master' into add_all_limits
unalmis Aug 15, 2023
097500c
Set multivalued limits to nan
unalmis Aug 16, 2023
a25f135
Update adding_compute_fun for axis limit example
unalmis Aug 16, 2023
49eceeb
Merge branch 'master' into add_all_limits
unalmis Aug 16, 2023
df90d2a
Continue to compute functions which are multivalued at magnetic axis
unalmis Aug 18, 2023
97cf821
Merge branch 'master' into add_all_limits
unalmis Aug 18, 2023
7c34329
Unicode latexify comments
unalmis Aug 18, 2023
19cd967
Merge branch 'master' into add_all_limits
unalmis Aug 18, 2023
bb843be
Add test to checks compuation values against master branch
unalmis Aug 18, 2023
0acb6a3
Change units as requested...
unalmis Aug 18, 2023
da35935
Add atol due to rounding errors from different machines
unalmis Aug 18, 2023
5e49354
Add justification for limit of current density J
unalmis Aug 19, 2023
299352d
Enforce cross product of mixed partial derivatives is 0 in
unalmis Aug 19, 2023
8f4d606
Remove D_current and D_shear from not_finite_limits by assuming
unalmis Aug 22, 2023
5be7dbe
Add units to iota_psi
unalmis Aug 22, 2023
2a8f941
Remove unneeded dependencies from D_current for now
unalmis Aug 22, 2023
092d6a3
add missing lambda function to iota_psi
unalmis Aug 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 19 additions & 40 deletions desc/compute/_basis_vectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,57 +322,39 @@ def _e_sub_rho_rt(params, transforms, profiles, data, **kwargs):
def _e_sub_rho_rrt(params, transforms, profiles, data, **kwargs):
data["e_rho_rrt"] = jnp.array(
[
-data["R_rt"] * data["omega_r"] ** 2
- data["R_t"] * data["omega_r"] * data["omega_rr"]
- 2 * data["R_r"] * data["omega_r"] * data["omega_rt"]
- 2
-3 * data["R_rt"] * data["omega_r"] ** 2
- 3 * data["R_t"] * data["omega_r"] * data["omega_rr"]
- 4 * data["R_r"] * data["omega_r"] * data["omega_rt"]
- 3
* data["R"]
* (
data["omega_rr"] * data["omega_rt"]
+ data["omega_r"] * data["omega_rrt"]
)
- data["omega_rt"]
* (2 * data["R_r"] * data["omega_r"] + data["R"] * data["omega_rr"])
- data["omega_rt"] * (2 * data["R_r"] * data["omega_r"])
- data["omega_t"]
* (
2 * data["R_rr"] * data["omega_r"]
3 * data["R_rr"] * data["omega_r"]
+ 3 * data["R_r"] * data["omega_rr"]
+ data["R"] * data["omega_rrr"]
)
+ data["R_rrrt"]
- data["omega_r"]
* (
2 * data["omega_r"] * data["R_rt"]
+ 2 * data["R_r"] * data["omega_rt"]
+ data["omega_t"] * data["R_rr"]
+ data["R_t"] * data["omega_rr"]
+ data["R"]
* (-data["omega_t"] * data["omega_r"] ** 2 + data["omega_rrt"])
),
2 * data["omega_rr"] * data["R_rt"]
+ 2 * data["omega_r"] * data["R_rrt"]
+ 2 * data["R_rr"] * data["omega_rt"]
+ data["omega_r"] * data["R"] * data["omega_t"] * data["omega_r"] ** 2,
3 * data["omega_rr"] * data["R_rt"]
+ 3 * data["omega_r"] * data["R_rrt"]
+ 3 * data["R_rr"] * data["omega_rt"]
+ 2 * data["R_r"] * data["omega_rrt"]
+ data["omega_rt"] * data["R_rr"]
+ data["omega_t"] * data["R_rrr"]
+ data["R_rt"] * data["omega_rr"]
+ data["R_t"] * data["omega_rrr"]
+ data["R_r"]
* (-data["omega_t"] * data["omega_r"] ** 2 + data["omega_rrt"])
* (-3 * data["omega_t"] * data["omega_r"] ** 2 + data["omega_rrt"])
+ data["R"]
* (
-data["omega_rt"] * data["omega_r"] ** 2
- data["omega_t"] * data["omega_r"] * data["omega_rr"]
-3 * data["omega_rt"] * data["omega_r"] ** 2
- 3 * data["omega_t"] * data["omega_r"] * data["omega_rr"]
+ data["omega_rrrt"]
)
+ data["omega_r"]
* (
-data["R_t"] * data["omega_r"] ** 2
- 2 * data["R"] * data["omega_r"] * data["omega_rt"]
- data["omega_t"]
* (2 * data["R_r"] * data["omega_r"] + data["R"] * data["omega_rr"])
+ data["R_rrt"]
),
- data["R_t"] * data["omega_r"] ** 3,
data["Z_rrrt"],
]
).T
Expand Down Expand Up @@ -418,8 +400,7 @@ def _e_sub_rho_rz(params, transforms, profiles, data, **kwargs):
+ data["R_rrz"],
2 * data["omega_r"] * data["R_rz"]
+ 2 * data["R_r"] * data["omega_rz"]
+ data["R_rr"]
+ data["omega_z"] * data["R_rr"]
+ (1 + data["omega_z"]) * data["R_rr"]
+ data["R_z"] * data["omega_rr"]
- data["R"]
* ((1 + data["omega_z"]) * data["omega_r"] ** 2 - data["omega_rrz"]),
Expand Down Expand Up @@ -469,7 +450,7 @@ def _e_sub_rho_rrz(params, transforms, profiles, data, **kwargs):
* (1 + data["omega_z"])
* (data["R_rr"] * data["omega_r"] + data["R_r"] * data["omega_rr"])
- data["R_rz"] * data["omega_r"] ** 2
- data["R_z"] * 2 * data["omega_r"] * data["omega_rr"]
- 2 * data["R_z"] * data["omega_r"] * data["omega_rr"]
- 2 * data["R_r"] * data["omega_r"] * data["omega_rz"]
- 2
* data["R"]
Expand All @@ -488,8 +469,7 @@ def _e_sub_rho_rrz(params, transforms, profiles, data, **kwargs):
* (
2 * data["omega_r"] * data["R_rz"]
+ 2 * data["R_r"] * data["omega_rz"]
+ data["R_rr"]
+ data["omega_z"] * data["R_rr"]
+ (1 + data["omega_z"]) * data["R_rr"]
+ data["R_z"] * data["omega_rr"]
- data["R"]
* ((1 + data["omega_z"]) * data["omega_r"] ** 2 - data["omega_rrz"])
Expand All @@ -498,17 +478,16 @@ def _e_sub_rho_rrz(params, transforms, profiles, data, **kwargs):
+ 2 * data["omega_r"] * data["R_rrz"]
+ 2 * data["R_rr"] * data["omega_rz"]
+ 2 * data["R_r"] * data["omega_rrz"]
+ data["R_rrr"]
+ data["omega_rz"] * data["R_rr"]
+ data["omega_z"] * data["R_rrr"]
+ (1 + data["omega_z"]) * data["R_rrr"]
+ data["R_rz"] * data["omega_rr"]
+ data["R_z"] * data["omega_rrr"]
- data["R_r"]
* ((1 + data["omega_z"]) * data["omega_r"] ** 2 - data["omega_rrz"])
- data["R"]
* (
data["omega_rz"] * data["omega_r"] ** 2
+ (1 + data["omega_z"]) * 2 * data["omega_r"] * data["omega_rr"]
+ 2 * (1 + data["omega_z"]) * data["omega_r"] * data["omega_rr"]
- data["omega_rrrz"]
)
+ data["omega_r"]
Expand Down
11 changes: 10 additions & 1 deletion desc/compute/_equil.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,18 @@
profiles=[],
coordinates="rtz",
data=["sqrt(g)", "B_zeta_t", "B_theta_z"],
axis_limit_data=["sqrt(g)_r", "B_zeta_rt", "B_theta_rz"],
)
def _J_sup_rho(params, transforms, profiles, data, **kwargs):
data["J^rho"] = (data["B_zeta_t"] - data["B_theta_z"]) / (mu_0 * data["sqrt(g)"])
if transforms["grid"].axis.size:
# Recall that B_zeta_t(r=0) = -psi_r sqrt(g)_t ||e_zeta|| / sqrt(g)^2,
# which is not equal to zero at the magnetic axis.
# Still, it can be shown J^rho is of the indeterminate form 0/0.
limit = (data["B_zeta_rt"] - data["B_theta_rz"]) / (mu_0 * data["sqrt(g)_r"])
data["J^rho"] = put(
data["J^rho"], transforms["grid"].axis, limit[transforms["grid"].axis]
)
return data


Expand Down Expand Up @@ -76,7 +85,6 @@ def _J_sup_zeta(params, transforms, profiles, data, **kwargs):
data=["J^rho", "J^theta", "J^zeta", "e_rho", "e_theta", "e_zeta"],
)
def _J(params, transforms, profiles, data, **kwargs):
# TODO: should be infinite because density at infinitesimal volume
data["J"] = (
data["J^rho"] * data["e_rho"].T
+ data["J^theta"] * data["e_theta"].T
Expand Down Expand Up @@ -424,6 +432,7 @@ def _Fmag_vol(params, transforms, profiles, data, **kwargs):
data=["B^theta", "B^zeta", "e^theta", "e^zeta"],
)
def _e_helical(params, transforms, profiles, data, **kwargs):
# TODO: ask question
data["e^helical"] = (
data["B^zeta"] * data["e^theta"].T - data["B^theta"] * data["e^zeta"].T
).T
Expand Down
67 changes: 57 additions & 10 deletions desc/compute/_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
surface_integrals,
surface_max,
surface_min,
surface_integrals_map,
)


Expand Down Expand Up @@ -2654,6 +2655,7 @@ def _B_rms(params, transforms, profiles, data, **kwargs):
profiles=[],
coordinates="r",
data=["sqrt(g)", "|B|", "V_r(r)"],
axis_limit_data=["sqrt(g)_r", "V_rr(r)"],
)
def _B_fsa(params, transforms, profiles, data, **kwargs):
data["<|B|>"] = surface_averages(
Expand All @@ -2662,6 +2664,16 @@ def _B_fsa(params, transforms, profiles, data, **kwargs):
data["sqrt(g)"],
denominator=data["V_r(r)"],
)
if transforms["grid"].axis.size:
limit = surface_averages(
transforms["grid"],
data["|B|"],
data["sqrt(g)_r"],
denominator=data["V_rr(r)"],
)
data["<|B|>"] = put(
data["<|B|>"], transforms["grid"].axis, limit[transforms["grid"].axis]
)
return data


Expand All @@ -2677,6 +2689,7 @@ def _B_fsa(params, transforms, profiles, data, **kwargs):
profiles=[],
coordinates="r",
data=["sqrt(g)", "|B|^2", "V_r(r)"],
axis_limit_data=["sqrt(g)_r", "V_rr(r)"],
)
def _B2_fsa(params, transforms, profiles, data, **kwargs):
data["<B^2>"] = surface_averages(
Expand All @@ -2685,6 +2698,16 @@ def _B2_fsa(params, transforms, profiles, data, **kwargs):
data["sqrt(g)"],
denominator=data["V_r(r)"],
)
if transforms["grid"].axis.size:
limit = surface_averages(
transforms["grid"],
data["|B|^2"],
data["sqrt(g)_r"],
denominator=data["V_rr(r)"],
)
data["<B^2>"] = put(
data["<B^2>"], transforms["grid"].axis, limit[transforms["grid"].axis]
)
return data


Expand All @@ -2700,6 +2723,7 @@ def _B2_fsa(params, transforms, profiles, data, **kwargs):
profiles=[],
coordinates="r",
data=["sqrt(g)", "|B|", "V_r(r)"],
axis_limit_data=["sqrt(g)_r", "V_rr(r)"],
)
def _1_over_B_fsa(params, transforms, profiles, data, **kwargs):
data["<1/|B|>"] = surface_averages(
Expand All @@ -2708,6 +2732,16 @@ def _1_over_B_fsa(params, transforms, profiles, data, **kwargs):
data["sqrt(g)"],
denominator=data["V_r(r)"],
)
if transforms["grid"].axis.size:
limit = surface_averages(
transforms["grid"],
1 / data["|B|"],
data["sqrt(g)_r"],
denominator=data["V_rr(r)"],
)
data["<1/|B|>"] = put(
data["<1/|B|>"], transforms["grid"].axis, limit[transforms["grid"].axis]
)
return data


Expand All @@ -2728,20 +2762,33 @@ def _1_over_B_fsa(params, transforms, profiles, data, **kwargs):
"B",
"B_r",
"|B|^2",
"<B^2>",
"V_r(r)",
"V_rr(r)",
],
axis_limit_data=["sqrt(g)_rr", "V_rrr(r)"],
)
def _B2_fsa_r(params, transforms, profiles, data, **kwargs):
compute_surface_integrals = surface_integrals_map(transforms["grid"])
num = compute_surface_integrals(data["sqrt(g)"] * data["|B|^2"])
num_r = compute_surface_integrals(
data["sqrt(g)_r"] * data["|B|^2"]
+ 2 * data["sqrt(g)"] * dot(data["B"], data["B_r"]),
)
data["<B^2>_r"] = (
surface_integrals(
transforms["grid"],
data["sqrt(g)_r"] * data["|B|^2"]
+ data["sqrt(g)"] * 2 * dot(data["B"], data["B_r"]),
num_r / data["V_r(r)"] - num * data["V_rr(r)"] / data["V_r(r)"] ** 2
)
if transforms["grid"].axis.size:
limit = (
compute_surface_integrals(
data["sqrt(g)_rr"] * data["|B|^2"]
+ 4 * data["sqrt(g)_r"] * dot(data["B"], data["B_r"])
)
* data["V_rr(r)"]
- num_r * data["V_rrr(r)"]
) / (2 * data["V_rr(r)"] ** 2)
data["<B^2>_r"] = put(
data["<B^2>_r"], transforms["grid"].axis, limit[transforms["grid"].axis]
)
- data["V_rr(r)"] * data["<B^2>"]
) / data["V_r(r)"]
return data


Expand Down Expand Up @@ -3336,9 +3383,9 @@ def _kappa_g(params, transforms, profiles, data, **kwargs):
)
def _grad_B_vec(params, transforms, profiles, data, **kwargs):
data["grad(B)"] = (
(data["B_r"][:, None, :] * data["e^rho"][:, :, None])
+ (data["B_t"][:, None, :] * data["e^theta"][:, :, None])
+ (data["B_z"][:, None, :] * data["e^zeta"][:, :, None])
(data["B_r"][:, jnp.newaxis, :] * data["e^rho"][:, :, jnp.newaxis])
+ (data["B_t"][:, jnp.newaxis, :] * data["e^theta"][:, :, jnp.newaxis])
+ (data["B_z"][:, jnp.newaxis, :] * data["e^zeta"][:, :, jnp.newaxis])
)
return data

Expand Down
25 changes: 21 additions & 4 deletions desc/compute/_geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,29 @@ def _V_r_of_r(params, transforms, profiles, data, **kwargs):
transforms={"grid": []},
profiles=[],
coordinates="r",
data=["sqrt(g)_r", "sqrt(g)"],
data=["sqrt(g)_r"],
)
def _V_rr_of_r(params, transforms, profiles, data, **kwargs):
data["V_rr(r)"] = surface_integrals(
transforms["grid"], data["sqrt(g)_r"] * jnp.sign(data["sqrt(g)"])
)
unalmis marked this conversation as resolved.
Show resolved Hide resolved
data["V_rr(r)"] = surface_integrals(transforms["grid"], data["sqrt(g)_r"])
return data


@register_compute_fun(
name="V_rrr(r)",
label="\\partial_{\\rho\\rho\\rho} V(\\rho)",
units="m^{3}",
units_long="cubic meters",
description="Volume enclosed by flux surfaces, third derivative wrt radial "
+ "coordinate",
dim=1,
params=[],
transforms={"grid": []},
profiles=[],
coordinates="r",
data=["sqrt(g)_rr"],
)
def _V_rrr_of_r(params, transforms, profiles, data, **kwargs):
data["V_rrr(r)"] = surface_integrals(transforms["grid"], data["sqrt(g)_rr"])
return data


Expand Down
5 changes: 2 additions & 3 deletions desc/compute/_qs.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,8 @@ def _B_mn(params, transforms, profiles, data, **kwargs):
norm = 2 ** (3 - jnp.sum((transforms["B"].basis.modes == 0), axis=1))
data["|B|_mn"] = (
norm # 1 if m=n=0, 2 if m=0 or n=0, 4 if m!=0 and n!=0
* jnp.matmul(
transforms["B"].basis.evaluate(nodes).T, data["sqrt(g)_B"] * data["|B|"]
)
* transforms["B"].basis.evaluate(nodes).T
@ (data["sqrt(g)_B"] * data["|B|"])
/ transforms["B"].grid.num_nodes
)
return data
Expand Down
8 changes: 7 additions & 1 deletion desc/compute/_stability.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from scipy.constants import mu_0

from desc.backend import jnp
from desc.backend import jnp, put

from .data_index import register_compute_fun
from .utils import dot, surface_integrals
Expand All @@ -25,6 +25,9 @@ def _D_shear(params, transforms, profiles, data, **kwargs):
# Implements equations 4.16 in M. Landreman & R. Jorge (2020)
# doi:10.1017/S002237782000121X.
data["D_shear"] = (data["iota_r"] / (4 * jnp.pi * data["psi_r"])) ** 2
# TODO: limit at magnetic axis is
# data["iota_rrr"] / (2 * (4 * jnp.pi * data["psi_rr"]) ** 2)
# if iota_r = iota_rr = 0, and nan otherwise.
return data


Expand Down Expand Up @@ -199,4 +202,7 @@ def _magnetic_well(params, transforms, profiles, data, **kwargs):
* (2 * mu_0 * data["p_r"] + data["<B^2>_r"])
/ (data["V_r(r)"] * data["<B^2>"])
)
if transforms["grid"].axis.size:
# coefficient of limit is V_r / V_rr = 0
data["magnetic well"] = put(data["magnetic well"], transforms["grid"].axis, 0)
return data