Skip to content

Commit

Permalink
missing file
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Giuliani committed Mar 29, 2024
1 parent 020a7e7 commit 550b0d2
Showing 1 changed file with 88 additions and 0 deletions.
88 changes: 88 additions & 0 deletions src/simsopt/field/magnetic_axis_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import numpy as np
from simsopt.geo import CurveRZFourier
from scipy.integrate import solve_ivp

def compute_on_axis_iota(axis, magnetic_field):
"""
Computes the rotational transform on the magnetic axis of a device using a method based on
equation (13) of Greene, Journal of Mathematical Physics 20, 1183 (1979); doi: 10.1063/1.524170.
This method was shared by Stuart Hudson and Matt Landreman. NOTE: this function does not check that the provided
axis is actually a magnetic axis of the input magnetic_field.
Args:
axis: a CurveRZFourier corresponding to the magnetic axis of the magnetic field.
magnetic_field: the magnetic field in which the axis lies.
Returns:
iota: the rotational transform on the given axis.
"""
assert type(axis) is CurveRZFourier

Check warning on line 19 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L19

Added line #L19 was not covered by tests

def tangent_map(phi, x):
ind = np.array(phi)
out = np.zeros((1, 3))
axis.gamma_impl(out, ind)
magnetic_field.set_points(out)

Check warning on line 25 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L21-L25

Added lines #L21 - L25 were not covered by tests

out = out.flatten()
B = magnetic_field.B().flatten()
dB_by_dX = magnetic_field.dB_by_dX().reshape((3, 3))
B1 = B[0]
B2 = B[1]
B3 = B[2]

Check warning on line 32 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L27-L32

Added lines #L27 - L32 were not covered by tests

dB1_dx = dB_by_dX[0, 0]
dB1_dy = dB_by_dX[0, 1]
dB1_dz = dB_by_dX[0, 2]

Check warning on line 36 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L34-L36

Added lines #L34 - L36 were not covered by tests

dB2_dx = dB_by_dX[1, 0]
dB2_dy = dB_by_dX[1, 1]
dB2_dz = dB_by_dX[1, 2]

Check warning on line 40 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L38-L40

Added lines #L38 - L40 were not covered by tests

dB3_dx = dB_by_dX[2, 0]
dB3_dy = dB_by_dX[2, 1]
dB3_dz = dB_by_dX[2, 2]

Check warning on line 44 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L42-L44

Added lines #L42 - L44 were not covered by tests

c = np.cos(2*np.pi*phi)
s = np.sin(2*np.pi*phi)

Check warning on line 47 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L46-L47

Added lines #L46 - L47 were not covered by tests

R = np.sqrt(out[0]**2 + out[1]**2)
dx_dR = c
dy_dR = s

Check warning on line 51 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L49-L51

Added lines #L49 - L51 were not covered by tests

BR = c*B1 + s*B2
Bphi =-s*B1 + c*B2
BZ = B3

Check warning on line 55 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L53-L55

Added lines #L53 - L55 were not covered by tests

dB1_dR = dB1_dx * dx_dR + dB1_dy * dy_dR
dB2_dR = dB2_dx * dx_dR + dB2_dy * dy_dR
dB3_dR = dB3_dx * dx_dR + dB3_dy * dy_dR

Check warning on line 59 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L57-L59

Added lines #L57 - L59 were not covered by tests

dBR_dR = c*dB1_dR + s*dB2_dR
dBphi_dR = -s*dB1_dR + c*dB2_dR
dBZ_dR = dB3_dR

Check warning on line 63 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L61-L63

Added lines #L61 - L63 were not covered by tests

dBR_dZ = c*dB1_dz + s*dB2_dz
dBphi_dZ = -s*dB1_dz + c*dB2_dz
dBZ_dZ = dB3_dz

Check warning on line 67 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L65-L67

Added lines #L65 - L67 were not covered by tests

Bphi_R = Bphi/R
d_Bphi_R_dR = (dBphi_dR * R - Bphi)/R**2
d_Bphi_R_dZ = dBphi_dZ/R

Check warning on line 71 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L69-L71

Added lines #L69 - L71 were not covered by tests

A11 = (dBR_dR - (BR / Bphi_R) * d_Bphi_R_dR) / Bphi_R
A21 = (dBZ_dR - (BZ / Bphi_R) * d_Bphi_R_dR) / Bphi_R
A12 = (dBR_dZ - (BR / Bphi_R) * d_Bphi_R_dZ) / Bphi_R
A22 = (dBZ_dZ - (BZ / Bphi_R) * d_Bphi_R_dZ) / Bphi_R
A = np.array([[A11,A12],[A21,A22]])
return 2*np.pi*np.array([A@x[:2], A@x[2:]]).flatten()

Check warning on line 78 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L73-L78

Added lines #L73 - L78 were not covered by tests

t_span = [0, 1/axis.nfp]
t_eval = t_span

Check warning on line 81 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L80-L81

Added lines #L80 - L81 were not covered by tests

y0 = np.array([1, 0, 0, 1])
results = solve_ivp(tangent_map, t_span, y0, t_eval=t_eval, rtol=1e-12, atol=1e-12, method='RK45')
M = results.y[:, -1].reshape((2,2))
evals, evecs = np.linalg.eig(M)
iota = np.arctan2(np.imag(evals[0]), np.real(evals[0])) * axis.nfp/(2*np.pi)
return iota

Check warning on line 88 in src/simsopt/field/magnetic_axis_helpers.py

View check run for this annotation

Codecov / codecov/patch

src/simsopt/field/magnetic_axis_helpers.py#L83-L88

Added lines #L83 - L88 were not covered by tests

0 comments on commit 550b0d2

Please sign in to comment.