Skip to content

Commit 645550d

Browse files
committed
correctly read in power_series_I vmec input files
1 parent bdca2b9 commit 645550d

File tree

2 files changed

+44
-12
lines changed

2 files changed

+44
-12
lines changed

desc/input_reader.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,7 +1101,7 @@ def parse_vmec_inputs(vmec_fname, threshold=0): # noqa: C901
11011101
)
11021102
)
11031103
ctype = vmec_indata.get("PCURR_TYPE", "power_series")
1104-
if ctype.lower() != "power_series":
1104+
if not ctype.lower() in ["power_series", "power_series_i"]:
11051105
warnings.warn(
11061106
colored(
11071107
"current is not a power series! DESC can only read power series"
@@ -1135,7 +1135,11 @@ def parse_vmec_inputs(vmec_fname, threshold=0): # noqa: C901
11351135
# read current
11361136
curr_tor = vmec_indata.get("CURTOR", None)
11371137
AC = np.atleast_1d(vmec_indata.get("AC", np.array([0.0]))).astype(float)
1138-
ls = np.arange(0, AC.size) * 2
1138+
ls = (
1139+
np.arange(0, AC.size) * 2
1140+
if ctype.lower == "power_series"
1141+
else np.arange(1, AC.size + 1) * 2
1142+
)
11391143
inputs["current"] = np.vstack([ls, AC]).T
11401144

11411145
# axis
@@ -1511,16 +1515,17 @@ def parse_vmec_inputs(vmec_fname, threshold=0): # noqa: C901
15111515
# scale pressure profile
15121516
inputs["pressure"][:, 1] *= pres_scale
15131517
if not iota_flag:
1514-
# integrate current profile wrt s=rho^2
1515-
inputs["current"] = np.pad(
1516-
np.vstack(
1517-
(
1518-
inputs["current"][:, 0] + 2,
1519-
inputs["current"][:, 1] * 2 / (inputs["current"][:, 0] + 2),
1520-
)
1521-
).T,
1522-
((1, 0), (0, 0)),
1523-
)
1518+
if ctype == "power_series":
1519+
# integrate current derivative profile wrt s=rho^2
1520+
inputs["current"] = np.pad(
1521+
np.vstack(
1522+
(
1523+
inputs["current"][:, 0] + 2,
1524+
inputs["current"][:, 1] * 2 / (inputs["current"][:, 0] + 2),
1525+
)
1526+
).T,
1527+
((1, 0), (0, 0)),
1528+
)
15241529
# scale current profile
15251530
if curr_tor is not None:
15261531
inputs["current"][:, 1] *= curr_tor / (

tests/test_vmec.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,3 +1697,30 @@ def test_write_vmec_input(TmpDir):
16971697
np.testing.assert_allclose(W0, W1)
16981698
np.testing.assert_allclose(rho_err, 0, atol=1e-4)
16991699
np.testing.assert_allclose(theta_err, 0, atol=1e-4)
1700+
1701+
1702+
@pytest.mark.unit
1703+
def test_write_vmec_input_current_power_series(TmpDir):
1704+
"""Test generated VMEC input file gives the original equilibrium profiles."""
1705+
# write VMEC input file
1706+
fname = str(TmpDir.join("input.SOLOVEV_current"))
1707+
eq0 = get("SOLOVEV")
1708+
current_profile = eq0.get_profile("current", kind="power_series")
1709+
current_profile.params[0] = 0.0 # zero out the axis current
1710+
with pytest.warns(UserWarning, match="Setting toroidal"):
1711+
eq0.current = current_profile
1712+
VMECIO.write_vmec_input(eq0, fname)
1713+
eq1 = Equilibrium.from_input_file(fname, spectral_indexing="fringe")
1714+
# to match the original eq's L, which is not default
1715+
eq1.change_resolution(L=2 * eq1.M, L_grid=2 * eq1.M_grid)
1716+
1717+
# check that loaded eq matches original equilibrium
1718+
np.testing.assert_allclose(eq0.L, eq1.L)
1719+
np.testing.assert_allclose(eq0.M, eq1.M)
1720+
np.testing.assert_allclose(eq0.N, eq1.N)
1721+
np.testing.assert_allclose(eq0.NFP, eq1.NFP)
1722+
np.testing.assert_allclose(eq0.Psi, eq1.Psi)
1723+
np.testing.assert_allclose(eq0.p_l, eq1.p_l)
1724+
np.testing.assert_allclose(eq0.c_l, eq1.c_l, atol=1e-5)
1725+
np.testing.assert_allclose(eq0.Rb_lmn, eq1.Rb_lmn)
1726+
np.testing.assert_allclose(eq0.Zb_lmn, eq1.Zb_lmn)

0 commit comments

Comments
 (0)