From e237c4d8126512afc5f23429f1e9e6203833cefa Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 6 Oct 2023 11:38:40 -0400 Subject: [PATCH 001/131] initial commit --- src/simsopt/_core/derivative.py | 28 ++++++++++++++++++---------- tests/geo/test_surface_objectives.py | 12 ++++++++---- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/simsopt/_core/derivative.py b/src/simsopt/_core/derivative.py index c3acfce6e..394677f92 100644 --- a/src/simsopt/_core/derivative.py +++ b/src/simsopt/_core/derivative.py @@ -176,20 +176,28 @@ def __call__(self, optim, as_derivative=False): """ from .optimizable import Optimizable # Import here to avoid circular import assert isinstance(optim, Optimizable) - derivs = [] - keys = [] - for k in optim.unique_dof_lineage: - if np.any(k.dofs_free_status): - local_derivs = np.zeros(k.local_dof_size) + + if not as_derivative: + derivs = [] + keys = [] + for k in optim.unique_dof_lineage: + if np.any(k.dofs_free_status): + local_derivs = np.zeros(k.local_dof_size) + for opt in k.dofs.dep_opts(): + local_derivs += self.data[opt][opt.local_dofs_free_status] + keys.append(opt) + derivs.append(local_derivs) + return np.concatenate(derivs) + else: + derivs = [] + keys = [] + for k in optim.unique_dof_lineage: + local_derivs = np.zeros(k.local_full_dof_size) for opt in k.dofs.dep_opts(): - local_derivs += self.data[opt][opt.local_dofs_free_status] + local_derivs += self.data[opt] keys.append(opt) derivs.append(local_derivs) - - if as_derivative: return Derivative({k: d for k, d in zip(keys, derivs)}) - else: - return np.concatenate(derivs) # https://stackoverflow.com/questions/11624955/avoiding-python-sum-default-start-arg-behavior def __radd__(self, other): diff --git a/tests/geo/test_surface_objectives.py b/tests/geo/test_surface_objectives.py index 0f7d82db6..990952638 100644 --- a/tests/geo/test_surface_objectives.py +++ b/tests/geo/test_surface_objectives.py @@ -318,14 +318,18 @@ def test_nonQSratio_derivative(self): """ for label in ["Volume", "ToroidalFlux"]: for axis in [False, True]: - with self.subTest(label=label, axis=axis): - self.subtest_nonQSratio_derivative(label, axis) + for fix_coil_dof in [True, False]: + with self.subTest(label=label, axis=axis, fix_coil_dof=fix_coil_dof): + self.subtest_nonQSratio_derivative(label, axis, fix_coil_dof) - def subtest_nonQSratio_derivative(self, label, axis): + def subtest_nonQSratio_derivative(self, label, axis, fix_coil_dof): bs, boozer_surface = get_boozer_surface(label=label) - coeffs = bs.x io = NonQuasiSymmetricRatio(boozer_surface, bs, quasi_poloidal=axis) + + if fix_coil_dof: + bs.coils[0].curve.fix('xc(0)') + coeffs = bs.x def f(dofs): bs.x = dofs return io.J() From eabe058e102fab5ce4a4ce5dbee6eaeebb21b6b4 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 6 Oct 2023 11:42:15 -0400 Subject: [PATCH 002/131] linting fix --- tests/geo/test_surface_objectives.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/geo/test_surface_objectives.py b/tests/geo/test_surface_objectives.py index 990952638..36d787df9 100644 --- a/tests/geo/test_surface_objectives.py +++ b/tests/geo/test_surface_objectives.py @@ -330,6 +330,7 @@ def subtest_nonQSratio_derivative(self, label, axis, fix_coil_dof): bs.coils[0].curve.fix('xc(0)') coeffs = bs.x + def f(dofs): bs.x = dofs return io.J() From f723178ac58e6b34dc5384b73eeeebd8a995a2a6 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 6 Oct 2023 12:49:11 -0400 Subject: [PATCH 003/131] rearrange --- src/simsopt/_core/derivative.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/simsopt/_core/derivative.py b/src/simsopt/_core/derivative.py index 394677f92..d983c2e17 100644 --- a/src/simsopt/_core/derivative.py +++ b/src/simsopt/_core/derivative.py @@ -177,27 +177,28 @@ def __call__(self, optim, as_derivative=False): from .optimizable import Optimizable # Import here to avoid circular import assert isinstance(optim, Optimizable) - if not as_derivative: + if as_derivative: + derivs = [] + keys = [] + for k in optim.unique_dof_lineage: + local_derivs = np.zeros(k.local_full_dof_size) + for opt in k.dofs.dep_opts(): + local_derivs += self.data[opt] #return the full derivative here, including the derivatives of fixed dofs + keys.append(opt) + derivs.append(local_derivs) + return Derivative({k: d for k, d in zip(keys, derivs)}) + else: derivs = [] keys = [] for k in optim.unique_dof_lineage: if np.any(k.dofs_free_status): local_derivs = np.zeros(k.local_dof_size) for opt in k.dofs.dep_opts(): - local_derivs += self.data[opt][opt.local_dofs_free_status] + local_derivs += self.data[opt][opt.local_dofs_free_status] # filter out the derivatives of fixed dofs keys.append(opt) derivs.append(local_derivs) return np.concatenate(derivs) - else: - derivs = [] - keys = [] - for k in optim.unique_dof_lineage: - local_derivs = np.zeros(k.local_full_dof_size) - for opt in k.dofs.dep_opts(): - local_derivs += self.data[opt] - keys.append(opt) - derivs.append(local_derivs) - return Derivative({k: d for k, d in zip(keys, derivs)}) + # https://stackoverflow.com/questions/11624955/avoiding-python-sum-default-start-arg-behavior def __radd__(self, other): From c8b4ccb4b90b35444cc65f67ad744bc6a3e066eb Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 6 Oct 2023 14:25:29 -0400 Subject: [PATCH 004/131] linting fix --- src/simsopt/_core/derivative.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/simsopt/_core/derivative.py b/src/simsopt/_core/derivative.py index d983c2e17..33abe3576 100644 --- a/src/simsopt/_core/derivative.py +++ b/src/simsopt/_core/derivative.py @@ -183,7 +183,7 @@ def __call__(self, optim, as_derivative=False): for k in optim.unique_dof_lineage: local_derivs = np.zeros(k.local_full_dof_size) for opt in k.dofs.dep_opts(): - local_derivs += self.data[opt] #return the full derivative here, including the derivatives of fixed dofs + local_derivs += self.data[opt] # return the full derivative here, including the derivatives of fixed dofs keys.append(opt) derivs.append(local_derivs) return Derivative({k: d for k, d in zip(keys, derivs)}) @@ -194,12 +194,11 @@ def __call__(self, optim, as_derivative=False): if np.any(k.dofs_free_status): local_derivs = np.zeros(k.local_dof_size) for opt in k.dofs.dep_opts(): - local_derivs += self.data[opt][opt.local_dofs_free_status] # filter out the derivatives of fixed dofs + local_derivs += self.data[opt][opt.local_dofs_free_status] # filter out the derivatives of fixed dofs keys.append(opt) derivs.append(local_derivs) return np.concatenate(derivs) - # https://stackoverflow.com/questions/11624955/avoiding-python-sum-default-start-arg-behavior def __radd__(self, other): # This allows sum() to work (the default start value is zero) From 2bf764fd141af7d980236c650125f00eef9dadff Mon Sep 17 00:00:00 2001 From: Joaquim Loizu Date: Mon, 6 Nov 2023 18:53:45 +0100 Subject: [PATCH 005/131] Updated CircularCoil class to alllow for dofs --- src/simsopt/field/magneticfieldclasses.py | 96 +++++++++++++++-------- 1 file changed, 65 insertions(+), 31 deletions(-) diff --git a/src/simsopt/field/magneticfieldclasses.py b/src/simsopt/field/magneticfieldclasses.py index 101fe80e7..c2ca30255 100644 --- a/src/simsopt/field/magneticfieldclasses.py +++ b/src/simsopt/field/magneticfieldclasses.py @@ -46,6 +46,7 @@ def _B_impl(self, B): def _dB_by_dX_impl(self, dB): points = self.get_points_cart_ref() + phi = np.arctan2(points[:, 1], points[:, 0]) R = np.sqrt(np.square(points[:, 0]) + np.square(points[:, 1])) x = points[:, 0] @@ -65,6 +66,8 @@ def _dB_by_dX_impl(self, dB): def _d2B_by_dXdX_impl(self, ddB): points = self.get_points_cart_ref() + x = points[:, 0] + y = points[:, 1] ddB[:] = 2*self.B0*self.R0*np.multiply( 1/(points[:, 0]**2+points[:, 1]**2)**3, np.array([ [[3*points[:, 0]**2+points[:, 1]**3, points[:, 0]**3-3*points[:, 0]*points[:, 1]**2, np.zeros((len(points)))], [ @@ -359,14 +362,44 @@ def __init__(self, r0=0.1, center=[0, 0, 0], I=5e5/np.pi, normal=[0, 0]): self.Inorm = I*4e-7 self.center = center self.normal = normal - if len(normal) == 2: - theta = normal[0] - phi = normal[1] - else: - theta = np.arctan2(normal[1], normal[0]) - phi = np.arctan2(np.sqrt(normal[0]**2+normal[1]**2), normal[2]) - self.rotMatrix = np.array([ + super().__init__(x0=self.get_dofs(), names=self._make_names(),external_dof_setter=CircularCoil.set_dofs_impl) + + def _make_names(self): + if len(self.normal)==2: + normal_names = ['theta', 'phi'] + elif len(self.normal)==3: + normal_names = ['x', 'y', 'z'] + return ['r0', 'x0', 'y0', 'z0', 'Inorm'] + normal_names + + def num_dofs(self): + return 5+len(self.normal) + + def get_dofs(self): + return np.concatenate([np.array([self.r0]), np.array(self.center), np.array([self.Inorm]), np.array(self.normal)]) + + def set_dofs_impl(self, dofs): + self.r0 = dofs[0] + self.center = dofs[1:4] + self.Inorm = dofs[4] + self.normal = dofs[5:] + + @property + def I(self): + return self.Inorm * 25e5 + + def _rotmat(self): + if len(self.normal) == 2: + theta = self.get('theta') + phi = self.get('phi') + else: + xn = self.get('x') + yn = self.get('y') + zn = self.get('z') + theta = np.arctan2(yn, xn) + phi = np.arctan2(np.sqrt(xn**2+yn**2), zn) + + m = np.array([ [np.cos(phi) * np.cos(theta)**2 + np.sin(theta)**2, -np.sin(phi / 2)**2 * np.sin(2 * theta), np.cos(theta) * np.sin(phi)], @@ -377,16 +410,16 @@ def __init__(self, r0=0.1, center=[0, 0, 0], I=5e5/np.pi, normal=[0, 0]): -np.sin(phi) * np.sin(theta), np.cos(phi)] ]) + return m - self.rotMatrixInv = np.array(self.rotMatrix.T) - - @property - def I(self): - return self.Inorm * 25e5 + def _rotmatinv(self): + m = self._rotmat() + minv = np.array(m.T) + return minv def _B_impl(self, B): points = self.get_points_cart_ref() - points = np.array(np.dot(self.rotMatrixInv, np.array(np.subtract(points, self.center)).T).T) + points = np.array(np.dot(self._rotmatinv(), np.array(np.subtract(points, self.center)).T).T) rho = np.sqrt(np.square(points[:, 0]) + np.square(points[:, 1])) r = np.sqrt(np.square(points[:, 0]) + np.square(points[:, 1]) + np.square(points[:, 2])) alpha = np.sqrt(self.r0**2 + np.square(r) - 2*self.r0*rho) @@ -394,14 +427,15 @@ def _B_impl(self, B): k = np.sqrt(1-np.divide(np.square(alpha), np.square(beta))) ellipek2 = ellipe(k**2) ellipkk2 = ellipk(k**2) - B[:] = np.dot(self.rotMatrix, np.array( + gamma = np.square(points[:, 0]) - np.square(points[:, 1]) + B[:] = np.dot(self._rotmat(), np.array( [self.Inorm*points[:, 0]*points[:, 2]/(2*alpha**2*beta*rho**2+1e-31)*((self.r0**2+r**2)*ellipek2-alpha**2*ellipkk2), self.Inorm*points[:, 1]*points[:, 2]/(2*alpha**2*beta*rho**2+1e-31)*((self.r0**2+r**2)*ellipek2-alpha**2*ellipkk2), self.Inorm/(2*alpha**2*beta+1e-31)*((self.r0**2-r**2)*ellipek2+alpha**2*ellipkk2)])).T def _dB_by_dX_impl(self, dB): points = self.get_points_cart_ref() - points = np.array(np.dot(self.rotMatrixInv, np.array(np.subtract(points, self.center)).T).T) + points = np.array(np.dot(self._rotmatinv(), np.array(np.subtract(points, self.center)).T).T) rho = np.sqrt(np.square(points[:, 0]) + np.square(points[:, 1])) r = np.sqrt(np.square(points[:, 0]) + np.square(points[:, 1]) + np.square(points[:, 2])) alpha = np.sqrt(self.r0**2 + np.square(r) - 2*self.r0*rho) @@ -459,19 +493,19 @@ def _dB_by_dX_impl(self, dB): [dBxdz, dBydz, dBzdz]]) dB[:] = np.array([ - [np.dot(self.rotMatrixInv[:, 0], np.dot(self.rotMatrix[0, :], dB_by_dXm)), - np.dot(self.rotMatrixInv[:, 1], np.dot(self.rotMatrix[0, :], dB_by_dXm)), - np.dot(self.rotMatrixInv[:, 2], np.dot(self.rotMatrix[0, :], dB_by_dXm))], - [np.dot(self.rotMatrixInv[:, 0], np.dot(self.rotMatrix[1, :], dB_by_dXm)), - np.dot(self.rotMatrixInv[:, 1], np.dot(self.rotMatrix[1, :], dB_by_dXm)), - np.dot(self.rotMatrixInv[:, 2], np.dot(self.rotMatrix[1, :], dB_by_dXm))], - [np.dot(self.rotMatrixInv[:, 0], np.dot(self.rotMatrix[2, :], dB_by_dXm)), - np.dot(self.rotMatrixInv[:, 1], np.dot(self.rotMatrix[2, :], dB_by_dXm)), - np.dot(self.rotMatrixInv[:, 2], np.dot(self.rotMatrix[2, :], dB_by_dXm))]]).T + [np.dot(self._rotmatinv()[:, 0], np.dot(self._rotmat()[0, :], dB_by_dXm)), + np.dot(self._rotmatinv()[:, 1], np.dot(self._rotmat()[0, :], dB_by_dXm)), + np.dot(self._rotmatinv()[:, 2], np.dot(self._rotmat()[0, :], dB_by_dXm))], + [np.dot(self._rotmatinv()[:, 0], np.dot(self._rotmat()[1, :], dB_by_dXm)), + np.dot(self._rotmatinv()[:, 1], np.dot(self._rotmat()[1, :], dB_by_dXm)), + np.dot(self._rotmatinv()[:, 2], np.dot(self._rotmat()[1, :], dB_by_dXm))], + [np.dot(self._rotmatinv()[:, 0], np.dot(self._rotmat()[2, :], dB_by_dXm)), + np.dot(self._rotmatinv()[:, 1], np.dot(self._rotmat()[2, :], dB_by_dXm)), + np.dot(self._rotmatinv()[:, 2], np.dot(self._rotmat()[2, :], dB_by_dXm))]]).T def _A_impl(self, A): points = self.get_points_cart_ref() - points = np.array(np.dot(self.rotMatrixInv, np.array(np.subtract(points, self.center)).T).T) + points = np.array(np.dot(self._rotmatinv(), np.array(np.subtract(points, self.center)).T).T) rho = np.sqrt(np.square(points[:, 0]) + np.square(points[:, 1])) r = np.sqrt(np.square(points[:, 0]) + np.square(points[:, 1]) + np.square(points[:, 2])) alpha = np.sqrt(self.r0**2 + np.square(r) - 2*self.r0*rho) @@ -484,7 +518,7 @@ def _A_impl(self, A): denom = ((points[:, 0]**2+points[:, 1]**2+1e-31)*np.sqrt(self.r0**2+points[:, 0]**2+points[:, 1]**2+2*self.r0*np.sqrt(points[:, 0]**2+points[:, 1]**2)+points[:, 2]**2+1e-31)) fak = num/denom pts = fak[:, None]*np.concatenate((-points[:, 1][:, None], points[:, 0][:, None], np.zeros((points.shape[0], 1))), axis=-1) - A[:] = -self.Inorm/2*np.dot(self.rotMatrix, pts.T).T + A[:] = -self.Inorm/2*np.dot(self._rotmat(), pts.T).T def as_dict(self, serial_objs_dict): d = super().as_dict(serial_objs_dict=serial_objs_dict) @@ -662,6 +696,7 @@ def _toVTK(self, vtkname): mx = np.ascontiguousarray(self.m_vec[:, 0]) my = np.ascontiguousarray(self.m_vec[:, 1]) mz = np.ascontiguousarray(self.m_vec[:, 2]) + mmag = np.sqrt(mx ** 2 + my ** 2 + mz ** 2) mx_normalized = np.ascontiguousarray(mx / self.m_maxima) my_normalized = np.ascontiguousarray(my / self.m_maxima) mz_normalized = np.ascontiguousarray(mz / self.m_maxima) @@ -675,12 +710,11 @@ def _toVTK(self, vtkname): mtheta_normalized = np.ascontiguousarray(mtheta / self.m_maxima) # Save all the data to a vtk file which can be visualized nicely with ParaView - data = {"m": (mx, my, mz), "m_normalized": (mx_normalized, my_normalized, mz_normalized), - "m_rphiz": (mr, mphi, mz), "m_rphiz_normalized": (mr_normalized, mphi_normalized, mz_normalized), - "m_rphitheta": (mrminor, mphi, mtheta), - "m_rphitheta_normalized": (mrminor_normalized, mphi_normalized, mtheta_normalized)} + data = {"m": (mx, my, mz), "m_normalized": (mx_normalized, my_normalized, mz_normalized), "m_rphiz": (mr, mphi, mz), "m_rphiz_normalized": (mr_normalized, mphi_normalized, mz_normalized), "m_rphitheta": (mrminor, mphi, mtheta), "m_rphitheta_normalized": (mrminor_normalized, mphi_normalized, mtheta_normalized)} from pyevtk.hl import pointsToVTK - pointsToVTK(str(vtkname), ox, oy, oz, data=data) + pointsToVTK( + str(vtkname), ox, oy, oz, data=data + ) class Dommaschk(MagneticField): From bc92b85dd9bd78562a3db761ae3dd910ed666fd3 Mon Sep 17 00:00:00 2001 From: Jason Smoniewski Date: Mon, 13 Nov 2023 17:17:31 +0100 Subject: [PATCH 006/131] Add to_vtk output to CircularCoil --- src/simsopt/field/magneticfieldclasses.py | 38 +++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/simsopt/field/magneticfieldclasses.py b/src/simsopt/field/magneticfieldclasses.py index c2ca30255..d087fb753 100644 --- a/src/simsopt/field/magneticfieldclasses.py +++ b/src/simsopt/field/magneticfieldclasses.py @@ -533,6 +533,44 @@ def from_dict(cls, d, serial_objs_dict, recon_objs): field.set_points_cart(xyz) return field + def gamma(self, points=64): + """Export points of the coil.""" + + angle_points = np.linspace(0, 2*np.pi, points+1)[:-1] + + x = self.r0 * np.cos(angle_points) + y = self.r0 * np.sin(angle_points) + z = 0 * angle_points + + coords = np.add(np.dot(self._rotmat(), np.column_stack([x,y,z]).T).T, self.center) + return coords + + def to_vtk(self, filename, close=False): + """ + Export circular coil to VTK format + + Args: + filename: Name of the file to write. + close: Whether to draw the segment from the last quadrature point back to the first. + """ + from pyevtk.hl import polyLinesToVTK + + def wrap(data): + return np.concatenate([data, [data[0]]]) + + # get the coordinates + if close: + x = wrap(self.gamma()[:, 0]) + y = wrap(self.gamma()[:, 1]) + z = wrap(self.gamma()[:, 2]) + ppl = np.asarray([self.gamma().shape[0]+1]) + else: + x = self.gamma()[:, 0] + y = self.gamma()[:, 1] + z = self.gamma()[:, 2] + ppl = np.asarray([self.gamma().shape[0]]) + + polyLinesToVTK(str(filename), x, y, z, pointsPerLine=ppl) class DipoleField(MagneticField): r""" From 591fb07353cdda38eac2ae7839c35d02401021c8 Mon Sep 17 00:00:00 2001 From: Jason Smoniewski Date: Mon, 13 Nov 2023 17:18:55 +0100 Subject: [PATCH 007/131] Add unit tests to CircularCoil for optimization --- tests/field/test_magneticfields.py | 5 +- .../field/test_magneticfields_optimization.py | 125 ++++++++++++++++++ 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 tests/field/test_magneticfields_optimization.py diff --git a/tests/field/test_magneticfields.py b/tests/field/test_magneticfields.py index e3466c9a5..a85867e6f 100644 --- a/tests/field/test_magneticfields.py +++ b/tests/field/test_magneticfields.py @@ -372,7 +372,10 @@ def test_circularcoil_Bfield(self): field = CircularCoil(r0=radius, center=center, I=current, normal=[np.pi/2, -angle]) field.set_points(points) - np.allclose(field.B(), [[0.01016974, 0.00629875, -0.00220838]]) + assert np.allclose(field.B(), [[0.01016974, 0.00629875, -0.00220838]]) + # test coil location + assert np.allclose(field.gamma(points=4), [[1.3575,1.456,2.789],[0.123,center[1]+radius*np.cos(-angle),center[2]-radius*np.sin(-angle)], + [-1.1115,1.456,2.789],[0.123,center[1]-radius*np.cos(-angle),center[2]+radius*np.sin(-angle)]]) def test_circularcoil_Bfield_toroidal_arrangement(self): # This makes N_coils with centered at major radius R_m diff --git a/tests/field/test_magneticfields_optimization.py b/tests/field/test_magneticfields_optimization.py new file mode 100644 index 000000000..d8471a310 --- /dev/null +++ b/tests/field/test_magneticfields_optimization.py @@ -0,0 +1,125 @@ +import unittest +import numpy as np +from pathlib import Path + +from monty.tempfile import ScratchDir + +from simsopt.field import CircularCoil +from simsopt.objectives import LeastSquaresProblem +from simsopt.solve.serial import least_squares_serial_solve +from simsopt import make_optimizable + +TEST_DIR = (Path(__file__).parent / ".." / "test_files").resolve() + +class Testing(unittest.TestCase): + + def test_circularcoil_optimization(self): + + # test I,r0 optimization + coil = CircularCoil() + x0 = np.random.rand(coil.dof_size) + x0[1] = 0 + x0[2] = 0 + x0[3] = 0 + x0[5] = 0 + x0[6] = 0 + coil.x = x0 + coil.fix([1,2,3,5,6]) + + print('Initial coil radius: ', coil.x[0]) + print('Initial coil current: ', coil.x[1]) + + points = np.array([[0, 0, 0]]) + coil.set_points(points) + + def I(c): + return c.I + def B(c): + return c.B()[0][2] + + I_coil = make_optimizable(I, coil) + B_coil = make_optimizable(B, coil) + + Bmag = 1.2*2*np.pi/1.12345 + prob = LeastSquaresProblem.from_tuples([(I_coil.J, 1.2e7, 2e6),(B_coil.J, Bmag, 1.0)]) + + with ScratchDir("."): + least_squares_serial_solve(prob) + + print(' Final coil radius: ', coil.x[0]) + print(' Final coil current: ', coil.x[1]) + assert np.allclose(coil.x, [1.12345, 4.8]) + + + # test center optimization + coil = CircularCoil() + x0 = np.random.rand(coil.dof_size) + x0[0] = 1.12345 + x0[4] = 4.8 + x0[5] = 0 + x0[6] = 0 + coil.x = x0 + coil.fix([0,4,5,6]) + + print('Initial coil position: ', coil.x) + + points = np.array([[0, 0, 0]]) + coil.set_points(points) + + def Bx(c): + return c.B()[0][0] + def By(c): + return c.B()[0][1] + def Bz(c): + return c.B()[0][2] + + Bx_coil = make_optimizable(Bx, coil) + By_coil = make_optimizable(By, coil) + Bz_coil = make_optimizable(Bz, coil) + + Bmag = 1.2*2*np.pi/1.12345 + prob = LeastSquaresProblem.from_tuples([(Bx_coil.J, 0, 1.0),(By_coil.J, 0, 1.0),(Bz_coil.J, Bmag, 1.0)]) + + with ScratchDir("."): + least_squares_serial_solve(prob, gtol=1e-24) + + print(' Final coil position: ', coil.x) + assert np.allclose(coil.x, [0, 0, 0]) + + + # test normal optimization + coil = CircularCoil() + x0 = np.random.rand(coil.dof_size) + x0[0] = 1.12345 + x0[1] = 0 + x0[2] = 0 + x0[3] = 0 + x0[4] = 4.8 + coil.x = x0 + coil.fix([0,1,2,3,4]) + + print('Initial coil normal: ', coil.x) + + points = np.array([[0, 0, 0]]) + coil.set_points(points) + + def Bx(c): + return c.B()[0][0] + def By(c): + return c.B()[0][1] + def Bz(c): + return c.B()[0][2] + + Bx_coil = make_optimizable(Bx, coil) + By_coil = make_optimizable(By, coil) + Bz_coil = make_optimizable(Bz, coil) + + Bmag = np.sqrt(2)/2*1.2*2*np.pi/1.12345 + prob = LeastSquaresProblem.from_tuples([(Bx_coil.J, Bmag, 1.0),(By_coil.J, 0, 1.0),(Bz_coil.J, Bmag, 1.0)]) + + with ScratchDir("."): + least_squares_serial_solve(prob) + + print(' Final coil normal: ', coil.x) + assert np.allclose(coil.x, [0, np.pi/4]) + From c21413f4d3a36d2b59fb7bf8ed4efa89dc743bb6 Mon Sep 17 00:00:00 2001 From: Jason Smoniewski Date: Tue, 14 Nov 2023 12:27:28 +0100 Subject: [PATCH 008/131] Split CircularCoil optimization tests --- tests/field/test_magneticfields_optimization.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/field/test_magneticfields_optimization.py b/tests/field/test_magneticfields_optimization.py index d8471a310..1449d7bf0 100644 --- a/tests/field/test_magneticfields_optimization.py +++ b/tests/field/test_magneticfields_optimization.py @@ -13,7 +13,7 @@ class Testing(unittest.TestCase): - def test_circularcoil_optimization(self): + def test_circularcoil_current_optimization(self): # test I,r0 optimization coil = CircularCoil() @@ -50,6 +50,7 @@ def B(c): print(' Final coil current: ', coil.x[1]) assert np.allclose(coil.x, [1.12345, 4.8]) + def test_circularcoil_position_optimization(self): # test center optimization coil = CircularCoil() @@ -86,6 +87,7 @@ def Bz(c): print(' Final coil position: ', coil.x) assert np.allclose(coil.x, [0, 0, 0]) + def test_circularcoil_orientation_optimization(self): # test normal optimization coil = CircularCoil() From 35819d7c8615e2b0cf413db3c7293f0023fe51a9 Mon Sep 17 00:00:00 2001 From: Jason Smoniewski Date: Wed, 15 Nov 2023 09:22:04 +0100 Subject: [PATCH 009/131] Fix CircularCoil tests failing tolerance --- .../field/test_magneticfields_optimization.py | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/tests/field/test_magneticfields_optimization.py b/tests/field/test_magneticfields_optimization.py index 1449d7bf0..54ce966f3 100644 --- a/tests/field/test_magneticfields_optimization.py +++ b/tests/field/test_magneticfields_optimization.py @@ -48,7 +48,7 @@ def B(c): print(' Final coil radius: ', coil.x[0]) print(' Final coil current: ', coil.x[1]) - assert np.allclose(coil.x, [1.12345, 4.8]) + assert np.allclose(coil.x, [1.12345, 4.8], atol=1e-6) def test_circularcoil_position_optimization(self): @@ -64,9 +64,6 @@ def test_circularcoil_position_optimization(self): print('Initial coil position: ', coil.x) - points = np.array([[0, 0, 0]]) - coil.set_points(points) - def Bx(c): return c.B()[0][0] def By(c): @@ -81,11 +78,42 @@ def Bz(c): Bmag = 1.2*2*np.pi/1.12345 prob = LeastSquaresProblem.from_tuples([(Bx_coil.J, 0, 1.0),(By_coil.J, 0, 1.0),(Bz_coil.J, Bmag, 1.0)]) + # Optimize z + coil.fix('x0') + coil.fix('y0') + points = np.array([[coil.get('x0'), coil.get('y0'), 1]]) + coil.set_points(points) + + with ScratchDir("."): + least_squares_serial_solve(prob, ftol=1e-15, xtol=1e-15, gtol=1e-15) + + print('Next coil position: ', coil.full_x[1:4]) + + # Optimize y + coil.fix('z0') + coil.unfix('y0') + points[0][1] = 1 + coil.set_points(points) + + with ScratchDir("."): + least_squares_serial_solve(prob, ftol=1e-15, xtol=1e-15, gtol=1e-15) + + print('Next coil position: ', coil.full_x[1:4]) + + # Optimize x + coil.fix('y0') + coil.unfix('x0') + points[0][0] = 1 + coil.set_points(points) + with ScratchDir("."): - least_squares_serial_solve(prob, gtol=1e-24) + least_squares_serial_solve(prob, ftol=1e-15, xtol=1e-15, gtol=1e-15) + + coil.unfix('y0') + coil.unfix('z0') print(' Final coil position: ', coil.x) - assert np.allclose(coil.x, [0, 0, 0]) + assert np.allclose(coil.x, np.ones(3), atol=1e-6) def test_circularcoil_orientation_optimization(self): @@ -123,5 +151,5 @@ def Bz(c): least_squares_serial_solve(prob) print(' Final coil normal: ', coil.x) - assert np.allclose(coil.x, [0, np.pi/4]) + assert np.allclose(coil.x, [0, np.pi/4], atol=1e-6) From 0cd05576d2c9a7b2a33fe44f54b90badfff73a7e Mon Sep 17 00:00:00 2001 From: Jason Smoniewski Date: Wed, 15 Nov 2023 09:36:18 +0100 Subject: [PATCH 010/131] Remove unnecessary CircularCoil optimization steps --- .../field/test_magneticfields_optimization.py | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/tests/field/test_magneticfields_optimization.py b/tests/field/test_magneticfields_optimization.py index 54ce966f3..2f9b7dac4 100644 --- a/tests/field/test_magneticfields_optimization.py +++ b/tests/field/test_magneticfields_optimization.py @@ -78,32 +78,7 @@ def Bz(c): Bmag = 1.2*2*np.pi/1.12345 prob = LeastSquaresProblem.from_tuples([(Bx_coil.J, 0, 1.0),(By_coil.J, 0, 1.0),(Bz_coil.J, Bmag, 1.0)]) - # Optimize z - coil.fix('x0') - coil.fix('y0') - points = np.array([[coil.get('x0'), coil.get('y0'), 1]]) - coil.set_points(points) - - with ScratchDir("."): - least_squares_serial_solve(prob, ftol=1e-15, xtol=1e-15, gtol=1e-15) - - print('Next coil position: ', coil.full_x[1:4]) - - # Optimize y - coil.fix('z0') - coil.unfix('y0') - points[0][1] = 1 - coil.set_points(points) - - with ScratchDir("."): - least_squares_serial_solve(prob, ftol=1e-15, xtol=1e-15, gtol=1e-15) - - print('Next coil position: ', coil.full_x[1:4]) - - # Optimize x - coil.fix('y0') - coil.unfix('x0') - points[0][0] = 1 + points = np.array([[1, 1, 1]]) coil.set_points(points) with ScratchDir("."): From da226f95aaad51aec0756abae6a56f675ff063bb Mon Sep 17 00:00:00 2001 From: smoniewski Date: Tue, 6 Feb 2024 10:24:12 +0100 Subject: [PATCH 011/131] Avoid unnecessary changes in magneticfieldclasses.py --- src/simsopt/field/magneticfieldclasses.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/simsopt/field/magneticfieldclasses.py b/src/simsopt/field/magneticfieldclasses.py index d087fb753..5c428fd4d 100644 --- a/src/simsopt/field/magneticfieldclasses.py +++ b/src/simsopt/field/magneticfieldclasses.py @@ -46,7 +46,6 @@ def _B_impl(self, B): def _dB_by_dX_impl(self, dB): points = self.get_points_cart_ref() - phi = np.arctan2(points[:, 1], points[:, 0]) R = np.sqrt(np.square(points[:, 0]) + np.square(points[:, 1])) x = points[:, 0] @@ -66,8 +65,6 @@ def _dB_by_dX_impl(self, dB): def _d2B_by_dXdX_impl(self, ddB): points = self.get_points_cart_ref() - x = points[:, 0] - y = points[:, 1] ddB[:] = 2*self.B0*self.R0*np.multiply( 1/(points[:, 0]**2+points[:, 1]**2)**3, np.array([ [[3*points[:, 0]**2+points[:, 1]**3, points[:, 0]**3-3*points[:, 0]*points[:, 1]**2, np.zeros((len(points)))], [ @@ -427,7 +424,6 @@ def _B_impl(self, B): k = np.sqrt(1-np.divide(np.square(alpha), np.square(beta))) ellipek2 = ellipe(k**2) ellipkk2 = ellipk(k**2) - gamma = np.square(points[:, 0]) - np.square(points[:, 1]) B[:] = np.dot(self._rotmat(), np.array( [self.Inorm*points[:, 0]*points[:, 2]/(2*alpha**2*beta*rho**2+1e-31)*((self.r0**2+r**2)*ellipek2-alpha**2*ellipkk2), self.Inorm*points[:, 1]*points[:, 2]/(2*alpha**2*beta*rho**2+1e-31)*((self.r0**2+r**2)*ellipek2-alpha**2*ellipkk2), @@ -734,7 +730,6 @@ def _toVTK(self, vtkname): mx = np.ascontiguousarray(self.m_vec[:, 0]) my = np.ascontiguousarray(self.m_vec[:, 1]) mz = np.ascontiguousarray(self.m_vec[:, 2]) - mmag = np.sqrt(mx ** 2 + my ** 2 + mz ** 2) mx_normalized = np.ascontiguousarray(mx / self.m_maxima) my_normalized = np.ascontiguousarray(my / self.m_maxima) mz_normalized = np.ascontiguousarray(mz / self.m_maxima) @@ -750,9 +745,7 @@ def _toVTK(self, vtkname): # Save all the data to a vtk file which can be visualized nicely with ParaView data = {"m": (mx, my, mz), "m_normalized": (mx_normalized, my_normalized, mz_normalized), "m_rphiz": (mr, mphi, mz), "m_rphiz_normalized": (mr_normalized, mphi_normalized, mz_normalized), "m_rphitheta": (mrminor, mphi, mtheta), "m_rphitheta_normalized": (mrminor_normalized, mphi_normalized, mtheta_normalized)} from pyevtk.hl import pointsToVTK - pointsToVTK( - str(vtkname), ox, oy, oz, data=data - ) + pointsToVTK(str(vtkname), ox, oy, oz, data=data) class Dommaschk(MagneticField): From a04ca9211d9cdaf27ba5b8c8d818377b05703de2 Mon Sep 17 00:00:00 2001 From: Joaquim Loizu Date: Tue, 6 Feb 2024 16:20:27 +0100 Subject: [PATCH 012/131] minor conversion of normal and center arrays in set_dofs_impl into lists, this avoid errors when using load/save --- src/simsopt/field/magneticfieldclasses.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/simsopt/field/magneticfieldclasses.py b/src/simsopt/field/magneticfieldclasses.py index 5c428fd4d..915ced98b 100644 --- a/src/simsopt/field/magneticfieldclasses.py +++ b/src/simsopt/field/magneticfieldclasses.py @@ -377,9 +377,9 @@ def get_dofs(self): def set_dofs_impl(self, dofs): self.r0 = dofs[0] - self.center = dofs[1:4] + self.center = dofs[1:4].tolist() self.Inorm = dofs[4] - self.normal = dofs[5:] + self.normal = dofs[5:].tolist() @property def I(self): From 9ea4a81d616766b879736d16cc84e67d8de3b690 Mon Sep 17 00:00:00 2001 From: Chris Smiet Date: Fri, 9 Feb 2024 11:17:38 +0100 Subject: [PATCH 013/131] test_magneticfields_optimization: fix short fn name linting fix --- tests/field/test_magneticfields_optimization.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/field/test_magneticfields_optimization.py b/tests/field/test_magneticfields_optimization.py index 2f9b7dac4..8545549b4 100644 --- a/tests/field/test_magneticfields_optimization.py +++ b/tests/field/test_magneticfields_optimization.py @@ -32,13 +32,13 @@ def test_circularcoil_current_optimization(self): points = np.array([[0, 0, 0]]) coil.set_points(points) - def I(c): + def get_I(c): return c.I - def B(c): + def get_B(c): return c.B()[0][2] - I_coil = make_optimizable(I, coil) - B_coil = make_optimizable(B, coil) + I_coil = make_optimizable(get_I, coil) + B_coil = make_optimizable(get_B, coil) Bmag = 1.2*2*np.pi/1.12345 prob = LeastSquaresProblem.from_tuples([(I_coil.J, 1.2e7, 2e6),(B_coil.J, Bmag, 1.0)]) From ee590e36e59faaa0bad315fff308bef3550deedd Mon Sep 17 00:00:00 2001 From: Bharat Medasani Date: Wed, 3 Apr 2024 16:45:03 -0400 Subject: [PATCH 014/131] Tmp commit to license --- LICENSE | 1 + 1 file changed, 1 insertion(+) diff --git a/LICENSE b/LICENSE index 47140c918..9c839b9b3 100644 --- a/LICENSE +++ b/LICENSE @@ -19,3 +19,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + From 3c6523ca5f0be1468474042497c03c0d24adcd0c Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 5 Apr 2024 12:57:09 -0400 Subject: [PATCH 015/131] cleaning up files --- .../inputs/input_ncsx/surface_0.json | 7022 ----------------- .../inputs/input_ncsx/surface_0.vts | Bin 31872 -> 0 bytes .../inputs/input_ncsx/surface_1.json | 7022 ----------------- .../inputs/input_ncsx/surface_1.vts | Bin 31872 -> 0 bytes .../inputs/input_ncsx/surface_2.json | 7022 ----------------- .../inputs/input_ncsx/surface_2.vts | Bin 31872 -> 0 bytes .../inputs/input_ncsx/surface_3.json | 7022 ----------------- .../inputs/input_ncsx/surface_3.vts | Bin 31872 -> 0 bytes .../inputs/input_ncsx/surface_4.json | 7022 ----------------- .../inputs/input_ncsx/surface_4.vts | Bin 31872 -> 0 bytes .../inputs/input_ncsx/surface_5.json | 7022 ----------------- .../inputs/input_ncsx/surface_5.vts | Bin 31872 -> 0 bytes .../inputs/input_ncsx/surface_6.json | 7022 ----------------- .../inputs/input_ncsx/surface_6.vts | Bin 31872 -> 0 bytes .../inputs/input_ncsx/surface_7.json | 7022 ----------------- .../inputs/input_ncsx/surface_7.vts | Bin 31872 -> 0 bytes .../inputs/input_ncsx/surface_8.json | 7022 ----------------- .../inputs/input_ncsx/surface_8.vts | Bin 31872 -> 0 bytes .../inputs/input_ncsx/surface_9.json | 7022 ----------------- .../inputs/input_ncsx/surface_9.vts | Bin 31872 -> 0 bytes 20 files changed, 70220 deletions(-) delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_0.json delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_0.vts delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_1.json delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_1.vts delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_2.json delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_2.vts delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_3.json delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_3.vts delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_4.json delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_4.vts delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_5.json delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_5.vts delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_6.json delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_6.vts delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_7.json delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_7.vts delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_8.json delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_8.vts delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_9.json delete mode 100644 examples/2_Intermediate/inputs/input_ncsx/surface_9.vts diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_0.json b/examples/2_Intermediate/inputs/input_ncsx/surface_0.json deleted file mode 100644 index 15dffe388..000000000 --- a/examples/2_Intermediate/inputs/input_ncsx/surface_0.json +++ /dev/null @@ -1,7022 +0,0 @@ -{ - "@module": "simsopt._core.json", - "@class": "SIMSON", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "graph": [ - { - "$type": "ref", - "value": "BoozerSurface1" - }, - { - "iota": -0.40631610013137615, - "G": 13.88747927294629 - } - ], - "simsopt_objs": { - "140342738246336": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738246336", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.506387961733893, - 0.1058930714809362, - 0.7258942274042265, - -0.001249592121112775, - 0.2763105569564668, - 0.01482550301512887, - -0.1280092780227772, - 0.005921392096802394, - 0.01864241438718947, - -0.01034831723350223, - 0.0001022108294955593, - 0.01892666378143068, - -0.007192153616853929, - -0.007355339046239706, - -0.01884714563379878, - -0.002596706082945131, - 0.01131859363705868, - 0.00964754529816095, - -0.0113260687651076, - -0.006628855789771619, - 0.000322284209286623, - 0.001842953924532827, - -0.0004161340928027646, - 0.00176264188836799, - 0.001814459617914206, - -0.001883356200860781, - -0.003584967425237995, - 0.0003165409191237933, - 0.00198839685289703, - 0.0007998064690618334, - 0.0005809753916376526, - 4.996792424044994e-05, - -0.0009656219012175038, - -0.001300735471703214, - -0.0004500391754653399, - 0.002413016477450284, - 0.00190334965179141, - -0.001622873850792805, - -0.001817132111793323, - 0.0005008124937015768, - 0.0009410326413637304, - 0.0005073038161052906, - -0.0001747050570155717, - -0.0004010070348672179, - 0.0002171330554898199, - 0.0001868680753017027, - -0.00049371483741256, - -1.263882515020243e-05, - 0.0005663593123846766, - 0.0001291744509577553, - -0.0002415255915965764, - 0.2855239540187146, - 0.02831674064739627, - 0.1230646086878452, - -0.1881027707999307, - -0.03092022550185042, - 0.07598032813641656, - 0.032842960392996, - -0.02022733960800226, - 0.03368541189764687, - -0.02527069889002642, - 0.03990545352197854, - 0.03266977475756579, - 0.007041509561223136, - -0.01843202758194484, - -0.003255107459418295, - 0.001087406605704745, - 0.02057587403483786, - 0.004332699549632209, - -0.003239348172858322, - -0.008060517809116506, - 0.0008303250764389791, - 0.002593682135814645, - 0.005122620691996364, - 0.002329497971206275, - -0.007021762243403233, - -0.002076255998522319, - 0.005455573755227739, - 0.0004034355313731426, - -0.002121189074115063, - -0.001155709211846629, - 0.0007060503790857225, - 0.001458108819397405, - 0.0007612900914783658, - -0.001579374591052191, - -0.0005648184298353118, - -3.483600030825498e-05, - 0.0006434230018098444, - 0.0002266872576160417, - -0.0005870263149471541, - -0.0004782734366555642, - 0.0004131000234993432, - -0.0002086017812282408, - -0.0002217317708794842, - 0.0004459870616389726, - 0.0002232186481886098, - -0.000550989811641543, - -0.0004679750418668452, - 0.0001971289820931924, - 0.0006305703105299488, - 1.94634036466225e-05, - -0.0005071137243856577, - 0.0009455853398023695, - -1.066704925256128, - 0.01954765252843791, - -0.03091192279856904, - -0.009251669123731003, - 0.03622032973711591, - 0.01289395028459556, - -0.01341289215090563, - -0.01055557464591715, - -0.007044726977866961, - -0.007171173731457627, - 0.01327231838496817, - 0.003220259676106272, - -0.006043809337864334, - -0.006228107449831786, - -0.0004722020937025503, - -0.0007632924616726337, - 0.0002557840887866895, - -0.0008300983337148277, - 0.001290373849098229, - 0.0002249498117545818, - -0.0003276137574950353, - -0.001560853624251917, - -0.003125967131907846, - 0.0007111137798287738, - 0.001688245514976161, - 0.00083638883723687, - -3.216802700299113e-05, - -0.003601309499252412, - -0.003364173533240832, - 0.003283863928203238, - 0.003620244544063828, - -0.001109032285114347, - -0.002277398193829699, - -0.0015519788484098, - 0.0002155015553257128, - 0.002349143532954114, - 0.000703914196138795, - -0.001628934087145739, - -0.0005728748367786014, - 0.000379102967651227, - 3.674770297429017e-05, - 0.0003644795696035227, - 0.0001196573774128766, - -0.0004826910821886253, - 1.895960151025164e-05, - 0.0002282029938596129, - -3.982416558199763e-05, - -0.0001869395233315697, - -0.0002051724761620464, - 0.0001303574263284748 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier1": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738246336" - } - }, - "140342738367104": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367104", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 652271.9419853 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current1": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 652271.9419853, - "dofs": { - "$type": "ref", - "value": "140342738367104" - } - }, - "Coil1": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "140342738247296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738247296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.268960636199869, - 0.2234285580503567, - 0.5468300987692021, - -0.07598922426224614, - 0.2314838962751658, - 0.01035784318060333, - -0.08314304549672957, - -0.04624738986383844, - 0.05377747860630284, - -0.001074456865203822, - -0.02151604922154927, - -0.01446679290684195, - 0.008416712252875694, - -0.009228184118107326, - 0.005277266362275169, - 0.01142201731157229, - 0.01681398796325401, - 0.009993706195866578, - 0.001370286955930781, - -0.008399573830195455, - -0.005099919856215084, - 0.005334309041669094, - -0.001419513324650316, - -0.003333508834690296, - 0.0002887180426140212, - -0.0001690909516323616, - -0.001592036575525169, - -4.507713399549196e-05, - 0.005287560419413426, - 0.001265480827581528, - -0.001229918688675425, - 0.001129035262308468, - -0.002142778995712242, - -0.001748186446934164, - 0.000763477629872682, - 0.0006002693299791978, - -0.0003618301004192371, - 0.000988040168005559, - 0.0007880569343915778, - -0.001135722890360471, - -0.0008706368325040781, - 0.0005507322770281398, - 0.0009555809731928289, - -0.0001476990895937402, - -0.001054028588515068, - -1.482885559572655e-05, - -0.0001592869344899095, - -0.0004579572172035079, - 0.0006274586578504227, - 0.0005393401407410331, - -3.182089243244368e-05, - 0.7629396044020591, - 0.189701305549749, - 0.2946730680990991, - -0.1569360429309221, - -0.08805875862294558, - -0.03077704895086764, - 0.1149783480591024, - 0.1301411562027019, - -0.001461622206151801, - 0.04030157913855995, - 0.0006901390690664732, - -0.02740323125842794, - -0.02323299800745342, - 0.006389595554305861, - 0.003627095782551136, - -0.01015301262258172, - -0.00621023311542419, - -0.003238881121248944, - -0.006852312518149265, - 0.005609446955056436, - 0.004762124576622897, - 0.006665063843140196, - -6.70526269177163e-05, - -0.003587348009623233, - -0.00322170321999071, - -0.004203038352780501, - 0.0006017815497404605, - 0.001489961187320675, - 0.002190828148742953, - -0.001018226063168117, - -0.002311412742654803, - 0.0005349636274747352, - 0.0005836793424641873, - 0.0003330260000362103, - 0.0006191475972028521, - 0.0004562062905476333, - -0.0003998259903290102, - -0.001606870160409875, - -0.0001005634411503442, - 0.0003784623778643909, - 0.0003873441313675419, - 0.0004934685418203405, - 0.0004248568990090018, - -0.0001368925780341768, - -0.0005224641202364183, - 7.402330001924084e-06, - 0.0001942482764948633, - 3.004761739695799e-05, - 0.0001571480542442944, - -1.517325817427362e-05, - -0.0001596571201453762, - -0.004342453367498795, - -0.8322915538683627, - 0.01842619538559772, - -0.1445740110997678, - -0.03919221672360253, - 0.0181885023851906, - 0.007857938792447916, - -0.0008409533080505334, - 0.0679882056193599, - -0.008440199737942872, - -0.05052693032193879, - 0.0111459982531894, - -0.002854468104354866, - -0.01157234174126346, - -0.002254287431014864, - 0.01222589681633306, - 0.007524606302699996, - -0.006381505382857464, - 0.003239076046582923, - 0.00341366498860203, - -0.00384676331619515, - 0.0004019843766106519, - 0.003278371413101953, - -0.001659157168404143, - -0.008498109023400214, - -0.0005869360684358228, - 0.001643969359882166, - -0.001687685453312147, - 0.001913710312578008, - 0.00307704389234268, - -0.001526906838827543, - -0.002096608532065649, - 0.002116359835823416, - 0.0002080593023590777, - -0.001289011271870523, - 0.0003465163727308783, - 0.0003373949660992973, - -0.0005853247790129025, - -0.0007569823284455652, - -3.821511752005806e-05, - 0.0008610335506290439, - 0.0002833895542749826, - -4.205984435378816e-05, - 0.0001112528084110792, - -0.0002379239249443648, - -0.0002104661224579025, - 0.0001263747200842462, - -0.0001533284829536013, - 0.0001522993485716547, - 0.0003185888026784711, - -0.0001603437887349448 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier2": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738247296" - } - }, - "140342738367296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 651868.5693674 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current2": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 651868.5693674, - "dofs": { - "$type": "ref", - "value": "140342738367296" - } - }, - "Coil2": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "140342738366624": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738366624", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.8980851593547453, - 0.1942559921705813, - 0.3889755333770718, - -0.1446923384557668, - 0.2616477438027761, - 0.03731920597998046, - -0.03289705406442186, - 0.02547136484396155, - 0.0532217952204826, - 0.050428478861979, - -0.03624366941253683, - -0.005451626158324006, - -0.01668041626206209, - 0.008182439166261426, - 0.003842296843932926, - 0.01470476196344816, - 0.01901860245900076, - 0.0218942171541043, - -0.00945061997881808, - 0.002564135600286371, - -0.006766476390874592, - -0.001269140258791196, - 0.002139997339095541, - 0.001657675366985779, - 0.0002979912903074711, - 0.006328865782046154, - 0.0004567550240531948, - -0.0008525115686061069, - -0.000977103914377314, - 0.0005522046297053057, - -0.0009600861596635313, - -0.001340814451660981, - -0.001495132545615355, - 0.0006434008787568705, - 0.000495245187218385, - -0.00134743162348104, - 0.0002393656261548005, - 0.0003132890671380592, - 0.0006144326019911972, - -0.0005029044211924421, - -0.000783957033721161, - -0.0004002250154653492, - 0.0002391300413782915, - -0.0003806672575232206, - -0.000145466845504183, - -7.221379723120868e-05, - 0.0006927366534479363, - -0.0001275371930022123, - -0.0001401106599127933, - -0.0002158625680600062, - -7.139828388354475e-05, - 1.129181984052873, - 0.2708936854358476, - 0.468646640557997, - 0.02081652240284051, - -0.1928735276123626, - -0.03518255586981031, - 0.01192001522947444, - -0.06439441858177399, - -0.004172035660790115, - -0.016589458610143, - 0.001628354566592241, - 0.003299047220307412, - 0.02371335634022325, - -0.02489732104888577, - 0.01517053799913132, - -0.007490250276888437, - -0.02121728304870823, - -0.006509759115093021, - 0.002045879344162137, - 0.0002421911767798572, - 0.005286626183968976, - -0.002423351884665077, - 0.003037404376098953, - -0.001045524131070646, - -0.001371894636819662, - 0.0002683048956511064, - 0.0006396825080884871, - 0.0006110891778951719, - -0.001898949452431453, - -0.001413075309279682, - -0.000175565426273192, - 0.00025798969577147, - 0.001643409441239691, - 7.18696208370806e-05, - -0.0001583133254478763, - 0.001580406281910882, - -0.002161287927547965, - -0.0003891297580205399, - 0.0004807171148380796, - -0.0003779554431875909, - -0.000203599914921071, - 0.0002418121495980502, - -0.0001924002563136939, - 0.0004205862222447268, - -0.0003081775538974041, - -1.457104090324735e-05, - -0.0001305465480840895, - -2.931233724533855e-05, - 3.39235991969411e-05, - -8.787891234509293e-05, - -0.0002714497625897205, - 0.01443108431390148, - -0.5884600992390547, - 0.1639153375972931, - -0.02326901782799053, - -0.09503676743509344, - -0.001882227773385535, - -0.1358423641287697, - -0.04946480830906624, - 0.01080325660372903, - -0.004462853204566593, - 0.02204832208587066, - -0.01988057349197482, - 0.006713767349457029, - 0.009816410920710776, - -0.004595941635687146, - 0.01307328931917959, - 0.0183731152740804, - -0.002049019816619709, - -0.009421893063595877, - 0.0003683472428279665, - 0.005559370162880608, - -0.001158799750525409, - 0.002656529580593774, - 0.005458828901239469, - 0.003685058507882478, - 0.005539080181031877, - 0.0003319744004354147, - 0.003297209047830778, - -0.001172958360845208, - -6.403055114502017e-05, - -0.0028127900802783, - -7.412199662635927e-05, - -1.404234804116165e-06, - 0.002212349409834762, - 0.001726905111358576, - 0.0009310945379894919, - -0.0002426222281296402, - 0.0007504861042380895, - -0.001511448440947522, - -0.0002060956498950368, - -0.000206480198377301, - 8.668234567299965e-05, - 0.0001267761162311387, - 1.493158313140079e-05, - 0.0001119337013982711, - 0.0003201242558262467, - 0.00016404919743365, - -0.0002679743018523173, - -0.000169663995881007, - 0.0002693900147788098, - -0.0001731877336642894 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier3": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738366624" - } - }, - "140342738367776": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367776", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 537743.5886473 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current3": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 537743.5886473, - "dofs": { - "$type": "ref", - "value": "140342738367776" - } - }, - "Coil3": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve1": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent1": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil4": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve1" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent1" - } - }, - "RotatedCurve2": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent2": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil5": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve2" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent2" - } - }, - "RotatedCurve3": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent3": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil6": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve3" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent3" - } - }, - "RotatedCurve4": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil7": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve4" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve5": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil8": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve5" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve6": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil9": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve6" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve7": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent4": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil10": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve7" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent4" - } - }, - "RotatedCurve8": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent5": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil11": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve8" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent5" - } - }, - "RotatedCurve9": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent6": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil12": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve9" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent6" - } - }, - "RotatedCurve10": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil13": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve10" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve11": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil14": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve11" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve12": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil15": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve12" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve13": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent7": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil16": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil16", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve13" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent7" - } - }, - "RotatedCurve14": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent8": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil17": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil17", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve14" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent8" - } - }, - "RotatedCurve15": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent9": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil18": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil18", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve15" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent9" - } - }, - "BiotSavart1": { - "@module": "simsopt.field.biotsavart", - "@class": "BiotSavart", - "@name": "BiotSavart1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "coils": [ - { - "$type": "ref", - "value": "Coil1" - }, - { - "$type": "ref", - "value": "Coil2" - }, - { - "$type": "ref", - "value": "Coil3" - }, - { - "$type": "ref", - "value": "Coil4" - }, - { - "$type": "ref", - "value": "Coil5" - }, - { - "$type": "ref", - "value": "Coil6" - }, - { - "$type": "ref", - "value": "Coil7" - }, - { - "$type": "ref", - "value": "Coil8" - }, - { - "$type": "ref", - "value": "Coil9" - }, - { - "$type": "ref", - "value": "Coil10" - }, - { - "$type": "ref", - "value": "Coil11" - }, - { - "$type": "ref", - "value": "Coil12" - }, - { - "$type": "ref", - "value": "Coil13" - }, - { - "$type": "ref", - "value": "Coil14" - }, - { - "$type": "ref", - "value": "Coil15" - }, - { - "$type": "ref", - "value": "Coil16" - }, - { - "$type": "ref", - "value": "Coil17" - }, - { - "$type": "ref", - "value": "Coil18" - } - ], - "points": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - [ - 1.638555384855393, - 0.0, - 0.0 - ], - [ - 1.6320046060004947, - 0.00914340729162326, - -0.08295822399845987 - ], - [ - 1.6140444801159073, - 0.01822262319139582, - -0.15765927660150708 - ], - [ - 1.5894200473821325, - 0.026733828254299038, - -0.2162382227584297 - ], - [ - 1.5648995337320422, - 0.03346213093683796, - -0.25202031670064196 - ], - [ - 1.5474434569028597, - 0.03672677607787672, - -0.26036002538206104 - ], - [ - 1.5418642189065443, - 0.03493458745684996, - -0.23834108850594773 - ], - [ - 1.5481699199303507, - 0.027369071570533754, - -0.18447103473368662 - ], - [ - 1.5595068898491926, - 0.014968227190756826, - -0.10139465991565853 - ], - [ - 1.5651095696310926, - 5.400188259376037e-18, - -3.6754349253959105e-17 - ], - [ - 1.5595068898491926, - -0.014968227190756815, - 0.10139465991565848 - ], - [ - 1.5481699199303505, - -0.027369071570533737, - 0.18447103473368653 - ], - [ - 1.5418642189065443, - -0.03493458745684995, - 0.23834108850594765 - ], - [ - 1.5474434569028597, - -0.03672677607787672, - 0.26036002538206104 - ], - [ - 1.564899533732042, - -0.03346213093683797, - 0.25202031670064207 - ], - [ - 1.5894200473821325, - -0.026733828254299048, - 0.2162382227584298 - ], - [ - 1.6140444801159073, - -0.01822262319139583, - 0.1576592766015072 - ], - [ - 1.6320046060004947, - -0.009143407291623284, - 0.08295822399846005 - ], - [ - 1.6226871137507008, - 0.1820858670625909, - 0.008141613332533196 - ], - [ - 1.621791362735948, - 0.19125489133074713, - -0.07299648567715147 - ], - [ - 1.6095068368043206, - 0.19897938970373724, - -0.14518691756498145 - ], - [ - 1.5900373038024056, - 0.20498120270955858, - -0.2004586868089292 - ], - [ - 1.5695274569180595, - 0.20846280597968295, - -0.23209923550010486 - ], - [ - 1.5541928308848754, - 0.20828802699338184, - -0.2355609231102378 - ], - [ - 1.547893807474122, - 0.20341974804663196, - -0.2081633638272415 - ], - [ - 1.549595171229208, - 0.19354051290652075, - -0.14919040363771274 - ], - [ - 1.5521927554184383, - 0.17958646777178755, - -0.0629810401887963 - ], - [ - 1.5467230098618456, - 0.16352348568011543, - 0.037822034913934904 - ], - [ - 1.5311231405664585, - 0.14794301735173188, - 0.13469446925914352 - ], - [ - 1.5134694072254733, - 0.13593820291077097, - 0.2109951775764715 - ], - [ - 1.5048788500945536, - 0.13013470449763131, - 0.2580242226408799 - ], - [ - 1.5111573666394884, - 0.13124150240660107, - 0.2744610527708378 - ], - [ - 1.531149448424876, - 0.13800281601569822, - 0.26214204947249126 - ], - [ - 1.5592619594704633, - 0.1482930577543002, - 0.22395176247426204 - ], - [ - 1.5881317198649367, - 0.16000284649339425, - 0.1644214818207289 - ], - [ - 1.6108627174667585, - 0.17155678023089035, - 0.08996975094317773 - ], - [ - 1.5762847575421937, - 0.35759128262067086, - 0.015518629279982822 - ], - [ - 1.580234399751114, - 0.36800560834751783, - -0.06094001469003677 - ], - [ - 1.5733258051578176, - 0.37561353452777346, - -0.12809227520878988 - ], - [ - 1.558944396056383, - 0.3799976160041568, - -0.17807767656838522 - ], - [ - 1.54218869213224, - 0.38059325236618025, - -0.2043306483457884 - ], - [ - 1.5281983946882407, - 0.3767813330751487, - -0.20261585569221535 - ], - [ - 1.519814266292255, - 0.36806880254256175, - -0.17081176050428015 - ], - [ - 1.5153863386856297, - 0.3545212759647579, - -0.10944014153920659 - ], - [ - 1.5086989784685734, - 0.33732123437131956, - -0.024605178446917935 - ], - [ - 1.4936315236743867, - 0.3187708422798549, - 0.07035241384620904 - ], - [ - 1.4711547725013547, - 0.3019732878546931, - 0.15838513528457268 - ], - [ - 1.4504499874125834, - 0.29039469025110204, - 0.2254593883284215 - ], - [ - 1.4418493663436378, - 0.2865772948855142, - 0.2649041269537688 - ], - [ - 1.4498387411022267, - 0.2907710204946833, - 0.27621769493622006 - ], - [ - 1.4722555174915155, - 0.30115646313401767, - 0.2612336679534447 - ], - [ - 1.50299782759172, - 0.31513108318134514, - 0.2226209622416821 - ], - [ - 1.534634038519224, - 0.3302718644619936, - 0.1646440875277168 - ], - [ - 1.56052458548653, - 0.34479354716615823, - 0.09326901363102057 - ], - [ - 1.5029866200503534, - 0.5218554350505877, - 0.021222108126255947 - ], - [ - 1.5101898388747432, - 0.5336804283819246, - -0.04818316489419016 - ], - [ - 1.507297261437279, - 0.541514783741956, - -0.10831382382398552 - ], - [ - 1.4968985421504684, - 0.5445894997475598, - -0.15160863006755165 - ], - [ - 1.4829095654480609, - 0.5422967813736566, - -0.17185579272481338 - ], - [ - 1.4692622999954346, - 0.5343722864969254, - -0.1653947943926757 - ], - [ - 1.4578921075241607, - 0.5209044144506049, - -0.13100132529402378 - ], - [ - 1.4471279741520566, - 0.5026435517620698, - -0.0706744369348434 - ], - [ - 1.4325012131707258, - 0.48154934770380736, - 0.008186640899027263 - ], - [ - 1.4109038928709043, - 0.46061859617400686, - 0.09291783561035653 - ], - [ - 1.385332700285414, - 0.44328633459839867, - 0.16925408732975286 - ], - [ - 1.364750521958894, - 0.4329207731970006, - 0.22605631476004315 - ], - [ - 1.3580238248136356, - 0.43167371241516594, - 0.2581904776834478 - ], - [ - 1.3682889047153035, - 0.4392748847302019, - 0.26542852609544565 - ], - [ - 1.3926431591136021, - 0.45339685596423457, - 0.2493242816942946 - ], - [ - 1.4248281810682715, - 0.4710329381566305, - 0.21225220829869418 - ], - [ - 1.4576609111122072, - 0.4894892448841586, - 0.15813646539557977 - ], - [ - 1.484997207169361, - 0.5068339515362503, - 0.09234926081025738 - ], - [ - 1.4078578477099184, - 0.6737649064848256, - 0.024307792509068022 - ], - [ - 1.4166430978862397, - 0.6861058149345451, - -0.03668287047733509 - ], - [ - 1.416038317577801, - 0.6933636002768198, - -0.08870482144760054 - ], - [ - 1.4079347184674191, - 0.6944607853616265, - -0.12469419343935062 - ], - [ - 1.3952180104962617, - 0.688664069381561, - -0.13910800896691175 - ], - [ - 1.3808288590424311, - 0.6760485433506997, - -0.12915567931411967 - ], - [ - 1.366137480731372, - 0.6574799343994665, - -0.09466234513432181 - ], - [ - 1.3499559795470109, - 0.6347287137711873, - -0.03883779487693172 - ], - [ - 1.329825512213804, - 0.6106772485733342, - 0.030581760032938686 - ], - [ - 1.3051366136641318, - 0.5887389073654695, - 0.10274221633360084 - ], - [ - 1.2798654069000786, - 0.5722251638209279, - 0.16659718939148827 - ], - [ - 1.2619160871799793, - 0.5641208948569396, - 0.21358619331228607 - ], - [ - 1.2583627900191456, - 0.566087639375891, - 0.2395621530935762 - ], - [ - 1.271077103251216, - 0.5773573712401351, - 0.24413843983431646 - ], - [ - 1.296730546669087, - 0.5952183585735008, - 0.22841915301373586 - ], - [ - 1.329238258282934, - 0.6163497837526005, - 0.194481200301495 - ], - [ - 1.3619028558716904, - 0.6377638442681381, - 0.14586759334550445 - ], - [ - 1.3892080508677995, - 0.657333950521263, - 0.08728295416351624 - ], - [ - 1.2954508844340629, - 0.8141778928244755, - 0.02399177691466328 - ], - [ - 1.3042647446708695, - 0.8258513767697385, - -0.028313158617015333 - ], - [ - 1.3042666452904257, - 0.8312588155148407, - -0.0720855527082241 - ], - [ - 1.29676076597788, - 0.8291251524071, - -0.10106279050948742 - ], - [ - 1.2839237774198018, - 0.8188006323175061, - -0.11073049357727645 - ], - [ - 1.2681297254364476, - 0.8009998291296261, - -0.09927718170466276 - ], - [ - 1.2505901271386175, - 0.7776405721509883, - -0.06732725184156398 - ], - [ - 1.230864762403623, - 0.751578840397086, - -0.018579068989095046 - ], - [ - 1.2082321588524392, - 0.7263502312328335, - 0.039914480479270306 - ], - [ - 1.1836708151842839, - 0.7053064216984948, - 0.09960906851992062 - ], - [ - 1.1612394474221837, - 0.691218039755721, - 0.15226352786744868 - ], - [ - 1.1474249134564796, - 0.6864506650828798, - 0.19117673108176023 - ], - [ - 1.1475566910435113, - 0.6921207114890748, - 0.21269843796217933 - ], - [ - 1.1624608604778306, - 0.707078960310108, - 0.2160542119969352 - ], - [ - 1.1886471518025468, - 0.7284139499267177, - 0.2018700793718865 - ], - [ - 1.2204015202114946, - 0.7526010295685303, - 0.17195326974631964 - ], - [ - 1.2516457113085349, - 0.7763670506533111, - 0.12946265161658746 - ], - [ - 1.277574486893216, - 0.7973556205019062, - 0.07849657456029567 - ], - [ - 1.1694183680187078, - 0.9433538416580577, - 0.020264659855346027 - ], - [ - 1.1767603031042293, - 0.9531181913943334, - -0.024007086928293453 - ], - [ - 1.1758307131660688, - 0.9552709414828682, - -0.060349223665873454 - ], - [ - 1.1675849688365312, - 0.9485105049752044, - -0.08361732967362852 - ], - [ - 1.1538692140216178, - 0.9327054954821805, - -0.0904600096573003 - ], - [ - 1.1368273982453327, - 0.9096268539699434, - -0.07978367865704092 - ], - [ - 1.1177330459731476, - 0.8823714790694308, - -0.0524764657220679 - ], - [ - 1.0968675364029052, - 0.8546942706677535, - -0.011969448925892776 - ], - [ - 1.0746663093483044, - 0.8303911548651973, - 0.03602594377682832 - ], - [ - 1.0527547324376558, - 0.8122951086241418, - 0.0851631356849922 - ], - [ - 1.0346837085543894, - 0.8022615384003178, - 0.12916037352601734 - ], - [ - 1.0255375840532583, - 0.8018380921741484, - 0.16237730283965263 - ], - [ - 1.0291973682221012, - 0.8115906482686784, - 0.18130873847250922 - ], - [ - 1.0457343892235815, - 0.8301024047519692, - 0.18475326970858377 - ], - [ - 1.071665121710705, - 0.8543842387250467, - 0.17291261724772258 - ], - [ - 1.1016977099758276, - 0.8808121871885549, - 0.14732232657225935 - ], - [ - 1.1304000804063976, - 0.9059384229840312, - 0.1107744562527541 - ], - [ - 1.1536993071421182, - 0.9272701471897596, - 0.06692259946530392 - ], - [ - 1.0328310330619934, - 1.0617112387317982, - 0.014248508121768548 - ], - [ - 1.0374040945611063, - 1.068019010779002, - -0.02352233225553281 - ], - [ - 1.0343759429201471, - 1.0653257365004907, - -0.05439146945858681 - ], - [ - 1.0246923630374587, - 1.0526833711088668, - -0.07432485691820791 - ], - [ - 1.0101100374231857, - 1.0309534192256853, - -0.08079266879192736 - ], - [ - 0.9926093666277078, - 1.0031737906678204, - -0.07289515758360153 - ], - [ - 0.9735006297720203, - 0.9734920272076855, - -0.05130049732384522 - ], - [ - 0.9535641729387689, - 0.946219341817484, - -0.018738231053827395 - ], - [ - 0.9338353592882697, - 0.9249601236231115, - 0.020546622675539788 - ], - [ - 0.9159881466385641, - 0.9116234581413379, - 0.06187322668567007 - ], - [ - 0.9028460103820016, - 0.9069453454345874, - 0.1000498688605168 - ], - [ - 0.8982717992373163, - 0.9116385651302865, - 0.12992519144514658 - ], - [ - 0.9050182235567603, - 0.9257704490383738, - 0.14801455745252845 - ], - [ - 0.9226314365401006, - 0.9476933784738156, - 0.15276565055825672 - ], - [ - 0.9477058880262387, - 0.9743602166653276, - 0.14398858609440174 - ], - [ - 0.9753551170239951, - 1.0021048849486718, - 0.12288604104863514 - ], - [ - 1.0007405922363204, - 1.0274172825974923, - 0.09187218045539916 - ], - [ - 1.0204472200619186, - 1.0477800379572664, - 0.0542661561592562 - ], - [ - 0.8870494921179659, - 1.1702679322998037, - 0.007268979860060467 - ], - [ - 0.8880756073074626, - 1.171358341523124, - -0.0264345415115381 - ], - [ - 0.882578947586328, - 1.1623459612451947, - -0.05478356199777975 - ], - [ - 0.8716524530056686, - 1.143116392736364, - -0.0743620232225025 - ], - [ - 0.8569064884145863, - 1.1157261521387274, - -0.08282485076575251 - ], - [ - 0.8400329159460485, - 1.0843419789939506, - -0.07901180445210902 - ], - [ - 0.8222703821602239, - 1.0538724451442374, - -0.06312236883605978 - ], - [ - 0.8046488384049088, - 1.028823621484977, - -0.037082039874215905 - ], - [ - 0.7884146432930279, - 1.012234865497902, - -0.003959940873644552 - ], - [ - 0.7750555207615841, - 1.0048799122506498, - 0.032500425626644486 - ], - [ - 0.7667393802158297, - 1.0063775751337485, - 0.06752618160322345 - ], - [ - 0.7663448806175952, - 1.0166856499793187, - 0.09620695825610852 - ], - [ - 0.775698633842408, - 1.035407507212013, - 0.11510715257443753 - ], - [ - 0.7938911034437937, - 1.060640304306767, - 0.12236150871866945 - ], - [ - 0.817576662648942, - 1.0892612928857894, - 0.1173390006083735 - ], - [ - 0.8422488997104679, - 1.117587365289762, - 0.10083181583639055 - ], - [ - 0.8636250056788233, - 1.1420619283995748, - 0.07485520073769422 - ], - [ - 0.8789094167606091, - 1.1601220933920826, - 0.042395493533104976 - ], - [ - 0.7321950723753204, - 1.268199066405626, - 2.609239737498941e-18 - ], - [ - 0.7298350555585253, - 1.2627403617406865, - -0.03279591448173221 - ], - [ - 0.7225232848565059, - 1.2467860726009767, - -0.06185995394114709 - ], - [ - 0.7113118601926944, - 1.2212301615495098, - -0.08374750474203659 - ], - [ - 0.6974534644956215, - 1.1891213689605176, - -0.09584508603247537 - ], - [ - 0.6822540551633787, - 1.155417545600495, - -0.0965604584826825 - ], - [ - 0.6668186696315086, - 1.125515480901797, - -0.0855760657712594 - ], - [ - 0.6522346114453441, - 1.1039103692313952, - -0.06409474720750231 - ], - [ - 0.6397383619824913, - 1.0929536939082332, - -0.03442570577993494 - ], - [ - 0.6306356150916351, - 1.092292926401162, - -8.405962558080531e-19 - ], - [ - 0.626656483093326, - 1.1005065202063988, - 0.03442570577993494 - ], - [ - 0.6298971175327758, - 1.1168069273548378, - 0.06409474720750227 - ], - [ - 0.6413156639978614, - 1.1402396480695278, - 0.08557606577125937 - ], - [ - 0.6594939188866045, - 1.168558116406683, - 0.0965604584826825 - ], - [ - 0.681082581454926, - 1.1985731026909348, - 0.0958450860324754 - ], - [ - 0.7019604136733024, - 1.2266292217147932, - 0.08374750474203663 - ], - [ - 0.7184867695288225, - 1.2491165558120025, - 0.061859953941147135 - ], - [ - 0.7286477038721237, - 1.2634258795564532, - 0.03279591448173228 - ], - [ - 0.569957012546935, - 1.3533413607381442, - -0.007268979860060445 - ], - [ - 0.5652404959888223, - 1.341218929236093, - -0.04239549353310487 - ], - [ - 0.557242139849665, - 1.3189521584611281, - -0.07485520073769412 - ], - [ - 0.5467345994342194, - 1.288202626103638, - -0.10083181583639043 - ], - [ - 0.5345396196737048, - 1.2526728058381784, - -0.1173390006083734 - ], - [ - 0.521595896085421, - 1.217850015574168, - -0.12236150871866938 - ], - [ - 0.5088398875935188, - 1.189478476194415, - -0.11510715257443743 - ], - [ - 0.49730316023638665, - 1.1720169596646495, - -0.09620695825610846 - ], - [ - 0.4881788557568941, - 1.167204568915718, - -0.06752618160322334 - ], - [ - 0.4827237713809485, - 1.1736577264482337, - -0.03250042562664441 - ], - [ - 0.4824137864709939, - 1.1889045425563594, - 0.003959940873644638 - ], - [ - 0.48866297301704137, - 1.2112581459267786, - 0.037082039874215926 - ], - [ - 0.50154511876322, - 1.2390432623024108, - 0.06312236883605982 - ], - [ - 0.5190512422256294, - 1.2696608347213711, - 0.07901180445210906 - ], - [ - 0.5377939472115063, - 1.2999658637041105, - 0.08282485076575258 - ], - [ - 0.5541416090892863, - 1.3264313639421121, - 0.07436202322250254 - ], - [ - 0.5653316566314175, - 1.3455087700776918, - 0.054783561997779805 - ], - [ - 0.5703882770401028, - 1.3547752071711174, - 0.026434541511538196 - ], - [ - 0.4030533876941856, - 1.425313531814511, - -0.014248508121768541 - ], - [ - 0.397180520418257, - 1.407623234773464, - -0.054266156159256104 - ], - [ - 0.38939917089844395, - 1.380375416773684, - -0.09187218045539912 - ], - [ - 0.3801707291100345, - 1.3457347515282598, - -0.12288604104863504 - ], - [ - 0.36996775605596444, - 1.3079174826794773, - -0.1439885860944017 - ], - [ - 0.35941082248657485, - 1.2728689516107652, - -0.15276565055825672 - ], - [ - 0.34923161516177886, - 1.2466539970072057, - -0.14801455745252845 - ], - [ - 0.34036625685376476, - 1.2337454802078147, - -0.1299251914451466 - ], - [ - 0.3340147037994052, - 1.2353602534135362, - -0.1000498688605168 - ], - [ - 0.3314950001169366, - 1.249080733625091, - -0.061873226685670094 - ], - [ - 0.3341212849010748, - 1.271205205907366, - -0.0205466226755398 - ], - [ - 0.34266790109674805, - 1.2989204688124136, - 0.01873823105382735 - ], - [ - 0.35631851105745754, - 1.3298222895865621, - 0.05130049732384517 - ], - [ - 0.3724693038152113, - 1.361211822867887, - 0.07289515758360152 - ], - [ - 0.3877768324562789, - 1.3902576626389713, - 0.08079266879192734 - ], - [ - 0.3993043600029913, - 1.4137513030087794, - 0.07432485691820795 - ], - [ - 0.40541117965471857, - 1.4284587118825753, - 0.05439146945858687 - ], - [ - 0.406229547778789, - 1.432427805269413, - 0.02352233225553289 - ], - [ - 0.232259207624167, - 1.4844229351853693, - -0.020264659855346017 - ], - [ - 0.22618985006620845, - 1.4627679819084596, - -0.06692259946530377 - ], - [ - 0.21936564836538447, - 1.431924397563928, - -0.11077445625275402 - ], - [ - 0.21195687508030917, - 1.3945042977244848, - -0.14732232657225922 - ], - [ - 0.2040858944735664, - 1.3552813391137364, - -0.17291261724772247 - ], - [ - 0.19602257564596698, - 1.32068374905461, - -0.1847532697085837 - ], - [ - 0.18825943476350615, - 1.2971063905227658, - -0.18130873847250917 - ], - [ - 0.1816433655182318, - 1.289060646412915, - -0.1623773028396526 - ], - [ - 0.17743701845666557, - 1.2971931456901542, - -0.12916037352601734 - ], - [ - 0.17709083321951913, - 1.3178598965573702, - -0.0851631356849922 - ], - [ - 0.1818066805170068, - 1.3458839019194961, - -0.036025943776828356 - ], - [ - 0.19175318266583496, - 1.3772622864452448, - 0.011969448925892684 - ], - [ - 0.20528959346240244, - 1.409170951996821, - 0.05247646572206779 - ], - [ - 0.21934626437982252, - 1.4393348335835987, - 0.07978367865704089 - ], - [ - 0.23081204632611146, - 1.4656327997285943, - 0.09046000965730026 - ], - [ - 0.23764170864666773, - 1.4854134965769004, - 0.08361732967362855 - ], - [ - 0.23937354623820745, - 1.4959347388932231, - 0.06034922366587349 - ], - [ - 0.23704441500445697, - 1.495663412350505, - 0.024007086928293526 - ], - [ - 0.05737329616864867, - 1.528982321687155, - -0.02399177691466328 - ], - [ - 0.05174297975834723, - 1.5050897711273474, - -0.07849657456029555 - ], - [ - 0.04653073287270025, - 1.4721405078576904, - -0.12946265161658738 - ], - [ - 0.041570850414923526, - 1.4331992341045674, - -0.17195326974631953 - ], - [ - 0.03650140920623034, - 1.3936056045603826, - -0.20187007937188645 - ], - [ - 0.03111791187112726, - 1.3602601162339731, - -0.2160542119969352 - ], - [ - 0.025615773113143517, - 1.3398736024710285, - -0.21269843796217938 - ], - [ - 0.020771257678257778, - 1.3369244565299123, - -0.1911767310817602 - ], - [ - 0.01799265827144486, - 1.3512718812220756, - -0.15226352786744865 - ], - [ - 0.018977871051054786, - 1.3777422065170724, - -0.09960906851992066 - ], - [ - 0.024921672866115588, - 1.409534858851944, - -0.039914480479270334 - ], - [ - 0.035453987528915154, - 1.4417495730631775, - 0.01857906898909494 - ], - [ - 0.04816142692691287, - 1.4718631058995477, - 0.06732725184156389 - ], - [ - 0.05962133773502715, - 1.498732472086962, - 0.09927718170466276 - ], - [ - 0.06714025951182119, - 1.5213109239271783, - 0.11073049357727645 - ], - [ - 0.06966306191225323, - 1.5375903421713613, - 0.10106279050948748 - ], - [ - 0.06775792871040147, - 1.5451574558876364, - 0.07208555270822416 - ], - [ - 0.06307589969751279, - 1.5424520905302663, - 0.028313158617015437 - ], - [ - -0.12043139866065335, - 1.5561231142764853, - -0.024307792509068022 - ], - [ - -0.12533612551250262, - 1.5317564384540108, - -0.08728295416351609 - ], - [ - -0.12863173718441473, - 1.4983243928055296, - -0.14586759334550434 - ], - [ - -0.13084455879466952, - 1.4593289912315022, - -0.19448120030149485 - ], - [ - -0.1328910540110165, - 1.4206107745654624, - -0.22841915301373578 - ], - [ - -0.13553240106944775, - 1.3894637472043565, - -0.24413843983431643 - ], - [ - -0.13893511854168691, - 1.3728179630215889, - -0.23956215309357623 - ], - [ - -0.14241501783826957, - 1.3749118363705906, - -0.21358619331228607 - ], - [ - -0.14437117489640344, - 1.3945085377108395, - -0.16659718939148827 - ], - [ - -0.1427054568572758, - 1.4246509165250694, - -0.1027422163336009 - ], - [ - -0.13605074532921013, - 1.4570013004644744, - -0.030581760032938773 - ], - [ - -0.12528679913623542, - 1.486460529164011, - 0.03883779487693154 - ], - [ - -0.11367441469722168, - 1.5118497305751755, - 0.0946623451343217 - ], - [ - -0.10493921678804413, - 1.533857141884777, - 0.1291556793141196 - ], - [ - -0.10120842649012962, - 1.5526262755981264, - 0.13910800896691172 - ], - [ - -0.10254667717844843, - 1.5665376257436898, - 0.12469419343935066 - ], - [ - -0.10754866688973544, - 1.5730069558929622, - 0.08870482144760056 - ], - [ - -0.11413648352557874, - 1.5699018183326412, - 0.03668287047733519 - ], - [ - -0.2995532461683874, - 1.5625523120370097, - -0.021222108126255947 - ], - [ - -0.3035675260538366, - 1.5394622817257346, - -0.09234926081025721 - ], - [ - -0.30492033460716006, - 1.5071160015688212, - -0.15813646539557968 - ], - [ - -0.3044876000712692, - 1.4694538699114121, - -0.2122522082986941 - ], - [ - -0.30366838429577975, - 1.4327627821811109, - -0.24932428169429455 - ], - [ - -0.3037212429368158, - 1.404610393564939, - -0.26542852609544565 - ], - [ - -0.30517151130934594, - 1.3919199874406993, - -0.2581904776834478 - ], - [ - -0.3074548735648431, - 1.398369008442975, - -0.22605631476004323 - ], - [ - -0.30876912323000494, - 1.4213764784396616, - -0.16925408732975292 - ], - [ - -0.3065445406932365, - 1.4521879116115646, - -0.09291783561035659 - ], - [ - -0.29921663829803996, - 1.4813571154097795, - -0.00818664089902733 - ], - [ - -0.2882619022016374, - 1.504571364023826, - 0.07067443693484325 - ], - [ - -0.2778295979043986, - 1.5230238083180598, - 0.13100132529402367 - ], - [ - -0.27185117481300364, - 1.539604619867262, - 0.1653947943926757 - ], - [ - -0.27181199366390785, - 1.5553857458797913, - 0.17185579272481338 - ], - [ - -0.27682092965958816, - 1.5686469142639767, - 0.15160863006755174 - ], - [ - -0.28468307147326893, - 1.5761151113303762, - 0.10831382382398559 - ], - [ - -0.29291411095606296, - 1.574702979193618, - 0.04818316489419031 - ], - [ - -0.47845924384973454, - 1.5438982849400695, - -0.015518629279982843 - ], - [ - -0.4816623218364234, - 1.5238507078445949, - -0.0932690136310204 - ], - [ - -0.48129319448027424, - 1.4941679951009517, - -0.1646440875277167 - ], - [ - -0.47858739023870756, - 1.459199842117926, - -0.22262096224168199 - ], - [ - -0.47531861115782625, - 1.4255889105764663, - -0.2612336679534446 - ], - [ - -0.4731042801183914, - 1.4009826914327195, - -0.27621769493622006 - ], - [ - -0.47274146565313885, - 1.391966827126843, - -0.2649041269537687 - ], - [ - -0.4737358148247238, - 1.4013238811436677, - -0.2254593883284216 - ], - [ - -0.4740608477042018, - 1.425044049812236, - -0.15838513528457285 - ], - [ - -0.47075211443707593, - 1.4529082645352045, - -0.07035241384620923 - ], - [ - -0.462220731032799, - 1.475232259203076, - 0.02460517844691773 - ], - [ - -0.4506687381752605, - 1.4896237038320232, - 0.10944014153920627 - ], - [ - -0.44115019980375014, - 1.500232164914381, - 0.17081176050427993 - ], - [ - -0.4377969912292751, - 1.5118492983601888, - 0.20261585569221524 - ], - [ - -0.44149092100806553, - 1.5258712109987083, - 0.2043306483457883 - ], - [ - -0.450384609191067, - 1.5400842580742953, - 0.17807767656838525 - ], - [ - -0.4613720396725931, - 1.5503468829601628, - 0.12809227520878994 - ], - [ - -0.47141499431145933, - 1.5525259382922774, - 0.06094001469003688 - ], - [ - -0.6536525703290299, - 1.4963311964330517, - -0.008141613332533236 - ], - [ - -0.6568588288619635, - 1.480826425450893, - -0.08996975094317755 - ], - [ - -0.6554993301913663, - 1.4553638372056041, - -0.16442148182072885 - ], - [ - -0.6512054245151341, - 1.4245069969332733, - -0.2239517624742619 - ], - [ - -0.6460607797490526, - 1.395015727334323, - -0.2621420494724912 - ], - [ - -0.6419202082047905, - 1.3743214198290925, - -0.2744610527708378 - ], - [ - -0.6397394650383462, - 1.3683306660486132, - -0.25802422264088 - ], - [ - -0.6390087665472047, - 1.3786720559632213, - -0.21099517757647168 - ], - [ - -0.6374391589441066, - 1.3999630447286309, - -0.13469446925914375 - ], - [ - -0.6317460122165613, - 1.421263161998345, - -0.03782203491393514 - ], - [ - -0.6205699344429351, - 1.4340315916484272, - 0.06298104018879604 - ], - [ - -0.6071865847760861, - 1.4387590403194512, - 0.14919040363771244 - ], - [ - -0.597780234297247, - 1.4422252336565247, - 0.20816336382724124 - ], - [ - -0.5967136927620293, - 1.4501144874226448, - 0.23556092311023763 - ], - [ - -0.6042296427364368, - 1.463482052618067, - 0.23209923550010472 - ], - [ - -0.6174997230564367, - 1.479503299412578, - 0.20045868680892914 - ], - [ - -0.6324322120891992, - 1.493363503089145, - 0.1451869175649815 - ], - [ - -0.645264086877514, - 1.5001399654328882, - 0.07299648567715158 - ] - ] - } - }, - "140342738037920": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738037920", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.46855350080303, - 0.10885907179087682, - 0.001063516755472813, - -0.0006461718830387663, - -0.00011134663559380221, - -6.595950617135923e-05, - 3.468090462025979e-05, - 0.07193408688149867, - -0.03138657220581287, - -0.00033480778239255955, - 0.00027298717552230473, - 6.776308623563073e-05, - -6.503892240242274e-05, - -1.720768935810681e-05, - 0.009437833998917473, - 0.011169533387605369, - 0.0029094209756365874, - -0.00011432276479625831, - 4.990230029863758e-05, - -1.5821962089705287e-05, - 7.235609025966455e-06, - -0.001947060387053358, - -0.0011600393383437622, - -0.00048406507925431594, - -4.772181674406972e-05, - 2.9534593131139377e-05, - -1.3118299948281696e-06, - -3.09762886930019e-07, - 0.00022471903439034714, - 0.0002900313609933661, - 0.00012718190783794867, - 2.4442135287249818e-05, - 1.54283255691951e-05, - 4.579695439486621e-07, - 8.53787716061948e-07, - -7.50645833403012e-05, - -2.1275205414708093e-05, - -3.093419223257907e-05, - -8.228996602443203e-06, - -1.0608482235241774e-06, - -1.073695974851291e-06, - 3.0821179401346685e-07, - 1.4974887009099306e-05, - -4.415144174970952e-06, - 2.8949661376707803e-06, - 3.921760310619993e-06, - 7.11441873797778e-07, - 1.2774379723054856e-07, - 7.329315701760449e-08, - 0.07075451442878902, - 0.0017194347259494995, - 0.00022335553667715902, - 3.9968148431262596e-05, - 1.2469756197824699e-05, - -1.0646939378598767e-05, - -0.008585608729042887, - -0.0021846222441528986, - 0.00021139547014008189, - -6.153140178887092e-05, - 1.0829265217113755e-06, - -1.2437675807953241e-06, - 0.0009640150609280265, - 0.0005241938997718694, - 0.00011834265211815907, - 1.077647199412823e-06, - 6.9822978103379945e-06, - 3.7353275575040515e-07, - -0.0001169981325575714, - -0.00011741970841212746, - -2.119421995437428e-05, - -1.9541696068505665e-05, - 7.818234731539757e-07, - -3.6492038316393457e-07, - -1.5111260641921128e-05, - 2.662743775584343e-05, - 1.1604467586237973e-05, - 3.574967499533016e-06, - 1.7626385185007257e-06, - 1.1210195843006657e-07, - 9.583822472768207e-06, - -1.7232870587106826e-06, - -4.795946452965562e-06, - -1.1766553567149514e-06, - -2.0561812280157258e-07, - -1.997241970377709e-07, - -0.03950441743696766, - 0.003742987347466362, - 0.0007329784709402334, - 0.00019177880398720692, - -0.00010212332378626435, - -4.3828059500343815e-05, - 0.014468873167376797, - -4.276092578780327e-05, - -0.0003698711232151676, - 3.0662873280396434e-05, - -5.856395500173107e-05, - 3.2193597007652456e-05, - -0.0058162393714656, - -0.0004590680920159008, - 0.0002319942594883885, - 0.00014376848850681273, - 2.5635463719070695e-05, - -2.4976503620412403e-06, - 0.0003096961461784939, - 0.00023951822677213455, - -3.080172972274953e-05, - -1.4094439525472437e-05, - -1.3426783061402316e-05, - 1.8080198844630623e-07, - -3.5015708650911324e-05, - -1.8772936290309538e-05, - -1.3022304429600124e-06, - 1.5339170430450555e-05, - 7.426505121323719e-06, - 2.6842858844488075e-06, - 1.97846294197715e-06, - 4.4406177787821835e-06, - 1.4720667677140285e-06, - -9.260863634146162e-07, - -1.6830101039901726e-06, - -8.710476370733436e-07, - 3.857961241984364e-06, - 4.213368942150025e-07, - -4.824009906491425e-07, - 6.328674356897564e-07, - 5.219906679524811e-07, - 3.9300995575722347e-07, - 0.013656113201176141, - 0.02411124739603273, - -0.001618288221491656, - -0.0005325521075867246, - -0.00010129757817670953, - 1.7212653639949963e-05, - 4.1217011872316364e-05, - 0.0008192697420615711, - -0.005014201230434793, - -0.0004784254047269628, - -2.3924940317833553e-05, - 5.929421223418001e-06, - 2.3963395817244558e-05, - 7.332230845520765e-06, - -0.00027309624060928994, - 0.00015450212097394188, - 0.00016936281979102025, - -0.00010511337897278106, - -2.3218754568158265e-05, - -1.2101234835534153e-05, - -3.784817264480561e-06, - 4.510525991883723e-05, - 5.375744556112898e-05, - -2.2160169360176834e-05, - -1.3565337053579426e-05, - 4.487304840626748e-06, - 4.926902175649076e-06, - 2.1023415377541553e-06, - -1.648290234233873e-05, - -1.5081641096610996e-05, - 2.2672067479577504e-06, - 1.673540626843115e-06, - -8.230568175204095e-08, - -1.8975219489540075e-06, - -1.0204321687231934e-06, - 2.2095750117382083e-06, - 6.741086987731593e-06, - 1.8733537284709906e-06, - -5.985690715433127e-07, - 1.505570116475656e-07, - 2.961589902448659e-07, - 2.942860387519519e-07, - 0.057753998910337404, - 0.00028888103717561865, - 5.479317095949965e-05, - -9.486631490095862e-05, - -5.430489039751829e-07, - -4.70006145202736e-06, - -0.03896744761196523, - -0.0013426538615572072, - -0.00020457038178381802, - 7.678944729699289e-05, - 2.598346423496191e-05, - -6.692978218063212e-06, - 0.005527835923895802, - 0.002060468117918188, - -0.00035254079990252094, - 4.0341015967558634e-05, - 1.3383007079192748e-06, - -5.839518316441021e-06, - -0.0004720723760084336, - -0.0004978433496690715, - -0.00010672743058346078, - 1.9746677567021184e-05, - 1.4850664319189002e-06, - 1.0148351082635055e-06, - 0.00012622298024049056, - 0.00012638506748488066, - 1.187295598105266e-05, - 1.7163988235772435e-05, - -1.9901809843280144e-06, - 1.973939623012395e-07, - 3.447611472890403e-05, - -2.721381040742848e-05, - -8.0399185488916e-06, - -2.0496102732707136e-06, - -1.1623774445419372e-06, - 1.8927104368752415e-07, - -2.5443759280679488e-05, - 2.8659928520010928e-06, - 4.414241040540377e-06, - 9.809729588773607e-07, - 6.229592085702438e-08, - 1.5174658402691218e-07, - -0.17722655392090608, - -0.08266349611508506, - -0.0031370911913935562, - 0.000290441947256058, - 0.0002155256264555718, - 2.098363388667433e-05, - 1.7700715317718193e-06, - 0.005216438091686312, - 0.006339350464257255, - 0.002049028985847243, - -0.00020849186406803833, - -1.412863628852419e-05, - -5.888260180402124e-07, - 7.087661720359001e-06, - -0.0009414727489213521, - -0.0012150665002617516, - -0.0005286658230733393, - -6.990847932796645e-05, - 3.6482114291275345e-05, - 2.0953422266370744e-06, - 2.440737705350068e-06, - 0.00020949944212106576, - 0.0002751837587062734, - 0.000131622010755458, - 4.272481968009884e-06, - 8.959293470897377e-06, - -1.8741098732200699e-06, - -6.248920357775795e-08, - -9.405174519624665e-06, - 2.2700204333695387e-07, - -3.201371782968914e-05, - -5.165254213487304e-06, - -8.10109618952807e-08, - -8.929265106849079e-07, - 3.9886026040190554e-07, - 3.8069700028069534e-06, - -1.724829363794602e-05, - 2.9795119389688718e-06, - 3.278215154044178e-06, - 4.113498352796076e-07, - -7.723996833893412e-08, - -4.3410543568648205e-09 - ] - }, - "names": [ - "x0", - "x1", - "x2", - "x3", - "x4", - "x5", - "x6", - "x7", - "x8", - "x9", - "x10", - "x11", - "x12", - "x13", - "x14", - "x15", - "x16", - "x17", - "x18", - "x19", - "x20", - "x21", - "x22", - "x23", - "x24", - "x25", - "x26", - "x27", - "x28", - "x29", - "x30", - "x31", - "x32", - "x33", - "x34", - "x35", - "x36", - "x37", - "x38", - "x39", - "x40", - "x41", - "x42", - "x43", - "x44", - "x45", - "x46", - "x47", - "x48", - "x49", - "x50", - "x51", - "x52", - "x53", - "x54", - "x55", - "x56", - "x57", - "x58", - "x59", - "x60", - "x61", - "x62", - "x63", - "x64", - "x65", - "x66", - "x67", - "x68", - "x69", - "x70", - "x71", - "x72", - "x73", - "x74", - "x75", - "x76", - "x77", - "x78", - "x79", - "x80", - "x81", - "x82", - "x83", - "x84", - "x85", - "x86", - "x87", - "x88", - "x89", - "x90", - "x91", - "x92", - "x93", - "x94", - "x95", - "x96", - "x97", - "x98", - "x99", - "x100", - "x101", - "x102", - "x103", - "x104", - "x105", - "x106", - "x107", - "x108", - "x109", - "x110", - "x111", - "x112", - "x113", - "x114", - "x115", - "x116", - "x117", - "x118", - "x119", - "x120", - "x121", - "x122", - "x123", - "x124", - "x125", - "x126", - "x127", - "x128", - "x129", - "x130", - "x131", - "x132", - "x133", - "x134", - "x135", - "x136", - "x137", - "x138", - "x139", - "x140", - "x141", - "x142", - "x143", - "x144", - "x145", - "x146", - "x147", - "x148", - "x149", - "x150", - "x151", - "x152", - "x153", - "x154", - "x155", - "x156", - "x157", - "x158", - "x159", - "x160", - "x161", - "x162", - "x163", - "x164", - "x165", - "x166", - "x167", - "x168", - "x169", - "x170", - "x171", - "x172", - "x173", - "x174", - "x175", - "x176", - "x177", - "x178", - "x179", - "x180", - "x181", - "x182", - "x183", - "x184", - "x185", - "x186", - "x187", - "x188", - "x189", - "x190", - "x191", - "x192", - "x193", - "x194", - "x195", - "x196", - "x197", - "x198", - "x199", - "x200", - "x201", - "x202", - "x203", - "x204", - "x205", - "x206", - "x207", - "x208", - "x209", - "x210", - "x211", - "x212", - "x213", - "x214", - "x215", - "x216", - "x217", - "x218", - "x219", - "x220", - "x221", - "x222", - "x223", - "x224", - "x225", - "x226", - "x227", - "x228", - "x229", - "x230", - "x231", - "x232", - "x233", - "x234", - "x235", - "x236", - "x237", - "x238", - "x239", - "x240", - "x241", - "x242", - "x243", - "x244", - "x245", - "x246", - "x247", - "x248", - "x249", - "x250", - "x251", - "x252" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "SurfaceXYZTensorFourier1": { - "@module": "simsopt.geo.surfacexyztensorfourier", - "@class": "SurfaceXYZTensorFourier", - "@name": "SurfaceXYZTensorFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "nfp": 3, - "stellsym": true, - "mpol": 6, - "ntor": 6, - "clamped_dims": [ - false, - false, - false - ], - "quadpoints_phi": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.018518518518518517, - 0.037037037037037035, - 0.05555555555555555, - 0.07407407407407407, - 0.09259259259259259, - 0.1111111111111111, - 0.12962962962962962, - 0.14814814814814814, - 0.16666666666666666, - 0.18518518518518517, - 0.2037037037037037, - 0.2222222222222222, - 0.24074074074074073, - 0.25925925925925924, - 0.2777777777777778, - 0.2962962962962963, - 0.31481481481481477 - ] - }, - "quadpoints_theta": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.05555555555555555, - 0.1111111111111111, - 0.16666666666666666, - 0.2222222222222222, - 0.2777777777777778, - 0.3333333333333333, - 0.38888888888888884, - 0.4444444444444444, - 0.5, - 0.5555555555555556, - 0.611111111111111, - 0.6666666666666666, - 0.7222222222222222, - 0.7777777777777777, - 0.8333333333333333, - 0.8888888888888888, - 0.9444444444444444 - ] - }, - "dofs": { - "$type": "ref", - "value": "140342738037920" - } - }, - "Volume1": { - "@module": "simsopt.geo.surfaceobjectives", - "@class": "Volume", - "@name": "Volume1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "range": null, - "nphi": null, - "ntheta": null - }, - "BoozerSurface1": { - "@module": "simsopt.geo.boozersurface", - "@class": "BoozerSurface", - "@name": "BoozerSurface1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "biotsavart": { - "$type": "ref", - "value": "BiotSavart1" - }, - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "label": { - "$type": "ref", - "value": "Volume1" - }, - "targetlabel": -0.2960004452246598, - "constraint_weight": 1000.0, - "reg": null - } - } -} \ No newline at end of file diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_0.vts b/examples/2_Intermediate/inputs/input_ncsx/surface_0.vts deleted file mode 100644 index 8b6e88eecd133a6a8f5db99e29e6bab43041d12b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31872 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 Z0&pMakK~EY|MvmT|KADE_<-^K{|8@g+iw5> diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_2.json b/examples/2_Intermediate/inputs/input_ncsx/surface_2.json deleted file mode 100644 index b1df468fc..000000000 --- a/examples/2_Intermediate/inputs/input_ncsx/surface_2.json +++ /dev/null @@ -1,7022 +0,0 @@ -{ - "@module": "simsopt._core.json", - "@class": "SIMSON", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "graph": [ - { - "$type": "ref", - "value": "BoozerSurface3" - }, - { - "iota": -0.42145063872985117, - "G": 13.887479020465854 - } - ], - "simsopt_objs": { - "140342738246336": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738246336", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.506387961733893, - 0.1058930714809362, - 0.7258942274042265, - -0.001249592121112775, - 0.2763105569564668, - 0.01482550301512887, - -0.1280092780227772, - 0.005921392096802394, - 0.01864241438718947, - -0.01034831723350223, - 0.0001022108294955593, - 0.01892666378143068, - -0.007192153616853929, - -0.007355339046239706, - -0.01884714563379878, - -0.002596706082945131, - 0.01131859363705868, - 0.00964754529816095, - -0.0113260687651076, - -0.006628855789771619, - 0.000322284209286623, - 0.001842953924532827, - -0.0004161340928027646, - 0.00176264188836799, - 0.001814459617914206, - -0.001883356200860781, - -0.003584967425237995, - 0.0003165409191237933, - 0.00198839685289703, - 0.0007998064690618334, - 0.0005809753916376526, - 4.996792424044994e-05, - -0.0009656219012175038, - -0.001300735471703214, - -0.0004500391754653399, - 0.002413016477450284, - 0.00190334965179141, - -0.001622873850792805, - -0.001817132111793323, - 0.0005008124937015768, - 0.0009410326413637304, - 0.0005073038161052906, - -0.0001747050570155717, - -0.0004010070348672179, - 0.0002171330554898199, - 0.0001868680753017027, - -0.00049371483741256, - -1.263882515020243e-05, - 0.0005663593123846766, - 0.0001291744509577553, - -0.0002415255915965764, - 0.2855239540187146, - 0.02831674064739627, - 0.1230646086878452, - -0.1881027707999307, - -0.03092022550185042, - 0.07598032813641656, - 0.032842960392996, - -0.02022733960800226, - 0.03368541189764687, - -0.02527069889002642, - 0.03990545352197854, - 0.03266977475756579, - 0.007041509561223136, - -0.01843202758194484, - -0.003255107459418295, - 0.001087406605704745, - 0.02057587403483786, - 0.004332699549632209, - -0.003239348172858322, - -0.008060517809116506, - 0.0008303250764389791, - 0.002593682135814645, - 0.005122620691996364, - 0.002329497971206275, - -0.007021762243403233, - -0.002076255998522319, - 0.005455573755227739, - 0.0004034355313731426, - -0.002121189074115063, - -0.001155709211846629, - 0.0007060503790857225, - 0.001458108819397405, - 0.0007612900914783658, - -0.001579374591052191, - -0.0005648184298353118, - -3.483600030825498e-05, - 0.0006434230018098444, - 0.0002266872576160417, - -0.0005870263149471541, - -0.0004782734366555642, - 0.0004131000234993432, - -0.0002086017812282408, - -0.0002217317708794842, - 0.0004459870616389726, - 0.0002232186481886098, - -0.000550989811641543, - -0.0004679750418668452, - 0.0001971289820931924, - 0.0006305703105299488, - 1.94634036466225e-05, - -0.0005071137243856577, - 0.0009455853398023695, - -1.066704925256128, - 0.01954765252843791, - -0.03091192279856904, - -0.009251669123731003, - 0.03622032973711591, - 0.01289395028459556, - -0.01341289215090563, - -0.01055557464591715, - -0.007044726977866961, - -0.007171173731457627, - 0.01327231838496817, - 0.003220259676106272, - -0.006043809337864334, - -0.006228107449831786, - -0.0004722020937025503, - -0.0007632924616726337, - 0.0002557840887866895, - -0.0008300983337148277, - 0.001290373849098229, - 0.0002249498117545818, - -0.0003276137574950353, - -0.001560853624251917, - -0.003125967131907846, - 0.0007111137798287738, - 0.001688245514976161, - 0.00083638883723687, - -3.216802700299113e-05, - -0.003601309499252412, - -0.003364173533240832, - 0.003283863928203238, - 0.003620244544063828, - -0.001109032285114347, - -0.002277398193829699, - -0.0015519788484098, - 0.0002155015553257128, - 0.002349143532954114, - 0.000703914196138795, - -0.001628934087145739, - -0.0005728748367786014, - 0.000379102967651227, - 3.674770297429017e-05, - 0.0003644795696035227, - 0.0001196573774128766, - -0.0004826910821886253, - 1.895960151025164e-05, - 0.0002282029938596129, - -3.982416558199763e-05, - -0.0001869395233315697, - -0.0002051724761620464, - 0.0001303574263284748 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier1": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738246336" - } - }, - "140342738367104": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367104", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 652271.9419853 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current1": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 652271.9419853, - "dofs": { - "$type": "ref", - "value": "140342738367104" - } - }, - "Coil1": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "140342738247296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738247296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.268960636199869, - 0.2234285580503567, - 0.5468300987692021, - -0.07598922426224614, - 0.2314838962751658, - 0.01035784318060333, - -0.08314304549672957, - -0.04624738986383844, - 0.05377747860630284, - -0.001074456865203822, - -0.02151604922154927, - -0.01446679290684195, - 0.008416712252875694, - -0.009228184118107326, - 0.005277266362275169, - 0.01142201731157229, - 0.01681398796325401, - 0.009993706195866578, - 0.001370286955930781, - -0.008399573830195455, - -0.005099919856215084, - 0.005334309041669094, - -0.001419513324650316, - -0.003333508834690296, - 0.0002887180426140212, - -0.0001690909516323616, - -0.001592036575525169, - -4.507713399549196e-05, - 0.005287560419413426, - 0.001265480827581528, - -0.001229918688675425, - 0.001129035262308468, - -0.002142778995712242, - -0.001748186446934164, - 0.000763477629872682, - 0.0006002693299791978, - -0.0003618301004192371, - 0.000988040168005559, - 0.0007880569343915778, - -0.001135722890360471, - -0.0008706368325040781, - 0.0005507322770281398, - 0.0009555809731928289, - -0.0001476990895937402, - -0.001054028588515068, - -1.482885559572655e-05, - -0.0001592869344899095, - -0.0004579572172035079, - 0.0006274586578504227, - 0.0005393401407410331, - -3.182089243244368e-05, - 0.7629396044020591, - 0.189701305549749, - 0.2946730680990991, - -0.1569360429309221, - -0.08805875862294558, - -0.03077704895086764, - 0.1149783480591024, - 0.1301411562027019, - -0.001461622206151801, - 0.04030157913855995, - 0.0006901390690664732, - -0.02740323125842794, - -0.02323299800745342, - 0.006389595554305861, - 0.003627095782551136, - -0.01015301262258172, - -0.00621023311542419, - -0.003238881121248944, - -0.006852312518149265, - 0.005609446955056436, - 0.004762124576622897, - 0.006665063843140196, - -6.70526269177163e-05, - -0.003587348009623233, - -0.00322170321999071, - -0.004203038352780501, - 0.0006017815497404605, - 0.001489961187320675, - 0.002190828148742953, - -0.001018226063168117, - -0.002311412742654803, - 0.0005349636274747352, - 0.0005836793424641873, - 0.0003330260000362103, - 0.0006191475972028521, - 0.0004562062905476333, - -0.0003998259903290102, - -0.001606870160409875, - -0.0001005634411503442, - 0.0003784623778643909, - 0.0003873441313675419, - 0.0004934685418203405, - 0.0004248568990090018, - -0.0001368925780341768, - -0.0005224641202364183, - 7.402330001924084e-06, - 0.0001942482764948633, - 3.004761739695799e-05, - 0.0001571480542442944, - -1.517325817427362e-05, - -0.0001596571201453762, - -0.004342453367498795, - -0.8322915538683627, - 0.01842619538559772, - -0.1445740110997678, - -0.03919221672360253, - 0.0181885023851906, - 0.007857938792447916, - -0.0008409533080505334, - 0.0679882056193599, - -0.008440199737942872, - -0.05052693032193879, - 0.0111459982531894, - -0.002854468104354866, - -0.01157234174126346, - -0.002254287431014864, - 0.01222589681633306, - 0.007524606302699996, - -0.006381505382857464, - 0.003239076046582923, - 0.00341366498860203, - -0.00384676331619515, - 0.0004019843766106519, - 0.003278371413101953, - -0.001659157168404143, - -0.008498109023400214, - -0.0005869360684358228, - 0.001643969359882166, - -0.001687685453312147, - 0.001913710312578008, - 0.00307704389234268, - -0.001526906838827543, - -0.002096608532065649, - 0.002116359835823416, - 0.0002080593023590777, - -0.001289011271870523, - 0.0003465163727308783, - 0.0003373949660992973, - -0.0005853247790129025, - -0.0007569823284455652, - -3.821511752005806e-05, - 0.0008610335506290439, - 0.0002833895542749826, - -4.205984435378816e-05, - 0.0001112528084110792, - -0.0002379239249443648, - -0.0002104661224579025, - 0.0001263747200842462, - -0.0001533284829536013, - 0.0001522993485716547, - 0.0003185888026784711, - -0.0001603437887349448 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier2": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738247296" - } - }, - "140342738367296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 651868.5693674 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current2": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 651868.5693674, - "dofs": { - "$type": "ref", - "value": "140342738367296" - } - }, - "Coil2": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "140342738366624": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738366624", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.8980851593547453, - 0.1942559921705813, - 0.3889755333770718, - -0.1446923384557668, - 0.2616477438027761, - 0.03731920597998046, - -0.03289705406442186, - 0.02547136484396155, - 0.0532217952204826, - 0.050428478861979, - -0.03624366941253683, - -0.005451626158324006, - -0.01668041626206209, - 0.008182439166261426, - 0.003842296843932926, - 0.01470476196344816, - 0.01901860245900076, - 0.0218942171541043, - -0.00945061997881808, - 0.002564135600286371, - -0.006766476390874592, - -0.001269140258791196, - 0.002139997339095541, - 0.001657675366985779, - 0.0002979912903074711, - 0.006328865782046154, - 0.0004567550240531948, - -0.0008525115686061069, - -0.000977103914377314, - 0.0005522046297053057, - -0.0009600861596635313, - -0.001340814451660981, - -0.001495132545615355, - 0.0006434008787568705, - 0.000495245187218385, - -0.00134743162348104, - 0.0002393656261548005, - 0.0003132890671380592, - 0.0006144326019911972, - -0.0005029044211924421, - -0.000783957033721161, - -0.0004002250154653492, - 0.0002391300413782915, - -0.0003806672575232206, - -0.000145466845504183, - -7.221379723120868e-05, - 0.0006927366534479363, - -0.0001275371930022123, - -0.0001401106599127933, - -0.0002158625680600062, - -7.139828388354475e-05, - 1.129181984052873, - 0.2708936854358476, - 0.468646640557997, - 0.02081652240284051, - -0.1928735276123626, - -0.03518255586981031, - 0.01192001522947444, - -0.06439441858177399, - -0.004172035660790115, - -0.016589458610143, - 0.001628354566592241, - 0.003299047220307412, - 0.02371335634022325, - -0.02489732104888577, - 0.01517053799913132, - -0.007490250276888437, - -0.02121728304870823, - -0.006509759115093021, - 0.002045879344162137, - 0.0002421911767798572, - 0.005286626183968976, - -0.002423351884665077, - 0.003037404376098953, - -0.001045524131070646, - -0.001371894636819662, - 0.0002683048956511064, - 0.0006396825080884871, - 0.0006110891778951719, - -0.001898949452431453, - -0.001413075309279682, - -0.000175565426273192, - 0.00025798969577147, - 0.001643409441239691, - 7.18696208370806e-05, - -0.0001583133254478763, - 0.001580406281910882, - -0.002161287927547965, - -0.0003891297580205399, - 0.0004807171148380796, - -0.0003779554431875909, - -0.000203599914921071, - 0.0002418121495980502, - -0.0001924002563136939, - 0.0004205862222447268, - -0.0003081775538974041, - -1.457104090324735e-05, - -0.0001305465480840895, - -2.931233724533855e-05, - 3.39235991969411e-05, - -8.787891234509293e-05, - -0.0002714497625897205, - 0.01443108431390148, - -0.5884600992390547, - 0.1639153375972931, - -0.02326901782799053, - -0.09503676743509344, - -0.001882227773385535, - -0.1358423641287697, - -0.04946480830906624, - 0.01080325660372903, - -0.004462853204566593, - 0.02204832208587066, - -0.01988057349197482, - 0.006713767349457029, - 0.009816410920710776, - -0.004595941635687146, - 0.01307328931917959, - 0.0183731152740804, - -0.002049019816619709, - -0.009421893063595877, - 0.0003683472428279665, - 0.005559370162880608, - -0.001158799750525409, - 0.002656529580593774, - 0.005458828901239469, - 0.003685058507882478, - 0.005539080181031877, - 0.0003319744004354147, - 0.003297209047830778, - -0.001172958360845208, - -6.403055114502017e-05, - -0.0028127900802783, - -7.412199662635927e-05, - -1.404234804116165e-06, - 0.002212349409834762, - 0.001726905111358576, - 0.0009310945379894919, - -0.0002426222281296402, - 0.0007504861042380895, - -0.001511448440947522, - -0.0002060956498950368, - -0.000206480198377301, - 8.668234567299965e-05, - 0.0001267761162311387, - 1.493158313140079e-05, - 0.0001119337013982711, - 0.0003201242558262467, - 0.00016404919743365, - -0.0002679743018523173, - -0.000169663995881007, - 0.0002693900147788098, - -0.0001731877336642894 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier3": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738366624" - } - }, - "140342738367776": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367776", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 537743.5886473 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current3": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 537743.5886473, - "dofs": { - "$type": "ref", - "value": "140342738367776" - } - }, - "Coil3": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve1": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent1": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil4": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve1" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent1" - } - }, - "RotatedCurve2": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent2": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil5": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve2" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent2" - } - }, - "RotatedCurve3": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent3": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil6": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve3" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent3" - } - }, - "RotatedCurve4": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil7": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve4" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve5": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil8": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve5" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve6": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil9": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve6" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve7": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent4": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil10": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve7" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent4" - } - }, - "RotatedCurve8": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent5": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil11": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve8" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent5" - } - }, - "RotatedCurve9": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent6": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil12": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve9" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent6" - } - }, - "RotatedCurve10": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil13": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve10" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve11": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil14": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve11" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve12": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil15": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve12" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve13": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent7": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil16": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil16", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve13" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent7" - } - }, - "RotatedCurve14": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent8": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil17": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil17", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve14" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent8" - } - }, - "RotatedCurve15": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent9": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil18": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil18", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve15" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent9" - } - }, - "BiotSavart1": { - "@module": "simsopt.field.biotsavart", - "@class": "BiotSavart", - "@name": "BiotSavart1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "coils": [ - { - "$type": "ref", - "value": "Coil1" - }, - { - "$type": "ref", - "value": "Coil2" - }, - { - "$type": "ref", - "value": "Coil3" - }, - { - "$type": "ref", - "value": "Coil4" - }, - { - "$type": "ref", - "value": "Coil5" - }, - { - "$type": "ref", - "value": "Coil6" - }, - { - "$type": "ref", - "value": "Coil7" - }, - { - "$type": "ref", - "value": "Coil8" - }, - { - "$type": "ref", - "value": "Coil9" - }, - { - "$type": "ref", - "value": "Coil10" - }, - { - "$type": "ref", - "value": "Coil11" - }, - { - "$type": "ref", - "value": "Coil12" - }, - { - "$type": "ref", - "value": "Coil13" - }, - { - "$type": "ref", - "value": "Coil14" - }, - { - "$type": "ref", - "value": "Coil15" - }, - { - "$type": "ref", - "value": "Coil16" - }, - { - "$type": "ref", - "value": "Coil17" - }, - { - "$type": "ref", - "value": "Coil18" - } - ], - "points": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - [ - 1.6823511299700216, - 0.0, - 0.0 - ], - [ - 1.6656243294316084, - 0.01324928335501738, - -0.1436839017943719 - ], - [ - 1.6194177686194065, - 0.028306129741135014, - -0.27362059857069243 - ], - [ - 1.5544014364243677, - 0.04608886475724044, - -0.3758869285011543 - ], - [ - 1.4888818654508216, - 0.0634560830694565, - -0.43754665096222073 - ], - [ - 1.4434380727537952, - 0.0751922192945975, - -0.45303149709668017 - ], - [ - 1.430923947356372, - 0.07607729578769809, - -0.4235802861290252 - ], - [ - 1.4575974520412909, - 0.06158076713545835, - -0.34266481994691295 - ], - [ - 1.5089652197425227, - 0.03364463030437447, - -0.19726760909532678 - ], - [ - 1.5366061510061466, - 1.2047891156701813e-17, - -7.292015238373829e-17 - ], - [ - 1.5089652197425227, - -0.03364463030437445, - 0.19726760909532665 - ], - [ - 1.4575974520412909, - -0.061580767135458306, - 0.3426648199469127 - ], - [ - 1.4309239473563724, - -0.07607729578769808, - 0.4235802861290251 - ], - [ - 1.4434380727537952, - -0.0751922192945975, - 0.45303149709668017 - ], - [ - 1.4888818654508216, - -0.06345608306945655, - 0.43754665096222073 - ], - [ - 1.5544014364243677, - -0.046088864757240486, - 0.3758869285011545 - ], - [ - 1.6194177686194062, - -0.028306129741135038, - 0.2736205985706926 - ], - [ - 1.6656243294316084, - -0.013249283355017403, - 0.14368390179437224 - ], - [ - 1.6670743875766918, - 0.1909979328233626, - -0.0037708288399925555 - ], - [ - 1.6585704359902427, - 0.20392683893274668, - -0.14514812826851653 - ], - [ - 1.6211062040379558, - 0.2157768690943609, - -0.27193361453873316 - ], - [ - 1.5645274184863547, - 0.22801376561775782, - -0.36949762442372314 - ], - [ - 1.5070346878552976, - 0.23832639206624925, - -0.42458495033554017 - ], - [ - 1.467859007520592, - 0.24269445433360987, - -0.43245417646208834 - ], - [ - 1.458125324532024, - 0.23706772539873155, - -0.39383424098502084 - ], - [ - 1.4808653410262633, - 0.21851764104626684, - -0.3006338379781224 - ], - [ - 1.5156612566331042, - 0.1892307761151738, - -0.14403384664088525 - ], - [ - 1.5162209280826306, - 0.15434743013848548, - 0.054045859088592475 - ], - [ - 1.4655391616826403, - 0.11870499964150558, - 0.23930140800413924 - ], - [ - 1.4048847008539083, - 0.09102748279503277, - 0.3679646609433889 - ], - [ - 1.3788296947636296, - 0.08073901442414565, - 0.4356347269694033 - ], - [ - 1.3960298263348212, - 0.08828133625868456, - 0.4566002588339094 - ], - [ - 1.4479886485184403, - 0.10741096922639394, - 0.435388594866656 - ], - [ - 1.5201293505524922, - 0.13171389542317846, - 0.3702162215626687 - ], - [ - 1.5911869669467333, - 0.15533005380942277, - 0.26705037361795647 - ], - [ - 1.643459323699208, - 0.17506188805358308, - 0.13812438882187442 - ], - [ - 1.6223343766610094, - 0.3760666961869454, - -0.006996117210326947 - ], - [ - 1.6215602506067477, - 0.39127918612964147, - -0.14187624514639746 - ], - [ - 1.5937778276800012, - 0.4022204341560822, - -0.26192653838655844 - ], - [ - 1.547405364396518, - 0.40984058406999047, - -0.3518959563374569 - ], - [ - 1.4988992536633032, - 0.41313073695760383, - -0.39806561675468505 - ], - [ - 1.4651230920322045, - 0.40981523348258236, - -0.3970392571293972 - ], - [ - 1.4554322706618772, - 0.39712470575748343, - -0.349137309846548 - ], - [ - 1.4689152748921956, - 0.37289636639682977, - -0.24627468632240243 - ], - [ - 1.482287064299522, - 0.33884896606456194, - -0.08700322380082882 - ], - [ - 1.4579550478689747, - 0.29961997095143683, - 0.09974053964290322 - ], - [ - 1.3926602615322687, - 0.2615348094065577, - 0.26456369379857386 - ], - [ - 1.3299184223580387, - 0.2351098190900006, - 0.37418459172037816 - ], - [ - 1.3077813398027924, - 0.22954196446363426, - 0.4291634819636824 - ], - [ - 1.3306985607771713, - 0.24388703918913554, - 0.44301354191712133 - ], - [ - 1.3883424991507276, - 0.27048292176420413, - 0.41821379674094933 - ], - [ - 1.4648335787081588, - 0.30171060012077816, - 0.35259458186831877 - ], - [ - 1.5389471422933, - 0.3312621391962402, - 0.25251064667251394 - ], - [ - 1.59405244410479, - 0.3560545745229173, - 0.12887570296370515 - ], - [ - 1.5516460607446305, - 0.5506602781324357, - -0.009310300831525415 - ], - [ - 1.556285343637364, - 0.5690052700228216, - -0.13408677227519436 - ], - [ - 1.537081691001489, - 0.5806744252726596, - -0.2446786542055186 - ], - [ - 1.5011908633764435, - 0.5853035479135681, - -0.3247738067251294 - ], - [ - 1.461449103059182, - 0.5820412376902653, - -0.36020673836507855 - ], - [ - 1.431365541714213, - 0.5701066217878815, - -0.349678115534443 - ], - [ - 1.4184999916707564, - 0.5482548424483984, - -0.2937386920748534 - ], - [ - 1.4187921763719191, - 0.5152620791431418, - -0.18659869165296264 - ], - [ - 1.4106657614421236, - 0.4739347499901897, - -0.035152836140159065 - ], - [ - 1.3685761572422226, - 0.43043748879337307, - 0.13000374053050842 - ], - [ - 1.2983599222071058, - 0.39204397672754443, - 0.27018381204713837 - ], - [ - 1.2397930001492081, - 0.3688893752879442, - 0.36161896625135137 - ], - [ - 1.2240306682379833, - 0.3689319879470208, - 0.4061246748916627 - ], - [ - 1.2526853088312475, - 0.39003056368573435, - 0.41489539020365374 - ], - [ - 1.3141494272086112, - 0.42373158267757965, - 0.38843531227206524 - ], - [ - 1.3921656932326467, - 0.46172293145377946, - 0.32492307011746846 - ], - [ - 1.466256981487665, - 0.49704199322115616, - 0.23131662840489203 - ], - [ - 1.521285522504285, - 0.5265571960190064, - 0.11666942508337104 - ], - [ - 1.46007180764826, - 0.713442631207463, - -0.010839611828941245 - ], - [ - 1.4676587643043257, - 0.7336265945817245, - -0.12327103183995841 - ], - [ - 1.4548128511288114, - 0.7460459326817379, - -0.22220193711614222 - ], - [ - 1.4272212876376031, - 0.7483716188103139, - -0.2900175830435961 - ], - [ - 1.3935277928020133, - 0.7379707640719426, - -0.3135530087065599 - ], - [ - 1.3643545840588527, - 0.7153045404859985, - -0.2947617585192165 - ], - [ - 1.345913041956919, - 0.6819287043674273, - -0.23488545563136598 - ], - [ - 1.3325215720208576, - 0.6391143064899868, - -0.13135273555863794 - ], - [ - 1.3073837263495378, - 0.5918660777640088, - 0.002964056912448287 - ], - [ - 1.2564166366797433, - 0.547234767863363, - 0.14129973118074787 - ], - [ - 1.189631895998666, - 0.5117953934240059, - 0.2572233842201347 - ], - [ - 1.1400419153618035, - 0.4943139453868053, - 0.3335736662051312 - ], - [ - 1.1321189691027371, - 0.5008352441902544, - 0.37085625355592 - ], - [ - 1.1654986236156393, - 0.5280776526639489, - 0.37679323111096374 - ], - [ - 1.2285057322116786, - 0.5680886484244235, - 0.35025383377175817 - ], - [ - 1.305492574649259, - 0.6124978071915784, - 0.29089884066270466 - ], - [ - 1.377053066080424, - 0.6531906240670086, - 0.2061550486212699 - ], - [ - 1.4298129249509637, - 0.6866227867245536, - 0.10281020360038319 - ], - [ - 1.3515118400450052, - 0.8654321728485556, - -0.012210642520453233 - ], - [ - 1.360165778613561, - 0.8858111215889497, - -0.11100181336189875 - ], - [ - 1.3510418643458304, - 0.8974673341517525, - -0.19596530031753703 - ], - [ - 1.3277175292736865, - 0.8952767260554777, - -0.24962320943786165 - ], - [ - 1.2959951123799045, - 0.874691771388772, - -0.262608657869608 - ], - [ - 1.265472684859396, - 0.8389927620531274, - -0.23993961645762463 - ], - [ - 1.2412784703481436, - 0.7940219758927846, - -0.1824166797710812 - ], - [ - 1.2172484291855559, - 0.7437990455468149, - -0.08999692297304633 - ], - [ - 1.1822612975093156, - 0.6948017005340916, - 0.02224026311313613 - ], - [ - 1.1305828818325787, - 0.6535820063604789, - 0.13448021363097176 - ], - [ - 1.0727381237542686, - 0.6246880905368895, - 0.23022152778276328 - ], - [ - 1.0345417908607721, - 0.6147560408761562, - 0.2956730951050242 - ], - [ - 1.0344586939531675, - 0.6278376749257082, - 0.32890182895815023 - ], - [ - 1.071013463708978, - 0.6603141044108393, - 0.33381160958331946 - ], - [ - 1.1336250496814693, - 0.7056885424718883, - 0.30852029373167644 - ], - [ - 1.2074775631278702, - 0.7557464059537468, - 0.25479905750289744 - ], - [ - 1.2743339093671815, - 0.8010708062268455, - 0.17980476437393508 - ], - [ - 1.3230242399218926, - 0.8374218561316996, - 0.08828498388920031 - ], - [ - 1.2284378631116122, - 1.006709948293738, - -0.013529535200276758 - ], - [ - 1.236102950163345, - 1.0258295974722231, - -0.09799181414459161 - ], - [ - 1.227535948852175, - 1.0335391913624303, - -0.16770515402381425 - ], - [ - 1.2045001607897923, - 1.0220215414783167, - -0.2084343784698062 - ], - [ - 1.172267547143265, - 0.9876719493268439, - -0.21587967688742835 - ], - [ - 1.1403405033884342, - 0.9387661309758862, - -0.1952241648836396 - ], - [ - 1.1122487389129805, - 0.8848297134383258, - -0.14540665717224754 - ], - [ - 1.0823704380401167, - 0.8313599141190574, - -0.06842882836138325 - ], - [ - 1.0448664052199366, - 0.7855861305560277, - 0.021744812404612453 - ], - [ - 0.9985031821695326, - 0.7524686031107077, - 0.11298079588486422 - ], - [ - 0.9520084165563445, - 0.733182482309973, - 0.19453074153263378 - ], - [ - 0.9250942875518646, - 0.7318639415416757, - 0.2531383764310293 - ], - [ - 0.9317110056264915, - 0.7514171283133536, - 0.28457887122983416 - ], - [ - 0.9701512465111527, - 0.7886761549469881, - 0.28991190592638616 - ], - [ - 1.031101059933968, - 0.8385019338892936, - 0.26742500552108184 - ], - [ - 1.1001992386461583, - 0.8927161838047115, - 0.22038555953656397 - ], - [ - 1.1605506729118513, - 0.9409851406459288, - 0.154784042041404 - ], - [ - 1.2034656510082307, - 0.9787215506863501, - 0.07420499752637626 - ], - [ - 1.0933720887900484, - 1.1369037923354783, - -0.013112496993122674 - ], - [ - 1.0971055897265614, - 1.1520751045634454, - -0.08412421025936163 - ], - [ - 1.0858420683069347, - 1.1510581328419611, - -0.1412002266764009 - ], - [ - 1.0612111134709985, - 1.1257076957260874, - -0.17479861325275103 - ], - [ - 1.028853911299876, - 1.0765718956391888, - -0.183250594739715 - ], - [ - 0.9971284542332866, - 1.0166941163029852, - -0.16894117794278207 - ], - [ - 0.9677143154642579, - 0.9574642429595064, - -0.1293952600987554 - ], - [ - 0.9364739749261307, - 0.9052513829561364, - -0.06830553906351482 - ], - [ - 0.9016307846409007, - 0.8673712537815074, - 0.003735069950658553 - ], - [ - 0.863607262665753, - 0.8458142590235722, - 0.08082499134573345 - ], - [ - 0.8285713946775775, - 0.8378198831671338, - 0.15374965398211712 - ], - [ - 0.8116980963702448, - 0.845705592532285, - 0.20841542718182002 - ], - [ - 0.823907040135387, - 0.8720679205551519, - 0.23974690143778424 - ], - [ - 0.863441694443935, - 0.9141802098351967, - 0.24735597419777697 - ], - [ - 0.9218318691524919, - 0.9677153860880974, - 0.22967899069387682 - ], - [ - 0.9852160561751789, - 1.0244478659581238, - 0.19030095496673224 - ], - [ - 1.0381538942316293, - 1.0735223611291034, - 0.13360452870438777 - ], - [ - 1.0739951246870143, - 1.1106186415992958, - 0.06282875908717728 - ], - [ - 0.9464976313884446, - 1.2562025010484825, - -0.008530111820960177 - ], - [ - 0.9434962713258178, - 1.2625778554869702, - -0.07025848644378009 - ], - [ - 0.9283310279573187, - 1.2482928555911044, - -0.121848272611851 - ], - [ - 0.9032043614585116, - 1.2078283923374002, - -0.15593824832061062 - ], - [ - 0.8728011034895298, - 1.145850152352009, - -0.1702273700667534 - ], - [ - 0.843196556516351, - 1.0780069894683257, - -0.1642272892466967 - ], - [ - 0.8149834854523267, - 1.0169033130549567, - -0.13525307298602218 - ], - [ - 0.7857770655242343, - 0.9697891764236966, - -0.0874350264313162 - ], - [ - 0.7560880741494052, - 0.9429003816469205, - -0.027406160578747257 - ], - [ - 0.726724649551588, - 0.9344464757903965, - 0.04196384754346673 - ], - [ - 0.702150362603417, - 0.9383409081938053, - 0.11018893332716606 - ], - [ - 0.6943729515758192, - 0.9559645057155431, - 0.16310918653568157 - ], - [ - 0.7116269730709063, - 0.9897401498992222, - 0.1964965476907892 - ], - [ - 0.7516314223017545, - 1.036865062806896, - 0.20881316980044454 - ], - [ - 0.8065466588187717, - 1.0935490342576566, - 0.19790304179814464 - ], - [ - 0.8633850646738448, - 1.1517752014822356, - 0.1669610069434356 - ], - [ - 0.9081220817466271, - 1.2003021946674377, - 0.11894220918114103 - ], - [ - 0.935359055748825, - 1.2348278312001308, - 0.05727758355228221 - ], - [ - 0.7860552663004561, - 1.3614876587894733, - -3.3939822855268905e-18 - ], - [ - 0.776443372077041, - 1.3545604289713788, - -0.05998148596525217 - ], - [ - 0.759364903953762, - 1.3257396805421724, - -0.11414035638602617 - ], - [ - 0.7362692927306436, - 1.2723479488714893, - -0.1540805256944155 - ], - [ - 0.7097174719558952, - 1.2007471063391761, - -0.17639386833536636 - ], - [ - 0.6837342566968659, - 1.12775227463687, - -0.1791394964149477 - ], - [ - 0.6587498412653043, - 1.0673536660187912, - -0.15956493101872343 - ], - [ - 0.6336306446150545, - 1.0275264135343338, - -0.12095477636364205 - ], - [ - 0.6095865234045647, - 1.0128777760884076, - -0.06680712550294271 - ], - [ - 0.5877653830938002, - 1.018039506448647, - -9.678477605874886e-18 - ], - [ - 0.5723846233189652, - 1.0343563031171938, - 0.06680712550294267 - ], - [ - 0.5730486548727206, - 1.0625034416201136, - 0.12095477636364202 - ], - [ - 0.5949804689620726, - 1.1041709302841156, - 0.15956493101872346 - ], - [ - 0.6347949906627818, - 1.1560073730555913, - 0.17913949641494775 - ], - [ - 0.6850187616324339, - 1.215006913393063, - 0.17639386833536636 - ], - [ - 0.733750999810412, - 1.273801885966883, - 0.1540805256944156 - ], - [ - 0.7684417901777069, - 1.320499137837374, - 0.11414035638602622 - ], - [ - 0.7848620564118407, - 1.3496998993044598, - 0.05998148596525228 - ], - [ - 0.6146544625113118, - 1.4477922439284334, - 0.008530111820960154 - ], - [ - 0.6017127432449437, - 1.427458619538373, - -0.057277583552282074 - ], - [ - 0.5854311519269024, - 1.3866078898639067, - -0.11894220918114093 - ], - [ - 0.5657740515956343, - 1.3236009999967382, - -0.16696100694343544 - ], - [ - 0.5437679145416845, - 1.245264413003345, - -0.19790304179814447 - ], - [ - 0.5221357735364426, - 1.169364437399397, - -0.20881316980044443 - ], - [ - 0.5013266264226919, - 1.1111571116472405, - -0.19649654769078903 - ], - [ - 0.4807030712779854, - 1.0793268686232131, - -0.16310918653568152 - ], - [ - 0.46155188260428887, - 1.0772505053879167, - -0.11018893332716598 - ], - [ - 0.4458920617355301, - 1.0965852459632168, - -0.041963847543466645 - ], - [ - 0.4385316466695733, - 1.1262416705352973, - 0.027406160578747337 - ], - [ - 0.44697353033599296, - 1.1653974886670242, - 0.08743502643131623 - ], - [ - 0.4731723595719894, - 1.2142480585939786, - 0.13525307298602215 - ], - [ - 0.5119831600785785, - 1.2692331330608837, - 0.16422728924669674 - ], - [ - 0.5559347891223445, - 1.3287930042490277, - 0.17022737006675343 - ], - [ - 0.5944078904470508, - 1.3861121180006732, - 0.15593824832061062 - ], - [ - 0.6168878103258569, - 1.428104681127912, - 0.121848272611851 - ], - [ - 0.6216763614444855, - 1.4483806670875385, - 0.0702584864437802 - ], - [ - 0.43790152142636823, - 1.515339900848776, - 0.013112496993122672 - ], - [ - 0.424826395198048, - 1.4854163823192386, - -0.06282875908717714 - ], - [ - 0.41062068915264116, - 1.435828826006886, - -0.13360452870438774 - ], - [ - 0.39458984868490143, - 1.3654460658430838, - -0.19030095496673213 - ], - [ - 0.37715017340911267, - 1.2821875097481994, - -0.2296789906938767 - ], - [ - 0.35998243813230174, - 1.2048525469927271, - -0.24735597419777697 - ], - [ - 0.3432794529585379, - 1.149558387391666, - -0.23974690143778427 - ], - [ - 0.3265534790704079, - 1.1258039679262442, - -0.20841542718182005 - ], - [ - 0.3112876052796598, - 1.1364738182234515, - -0.15374965398211712 - ], - [ - 0.30069300386464864, - 1.1708129578730688, - -0.08082499134573347 - ], - [ - 0.30035014796669457, - 1.21452079122387, - -0.0037350699506585932 - ], - [ - 0.3157337069879443, - 1.2636359437470888, - 0.06830553906351472 - ], - [ - 0.34533119988603966, - 1.3167973022776691, - 0.12939526009875532 - ], - [ - 0.3819187054799127, - 1.3718856303538278, - 0.16894117794278207 - ], - [ - 0.4179116549739691, - 1.4292995717882686, - 0.18325059473971503 - ], - [ - 0.4442859049989358, - 1.4818896309072989, - 0.17479861325275103 - ], - [ - 0.4539245501203542, - 1.5158958820726238, - 0.14120022667640098 - ], - [ - 0.44917351275627665, - 1.5261588636188328, - 0.08412421025936175 - ], - [ - 0.25761745790909, - 1.5672133705721962, - 0.013529535200276756 - ], - [ - 0.24586490062156324, - 1.5315926016982804, - -0.07420499752637601 - ], - [ - 0.2346416999271219, - 1.4755589354437526, - -0.1547840420414038 - ], - [ - 0.22301527422129952, - 1.3991585817942276, - -0.22038555953656377 - ], - [ - 0.21061344590352435, - 1.3122106787165242, - -0.26742500552108167 - ], - [ - 0.19793796228754773, - 1.2345137024652915, - -0.28991190592638616 - ], - [ - 0.18489081914486982, - 1.1825939640147642, - -0.2845788712298341 - ], - [ - 0.1712656217129683, - 1.167087124686619, - -0.2531383764310294 - ], - [ - 0.15895044701199929, - 1.1910547145093788, - -0.19453074153263372 - ], - [ - 0.15240533475929696, - 1.24096342307377, - -0.11298079588486423 - ], - [ - 0.1579043433122704, - 1.2976739157594044, - -0.021744812404612502 - ], - [ - 0.17879358629509462, - 1.3530402527075607, - 0.06842882836138305 - ], - [ - 0.21016064040440507, - 1.4056505199450093, - 0.14540665717224738 - ], - [ - 0.2428250659433302, - 1.456946910386662, - 0.19522416488363953 - ], - [ - 0.26921522515071117, - 1.5090494505215615, - 0.21587967688742826 - ], - [ - 0.2828465377402576, - 1.5541385088455595, - 0.2084343784698062 - ], - [ - 0.2813032211006035, - 1.579846911445834, - 0.16770515402381422 - ], - [ - 0.2703430162832379, - 1.583411355270458, - 0.09799181414459175 - ], - [ - 0.07373032691671205, - 1.603159673418703, - 0.012210642520453223 - ], - [ - 0.06371648113342322, - 1.5644835296608066, - -0.08828498388920009 - ], - [ - 0.05658071373893907, - 1.5041409415293385, - -0.179804764373935 - ], - [ - 0.05075680481079683, - 1.4235794471453374, - -0.2547990575028973 - ], - [ - 0.04433168009953454, - 1.334592362626493, - -0.30852029373167633 - ], - [ - 0.036342057042468165, - 1.2576819195725577, - -0.33381160958331946 - ], - [ - 0.02649402896203601, - 1.2097863455919686, - -0.32890182895815034 - ], - [ - 0.015123453098310279, - 1.2033174926001544, - -0.29567309510502426 - ], - [ - 0.004626693969405571, - 1.2413625120476963, - -0.2302215277827633 - ], - [ - 0.0007271800482880897, - 1.3059044999310727, - -0.1344802136309718 - ], - [ - 0.010585274500493735, - 1.371269167821265, - -0.022240263113136247 - ], - [ - 0.035524654161382514, - 1.4260675851648021, - 0.08999692297304608 - ], - [ - 0.06700396711219482, - 1.4719896764385738, - 0.18241667977108103 - ], - [ - 0.09385270309958338, - 1.5154278739100997, - 0.2399396164576246 - ], - [ - 0.10950773831393501, - 1.5597105761958518, - 0.26260865786960796 - ], - [ - 0.11147362354416233, - 1.59747547242866, - 0.24962320943786165 - ], - [ - 0.10170857826920014, - 1.6187702431756545, - 0.1959653003175371 - ], - [ - 0.08705204494403643, - 1.6208436784320592, - 0.11100181336189893 - ], - [ - -0.11217646105565429, - 1.6211805923765907, - 0.010839611828941248 - ], - [ - -0.12027368635475362, - 1.5815657090291442, - -0.10281020360038286 - ], - [ - -0.12284685908437128, - 1.5191582496184026, - -0.2061550486212697 - ], - [ - -0.12230762653445937, - 1.436838637694, - -0.29089884066270444 - ], - [ - -0.12227366496872163, - 1.347961497002328, - -0.350253833771758 - ], - [ - -0.12542064942998463, - 1.2733902424589156, - -0.3767932311109637 - ], - [ - -0.13232343997202534, - 1.2308614094443469, - -0.37085625355592 - ], - [ - -0.1419325235310146, - 1.2344622327757933, - -0.3335736662051313 - ], - [ - -0.15158813575429242, - 1.2861491397990947, - -0.25722338422013474 - ], - [ - -0.15428910753611896, - 1.3617061090337421, - -0.14129973118074796 - ], - [ - -0.14112080419288112, - 1.4281605583950667, - -0.002964056912448443 - ], - [ - -0.11277156066802652, - 1.4735546857058313, - 0.13135273555863758 - ], - [ - -0.08238893942645907, - 1.5065592378031964, - 0.2348854556313657 - ], - [ - -0.0627053885261971, - 1.539217999807717, - 0.2947617585192163 - ], - [ - -0.05766246746449162, - 1.5758158514821723, - 0.3135530087065598 - ], - [ - -0.06550181045778522, - 1.6101957013212582, - 0.29001758304359615 - ], - [ - -0.08131169547196528, - 1.6329278531704878, - 0.2222019371161423 - ], - [ - -0.09849011435252202, - 1.637843071265286, - 0.12327103183995862 - ], - [ - -0.29893724065462124, - 1.61909504535312, - 0.009310300831525413 - ], - [ - -0.3046308529541804, - 1.580750506907697, - -0.11666942508337073 - ], - [ - -0.30267749786665843, - 1.5183367910551855, - -0.2313166284048919 - ], - [ - -0.2962190584675292, - 1.4365123223435357, - -0.3249230701174683 - ], - [ - -0.2901123986197353, - 1.349952579670216, - -0.3884353122720652 - ], - [ - -0.2885662780114134, - 1.2798725822382826, - -0.41489539020365374 - ], - [ - -0.29251086028817713, - 1.2445076476788457, - -0.4061246748916628 - ], - [ - -0.30042892988907277, - 1.2581369212073106, - -0.3616189662513515 - ], - [ - -0.309659917856824, - 1.3204346642507132, - -0.27018381204713854 - ], - [ - -0.31151827858487047, - 1.4004404635821377, - -0.13000374053050848 - ], - [ - -0.2948933474933307, - 1.4586397606528925, - 0.035152836140158954 - ], - [ - -0.2631660380412107, - 1.4863411070002646, - 0.18659869165296233 - ], - [ - -0.23444737452723016, - 1.502584449279089, - 0.2937386920748532 - ], - [ - -0.22195595352307404, - 1.524652232120124, - 0.349678115534443 - ], - [ - -0.22666205363968442, - 1.5566726684323662, - 0.36020673836507855 - ], - [ - -0.24370769026990918, - 1.5927211975698783, - 0.3247738067251295 - ], - [ - -0.2656620418866925, - 1.6214890047355617, - 0.2446786542055187 - ], - [ - -0.2853696530916943, - 1.6322852781387631, - 0.1340867722751946 - ], - [ - -0.485483875915325, - 1.593016131714699, - 0.006996117210326968 - ], - [ - -0.4886739153818886, - 1.5585171988208806, - -0.12887570296370482 - ], - [ - -0.4825921432907288, - 1.4983983899055837, - -0.2525106466725137 - ], - [ - -0.4711277450584367, - 1.4194383915381266, - -0.35259458186831844 - ], - [ - -0.4599261680377236, - 1.3375813343002074, - -0.4182137967409493 - ], - [ - -0.4541369087970228, - 1.2743622780069888, - -0.44301354191712117 - ], - [ - -0.45510149744130357, - 1.2473428450962845, - -0.4291634819636824 - ], - [ - -0.4613481351679148, - 1.269298048267984, - -0.3741845917203783 - ], - [ - -0.4698343418461336, - 1.3368465700313035, - -0.26456369379857403 - ], - [ - -0.46949901760938717, - 1.412436094506008, - -0.0997405396429035 - ], - [ - -0.4476917194917589, - 1.4531227364167247, - 0.08700322380082849 - ], - [ - -0.41151991116753317, - 1.4585661272620587, - 0.24627468632240204 - ], - [ - -0.38379605167453734, - 1.4590036727595965, - 0.3491373098465476 - ], - [ - -0.3776511429623345, - 1.4737414341123867, - 0.39703925712939697 - ], - [ - -0.3916679135421797, - 1.5046501998647581, - 0.398065616754685 - ], - [ - -0.4187703248917948, - 1.5450126475546964, - 0.35189595633745696 - ], - [ - -0.4485557999396267, - 1.5813623038372995, - 0.26192653838655855 - ], - [ - -0.47192241014300407, - 1.5999519638573252, - 0.14187624514639774 - ], - [ - -0.6681281318929996, - 1.539227736051482, - 0.0037708288399925733 - ], - [ - -0.6701216195607328, - 1.510808468436699, - -0.13812438882187397 - ], - [ - -0.661073710903202, - 1.4556733624512928, - -0.2670503736179562 - ], - [ - -0.6459970958083661, - 1.3823275823283885, - -0.37021622156266837 - ], - [ - -0.6309736962640538, - 1.307700438621663, - -0.4353885948666558 - ], - [ - -0.6215610332873529, - 1.2531379621760759, - -0.4566002588339093 - ], - [ - -0.6194928098139859, - 1.2344710503697196, - -0.43563472696940353 - ], - [ - -0.6236102378839042, - 1.2621795817251027, - -0.36796466094338925 - ], - [ - -0.629968035595553, - 1.3285466440788694, - -0.23930140800413952 - ], - [ - -0.6244416685325426, - 1.3902595565384197, - -0.05404585908859285 - ], - [ - -0.5939519690229655, - 1.4072165398337013, - 0.14403384664088487 - ], - [ - -0.551190842192015, - 1.391725825435784, - 0.30063383797812193 - ], - [ - -0.5237559896533167, - 1.3813074356455282, - 0.3938342409850205 - ], - [ - -0.523749940949787, - 1.3925504168534517, - 0.43245417646208817 - ], - [ - -0.5471206340059863, - 1.424293520100165, - 0.4245849503355401 - ], - [ - -0.5847979958056476, - 1.46892737213535, - 0.3694976244237233 - ], - [ - -0.6236848518341912, - 1.5118075894766099, - 0.2719336145387332 - ], - [ - -0.6526793949659047, - 1.5383275509997565, - 0.1451481282685168 - ] - ] - } - }, - "140342738037920": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738037920", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.4493535496003798, - 0.08325147988782641, - -0.0011494991500039988, - -0.00041319079884620454, - -6.155927889576924e-05, - -5.332073531606106e-05, - 4.239962021934183e-05, - 0.147989354758979, - -0.05683903073857911, - 0.0004295280569777099, - 0.0004773732328517161, - 2.792777478429475e-05, - -0.00013257924732847345, - -2.470062519829713e-05, - 0.032270038271179774, - 0.03307289504821164, - 0.008451927113977156, - -0.0009216105986820785, - -5.7453232240979744e-05, - -5.0037052279139516e-05, - 1.8975990502208598e-05, - -0.009708703356894355, - -0.005154415297131473, - -0.0019409541906424913, - -0.0002684008808912313, - 0.00021506813814514938, - -1.1333901816291265e-05, - 4.0629387826377814e-07, - 0.001193158834728476, - 0.0028335790313630997, - 0.0008666212640681613, - 2.572577832344851e-05, - 0.00017847212785997285, - -3.685344378884824e-06, - -1.3081674898566334e-06, - -0.0009552839550063532, - -0.0007106602283719055, - -0.0004760891472440242, - -4.265161945565775e-05, - 1.3406227566167038e-05, - -2.6998181636485175e-05, - 1.1226368951627446e-05, - 0.0004009932372981402, - -4.6685146316322666e-06, - 0.0001246078196868825, - 9.332760192948551e-05, - 1.6570443321182836e-05, - -1.4987566058863372e-06, - 2.1504465796822353e-06, - 0.12955397842317515, - 0.0006486800050074572, - -0.00015485403654202644, - -9.700366645264526e-05, - -1.4623291276584433e-05, - -2.2004588728503653e-05, - -0.02823148475141716, - -0.007141640393643781, - 0.0011961216040503938, - -6.839701641414605e-05, - 1.3906053679200137e-05, - -1.70746478216404e-05, - 0.005374337737530619, - 0.002505578592565698, - 0.000671636654113925, - -0.00015266273024483232, - -2.6252754132296384e-06, - -8.611853961489912e-06, - -0.0014885506315896002, - -0.0009076093593669751, - 2.2864462477555485e-05, - -0.00022025733650921252, - 2.399533480222319e-05, - 5.561666007695647e-06, - 0.000288599204150171, - 0.0004744383094247833, - 0.00010597569908482235, - 1.537413197299124e-05, - 3.0252867369998624e-05, - -1.001584900990688e-05, - 7.631330028116267e-05, - -9.001136923494332e-05, - -0.00010653021723705718, - -2.185606243410953e-05, - 3.439517018268934e-06, - -2.766948549926675e-06, - -0.0274190782986448, - 0.0034212326837745333, - 0.00045675089193134347, - 7.552844625090575e-05, - -0.00012888435983663462, - -2.913190639510925e-05, - 0.026369234032602523, - -0.00022527451595417714, - -0.0006630945471038989, - 9.928164392893598e-05, - -9.895070073005569e-05, - 5.836700555699283e-05, - -0.01867606699728206, - -0.0010484407057275197, - 0.0006465688815920653, - 0.00015925079302565417, - -6.0220731852433096e-05, - -1.6745435395126382e-05, - 0.0014506197703188744, - 0.0011728439887011167, - -0.0001968099616707447, - -6.963216937847807e-05, - -2.7575314965798237e-05, - 2.0298185233279393e-05, - -0.0004678800796003005, - 1.9819890056919078e-05, - -1.598747362090031e-05, - 0.00010449800507656954, - 3.5313167649741656e-05, - 1.1627074541469276e-05, - 0.0001356755701469291, - 7.512298582643416e-05, - 6.411857481616069e-06, - 1.2163092653749355e-05, - -1.1773809024522087e-05, - -9.067691156922598e-06, - 3.157821568661448e-05, - -1.6630278869267405e-05, - -1.3863909779582313e-05, - 1.6940279036488818e-05, - 8.29563769859082e-06, - 6.982729196297152e-06, - 0.02688569303958676, - 0.046395638501152865, - -0.003030600587690146, - -0.00021989630441359318, - 0.0001125735382740016, - 4.298487202820317e-05, - 7.08887813194455e-05, - 0.0031123385307896033, - -0.018819968958826067, - -0.0013608676204555086, - 0.0001506316275099254, - 2.5956882426493875e-05, - 2.34549589355703e-05, - 9.846738568730781e-06, - -0.0014672716594779638, - 0.0008198808749199534, - 0.0009930261504175252, - -0.0006180875005689887, - -7.871214710591496e-05, - -1.2029364200514969e-05, - 3.7946761342429052e-06, - 0.0004082147792561953, - 0.000384099014174492, - -0.0002120611374988894, - -0.00020183578876873032, - 2.7137677382252443e-05, - 3.7281996718364064e-05, - 1.238434569431264e-05, - -0.00025204921146895743, - -7.313536701112505e-05, - 6.477166051328089e-05, - -4.861940970784689e-06, - 2.0179945437207578e-05, - -1.7552665402768574e-05, - -1.2736257322618096e-05, - 8.207017069967471e-05, - 0.0001168388170464562, - 2.9037579343171604e-05, - -2.2595077909890958e-05, - 3.766329786989072e-06, - 4.5194289123798055e-06, - 6.3628843016666744e-06, - 0.04701992770005098, - -0.0017961844930162887, - 0.0006821881870725348, - -2.7616701285037306e-05, - -3.512353613149333e-05, - 1.4343895082901577e-05, - -0.07427293732946055, - -0.0004504881347213861, - -0.00024336822246996066, - 0.000113859331819959, - 1.1489815883296356e-05, - -1.2642848429815675e-05, - 0.015089978402473272, - 0.00688386868578505, - -0.0014670738785944278, - -2.0452161120466673e-05, - 5.104214980089241e-06, - -1.1117198522838905e-05, - -0.002510146901066237, - -0.0024639947234872945, - -0.0006759483395403726, - 0.00020990911753752012, - 2.6982294437713682e-05, - 6.130115198277204e-06, - 0.0018771172979451297, - 0.001093804193476947, - -0.00013600521090708902, - 0.000196919422384342, - -3.431126559250331e-05, - -7.2702566183380945e-06, - 5.6836044180162034e-05, - -0.00044812938555360837, - -5.780963617524435e-05, - 9.73209437525741e-06, - -2.7833801897773328e-05, - 9.202520758695822e-06, - -0.0005080385385322326, - 0.00011569066264907672, - 9.681887669242846e-05, - 1.6239602848207794e-05, - -6.9855648809125325e-06, - 4.0353508510655934e-06, - -0.3198481608452442, - -0.14108529973154624, - -0.002308365218503719, - 0.00044984158184431636, - 9.314143391675952e-05, - -2.2614412307898978e-05, - 1.9213211978934572e-05, - 0.011907317261862269, - 0.01546505667551466, - 0.006620347901938856, - -0.0008053940210493824, - -0.00012255309743329596, - 3.489197263065744e-05, - 1.9892470517015898e-05, - -0.0051682983075053, - -0.005384843223051991, - -0.002122928346874864, - -0.000443166388948808, - 0.0002520022345210494, - 2.483093528294158e-05, - 1.3914644792680282e-05, - 0.0018777902963215082, - 0.0026803740287078383, - 0.0010547921340934045, - -0.0001518385753927334, - 0.00014836916964325013, - -1.8655813556282743e-05, - -7.044940844641953e-06, - -0.00022891089684964596, - -0.0003605537753093528, - -0.0005192546944023529, - -2.4838439286763356e-05, - 2.2574845423083476e-05, - -2.8018991623479383e-05, - 9.369547200810535e-06, - 0.00013910408293547796, - -0.0003317722555313199, - 0.00011562779290535079, - 7.44284978050918e-05, - 1.0437652922335508e-05, - -5.5926765978954235e-06, - 2.449612536107737e-06 - ] - }, - "names": [ - "x0", - "x1", - "x2", - "x3", - "x4", - "x5", - "x6", - "x7", - "x8", - "x9", - "x10", - "x11", - "x12", - "x13", - "x14", - "x15", - "x16", - "x17", - "x18", - "x19", - "x20", - "x21", - "x22", - "x23", - "x24", - "x25", - "x26", - "x27", - "x28", - "x29", - "x30", - "x31", - "x32", - "x33", - "x34", - "x35", - "x36", - "x37", - "x38", - "x39", - "x40", - "x41", - "x42", - "x43", - "x44", - "x45", - "x46", - "x47", - "x48", - "x49", - "x50", - "x51", - "x52", - "x53", - "x54", - "x55", - "x56", - "x57", - "x58", - "x59", - "x60", - "x61", - "x62", - "x63", - "x64", - "x65", - "x66", - "x67", - "x68", - "x69", - "x70", - "x71", - "x72", - "x73", - "x74", - "x75", - "x76", - "x77", - "x78", - "x79", - "x80", - "x81", - "x82", - "x83", - "x84", - "x85", - "x86", - "x87", - "x88", - "x89", - "x90", - "x91", - "x92", - "x93", - "x94", - "x95", - "x96", - "x97", - "x98", - "x99", - "x100", - "x101", - "x102", - "x103", - "x104", - "x105", - "x106", - "x107", - "x108", - "x109", - "x110", - "x111", - "x112", - "x113", - "x114", - "x115", - "x116", - "x117", - "x118", - "x119", - "x120", - "x121", - "x122", - "x123", - "x124", - "x125", - "x126", - "x127", - "x128", - "x129", - "x130", - "x131", - "x132", - "x133", - "x134", - "x135", - "x136", - "x137", - "x138", - "x139", - "x140", - "x141", - "x142", - "x143", - "x144", - "x145", - "x146", - "x147", - "x148", - "x149", - "x150", - "x151", - "x152", - "x153", - "x154", - "x155", - "x156", - "x157", - "x158", - "x159", - "x160", - "x161", - "x162", - "x163", - "x164", - "x165", - "x166", - "x167", - "x168", - "x169", - "x170", - "x171", - "x172", - "x173", - "x174", - "x175", - "x176", - "x177", - "x178", - "x179", - "x180", - "x181", - "x182", - "x183", - "x184", - "x185", - "x186", - "x187", - "x188", - "x189", - "x190", - "x191", - "x192", - "x193", - "x194", - "x195", - "x196", - "x197", - "x198", - "x199", - "x200", - "x201", - "x202", - "x203", - "x204", - "x205", - "x206", - "x207", - "x208", - "x209", - "x210", - "x211", - "x212", - "x213", - "x214", - "x215", - "x216", - "x217", - "x218", - "x219", - "x220", - "x221", - "x222", - "x223", - "x224", - "x225", - "x226", - "x227", - "x228", - "x229", - "x230", - "x231", - "x232", - "x233", - "x234", - "x235", - "x236", - "x237", - "x238", - "x239", - "x240", - "x241", - "x242", - "x243", - "x244", - "x245", - "x246", - "x247", - "x248", - "x249", - "x250", - "x251", - "x252" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "SurfaceXYZTensorFourier1": { - "@module": "simsopt.geo.surfacexyztensorfourier", - "@class": "SurfaceXYZTensorFourier", - "@name": "SurfaceXYZTensorFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "nfp": 3, - "stellsym": true, - "mpol": 6, - "ntor": 6, - "clamped_dims": [ - false, - false, - false - ], - "quadpoints_phi": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.018518518518518517, - 0.037037037037037035, - 0.05555555555555555, - 0.07407407407407407, - 0.09259259259259259, - 0.1111111111111111, - 0.12962962962962962, - 0.14814814814814814, - 0.16666666666666666, - 0.18518518518518517, - 0.2037037037037037, - 0.2222222222222222, - 0.24074074074074073, - 0.25925925925925924, - 0.2777777777777778, - 0.2962962962962963, - 0.31481481481481477 - ] - }, - "quadpoints_theta": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.05555555555555555, - 0.1111111111111111, - 0.16666666666666666, - 0.2222222222222222, - 0.2777777777777778, - 0.3333333333333333, - 0.38888888888888884, - 0.4444444444444444, - 0.5, - 0.5555555555555556, - 0.611111111111111, - 0.6666666666666666, - 0.7222222222222222, - 0.7777777777777777, - 0.8333333333333333, - 0.8888888888888888, - 0.9444444444444444 - ] - }, - "dofs": { - "$type": "ref", - "value": "140342738037920" - } - }, - "Volume1": { - "@module": "simsopt.geo.surfaceobjectives", - "@class": "Volume", - "@name": "Volume1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "range": null, - "nphi": null, - "ntheta": null - }, - "BoozerSurface3": { - "@module": "simsopt.geo.boozersurface", - "@class": "BoozerSurface", - "@name": "BoozerSurface3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "biotsavart": { - "$type": "ref", - "value": "BiotSavart1" - }, - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "label": { - "$type": "ref", - "value": "Volume1" - }, - "targetlabel": -1.101084790730291, - "constraint_weight": 1000.0, - "reg": null - } - } -} \ No newline at end of file diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_2.vts b/examples/2_Intermediate/inputs/input_ncsx/surface_2.vts deleted file mode 100644 index c0b7ec8cd494476dc0abdb66cc76adbd7d948adc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31872 zcmbrGd00=;+wL2rNt)+*o;6Q~o>d}aq!3Y}Qlipmh!P2vAtVxINQHz35^E)zq?t|UVH7ep69+l_x@T9CypJJ@^kX?cJ**yBcruKQwEIL zR`0Ujyx#Swla$X%Pp369Rz6<7hkSg!oE*))TpeZp`{7atPx?67dw4lId99Jz;_Bmb z)M=f&qpO3vjFgL$1MR2w)Jb-3bobHMm7$&dzn@NOw~GhupPcYD-&zKL zzWnFl?XFIToTUE$f9>Jw?&D26&dkBb!NkkU;iQy>!!g>JJ^%cLjFg4%v4c)t+nm>W z9P{*Wr(MH)jf{@W-y2(h)WhLFgOYOg@H*x|yS#&^r<1#*6YU;7oSnU${xcvM4cgf? zw*R}%pKtziF{xcnhkQJ|Xs2`Zba9nBA?4`f;^gD-pE3X6WBKm~{EvrZU|^{GXH@^M z>-^8}SW8b&-|+u^e(DbY$2Xv@qob$&f6VKD?&HrS|L0l%=bQh<EoR`TJb{OuUo( zArD7a_rq&syd3;#^KE}Xg6_|+^_Hp&-90lv{po*yedqN}W!H-tP*L{B54;MXYh4E2 ze49J&FK}q!8=r=OsdoBP+%+Iu$4W+?1>mRtUyH6(PQm@uC+ip}C%iH-y~M3^5j%{r)D}G)hr$idavr?y1)aQrC9U+A@x*ukV=2!@ z!J1#C?zHF-EEZx9Dyw46pV~X*7j^+rktaRU(`RfYy+OD=Ued7RJQO^H# zSa=NBM>M)uo;Zhl>Swm?SNsi9qQ6%@D;Nj6fl$tpt=qC44zd-(^EOx}<1MeGG70m; ze~t&esJ^AQmezx+`cAqZ##6vbogY@SxU_r^D1(J(i{=)*(=bbo2SVg*0_L0Ez|#%h znO72~L6;go_$6@^L}zB>5&BI_ZHJ~IgSuZBiK|H}l&-{C2cD>vbxr@9AE2{t7*^qF z!U$dQSqPX018P3uw*uEH3x^J@zWmqfmvK|DeEpyK2gOC7mre;YFzveflBY}<@DwJc ztaAK}(@Z#I&Rw1Xv*Ool*NYTEbVG-?{;kjW!>=&e-^0_8RWewT$yN(pM@}{@Dt*TO zC3if+I;TL2zA9*wUMqb6c8M-WIS2ccX>%D(;v2)_$1;6W{Z(Vf?As zE&PaP(1}u*yuU&B@VO~?XS}ddc<~M16{W-dep@Q+;H#{WWSNG{Q>E%PcQf$rw~wBg z6n(;}!MSCE7Sj;Nzr5v(Wfo@h>2>A_ti)<{B};NPO@q1qt#S6okNB#L@v!^)CM?_& znf_{U3JS}ZVi(U6Y+kdc<T-H{}o4W%jt@-9|q0# zo|X?sMqsmV-ee8WXWY|-jM~!rLCmDLnSOc{eEd=kytFV5YAcA!+|mu2SIcu(>W_ol zGs)R4h9B{_dV*;+{OXMwheZuK27Gp8yzhM1g6stHr0jtFl%wT~<%AQRS`*cLMh+q*qaPL$^2o^b6;@>4H>(Z_*jf@=zl#!XLGGv?#I_E4L4 zFN^~P2O3UTOhHfX;M0wVitu&+5HD`~O1z}`-YqK0aY3;Ir&}Z`cy5}66$ZzR_X?I{f$+OrRgF{d#cRpF@#tp| zR^*x$y1WJphwbRwN?SMVmptjOYJ3OZzDcIqr`1@pZ@rw_=P8Idm^ECv@)ywS@UQg? z`H6qf*=IH{nS!^6Uiz10wL-heP=;V(6}~(oHP`WD0<0&`%qEU>0W;rl#M5gP*fGxX zy|wW;^q+6uDw@y-`g4;p38SU>)QP0w_;sVerv1}EXYUXU_iE%$zbwKhYQ6@%n;C*P zmxh@;8AhOSRYqK~eIAzl_3Znyu0GiPxW00&)hLAUGzArm=i;)Z_oFXd>w;bWerGS+ zj=@yjyXx+Dx!C{PCY1`2R!DJaGCZL^4n8WMRc7qIVo#n8WE|B3tCrhDL(MpxiG`o} zwgp&2LMu5ptQg|-LH4_im|pv-py}wNgx}z6K3-!fFWY=a-2mOep<8j zTEsStp$_?)+8~87w!0tT~Gw0#02d4^MmIvuv)dH zvg>3mE)r5WC3J8S=DK!u^ToBoV4I~z97i?Y)Ie9-ws`_>2VE)iiS2?FM;~lJ+*Mfr zlZd@j_81sE;JtEkz8B2jUR!;uqzu0e3%ehaGXn3mZ^$#m41yt}WWaFzH(Z<W>0SHB9BXm4~DJ4JN{zY5mpI|KPp8QFvYwmELMyh*#x#`mdC&fyAwL+|}pDK)m5> zvV`+@ybvrH<1k(Xn+Dqw$`;0e&?VhGBVLZT_}^E5@+JWU`rckWvv(YXQ2wiLpDM9) zTHAN4tr%AyIUs>73(pDM_&TWBj_00x?%CZp2GGV_bhx1o!`gLGJA@`-NnX>( zZ}1kr4|@ChFVthn%R>cw0wzJD$ouqtu2OKTEAO^?S%-ISSTQbld=kv)Oz*kU_Sc2{ z?^6PTWk~1;;Zj9XQ>=Gq>}Dq8w;S4Igo?pc%i!*~ShYOt|A+W@HK?!F>2Ux39l>IYAD z4?@1N&@u)b)f5|aeyZWV!>i!>? zon7i(0SCcqmb)&L*pInfVR^GX{9{*k_pRa6d!_Fl({=b%u!D)%n(LuuooUF3y7FWjva2cpq z6`yKQ+6rUN;0W4fB~(+j21bGO4Sl_&Q*R zjO)o3-eE|Lx7z#g=ocKud`hm7tr^Vpbh5VO4?~La5w&84LhL0kbZFDm4+yEPcD&yOvBJ1tEu!P*TU?gl021BrFY?CKqX@C!VGSM)1zbaB%XBpm}feEjqqZAU?Q*q=kl1>qrjod8Yh}vjg1a<1qHsVz;SoNhk|~OLL@2V8=0@gCg;U@ z4@xy)3;z#w;^U)m_LM}KtA8Di-+JVJYegGgcx+hgNLwcdRs|?}w$x!pOYdCE9g|?5 zbdUag=qvaodri`C;0NwdDeipudJ@VjD>DvGeS?67BS&tpsl>tjEW2I?(R6T&amuBJ zYA{w!_7f}-#Xuknj# zy&Iz^`{8!GQE~ZXA0#%^96Ay38ncI_P4LVAhWV?m4(C}0VP!3AkL_L^a@Cmc z-tB!^7aOq3Vof;vwlSEChtPKyGZQa+u;Im2xC{WljRy<<1*# zU;Tg^DH0CV>oTzKi12!W$O$;bfILR58{xy+urJ|@@%Zhd8a?*jF*w3+t#D(g721{* zy%pKu0$PI$Kd$tQK!javY1yhy7%8mTp_ms1+mf4Vzh(}BqCWS{5ZT|5?K~v9-Yg2< z&kz4l`qc*mt2P`xm(vT!=B~3c-*tz3Gjs_}THSES%P??_+5lANGn};Lx{r+=79M^$ z*9P%dYVEM@5X1#%Z(1kv8oy^fF~)VJ0Zs&|^SZ4bhE8U6wcUEz*e#K@O{T9Be&0E7 zw76mfM#G(Kxl?lSx58^2XKcPejNxUkYs+bMl8L$5p|b#MO4kT@jd}scrqRU*v^r7x z%D<+=|2zKVedpMk!@2mWUgHYxTVr60pSIihm0{0}lpp@(m6*BTUMWaw91=70YEn0q zY{>^Dm7SYKFHHOpiiKBVs2bS%CE3yD0n z8M-|MOe$gK<@s)_Ro>@2UtMxL+r{6y-P3dmR9AeEO3cZHHL-S89nYVG{C z)|U-;Ix5NYN4;PeDkk%rs~0A1y|hPC)4;MyN5tBs3z7_t?B+WA;c!^kz=nXQpwo8Q zak``xB9C=dwQU>%`%@7|lr5dJ)8uCd&R(vE_^uBOv0=lohdLhbK6QT}!nhLjgxDag>ik%p^IXP~;9Q7tFAtjgHTrKnIH<-=M6}8r;x_zLoNFJ0ero(!@nHnbedXfq zuQ(jS3&%l$x?ilK`F>B&U?u+4@?fK`%LFh}^MgyxM`G43Ys8rklke}kI{{|YeB!&; z`-P9qw&B`%!-^o|3Gk%m|G)OvYHELBFKT~5#>O?PYP}|5QCIx6_n}YlmU_OB8)2)q zYr_OIbBW)X%Ps>8YCXX5!5I<$yfN_YbCk|E)Ke z;kp_$s5}h9yfAuvz70yK^$ES_mwW&68vrA(Q!7^ab^TkyE7 zC#m%h&mwfimYnE>hdpDr+LjK$5Vc<*Ypdsj>Fup>zwhqK_u)hEklJ6Mz2l8+7gs&} z5XMUcm`0$F+K=$`#JR3P!%Dct!hP_i`zXAm_Agd1KZEu3zd-q9J6@MN2D#LJ#|Pee z-pGC#0ull7)hMnM2c74e7&H(JB z`VlzioYFb6s}&~1ogOpN4a0M)f58@|H23}$t!z{;H8 z=9j@3+^6~@94d>lPjAfwPcHQcj)ZaOp!z9X7-+wZ5j{Fgw=%}E%f`Zf3j$+%}!mtoV#IF6%W5{9Y%4y;Vy(s%Frg;(A2^4&;#j@pzS zfNdkT%WNOFV4l$`>tM49@TT+w{L_b=ls?41ls<&FA+g_IangL9aEk5r=V@R^=@U3` zhe_`R%@3Rm*8CCg@Ey)jdIsJKuUZ>_dlWo8esJEtUkx`X{R19bmFtwmM*vR0O0Qnp z{7)}|B6$`kM|)m(YSKhOupN{reFY6mqB3um^+U)PdAj@T-4I6UF*yG@#>s1c53Hs` z?6Y0Hu$9tpVB&s@A>nH$M8;S}jXocQG)nJ*u(sM2KDIWP)WS-yl7}IQ(ud%$mjBIX zLn9cr(G>NuQHZ7VBm~NJadiv-1i3a7&U@VBAWP{__Ix`;^-p!6-M@95rrTreF=ye@2P5SaoKN)Lm>i`d=v3?Kq zZ3+q~{S4n$ZSxbqUW0efIGXXzXW{gVN8-EB-Ko_OY;s5eq_^$2WGYksdCxtglcl`4&5b^NgyHo6gkX^1> z`D68O0Lt%x*qS{N+v9uTYuUYy3Dgg7DSre<3$Hot=jet9FFAiMMh!tC<)>g|F7Cma z?d?!gB6*iS@W1>Q%+kLMQ90NQySvxBZYjDafGwBP1_LF!kd|#TJ|Paz3VU z+J4G!LNQ-XHiv65E;_K7GwnF_&!56iPTyZ1sx{amp|}6|tw{)^{44~ut6N{AJ+CLP zLgre{C%~2RzwqrZ-?&Nf4Ln5g4PY{j)1IL5>ym^)i;aOFz?AaWpll)YGC_X=G`@yD zzq73zZc=_6!WG%?<}4it>eslfzne z1ok%WRH3`w38EAq0GUQodnj-SdcWx~GyLd*T#6^a`7Nxsp9c2B$ijECi!>i5MezqH z@QN8*S^68A@Yi+ffy3~c;uY{lme2o1ZwH9CoaTS-ISOVJ-+(rbd)Wp>EwD#Q_jtDH zIJ8kb1a7`|_vOOBpt5YOzH8$I_)z==oSr{CT(PnoqIiBR;g+8QeTuihNo)4VH!RuU zF)Yn>b8HIMQ+x(gqW7;D3VDg&47_-GMSmL9D4qjqkq>sQW&DmW#7W9IEqLsL6-#&F1Vm7L3I6fJZxlbo*C~Don{mFn z_l_xWa>?9ES5IIU#jn8K`=0H%$0S_&luEa9TP0XiybHL$-;da~o>pgj8uvDaH-In2 z#~?hDOM6S(7)bZi)8D?^28>7l@HDu2SBS34augcRGx76kbORH`-vEalyKv;*Ff{0I zx*&a{54b5_2b%)COWQ6Eg6*AAcUi|F2&VWR#Jk){t&Qu2F59BA=f_6i6vYF<-!pYr z+o>+FyH?D3)?o~$DSimm=W?DNVrqlD@BWSF)hGV(MyO-XXI9S~k*Pr6Iu;VYE_oDbb9;f&`sIw;f1^G@xVW8&lua;cUqWCcA_6xCwKAeJ$ z0>PrrIzM2J;>pljR@YSMI|=-!qqHxVHo--TKSQ{(SfLBc1f(*L(+zdD!!X6G!6wLZ z=sAtQ)ck&_Z~y2w7*l*3KC5oL9(!X1a(VQt!o>z?b?Xlg2jwS5wP%>-zA2w9KVW}_jo|dqx`7+ z0y?CpTxHYiaq-REFw?EmK&ZR}?rFph8;!SNuahP6`!%Pao61K(;cx!MdgM?3g~h4- z3qH5A&c$q=fyxNuOUGRD;2o8}fXA=v;%m-LL(frq;k$)D;Rlu1K>6rie~sN!@O;%W zpR2Xau$Rhrpjcze+4Id4FgeL%SvJ)H8B`twWn61LMODXvqk_I!skjFUsr(2ER_<1H zG8qNam7j`VSq?%0l{bNp5zA?QjbZ3hxV}W_>o9FT|KwB9etz>Zzkz-*Al8Myaz??H z%CjKuWc5Up_-|nKz1UP(z9RKEg*r`^Q9n)~b=fPa_*%j46=q_FDvxdGM26 zDkH)?B8o(JiEo&PhyoE5+Vt7Pg^$dvQ@OX^Ook-Lidjjy%MnZ4yJg+t+~foor=44q z7(qSqhpS9w$-ClKZq<|}6RSXzxP*>9g*nRp54bow6r#FUXWHG z3Dogu(-W1*8xq{aOG;e-CyNT%PMsg+cLkf6>|aiHsHJg?E!Q9d)Oe7m{>L@%%9+T} zI=}VStF(y)HGcFewD|RkLxXtZu7J0GrMd*D`$eCG-zu(sJ`L-xTzti&Y(V6w`9a5j znETcD^PxLyHv6&{8h?E?)?-6)B z0{)w$pEf-fLZW9}^9>D*NYBfQo0~5%ld|p#C-j~Rg)YWPzc4Z&aUpA83wetW74-ZO8|ZTAtwdU6V9L8}46QC`XcHKW7OU4P$lX z=h5?^N_5{HRF>KyPd=RdXu5jo9QG+lwlJEOBP&8Ra~t-`kqTDLH=Gl*_>p-+%d-jz z@?aPExfjb2HRdBFV+CDUzwy=KmqdW%p7W2?+$}?{2)=8wtsRH@YafcwXz>u=?Ut?k zh%9Mf&P;t-%873ETpGOkgp0)NzjsLdhyw8~S3*0E3ZdNf-i5ECxX83>-NV^W%H+7K z(XX?U;;1E|qQw0eCy8=N!*k8*b#=Ps2& z2|-f+Rva_|H|&L9=Vis zIWFkR0z9YtQpI{o9yQwd>W(q#5n>;`lr3`x7gv9^X!|IQaszG{Kep8&O==&eLhE>m z^R8mY+owcOTL0L%{}WB(gV$TU(-9|2&Kb{ax8p{KDy?Knm#dOXH$(Eae~}_`Q6^;_ z50@bE&Y$9@QF6p}w(l2Pw-gD?TCmLWngzFm7hdsh7bBOI&!y~llq5qh&ujfSO@|(C z=6LP8i-!p5bI$v=h>_%mb*=qA9O#l>owXxjBg(H68MjG^6aT9BbFWo}Pz0&iS+a_i zto<;n7i=I!ey>Ptm-UlE;SLvDNC`VxF>t(8cEx_`-4mBK!>@ zC*{dXRSs8;e0lU!?4vg~GZz^b;8BrkS0bS-Cqwen6p{O`g@We6WklzmLH@SiYQ(`? zWAGD)GWwqK`9<`_CFI+d%H^?9nnVt|&oiYcqqoa%4N4n#;+3oBBKU4-6D8;L!%mgT zsEWJ)`e{jel(}v56Ava`vY4l-|9UHv1xlPW1(|l|LN8SHD~vTkFn6N}1lSSxzf94Q&;C1Ci%;^Biy!(U#X(A7m~fS47rJFZ@Y7rIjwGVo4304tD)X<|E}2!E#(3T~_;jF~^OLSPk5fii=Yv zS}u;g=HJ!Plj5cd9=%Ek-F9x>t%K_1@spY-k}K7bMUTd|{BagE7SgDOUDe4ErkM-s z>8gmW<=Lfm_9EnB#PDP}cMnWmbsfBXR}PKEx-mRp5g<0tJ$NVg_TbfSw_cn(A&uN@ z!`{@=FDLuEH$6)KFptI0t}?!^ERGHY6^pE6o5m~~p4oNs(UVK|FJpu!g-~*wmYMuu z8`#za-Tvq|i=z}vKf4|iLINA+I10?^(TJZ(vkToIewm^;GMOlbZpG47{=ChIQcoBh z%JizmI(_bMs}`hDJ!{t%e@@za2R_%@!x(o?G`C8iE%VktRnC z#L22{`c*>b6pTpoJkIX!b6ld)V$mK^aFAj=-vl2#zmP`k|^O;d+S%sl@pE&Z@7ud69 zGcQ^(n2~jD$ujieZh)*+w+za9`(#KffC7++t-W_x?SVWqSrWG{DBObJaN?-f6s>?nj#_#hImAMK*xj%NvEMkC;gXF| znmmdZtzPALo0-^err%|;VFaHLx^;OdK@R1%n!a2Yyo9Kxbuw%y7{g{;Iu)B7WzoYO zSg_D(9$&Yum^7#w#ai#bLey(%^xEgZQ}gbAtkO>Bsu16UKPXo&;hdL1yQQ~Iv&t7? z^kUE2#{Mg?r>S&jX9>Y93Zx5W>Ok2Mu)-S)jqWOLew}XyJdAP-(LVWnSG8!=3WF@_l*Rn`y*9L7ru5WnHuyOpjCqLS+cTPTaNE%s5ESFDI>Br@p zI-2KSaic&IG?ns15;;mawGEpN<6OPN8+%tQN4Cnh6QVst(W*1CohxDo@oBrFkE_nH z)9ONG4>t%R7B{OLC;s0!KR7g`WP}ZMj^FY8+Q5U3JjFcM6B;nXX>#*S*fKQo`}*Z= zgdIIO`J(#bzFa&JlVF~f#DxUs%2Mcj=#a`*GFDked%x$Vm4~x1KYAqAe8MfU9gH*2 zh#kZII3({&Rmr3X`pNx%+2gJjY|zNzOP8dDB36)#C8A47+Ly0IW9|~9WLDNkaJ??_ ztW;y;D(Hg)FD?h}R23jY+Bd@4xb@KPk>sN>o_t7KSmJ^HjYZ7!yuq={RR@(_#jzT{ zrBPsoz4O26(WESkHctJ#6uW~91@!6fmvN9oBJ=fOOY^1C zyX5h=Zng9%!RD<@+%svkwsLOYnl<9cP|?iDVCf_rdjE#yrL`pbY|Sg59n6n(Up(nw zeqbDUdn&G4nTVsQo69-KeRj0+Opk@2z%=YddGjq;42@-O(W$1r4{CFCzYV?R0=(ar zy{P9bj>eA8ot`i+#mBr<%A(IhXfYF-|&kGw(vgtsioz=lSRQEp9?&;M}g?m3*~e$dPxZ)>IiW2S0xD zTup*J8Lgy`Ze%1IN+WaCM%59~x=wduuM}~;TIp$Ewi=0A{n})@hn|dNacmuMkRnW& zC1v~BHR#HvtW$d=mm_UAHq&$-cCy3JG^k&16_Q$Rdr9n>3_9}SGOzf{MNq#R&eX4~ zkDNOF_7n%Gpt6neDZ)%5h(r}!WOmg=nen{uyx*!L+bqts;)^n(Lj1TpQqMI%BipXSl z1&huzQS_pTEBk;p7gEiZzE}NJ4xOD*mb;z9jm#92-yGKEL_bzNa0m#NMG_7w&MEB+ zVEJM0N9cDhq^Pl`F7LW5x**uu$aK9K$2s*Ug{1MIImg@I5Bta=51UH2Ti=+;n+t}o z(`o%-cW>d;YFz~sTYj1+i(Y`Nc)v0?WTyZcc(q03^loL;d)4PApP&?xx_v*xMwB11 zWgU*{m0f{K>Psb}AIp)q$2h}yTiFovzzWuzhT3RvSn62qZ$(0Tm-$+MQ!_qxdiWg5 z)kC)(&fDd%D3hN7PIE_R1c}F--n{xVLsU}}Qheuw0x45G`sLa z<3`t^>`vy0_uWSTx%fIAZCVsY<5%5`S(gZ)8pqksoMtPLrV|=CZBfEQ-i*sQe+!{~p!pjHB|X-BH;$WPAyFbv10Dv|JF$@PAreA18+> z3Q)6pQImDj-b@$?#7(e2o0LP}spCoTw`-BtyhV|+p-<^dxB{}F&QG$AJML4q6GxB5 zyjgvFmC-3`JcMcI89PkdZ_iTm>u=<1{2M(o)`geZ`Q~L`IQu_<7E0i7`wlPHMH*?~wu85%u>iHra2~8s#F&&hs>R5HGRu0{w z)&tu1`QZvC9W@kFbL(gnn-a34)(;Yh98R>UltZPr*N42+Q$iKgdPDn#IJOP%lR{@C z82EyAE1-UAeIn1jq2-qZ#ZZy@5IM>xhmxuFj0V(gZu;_ypm5&U$k$df=nS>~(VQ_u zVQPRd+S@&Kik?#%wNv{A1Q=As@68J%VW&%13WB8&7q!3e^!~n!O39*Vy^8hB-d!|b zO6^B7u=3?A`$}>2)cW!Bof>iosQpVq?dE+4q9xFrDaX#HRAm%Q?RVm~g)uJhxhPUR z^tu)LHPL#iK9DQ&3s25HB80mLGX~{OK2vd7vePpQbA_ZOvTwm++zts=wfScY?!)k_6C*swAtk2`~CV z^&=Af?cvg$CPL`JNV3?;1U{5O^)JFR7njr^E`mgUD9ITg6h=B!zax))_Pt<{6-5qr zxckRVq>&)i9|@Dnk@%wH!YH&i$M+ql(!YL6G&bJYpS^(>g)U$D`O1t2>ZkfI$*Ij3 zdGT%$w(jNHVd|lS)=~YMsPAC&kTzVzZiuS*yem%40abH^+;SLs#q7b z3;odpV0m5j_J&Lua$jaTqM2SBZKw1D68ftT&r|vk7ASoPbT?P+_^B_9D$G>4nL?MK zBRqff32cf!WXzbvgF2Y5a);$GqDj#|dIr}uZK<&E=Rh3YOlxabF2dC8AN@lTu1b!! zM6#i2=_Mk&vB=ZlBpb>&Od?GMhM}KY z9wWh44Ee`>mZJwnr#8`@7=VqGej_2m&M{1K+=#XATTtbv2{=mWJ#w{MtNX`14|+9W zziech5$&e*A;}DiUqMQFkw|gmFsmLnN~827+2wR$^V4V^^gOC0DRPA<8l?0mnU?Wf z8fwUao=QE9NZ%`qzEgUYY<>2%FmK}mloy@oI_;-~f+>AVY-$8$uLd;Wl=;uRYeiI% zE2W3YRMd@dv-z{&ZH%j9+W-)U5w-wOPia&ZAzQqmM=VuF$ z4c-E|2|?26C#BCp>#zSpl>Y)-%72j}WazVl^CK`cGlX{+f5n!R{wHnII%ReSWjJ}c zWNAdqC{CmN0@*iI`edLm7aP32on7{dp8WL}B<`^BgoeNuXkL>SFf_K5tfTx0sZz2? z52kB^PyY4J_ZL{mNy@(vxm?DbCCt4LK78ayfGG>fq5KXB+me%#?l2B}^KYbSUR^@M zD1SsW=kIc@>zjvThaYTy@O&CSq5KrNPE&{*(&^EVPRfPKGif-G@?V6ncR)`O(W8pU zp`EvM7l4oQYvdmK)qfyv8dl40{^%vbg|aDsM~&-$V<$uXSGsQRjD87Lw zDZW8CUQWO8+$l zHq7E%H#WClN#G}r6n`K^U1!Q$1BdWg=IcGZYq-d6 zidT?|M`6KMq#Y~!j^{bOWgtZq-yl;eLt83DJ20O(%R42NMyyNm5MrPwJ7#!m2#b6Q z3?I}Rfl7*>klsXt<(5Lz_!GO4U+c#OFr;`3`TSj(Zco|*E?Mp#FScR={_+`OSASJF z>dPEn@ZoBTbgufxbBI`sw!$daFy0d%AFqCpk%UnEhXfTU+)8FHho7?w9^ccsh!Dk# zh;g&Oah(+%+Oq1a^SvxSqEGQ9g8uTudAmRS5YtoqkgR%8`0&LYH4^YW%&7ey&p&=e zG-rdveEXgjn+3NV#jXU z5|Ox!#8Nzy92 zOA7w-`Rf#)$H^3*C#e^#LKXvcN$kE-&P{vy$u^1)lf%3pv){XDllrJ3yMx=M$O6Ta ziPl)&xQqgM1|tdeE44a+%`cjL?Oo}PXn7G5 zO7VPhMe%W~$16^WlMyJtD=J5rQ~u-y_+ayi;{{^V1{@Z_rf$ATmXFP~@cfU67% zqVg=#yEXN-w74*Fvq;t&B+_Jv%D>3>hqD8dhxmw^-aKaxlPsyB@-lp%Z*l!H1#Xh~ zN^9%XCk66p>7RTJo*#F~4Y|IIFfrO9%iU@uk;>!XQ`xh1A-0S}h^fljNLq{Bpz=E~ zkBPKbUD1XutFCgM#X2OE%KPAH^r=J5%=9Si)}3;5dVO-U;7>k?&#XPX@^F|SvSVPo za>mVom{55l>8>#xO_G#DSLZ@%Q!NZgIh8+>e>pSdC+X;p)y%)>%a%iJN;9#C-WB2F zo1Yao!3>ty@?QVgMGo2O)^e%l7T~s|Gj;syS&96M^s>rRvgp9u)1pc=J|=NIIo%_T zn?y<7=Zn{qLF?nl=J@mP@l5G4#?%ac@<5A^`^t8o#jH!e~-79-trNzlO;3vwVizuSy9>F^S?gOpE>zbmi%zq)h;T| zi01UE@f5I1G7Qkkk(h(d*SRBUpU?U`em}F>gjQ)eA{m##RifVj+JEoY>|@+FZEZOs z?kk<`$k>H9{hgm{m7}$%nB~ahuR7GJd3tTqc3CoioR>eqn}h87JO7d$ zlfG)zzaZ1m{+9MN8rLz{v~$OJ0oI*SKWoN3iZl5VwQDZQA(oHn=bB>^Afwqgo7HwH zsrtRH_ItT3%JZ@5>3>}br8XO)v?{qsMf$qZt3fiTN1Ma=cyu$kKUfmoy@{Wc+~2Db z%O{OG7LD#oShT~o6+i@A(++#R7tpZ;8*M4GU2aNXUGAX#$AaGm$gP4wvM&_sHBMJN6?bL1FzsVw0& zTx%=PM0-E;1IN&QwcogRw`p5gmn@MU&e|py*#IuNHq9cq8y}rZ1o7Xpgq3s1t0`?N)tw2jc)2c2dkJ47BE ztjn*(hbMi{90~7%SE4ZOBPNFwtPa@ikjlZTrOQWMf;zDM(o?AuG#-AF)k!ncwhD?4 znI#o&WFWJZkGdv*$fDXLP9`zIZm_))Y&q(%oFqtE3Wnd8L3t8CBON`4;bTWj-xp0< zUg@}s*Gg0xZQo8hEUGRJ9lEX&4J`KxJdWM}g3~K44)J8mqGbwZ zsSbi2@G~RO#>{FK7YBr9l)1?w*DVrfTw_N;NNlS~ksKQ-+Fo3@X1@#ywb1(6J~;#T z0-K*zeB&Xq&)mlni=~j8`(s>kj1G;b#D3f&D?|dfewdHT5JyM0$>*++VL%<l$;KgEWz5`_7bHXCJ7WC(ZRk)=k!#1wz)37H_jbMFbs4f$`|*bx`=((Z6n9#v z&EZY@yf5xPl_7m_o9%TZ?em}Q?X9N$3)oFHQdKBhhO8b8RW+HehLab&Obj{~@OVYg zogY7B$j z^GwR18@n!QN9`R3vkm*AUH6S*<&P<0nXhCJgJ_KWd$~DSsajY5G-oMce)CXtOR_Y| z)Tq1h%Ab}yB-hujALJ&IM_IkwN+c0Wn^oz`D@^D>P4vVZpAcDQegE|-K2gNtd)=$P znh7PGOW(R6AxTQ7%se}N+*{gIiK(&VJ-$O=V6CiJwlD)PaW-`J8@qo`&^ znpAqfSi|Z|kAfvmT3yPS#8P=(bkU2_B>cI1P}|fT*knj~MV?>4;R+%Z%crEtp=yrP zO$8H>b2l(yy9PZ8?{4_C*=5LOr67y#s`cN5#8k|8dw0X;c#W%zYfxaAJ^1sv)*taHFihGa?$e(3o=jGubl7ioulxh)&c4?JH4CZ!A!pAl(PpsrdkzPSUe74tPb zJKEsM{#R$ylw=TZlwXQmB<(#tM(Z)j3j>&;w2tX(g*4LiPAg3jV?f&UYU?^Pn8>xp zH%8V^q)+4Sc7`Y+S8&o702N!>ofKo;4pxbs4!iT%me z^9_}4aPIik6NwGS4oWIltpaRe@|UtWPru13}D45mj(0cW1Dt&v8nuWE^e z+R{G%y>pE__l-_qlywVI^p>XS&i~cbdB#=_uhN&y+_pVbKg$)<9_`9zaH1)y3XgE^M1Xauk$(YXIyRu zR7COvD;x2!X=v2t^z!5ig%JNbx~HFpfly{Y^IZN1BhqPqd_|2$oDe-OaoE*}iD(aK znVT`^Mz_Zql(<8M2nx+6lg6S=gx9&a4&MMl*Vu#m8*6*ej6*X{e5?j=%;G1L~FH34Jk-M?{9YR z14iPFrhBT^qcP|(@L?@zf%J*P*8*i#>4;-|kNT@D$@4tQq3hvH5~${f)RTr(YGS7m z%griCjcSm*XOw^hx+X-}R8IW?FJkm;D>Z15|IatIPQv8)yR0Tvv#$a@Gcj8SQ(ENF z`b_Yas04B|4^W*LnFmT`L_uIP4a&M6eP?371WGZjySW}W37i*CBsXwVBRVc&;-tL< zdjH$~=^L6Z&_{Lo3;)~-Yzno#z@H+4Y+W~PDNHJdW~n-k^H)b<#<#5J#or}RdZe+| znE4#cS{9w{LWc5XWzp{eZzt z#HN$moDTByp@ST+^lwB75TUf&B6P0O6NaJuO7`Z$XlV98h-Ly0@r_ZkY9-@0$Y?P? z8W1Xmnj2mg*6MH)v59JJ%F(^#y*Kf{F9=c4xyS2m^l#aShxcw2Df;z5p8aPbj}--_ z9`2>iFkmMBUKbd%db$LuXj&GsZ;<-riabMnI3w{^`iNUu9u@i_)oS}Zn1Yz7=gg${ z(i2z4e~`Dg(4x3W?U@G|6co>^H0`lSLyTKV3MfX>B5FPJg2WmM;w$h&b`6p@=^}MNdh+YDHr~mxpBl*56m-3>T-GA$F z&!?8=BdQXJAzjAmX2BGAa)|4VxymeLcNC}Ac_4vWBMv-0?354ObHajF{uaTbN4WcU zxk#WnT2}{sl__}T?7_#9&&Plu<&#wh`JPj@g!6O50`fe^nFp?-tn`G-j)&J-8U~?J zoS52p9EA`tv0ZVu-$dlFOzNzxGoS)_-TJjS56Wal~4#r$0u;MyR_UeC@K62JISZVqPYn z`=!GlUX;f&6KsrT+Y&d?qDLAxR_~ssAaU`~eNz6Lh_6i1A?8*zi1R1IkM#fwdJuW? zWYY%*;**(!wLl6LidDQ{z+Xr~Nfs{_l@J}_B5go;9S#*j*Sbn)fDWNbBiYYSrfd@HIyJ>el{jezE6tauBR!c?bbBg$$=Ogns zOF!pV(L#iZ&U3JZG7BE9-oMMhD1@Z8bEe%~;wKnh#GTq%nF)?{H3g@$i6CB0uGUT- zKH|r!Gt!M1fyQ?x+zR_dP_RXF&Oj;;aq8lZ4@B+~Jjz%g*?U$Lbqskv5B|ta@Q1}7 z?Ns>-QzP$aTrUtsPY&o>UXJ7<9A_jH{Jv2mx$E9%z8)7tc9BfE@D3+&$M=hgyeSPD zHkDj|P9u)C$lWj8?oR3!{Q2x5PB+#Rain#SUyAhrJ0Xm}pK)*h&l7TF-ks!_`DxD{?U(G0=@O_19v*gp$#5S2NqU~LwXccq`kug$5iyjwDv&}X7@;xGe+$iUCnu$a^Eks%lA@H?caZut$4`93^I2CSzmJ_bwvHQOSCl(BL67@cMG7G~M>VN)#d5ni&Q+Zekv<$B>UtUqJHt)_$~`3ng=6 zMZA6;Kb?+h(h^5Y67+ioq&SIiyx!$(wa>cmrl9f*#=YDXtON_*AKoOq;Jn~RL2aws z1+$`Q2?M;J41eLMUW}w5ZHpAKrgHor*XsNb26q14@^7iZ4PdykCi4JOV_H ziJ|WcoeJg`Sdj?c-+pb>FZ8c|ea7|clhw!_eQ{P)KB&rB#X})J;r(-+CrGuGoqS%j zYkSJ5#fWgUvEP<9HOl6G=0S2CMo$(xgb6RaKac%v;d`phhi-HGnHQ7AoDuKmn|gk5 z$*S_B@nUP6;AlbOB;Nm(%!2uDZWcg(W8n1soB(kJ*9(#N1uvgX2%tYzuN%`81c*^w zUshb224!*t(ZfE0D}HwT#8q661~`oTWs-%EUR3g#%t$^W8rLr$+rh5TVqxUMJ|Y`m z!Ar2XZq&OMl~sY06C&t$N}T=W+dM=lu8&bA2CWVnVn{RVU6W25xlVCCRR}1!&htVX zoizIMfhvQUh{p97GVAWxMy^Ljce8mDjo%;$*Xw3x26$4Ld|ux?v>MMh!(+Ipj0c32PW2#x5kPZmM{DY{1P*v*9suztY$5dG7K>R2D1NsTiI;bcK_ zWrJ}q0x3ko?+txY@vQjZ>2VIUW_ci~PDq^Ch4swu4|@y#@N*+ZZR3NJ@}fjH)<0Xg z9Lv*5Zv6bD`L?NEVd4tbON95!#_0FF=(b6&ObR2(F|fX(F>WxMfP6^Dh(`R%c_HE? z)?<(6eq|bz@gx2F{)e7t3lcA}e!DI$Ze*1zfZlNQqi6G&Z9e)Goc!-6V4gLApBqGp| zTMSXY3Tdeea}w@YuZ|eas&kP0r&4kD>u!4nA|317*Q&`9%VreRo#q#N7mfjOtcObq z-8MyAQ;@;>)O!5bJp8Ah_YcUGCc29wg|qd8wK>daE7se_3!!(lszuOiUpBob{p7iI ztk1bO{1^P^ze=(H>P(=V*3Q|44n7(Av~*O0pvU_Eu5j~BmE-KFb&V(S#W4zT6Z?e- zpI@{mCOOf<$WO8R;bO!;f3Zs_@i~#ejYNOl`FvVLl=$aIbPlAicZl*L?S4&1Gd>aG zpMP09!wH6+`H*nyo;`E6!o)wnbLqzxHQsmpD85DN(xYl2;-5b<$dmlY`&j_lXQJ7^ zGC~Bverk`lF4OC+d7 zQA?v#nB;RFq8IzSOVW#CM09dH&{~f6oX|=?e94OK$yJ`x3l|9y&oHlep04_2m{u6^h6f*b`dpAm!F+@5&zy=z znFtb(?|#Q>$xqN?9uls5$Me^q81m-Sj}h7s ze#iVrexm&@(=vN@Xq^?YV_xLidnSVrr=b48>`xrDJSZ0PrE44f5dPzbK@}VP za9QGnvrh;uYN=8dJ=82oC}4i2`DDs)Y?uYPYsDAj)k_fjG4E3U(yoT|Igz)Lgt0WD z5dZj?{8)wCkxe}4CcmZHF)}x~i+S3wvMJA^=^%4 z{v(2zf2^~;eJn`)#Qd;MW4l$DsyN~ZlpZh2BI_FFjn~earR}PvAYR*6gPsdq#0ktN zr{5QEabc81UaR4ZmTFAIB<7i$hqNAs43hi-rcAhz@2@&y{wcL;37vox`gl;We>n+3 zXUt1qy+3^F&rT_H@zSp9bdo>%W4>y0F?PrJBS{qa+Q~44h6UZkJT`bapw5MmKs|BI z2eo%|BL&QFoi_M9OvHR%6!ZB3GnT-JSJWu{@{&uM2g!9YAC5l#Z2OrbENIPzrE2p{ zNkR8EN}w5DAwf~{+-VZ# z`T7f9Up8%*L}{GAuIb(6Ao4N)7dE_6Y``mpv=X4Ws44@Yit~cy9j`9!jgdn1my5sc zBkva&#reWEs#DJ8?NaCxS~!1U=HqP+%3?;ZqFi+3X~_58a9%^zCvTzL&xv>wm-SuhB#65>-{GT+XgTJ| zi^}~kHM}aM5bih++8tkV`lO!#8g`-I;}$GVu>9P}kM?KGs|BnJA;pkaBIjI1i3prG zO-ZYDs0@jqn0wOKKZOYsjyRu6R`s~@UPK&KR%LW8P?6^g&u!#cdx>pbQ_B=|V<}l_ z#h9P)!}(Y1)wQY6eI$oBPT+Yj!c8pUysY}e;{{V{DO4%mu0hRC`fHr81+VFFagy)1 zHLS(cySvd5WjK$^vQ6BqF(-xe1?I;GW&TEgBrjb&inif zw@DN!Z$UFxT5q1YHU*b(KB%Y$aNP{CGOPzu?FQA~>S&Rl{>=J?t@Xe)kd3GPOEYM<;+X4l^N+_4dbs^;YCHBI+qyzpNpQ0$PhwessaCq4jIcw-1|ER)H=5b#WhIq(i&+55EeCZ-X*k zvBUX~%fP+lSNHQi(4tzZmgnobHPG*c0Z53c0AB;xEyR*(5aXM?&u0yCA=48E2I9XO zFcMv!s-;7X)&*PMjNeOy^*`Kc);HII*1G~?+?2oYj3|$kp{74P==y9o_1{_$pLUiz zOZGQ>z3ovIr@JrQEb>g=@^LjVSQ30T)wu|lQr`WXX7~oRbi#-&=kma2mMkX8sad!= z`gi-MZw2tp>0HO(Z{lD~iE(L3!Zb_`EmU3)uYwlh`RBEp>R=K>lxa=lG~_<*6>Ral z8qNi*(WKk=z@=*(WAD0W;kiJS6Vl36P%6#%%cJx`IAYoP^ZVxo_=Wc4sbbMm=vcV< zW)Lw7E3TfO;zP?&sXf9sBOQ9)m81F?-BN z-XE6P_cqKR1t?Fwo)&pE4EGL4r>#`dqCX+;w%I37L+zs4bwjQ?P=4vOvK2cun!9>1 z&GPa%T)m-1&)8B1xH+}-8@;Fy{mezr$(MuhO5$f8)e{9^Mcn$t7{gz9t*(6cT1Pi5 z4^!dbS;+-uclF;MFj<4s){`d#D|#zYH5nj>vXjt%D(9;G^HFNv@JtiDBvvNl_+bdfC6tX9=8wS( zpZXNOMAgGxyDiGI#wMUSb=S@;v1z!sN~>%iIS(1T*m-Mvxvk3q9s`Qwn~U zKu2F2xy=1@&|$7PC_rNY+VH$gw$u3ueMfFQ3HP3d6LL>X;mLoV=AMy`U9)`zxCJeEClafgetlE&O_5W z#3^u&3f;F%DCwiA1Rt-Pe7(mr2M4L&8yupiMu9wXhgjO?;FYi=PRz;;U?J^upsx5b zRXHOHSJPeip&Je>td_0PX7V)&tIQE!#PjpGuab= zLt15pM8=Zr2$y<@xkufhjU=xyQNp9a%FJSowtsT0)6oB$y>Ego$8?chpVv%xL?CF7W51+ zdwSvegP+oWTe@N3Y-T>YUKZ$hA-Py%N}dmU%6n{rG6I`VIhyYZM__y`N@}-IALM*< zd|JV28otba*>dAtJg_QOew>g(a{O;jn)^KG;I_@({uWAU@XV7=$@GR!`2F>4mSge) zjD4mZ5N=QjgEe$Hd7rgFYUAy!-BL^NuVSvf+ol$nG_~`}-u?Bk?z#J1pujS`abQ`k zjezE()rvZ3A04neA^q@~fsL7-F5cF%fq4`eoqPwG>dgh8iR-)tS~14<8vs!~q$ zz|>WF)`q(?Ft<{aYvEBR7?TT3xNxBx4oWKcw=T}YZyrN*;wyE)GdG81yB)C1K#!H_ z^BjDWmi}|{a2|N%IkN4uN;BmB%%J|bVGdeKM)4oI`WWas3vfr8)WP}+&b)W=bMS7( zZAUZn47m3tmlgYk3i#pEqm%^AIr!eo*5jRR9z3o#pf=@^5B1xX(vFb&=9l$aKGo?$ zm?LQ1;_jURvkslIZhbQYnKHgwUS27Hh9b7MNiwhDZhDPV7Nb+p^xjB>oo_CDB{n5y zpZy-_+fjWvXFmoj^CNdwo=k^}qLXj=R=$JzkdA#_eWFVD?m#p@c*O zl>WLNrY5%lLJsjrUJ6cuHi{01wuE=VVc*QZNMi}eT-8qRYOjKx{o=k}dj{dd43Q|c zDDs|J`P+*Q=`C;|nwq+&bqucEP7977TL4?rqt3?8bwOd)GorD#r(o^eUTuNQS@8Ov zne;oM9#}dru`l!dG+f@F6Vy020rp=o{Tb`j4IjS}U&@*xp^`$~4ggi=24+62nHJS7K_4=6Wj-{yFSEtzQRQ?A||L zy)y(2hq$fmD;vS#u$~9p)0I%)Nh_*dvmaKRQmIieYXFQdoOn|jilI(iL6P3qZg__` zGg_sP)WNS#Rmz3u!Dkn?ir!6chOJ4t@8v|AK~=5L%s|9Xc(9q8`;AitoSSv}GL z-oCNXQmsgayuy<-bd(e*Qm3)mx1$$$Ju~4B;33!P(|p| z+dG*ac<26;d;VK!iOYe%xlg+X0|RIK!$-yjAOrOcvD^H#M3!C{JMX1hXcLy=Opx!x zzrLQUB$Y@_Tn><2xUxNYo!Lpi;d9$%@FqQA@9^5qrZr@975WQIdvpvCaXIQC6EV{0q8q8&0i>=Mb^V^`h0`pB<)tr~iSnJR@X0$@ z=pPo~`1sWTOt)}fIYG@#B=;oI<-rzs?0in$(B=`SQkGr4_=}M^A^UOp+_?eRY4m{6 zf@cig2rjmfF`y%sPG0nKTOWq(CHngfTt=Z^>XWr+FQ^D(uZZPcX2bBi&w0Hgy@PPu z$xB=&{;Oc@>drl#;sfxY``C0+)xomO=4*!< zXMx~I3D;CqD?A!w9-gI;0N=P$jjO^LFi)ds_4;u=bhW(_ZLC;A-cMFURE^Dmvivi@o+q#|M+uI4&(KxnaNmQ_h~3DigE-f)nlBh0>u=blRY3QIGqzn+jF`$w>N z3xAhmBrdSIY--W^se10Icw1&sA1ryX>kRiK8>2190n*W z&7Se^gq$`5?+biZz{f2?`JOulpJA;?I{v)c zbw;(YJK50rYwQZC8^FKs??2=-Od}WpYd1Hk7O+nPR{VQ7Yt?0x_eO(!`6zyc)H%S8 zfB(3TiE|5U3b=p&$@-bp1z?5$FPDY8I|}&;av#nXRp>5&f8!HtV^knZDFP|9eds0G zpJH`nV>}1yWnbG->cPR0gt|<N|6*Ie18UONjznM;v%J?3;d zw7nY&;Q2Nk{k~I1e-aA&NIz{aZh|d%ex?PnDIMQE1er}`tUeBwKsr31>0gPs<_2`b z^Kj*28Q(LwiswIPMB*D}*#@{rlYQrjxk9jj*UR}E9)2Oe@}cI0;Lq{AX7F!)ee^6> zJy75ULw*^#H~IE~QoJ6OBUS$j$sj;W+@Nd78vbNUmO=Q*IpOw! z-(|2D@6S4lKflvP^}rye#|GX`Ki~@9&(+#uZe>1hg1eIp4+$KL02+AzSGQq3WbIx8 z!vtv5x|Iq*I<6Oe>tgP%$q8^I{(*m5T^-29^(Agt@y0AoDv(8@$>RnXH@AG#V+d#fpq2`X<3Gfit zN8{*6A>Cc;NZTG4Hi@%9GTT4Bd$9gG)=J#u- zZ;jyfpRg=#mp1Sm>#OU1_nghnw}JLsOLuoSbb~Ie$6oQ@=VIN|1!8>YsTD-}ffd$o zw4a|g)wA~iM$mShJ)XQ59qYYrG4uMDXL|wP&eyd4I%B{N>%%f?@5tiwec%)OA7#-U zlfVb-Nfl2zvxUk&kW8>#&y<}4>sWs_pPgW@(IM}{dMs_PMArRAtXJ71<1$8*dw_3x zs9ZYx2%x#Mp>JDi>mI3J?*s`CUBk52d&qloH}r7Cxzmin6U|^*;KnCy>K>+u@?ZFQd6CkTWe-Jv)67hGKmlyy3q_3$ z-46NXG-7S*#f>{zo1!N^Ozrufj+y*MX#7{@}9*F ze{s|5RCo^k1nBCjyZlYMAFQWu_>m@7sga)a32>A)mpzJe2zg*eH#^k2#Z=oA$S zITSSl-eJEpej+6+Sa||i+Aj~CWF80Z*dLkScDWjPd>pL3-Y!~hI0>92HvE*l=ZrvB z%_wl+B4N2pjJ!`B`>$4tt596*Fc|tOB>gdX8pLA1w%KmqcZJviP#?78hoIUtK-k|2 z1$%~N$MyhK>QmHaeG}lHA2hQree+SX1sESbCU@Ck1W;rD$Zcr!(C=Y6sJhq0qs!Y5 zc(C7Oyqg{|I++L@o?RY9ce+3h_NP0$e~O>ePKU1y>`$Z)w37X6HvH`JPfZQ0uja3;-GI-}9PFUB%fJfC!WIg*39yBp3GkUXBafsJ-Ta z@Qz*o&0ih|8ki3#-cw=n2$}=yG*0Cs>yzL#<_S-ff7^zc&VojLVHE*KvMyl$;QC>k zpzG$eN$jq;&@llHvMg&L?-}q8^Nq-dmsQ?R4uiDes)P~`355+P)qo)AEJW%wwu6p;(Fc{AnPK)?&3S7th zFvam!&2RNy@Of1hYQhPyh|`S z*H<%p0T<@a?z-Chp~ftbE&ss2@4^63v)bU*t-EO+KJJ?aqCc3JbYBjEam=?BR}*b~ z=_Uc9gr#=Y4}*U^T-v$F&*#es;BVqhxl%n09%FtU8C_N>l+#bvby|zT{vlw7d3)Rb zCtW*9exNaxXt6vw06t(o&%wuWuAZtA=(}zE`*2e)IFEULbEWpRI`j%eykz3utKR~| zG5;6+NN<}|nFH0fTbZufk>~btUeIM#f2e`HxBQ24q1fx8QV@^xh4!L*ho+V4VMCiq z)x*ka;Dqyt7dNbIWO!Sk`85;Sl$*_<80QyqEpPp5D!X9fuT+JCfo`yf^NyWTB5^wp z^~2Gd7uqzX1^_3{M~IF53tYnamlV#wzB4+UUc5I5OxCg=nP032@;HCVoA;?bloWyBR#AsuV2Sgih7`d(*PDHSzLn3uyr>sc;k=1Xf6exxPZ!W2^mtjtdcgqB zryO$C*BHMv0DrlUqc!Z^;9s6~?4|xm&cIv{bE$p@HQ6`hGtR$m_c|5%Dt&;eHe1fO ztQUYNoR`JdT8D(|6u^hGI;MRr0gxHzYh}0octFPrNdF{vf5VAvcogSxG|Y7&Py4H( zW%1KY!y7p;7Uy>=3P;jU+10{|q`l27Bbl%P=Y8*eADxMLR|hw}c>ebIULQDw^Fe`# zj0;b1H^3o1#x%{7*&qSuiNAUcjM#Eo;OTlzt1Rvs;DPf;vZM3=-@y6*ba=)M#t;1u D^<4R@ diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_3.json b/examples/2_Intermediate/inputs/input_ncsx/surface_3.json deleted file mode 100644 index d0914caa4..000000000 --- a/examples/2_Intermediate/inputs/input_ncsx/surface_3.json +++ /dev/null @@ -1,7022 +0,0 @@ -{ - "@module": "simsopt._core.json", - "@class": "SIMSON", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "graph": [ - { - "$type": "ref", - "value": "BoozerSurface4" - }, - { - "iota": -0.4271751366039177, - "G": 13.887478977083509 - } - ], - "simsopt_objs": { - "140342738246336": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738246336", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.506387961733893, - 0.1058930714809362, - 0.7258942274042265, - -0.001249592121112775, - 0.2763105569564668, - 0.01482550301512887, - -0.1280092780227772, - 0.005921392096802394, - 0.01864241438718947, - -0.01034831723350223, - 0.0001022108294955593, - 0.01892666378143068, - -0.007192153616853929, - -0.007355339046239706, - -0.01884714563379878, - -0.002596706082945131, - 0.01131859363705868, - 0.00964754529816095, - -0.0113260687651076, - -0.006628855789771619, - 0.000322284209286623, - 0.001842953924532827, - -0.0004161340928027646, - 0.00176264188836799, - 0.001814459617914206, - -0.001883356200860781, - -0.003584967425237995, - 0.0003165409191237933, - 0.00198839685289703, - 0.0007998064690618334, - 0.0005809753916376526, - 4.996792424044994e-05, - -0.0009656219012175038, - -0.001300735471703214, - -0.0004500391754653399, - 0.002413016477450284, - 0.00190334965179141, - -0.001622873850792805, - -0.001817132111793323, - 0.0005008124937015768, - 0.0009410326413637304, - 0.0005073038161052906, - -0.0001747050570155717, - -0.0004010070348672179, - 0.0002171330554898199, - 0.0001868680753017027, - -0.00049371483741256, - -1.263882515020243e-05, - 0.0005663593123846766, - 0.0001291744509577553, - -0.0002415255915965764, - 0.2855239540187146, - 0.02831674064739627, - 0.1230646086878452, - -0.1881027707999307, - -0.03092022550185042, - 0.07598032813641656, - 0.032842960392996, - -0.02022733960800226, - 0.03368541189764687, - -0.02527069889002642, - 0.03990545352197854, - 0.03266977475756579, - 0.007041509561223136, - -0.01843202758194484, - -0.003255107459418295, - 0.001087406605704745, - 0.02057587403483786, - 0.004332699549632209, - -0.003239348172858322, - -0.008060517809116506, - 0.0008303250764389791, - 0.002593682135814645, - 0.005122620691996364, - 0.002329497971206275, - -0.007021762243403233, - -0.002076255998522319, - 0.005455573755227739, - 0.0004034355313731426, - -0.002121189074115063, - -0.001155709211846629, - 0.0007060503790857225, - 0.001458108819397405, - 0.0007612900914783658, - -0.001579374591052191, - -0.0005648184298353118, - -3.483600030825498e-05, - 0.0006434230018098444, - 0.0002266872576160417, - -0.0005870263149471541, - -0.0004782734366555642, - 0.0004131000234993432, - -0.0002086017812282408, - -0.0002217317708794842, - 0.0004459870616389726, - 0.0002232186481886098, - -0.000550989811641543, - -0.0004679750418668452, - 0.0001971289820931924, - 0.0006305703105299488, - 1.94634036466225e-05, - -0.0005071137243856577, - 0.0009455853398023695, - -1.066704925256128, - 0.01954765252843791, - -0.03091192279856904, - -0.009251669123731003, - 0.03622032973711591, - 0.01289395028459556, - -0.01341289215090563, - -0.01055557464591715, - -0.007044726977866961, - -0.007171173731457627, - 0.01327231838496817, - 0.003220259676106272, - -0.006043809337864334, - -0.006228107449831786, - -0.0004722020937025503, - -0.0007632924616726337, - 0.0002557840887866895, - -0.0008300983337148277, - 0.001290373849098229, - 0.0002249498117545818, - -0.0003276137574950353, - -0.001560853624251917, - -0.003125967131907846, - 0.0007111137798287738, - 0.001688245514976161, - 0.00083638883723687, - -3.216802700299113e-05, - -0.003601309499252412, - -0.003364173533240832, - 0.003283863928203238, - 0.003620244544063828, - -0.001109032285114347, - -0.002277398193829699, - -0.0015519788484098, - 0.0002155015553257128, - 0.002349143532954114, - 0.000703914196138795, - -0.001628934087145739, - -0.0005728748367786014, - 0.000379102967651227, - 3.674770297429017e-05, - 0.0003644795696035227, - 0.0001196573774128766, - -0.0004826910821886253, - 1.895960151025164e-05, - 0.0002282029938596129, - -3.982416558199763e-05, - -0.0001869395233315697, - -0.0002051724761620464, - 0.0001303574263284748 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier1": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738246336" - } - }, - "140342738367104": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367104", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 652271.9419853 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current1": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 652271.9419853, - "dofs": { - "$type": "ref", - "value": "140342738367104" - } - }, - "Coil1": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "140342738247296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738247296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.268960636199869, - 0.2234285580503567, - 0.5468300987692021, - -0.07598922426224614, - 0.2314838962751658, - 0.01035784318060333, - -0.08314304549672957, - -0.04624738986383844, - 0.05377747860630284, - -0.001074456865203822, - -0.02151604922154927, - -0.01446679290684195, - 0.008416712252875694, - -0.009228184118107326, - 0.005277266362275169, - 0.01142201731157229, - 0.01681398796325401, - 0.009993706195866578, - 0.001370286955930781, - -0.008399573830195455, - -0.005099919856215084, - 0.005334309041669094, - -0.001419513324650316, - -0.003333508834690296, - 0.0002887180426140212, - -0.0001690909516323616, - -0.001592036575525169, - -4.507713399549196e-05, - 0.005287560419413426, - 0.001265480827581528, - -0.001229918688675425, - 0.001129035262308468, - -0.002142778995712242, - -0.001748186446934164, - 0.000763477629872682, - 0.0006002693299791978, - -0.0003618301004192371, - 0.000988040168005559, - 0.0007880569343915778, - -0.001135722890360471, - -0.0008706368325040781, - 0.0005507322770281398, - 0.0009555809731928289, - -0.0001476990895937402, - -0.001054028588515068, - -1.482885559572655e-05, - -0.0001592869344899095, - -0.0004579572172035079, - 0.0006274586578504227, - 0.0005393401407410331, - -3.182089243244368e-05, - 0.7629396044020591, - 0.189701305549749, - 0.2946730680990991, - -0.1569360429309221, - -0.08805875862294558, - -0.03077704895086764, - 0.1149783480591024, - 0.1301411562027019, - -0.001461622206151801, - 0.04030157913855995, - 0.0006901390690664732, - -0.02740323125842794, - -0.02323299800745342, - 0.006389595554305861, - 0.003627095782551136, - -0.01015301262258172, - -0.00621023311542419, - -0.003238881121248944, - -0.006852312518149265, - 0.005609446955056436, - 0.004762124576622897, - 0.006665063843140196, - -6.70526269177163e-05, - -0.003587348009623233, - -0.00322170321999071, - -0.004203038352780501, - 0.0006017815497404605, - 0.001489961187320675, - 0.002190828148742953, - -0.001018226063168117, - -0.002311412742654803, - 0.0005349636274747352, - 0.0005836793424641873, - 0.0003330260000362103, - 0.0006191475972028521, - 0.0004562062905476333, - -0.0003998259903290102, - -0.001606870160409875, - -0.0001005634411503442, - 0.0003784623778643909, - 0.0003873441313675419, - 0.0004934685418203405, - 0.0004248568990090018, - -0.0001368925780341768, - -0.0005224641202364183, - 7.402330001924084e-06, - 0.0001942482764948633, - 3.004761739695799e-05, - 0.0001571480542442944, - -1.517325817427362e-05, - -0.0001596571201453762, - -0.004342453367498795, - -0.8322915538683627, - 0.01842619538559772, - -0.1445740110997678, - -0.03919221672360253, - 0.0181885023851906, - 0.007857938792447916, - -0.0008409533080505334, - 0.0679882056193599, - -0.008440199737942872, - -0.05052693032193879, - 0.0111459982531894, - -0.002854468104354866, - -0.01157234174126346, - -0.002254287431014864, - 0.01222589681633306, - 0.007524606302699996, - -0.006381505382857464, - 0.003239076046582923, - 0.00341366498860203, - -0.00384676331619515, - 0.0004019843766106519, - 0.003278371413101953, - -0.001659157168404143, - -0.008498109023400214, - -0.0005869360684358228, - 0.001643969359882166, - -0.001687685453312147, - 0.001913710312578008, - 0.00307704389234268, - -0.001526906838827543, - -0.002096608532065649, - 0.002116359835823416, - 0.0002080593023590777, - -0.001289011271870523, - 0.0003465163727308783, - 0.0003373949660992973, - -0.0005853247790129025, - -0.0007569823284455652, - -3.821511752005806e-05, - 0.0008610335506290439, - 0.0002833895542749826, - -4.205984435378816e-05, - 0.0001112528084110792, - -0.0002379239249443648, - -0.0002104661224579025, - 0.0001263747200842462, - -0.0001533284829536013, - 0.0001522993485716547, - 0.0003185888026784711, - -0.0001603437887349448 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier2": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738247296" - } - }, - "140342738367296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 651868.5693674 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current2": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 651868.5693674, - "dofs": { - "$type": "ref", - "value": "140342738367296" - } - }, - "Coil2": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "140342738366624": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738366624", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.8980851593547453, - 0.1942559921705813, - 0.3889755333770718, - -0.1446923384557668, - 0.2616477438027761, - 0.03731920597998046, - -0.03289705406442186, - 0.02547136484396155, - 0.0532217952204826, - 0.050428478861979, - -0.03624366941253683, - -0.005451626158324006, - -0.01668041626206209, - 0.008182439166261426, - 0.003842296843932926, - 0.01470476196344816, - 0.01901860245900076, - 0.0218942171541043, - -0.00945061997881808, - 0.002564135600286371, - -0.006766476390874592, - -0.001269140258791196, - 0.002139997339095541, - 0.001657675366985779, - 0.0002979912903074711, - 0.006328865782046154, - 0.0004567550240531948, - -0.0008525115686061069, - -0.000977103914377314, - 0.0005522046297053057, - -0.0009600861596635313, - -0.001340814451660981, - -0.001495132545615355, - 0.0006434008787568705, - 0.000495245187218385, - -0.00134743162348104, - 0.0002393656261548005, - 0.0003132890671380592, - 0.0006144326019911972, - -0.0005029044211924421, - -0.000783957033721161, - -0.0004002250154653492, - 0.0002391300413782915, - -0.0003806672575232206, - -0.000145466845504183, - -7.221379723120868e-05, - 0.0006927366534479363, - -0.0001275371930022123, - -0.0001401106599127933, - -0.0002158625680600062, - -7.139828388354475e-05, - 1.129181984052873, - 0.2708936854358476, - 0.468646640557997, - 0.02081652240284051, - -0.1928735276123626, - -0.03518255586981031, - 0.01192001522947444, - -0.06439441858177399, - -0.004172035660790115, - -0.016589458610143, - 0.001628354566592241, - 0.003299047220307412, - 0.02371335634022325, - -0.02489732104888577, - 0.01517053799913132, - -0.007490250276888437, - -0.02121728304870823, - -0.006509759115093021, - 0.002045879344162137, - 0.0002421911767798572, - 0.005286626183968976, - -0.002423351884665077, - 0.003037404376098953, - -0.001045524131070646, - -0.001371894636819662, - 0.0002683048956511064, - 0.0006396825080884871, - 0.0006110891778951719, - -0.001898949452431453, - -0.001413075309279682, - -0.000175565426273192, - 0.00025798969577147, - 0.001643409441239691, - 7.18696208370806e-05, - -0.0001583133254478763, - 0.001580406281910882, - -0.002161287927547965, - -0.0003891297580205399, - 0.0004807171148380796, - -0.0003779554431875909, - -0.000203599914921071, - 0.0002418121495980502, - -0.0001924002563136939, - 0.0004205862222447268, - -0.0003081775538974041, - -1.457104090324735e-05, - -0.0001305465480840895, - -2.931233724533855e-05, - 3.39235991969411e-05, - -8.787891234509293e-05, - -0.0002714497625897205, - 0.01443108431390148, - -0.5884600992390547, - 0.1639153375972931, - -0.02326901782799053, - -0.09503676743509344, - -0.001882227773385535, - -0.1358423641287697, - -0.04946480830906624, - 0.01080325660372903, - -0.004462853204566593, - 0.02204832208587066, - -0.01988057349197482, - 0.006713767349457029, - 0.009816410920710776, - -0.004595941635687146, - 0.01307328931917959, - 0.0183731152740804, - -0.002049019816619709, - -0.009421893063595877, - 0.0003683472428279665, - 0.005559370162880608, - -0.001158799750525409, - 0.002656529580593774, - 0.005458828901239469, - 0.003685058507882478, - 0.005539080181031877, - 0.0003319744004354147, - 0.003297209047830778, - -0.001172958360845208, - -6.403055114502017e-05, - -0.0028127900802783, - -7.412199662635927e-05, - -1.404234804116165e-06, - 0.002212349409834762, - 0.001726905111358576, - 0.0009310945379894919, - -0.0002426222281296402, - 0.0007504861042380895, - -0.001511448440947522, - -0.0002060956498950368, - -0.000206480198377301, - 8.668234567299965e-05, - 0.0001267761162311387, - 1.493158313140079e-05, - 0.0001119337013982711, - 0.0003201242558262467, - 0.00016404919743365, - -0.0002679743018523173, - -0.000169663995881007, - 0.0002693900147788098, - -0.0001731877336642894 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier3": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738366624" - } - }, - "140342738367776": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367776", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 537743.5886473 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current3": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 537743.5886473, - "dofs": { - "$type": "ref", - "value": "140342738367776" - } - }, - "Coil3": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve1": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent1": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil4": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve1" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent1" - } - }, - "RotatedCurve2": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent2": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil5": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve2" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent2" - } - }, - "RotatedCurve3": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent3": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil6": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve3" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent3" - } - }, - "RotatedCurve4": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil7": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve4" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve5": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil8": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve5" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve6": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil9": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve6" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve7": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent4": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil10": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve7" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent4" - } - }, - "RotatedCurve8": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent5": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil11": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve8" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent5" - } - }, - "RotatedCurve9": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent6": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil12": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve9" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent6" - } - }, - "RotatedCurve10": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil13": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve10" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve11": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil14": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve11" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve12": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil15": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve12" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve13": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent7": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil16": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil16", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve13" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent7" - } - }, - "RotatedCurve14": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent8": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil17": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil17", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve14" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent8" - } - }, - "RotatedCurve15": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent9": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil18": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil18", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve15" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent9" - } - }, - "BiotSavart1": { - "@module": "simsopt.field.biotsavart", - "@class": "BiotSavart", - "@name": "BiotSavart1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "coils": [ - { - "$type": "ref", - "value": "Coil1" - }, - { - "$type": "ref", - "value": "Coil2" - }, - { - "$type": "ref", - "value": "Coil3" - }, - { - "$type": "ref", - "value": "Coil4" - }, - { - "$type": "ref", - "value": "Coil5" - }, - { - "$type": "ref", - "value": "Coil6" - }, - { - "$type": "ref", - "value": "Coil7" - }, - { - "$type": "ref", - "value": "Coil8" - }, - { - "$type": "ref", - "value": "Coil9" - }, - { - "$type": "ref", - "value": "Coil10" - }, - { - "$type": "ref", - "value": "Coil11" - }, - { - "$type": "ref", - "value": "Coil12" - }, - { - "$type": "ref", - "value": "Coil13" - }, - { - "$type": "ref", - "value": "Coil14" - }, - { - "$type": "ref", - "value": "Coil15" - }, - { - "$type": "ref", - "value": "Coil16" - }, - { - "$type": "ref", - "value": "Coil17" - }, - { - "$type": "ref", - "value": "Coil18" - } - ], - "points": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - [ - 1.6994002310970135, - 0.0, - 0.0 - ], - [ - 1.6783018259696605, - 0.013989715741971059, - -0.1636315863473969 - ], - [ - 1.6198439756699088, - 0.030964741074693672, - -0.3117520392562631 - ], - [ - 1.5367401587040257, - 0.0527383043076104, - -0.42721424309952216 - ], - [ - 1.4533793559794126, - 0.07505412701363659, - -0.4945960106143317 - ], - [ - 1.3977674246586664, - 0.09067971038199396, - -0.5090677526726153 - ], - [ - 1.3837646497917107, - 0.09273754020340279, - -0.47573267424024956 - ], - [ - 1.4189984558088469, - 0.07524290291647664, - -0.3885884328666778 - ], - [ - 1.488625413157553, - 0.04091589310339855, - -0.22685351074773188 - ], - [ - 1.5270112900117823, - 1.4598835763232583e-17, - -8.440277459175405e-17 - ], - [ - 1.488625413157553, - -0.04091589310339852, - 0.22685351074773175 - ], - [ - 1.4189984558088469, - -0.07524290291647659, - 0.38858843286667755 - ], - [ - 1.3837646497917109, - -0.09273754020340276, - 0.4757326742402494 - ], - [ - 1.3977674246586664, - -0.09067971038199396, - 0.5090677526726153 - ], - [ - 1.4533793559794128, - -0.07505412701363659, - 0.49459601061433184 - ], - [ - 1.5367401587040257, - -0.05273830430761048, - 0.42721424309952244 - ], - [ - 1.6198439756699088, - -0.030964741074693686, - 0.31175203925626327 - ], - [ - 1.6783018259696605, - -0.013989715741971097, - 0.16363158634739727 - ], - [ - 1.6842772255112095, - 0.19420224105350636, - -0.008055394996668203 - ], - [ - 1.6719250026284131, - 0.2076610322571218, - -0.16941311833921388 - ], - [ - 1.6227864154581646, - 0.2206024842412186, - -0.31413843035654115 - ], - [ - 1.5487656244550263, - 0.2355770905626783, - -0.4242336639374951 - ], - [ - 1.4749965147846282, - 0.24938195108033903, - -0.48414562579857334 - ], - [ - 1.427415008114949, - 0.25617741122630683, - -0.49028096131961496 - ], - [ - 1.417531244922719, - 0.25036618867897314, - -0.44709020590910264 - ], - [ - 1.449857747751978, - 0.22821675068372424, - -0.34548387414448184 - ], - [ - 1.5008383928838258, - 0.19296872639831852, - -0.1691261555542676 - ], - [ - 1.5058746112585182, - 0.15101838177786614, - 0.05948757176482956 - ], - [ - 1.4394473334126232, - 0.10744940820632023, - 0.2712899633567697 - ], - [ - 1.3602366419035334, - 0.07311260656762869, - 0.4125782417924735 - ], - [ - 1.3271492061036625, - 0.06069761265402513, - 0.48470135297904066 - ], - [ - 1.3473158465725596, - 0.070900447379398, - 0.5090193438473741 - ], - [ - 1.411166020759621, - 0.09551547943751455, - 0.48840106433464026 - ], - [ - 1.502334977107431, - 0.12608729030002952, - 0.4170359355005629 - ], - [ - 1.5917782209822333, - 0.15461353411260095, - 0.3004963236744969 - ], - [ - 1.6562451150262758, - 0.17704661510806263, - 0.15362341656536094 - ], - [ - 1.6399617322798796, - 0.382699232250926, - -0.015204138966055217 - ], - [ - 1.6361505248748751, - 0.3987930493198212, - -0.16979531952817206 - ], - [ - 1.5978425230103812, - 0.4101130655877241, - -0.3073413704096919 - ], - [ - 1.5355880119871803, - 0.4187567508438983, - -0.4090439665994181 - ], - [ - 1.4729755157787348, - 0.4238105353437439, - -0.4587089313771028 - ], - [ - 1.4324002016749848, - 0.42149571720479945, - -0.4548578000784214 - ], - [ - 1.4234877567638013, - 0.4075325092120673, - -0.4013186407197054 - ], - [ - 1.4462789995286485, - 0.3793699063595553, - -0.2874893545009086 - ], - [ - 1.4717610827746987, - 0.33941052493685775, - -0.10618203212219983 - ], - [ - 1.4456510033743932, - 0.2927423529583782, - 0.10953452054650564 - ], - [ - 1.3616543320485146, - 0.24619005557556925, - 0.2966303539283297 - ], - [ - 1.2812220262271168, - 0.21313098435175326, - 0.4156629340605351 - ], - [ - 1.2536342632692783, - 0.2062594460551207, - 0.47387548565056 - ], - [ - 1.2811061865047602, - 0.2247249545340336, - 0.49073063977543124 - ], - [ - 1.3521896547180359, - 0.2584444372097102, - 0.46619885566257085 - ], - [ - 1.4484457509781394, - 0.29729739057458465, - 0.39409351747290633 - ], - [ - 1.5408080527207988, - 0.3327083909847875, - 0.28096023640178674 - ], - [ - 1.6074722082140225, - 0.36085709100968216, - 0.14007464690003416 - ], - [ - 1.5699644076507298, - 0.5609430567921626, - -0.020618195772928002 - ], - [ - 1.5721346535028642, - 0.5808468211291525, - -0.16456788714055914 - ], - [ - 1.5440945641725337, - 0.5927057827190801, - -0.29239303403286043 - ], - [ - 1.4952524414497743, - 0.5971540307560984, - -0.3833427864981317 - ], - [ - 1.4440767716845355, - 0.5940011175304036, - -0.4202671979396572 - ], - [ - 1.4082273401581493, - 0.5813420777607314, - -0.4052912689425985 - ], - [ - 1.3961624699153694, - 0.5567915189770487, - -0.3422397146029258 - ], - [ - 1.4037571382962626, - 0.5189502465561905, - -0.22183297750954292 - ], - [ - 1.4024526238428119, - 0.4710498657980357, - -0.048149649880064295 - ], - [ - 1.3537854792583164, - 0.41968367380214866, - 0.1422047905077062 - ], - [ - 1.2642248156551643, - 0.3729564495280606, - 0.30035501759371114 - ], - [ - 1.18957231463363, - 0.34385158749364614, - 0.3991916630590425 - ], - [ - 1.1699125319170942, - 0.34354021762793435, - 0.446495419438404 - ], - [ - 1.204674909948544, - 0.36982459620419345, - 0.45811607371369506 - ], - [ - 1.28070261322415, - 0.41184964549777375, - 0.4313718214953074 - ], - [ - 1.378614214386285, - 0.45874170397609787, - 0.36096794004115507 - ], - [ - 1.470272653305162, - 0.5008920293658823, - 0.2549468731809324 - ], - [ - 1.5358449597337283, - 0.5343349461581237, - 0.12405579224915278 - ], - [ - 1.47943263840522, - 0.7274983324633081, - -0.024153647921828485 - ], - [ - 1.4848836328153898, - 0.74986090717152, - -0.1550865912955078 - ], - [ - 1.4652570522641715, - 0.7633561358585721, - -0.27082274356984937 - ], - [ - 1.4281152698920623, - 0.7655858469925065, - -0.34769821045564725 - ], - [ - 1.3850829515396341, - 0.753429779596402, - -0.3698209414628336 - ], - [ - 1.350208237301702, - 0.727063640870112, - -0.34498701408167254 - ], - [ - 1.3317468267390018, - 0.6885142574366762, - -0.2770841720763705 - ], - [ - 1.3227108234300677, - 0.6393422705520097, - -0.1594287439742389 - ], - [ - 1.29945130143365, - 0.5848613836156326, - -0.004984187713953002 - ], - [ - 1.2393329304317604, - 0.5325920660943073, - 0.15368042101712426 - ], - [ - 1.1546002243735143, - 0.4899549214292477, - 0.2842042913561131 - ], - [ - 1.091246269869086, - 0.46809954567368006, - 0.36738245415242793 - ], - [ - 1.0809366305893418, - 0.47528492630419295, - 0.40788994698457315 - ], - [ - 1.1214155059041317, - 0.5079940127364853, - 0.4165553904093905 - ], - [ - 1.1993658498030404, - 0.5568978318990657, - 0.3887264716237439 - ], - [ - 1.2958231756104137, - 0.6113394613821291, - 0.3219901301123801 - ], - [ - 1.3838571152594126, - 0.659813182044889, - 0.22568607237733873 - ], - [ - 1.4459947451523711, - 0.6977329991752353, - 0.10723325371267761 - ], - [ - 1.372142384271262, - 0.8835202499329097, - -0.02638763074471772 - ], - [ - 1.3791552589154634, - 0.9067693106694855, - -0.14254741906745022 - ], - [ - 1.3651915825627357, - 0.9210842485784534, - -0.2425116294476678 - ], - [ - 1.3345134594365777, - 0.918843462322586, - -0.3019479595009338 - ], - [ - 1.2940571128142813, - 0.8932121452088223, - -0.3110022689237121 - ], - [ - 1.2574480219683042, - 0.8495905565769875, - -0.28224996276748004 - ], - [ - 1.2323790951748657, - 0.7968666821705338, - -0.21713038520368647 - ], - [ - 1.2099789863223431, - 0.7392616975737065, - -0.11146908601899103 - ], - [ - 1.1734238098900842, - 0.6831869349668819, - 0.01728174348417251 - ], - [ - 1.1120660618846032, - 0.6356585670553434, - 0.14525134885241506 - ], - [ - 1.0389203687908508, - 0.6015934216909348, - 0.25356905443616035 - ], - [ - 0.9897052411246712, - 0.5891372383587713, - 0.3264238070222187 - ], - [ - 0.9884030038742997, - 0.6035741267018994, - 0.3637840816310097 - ], - [ - 1.0322619459886482, - 0.6413013044542528, - 0.37096231887975123 - ], - [ - 1.1096893850505247, - 0.6958390615182914, - 0.34308517980832454 - ], - [ - 1.202215588988796, - 0.7568904492000438, - 0.2817735027633683 - ], - [ - 1.2840782689724393, - 0.8109092079606037, - 0.19620068299593066 - ], - [ - 1.3409404467719361, - 0.8523334925181535, - 0.09069227787291592 - ], - [ - 1.2502538664690575, - 1.0292521373915045, - -0.027426592570212075 - ], - [ - 1.256941095358689, - 1.052229590730932, - -0.12699365670345827 - ], - [ - 1.2446279580842534, - 1.0632951843849379, - -0.20809838917967785 - ], - [ - 1.2146225729651223, - 1.04961346893345, - -0.25136689819756436 - ], - [ - 1.1735031793764026, - 1.005543982961032, - -0.25480786139485395 - ], - [ - 1.1356590371522042, - 0.9450001733029407, - -0.22988406555090737 - ], - [ - 1.1061879124536702, - 0.8818951153276099, - -0.17359600563416452 - ], - [ - 1.0758410568850862, - 0.820923005849376, - -0.08534430411690223 - ], - [ - 1.0350138022481514, - 0.7692629544813058, - 0.017401850617693983 - ], - [ - 0.9798507919612658, - 0.7322324093172012, - 0.12116090418432483 - ], - [ - 0.9209149041900989, - 0.7101145757129373, - 0.21466226502849456 - ], - [ - 0.8853211985256927, - 0.7077132652623788, - 0.28157757475460077 - ], - [ - 0.8914292083068057, - 0.7290388251204014, - 0.3176863999834083 - ], - [ - 0.9372024508963027, - 0.7714676545557816, - 0.3245104825844057 - ], - [ - 1.0128045306767095, - 0.8307688330784709, - 0.29858297114931937 - ], - [ - 1.0994960047446458, - 0.8967100648346599, - 0.24436833114403392 - ], - [ - 1.173083068525992, - 0.9543440150367465, - 0.1691693890539075 - ], - [ - 1.2228842218421325, - 0.9976259907082258, - 0.07554565895538257 - ], - [ - 1.1160721466297001, - 1.1642692035837445, - -0.02512721406814269 - ], - [ - 1.1187826695059224, - 1.1839965128922867, - -0.10782874302834074 - ], - [ - 1.1035917458414257, - 1.1848081907687937, - -0.17273751778101537 - ], - [ - 1.0717675882630793, - 1.1531746735709283, - -0.20806712977603087 - ], - [ - 1.0310662558452146, - 1.0900675158418494, - -0.21480863498130903 - ], - [ - 0.9942894248877221, - 1.016349081961585, - -0.1983864109643031 - ], - [ - 0.9631243156206923, - 0.9474115818784362, - -0.15348389702925708 - ], - [ - 0.9299886236306047, - 0.8882618935270896, - -0.08352860947752197 - ], - [ - 0.891341386402659, - 0.8466103888480658, - -0.0020869773980715617 - ], - [ - 0.845988295155644, - 0.8240320761086896, - 0.08612594453816622 - ], - [ - 0.8009135479675108, - 0.8153023156841509, - 0.17114439569961204 - ], - [ - 0.7771260902898445, - 0.823202537272848, - 0.23438372067921795 - ], - [ - 0.7895303641786381, - 0.8519004424534806, - 0.27031067788381624 - ], - [ - 0.8365903963318256, - 0.8994511099875337, - 0.2790290010096959 - ], - [ - 0.9092902505904025, - 0.9628631999173825, - 0.2580389861972914 - ], - [ - 0.9889604459032256, - 1.0318698538509965, - 0.21254216504650802 - ], - [ - 1.053363306683564, - 1.0905460906651514, - 0.14726613686132548 - ], - [ - 1.0947997857919431, - 1.1334411904691026, - 0.06424601735685824 - ], - [ - 0.969069291645036, - 1.2883099019968638, - -0.015897707201191248 - ], - [ - 0.9635974802732213, - 1.298131013363764, - -0.08641688385891148 - ], - [ - 0.9439004472794146, - 1.2823400125074071, - -0.14488587568104352 - ], - [ - 0.9122846717628605, - 1.2317699267530093, - -0.18241626798149946 - ], - [ - 0.8750794542821766, - 1.1531463250137057, - -0.19766700605182588 - ], - [ - 0.8414811191884496, - 1.0701160832754817, - -0.19117628234262732 - ], - [ - 0.811327489649873, - 0.9990996367815337, - -0.158098020908346 - ], - [ - 0.7795965104164222, - 0.9462491111207345, - -0.10361813816781541 - ], - [ - 0.7462326668013561, - 0.9181683752340059, - -0.035877500064915434 - ], - [ - 0.7107906732322347, - 0.911414736312963, - 0.04450828418002611 - ], - [ - 0.6781578922646787, - 0.9163064609223585, - 0.12474054465430301 - ], - [ - 0.6653031454498792, - 0.935042192032603, - 0.18570632175167526 - ], - [ - 0.6837352599493333, - 0.9720251606545622, - 0.22367672892582316 - ], - [ - 0.731349955033474, - 1.0250589590674866, - 0.23757299748098523 - ], - [ - 0.7998355770437744, - 1.0920459871344435, - 0.22431065605496744 - ], - [ - 0.8715260272296552, - 1.1630545233596028, - 0.18872583618416677 - ], - [ - 0.9261623640939791, - 1.221354424099197, - 0.13332703552087935 - ], - [ - 0.957570860423425, - 1.2619597390584323, - 0.060742988002651585 - ], - [ - 0.8064582886961086, - 1.3968267302067092, - -6.347491830740043e-18 - ], - [ - 0.7927706352632612, - 1.3901406076212797, - -0.06854591368434065 - ], - [ - 0.7714532715053678, - 1.3565763834625832, - -0.13135252311966725 - ], - [ - 0.7434590189105229, - 1.2909258942340487, - -0.17700631818295226 - ], - [ - 0.7118576885393798, - 1.2011640618789248, - -0.20229892591273496 - ], - [ - 0.6828587030071869, - 1.1119740038373975, - -0.20600708353194308 - ], - [ - 0.6561253980040709, - 1.0417796673764446, - -0.18372234044595792 - ], - [ - 0.6285190078958866, - 0.9977878131555104, - -0.139906278642292 - ], - [ - 0.6009547946673108, - 0.9845353340578062, - -0.07829336456386192 - ], - [ - 0.5737796224875098, - 0.9938154584960567, - -1.3256724137797602e-17 - ], - [ - 0.5521552128838036, - 1.0127097857368552, - 0.0782933645638619 - ], - [ - 0.5498500898312496, - 1.0432073341769845, - 0.1399062786422919 - ], - [ - 0.5741449580920682, - 1.089111096427923, - 0.18372234044595787 - ], - [ - 0.6215683841674879, - 1.1473599859182158, - 0.20600708353194308 - ], - [ - 0.6843097474303625, - 1.2170688730938357, - 0.20229892591273496 - ], - [ - 0.7462451093545682, - 1.2893173441661923, - 0.1770063181829524 - ], - [ - 0.7891029744999337, - 1.3463863226875539, - 0.1313525231196673 - ], - [ - 0.8075117634007333, - 1.381629813322951, - 0.0685459136843408 - ], - [ - 0.6311744572538069, - 1.483393575590424, - 0.015897707201191203 - ], - [ - 0.6141037623660716, - 1.460260560579625, - -0.06074298800265144 - ], - [ - 0.5946427762474283, - 1.412757347384037, - -0.13332703552087927 - ], - [ - 0.5714717496009905, - 1.336290941320011, - -0.18872583618416655 - ], - [ - 0.5458217784373954, - 1.238700922137716, - -0.22431065605496728 - ], - [ - 0.5220521214125398, - 1.1458971196493388, - -0.2375729974809851 - ], - [ - 0.4999308522698348, - 1.0781446849065606, - -0.22367672892582305 - ], - [ - 0.47711871918558246, - 1.0436905211935905, - -0.18570632175167523 - ], - [ - 0.4544657266782363, - 1.0454551929393012, - -0.12474054465430297 - ], - [ - 0.43391297841440446, - 1.0712701479486404, - -0.044508284180026 - ], - [ - 0.422040804503454, - 1.1053406342007857, - 0.03587750006491553 - ], - [ - 0.42967751333078924, - 1.148274938282688, - 0.1036181381678154 - ], - [ - 0.4595819215396772, - 1.2021800352162126, - 0.15809802090834593 - ], - [ - 0.5060071535206463, - 1.2638020676598989, - 0.1911762823426273 - ], - [ - 0.5611142846014479, - 1.3344142002450405, - 0.19766700605182583 - ], - [ - 0.6106017123043732, - 1.40594666460629, - 0.1824162679814995 - ], - [ - 0.6385888034809621, - 1.4586117722411704, - 0.14488587568104355 - ], - [ - 0.6424156948768459, - 1.4835654036211658, - 0.0864168838589116 - ], - [ - 0.4502506338325494, - 1.5486814332294234, - 0.025127214068142688 - ], - [ - 0.43418897174594806, - 1.5148450217881357, - -0.06424601735685803 - ], - [ - 0.41775896517204697, - 1.4575124283349208, - -0.1472661368613254 - ], - [ - 0.3991452838826863, - 1.3723997964156778, - -0.21254216504650786 - ], - [ - 0.3792188662024269, - 1.2689000563834985, - -0.2580389861972913 - ], - [ - 0.3606523125454029, - 1.17423409077922, - -0.27902900100969585 - ], - [ - 0.34300224257059864, - 1.1097035736646204, - -0.2703106778838163 - ], - [ - 0.32435126459317054, - 1.0846122047711089, - -0.23438372067921803 - ], - [ - 0.30561574316299944, - 1.1012626366170664, - -0.17114439569961207 - ], - [ - 0.2906385638655353, - 1.1446633929634202, - -0.08612594453816623 - ], - [ - 0.28751541064891745, - 1.1952294784931772, - 0.002086977398071511 - ], - [ - 0.3042630531928256, - 1.2495247200581734, - 0.08352860947752183 - ], - [ - 0.3389203399359804, - 1.3077959152692393, - 0.1534838970292569 - ], - [ - 0.3830394116478643, - 1.3692544416477792, - 0.19838641096430307 - ], - [ - 0.42849303263663036, - 1.4379633284677857, - 0.21480863498130903 - ], - [ - 0.4627947681817119, - 1.5047652951740715, - 0.20806712977603092 - ], - [ - 0.47427811889694227, - 1.5481425826898911, - 0.17273751778101543 - ], - [ - 0.46597972340394866, - 1.5608924695520416, - 0.10782874302834086 - ], - [ - 0.26623156464594555, - 1.5973776782376736, - 0.027426592570212086 - ], - [ - 0.2525273405078759, - 1.5578617973565652, - -0.0755456589553823 - ], - [ - 0.23994462670846486, - 1.493091745611284, - -0.16916938905390727 - ], - [ - 0.2268256936036837, - 1.4005465038856892, - -0.24436833114403372 - ], - [ - 0.21306464877995507, - 1.2924988691732417, - -0.2985829711493192 - ], - [ - 0.19950936159515342, - 1.197374958243127, - -0.3245104825844055 - ], - [ - 0.1856515387460257, - 1.1365197526293447, - -0.31768639998340825 - ], - [ - 0.17023706704960895, - 1.1205672810633258, - -0.2815775747546008 - ], - [ - 0.15451981006996263, - 1.1525929896088065, - -0.2146622650284945 - ], - [ - 0.1442064719623487, - 1.2146918824153576, - -0.12116090418432485 - ], - [ - 0.1486943596470074, - 1.2809797232550753, - -0.017401850617694038 - ], - [ - 0.17301964917409793, - 1.3421671886214719, - 0.08534430411690201 - ], - [ - 0.2106496171202824, - 1.3989343912079597, - 0.1735960056341643 - ], - [ - 0.25056463808494184, - 1.4560096628626547, - 0.22988406555090726 - ], - [ - 0.2840750441786392, - 1.5190555562422876, - 0.2548078613948539 - ], - [ - 0.3016806417681154, - 1.5767007386645389, - 0.2513668981975644 - ], - [ - 0.29852666235688846, - 1.6095270221537858, - 0.20809838917967785 - ], - [ - 0.2827870085073456, - 1.6146577150067292, - 0.12699365670345847 - ], - [ - 0.07907978906424543, - 1.6300702873547164, - 0.026387630744717717 - ], - [ - 0.06767223363106677, - 1.5874552381256284, - -0.09069227787291562 - ], - [ - 0.060228839770381716, - 1.517499005357982, - -0.1962006829959305 - ], - [ - 0.054378562394655314, - 1.4195944654899904, - -0.2817735027633681 - ], - [ - 0.047769611695101064, - 1.3089387285228316, - -0.3430851798083244 - ], - [ - 0.0392522481431576, - 1.2146157208132555, - -0.3709623188797512 - ], - [ - 0.028509024853702623, - 1.1577691738829419, - -0.3637840816310097 - ], - [ - 0.01535519417176863, - 1.1516785002519538, - -0.3264238070222188 - ], - [ - 0.001535001538528688, - 1.2005281427274415, - -0.25356905443616035 - ], - [ - -0.005536563739160019, - 1.2809067438062554, - -0.14525134885241517 - ], - [ - 0.004945336269905037, - 1.357808296253775, - -0.01728174348417257 - ], - [ - 0.035229916982467226, - 1.4175033889873456, - 0.11146908601899079 - ], - [ - 0.07391724260166962, - 1.465704944599581, - 0.21713038520368624 - ], - [ - 0.1070429938268796, - 1.5137772092515378, - 0.28224996276748 - ], - [ - 0.12651585231249446, - 1.5672924062495237, - 0.31100226892371197 - ], - [ - 0.12848505075432048, - 1.615144288725623, - 0.30194795950093384 - ], - [ - 0.11508656701327388, - 1.6428327158212368, - 0.2425116294476679 - ], - [ - 0.09570762895414685, - 1.6477681453184383, - 0.1425474190674504 - ], - [ - -0.10968428207856765, - 1.644975414278412, - 0.024153647921828485 - ], - [ - -0.1187428702317248, - 1.6011346826283765, - -0.10723325371267727 - ], - [ - -0.12051358022698579, - 1.528362008044946, - -0.22568607237733856 - ], - [ - -0.11847608391238704, - 1.4278855195823064, - -0.32199013011237987 - ], - [ - -0.1173952551644532, - 1.3171302103104772, - -0.3887264716237438 - ], - [ - -0.12077203295187375, - 1.2251713226789986, - -0.4165553904093903 - ], - [ - -0.1288594950794247, - 1.1737610451236213, - -0.40788994698457326 - ], - [ - -0.1402370368811816, - 1.1790967643284773, - -0.36738245415242804 - ], - [ - -0.15298670351981986, - 1.2448905862372996, - -0.28420429135611314 - ], - [ - -0.1584282061241691, - 1.33958983454767, - -0.1536804210171244 - ], - [ - -0.1432208348131711, - 1.4177885298301067, - 0.004984187713952829 - ], - [ - -0.10766876370376978, - 1.4651723102270757, - 0.15942874397423845 - ], - [ - -0.06960257556156053, - 1.4975837120836268, - 0.27708417207637004 - ], - [ - -0.045448535489328035, - 1.5328464543373375, - 0.3449870140816723 - ], - [ - -0.0400521466716222, - 1.5762319121802544, - 0.36982094146283345 - ], - [ - -0.05104084267269405, - 1.619577026755249, - 0.34769821045564725 - ], - [ - -0.07154272034383691, - 1.6506278982643618, - 0.27082274356984937 - ], - [ - -0.09304322149231362, - 1.660877401267612, - 0.155086591295508 - ], - [ - -0.2991912665668548, - 1.6401005884590016, - 0.020618195772928002 - ], - [ - -0.30517484236413855, - 1.5972482244827588, - -0.12405579224915245 - ], - [ - -0.3013511046685857, - 1.5237394829347621, - -0.25494687318093223 - ], - [ - -0.29202513777448075, - 1.423285783664898, - -0.3609679400411549 - ], - [ - -0.28367905107138736, - 1.315045820494117, - -0.4313718214953073 - ], - [ - -0.2820599597171182, - 1.2281913734192667, - -0.45811607371369506 - ], - [ - -0.28744171027112114, - 1.1849440816599435, - -0.44649541943840404 - ], - [ - -0.2970019474157096, - 1.2021256378582017, - -0.39919166305904286 - ], - [ - -0.30912264803103273, - 1.2813290312161014, - -0.30035501759371114 - ], - [ - -0.3134360165629157, - 1.3822544532132675, - -0.14220479050770632 - ], - [ - -0.2932851616910564, - 1.4500845327510345, - 0.04814964988006416 - ], - [ - -0.25245447233027246, - 1.4751644657864038, - 0.2218329775095426 - ], - [ - -0.2158856349118351, - 1.487507926245661, - 0.34223971460292557 - ], - [ - -0.20065666244945252, - 1.5102316897611128, - 0.4052912689425985 - ], - [ - -0.20761832818459214, - 1.5476077280590304, - 0.42026719793965733 - ], - [ - -0.23047566011783183, - 1.5935036147442576, - 0.3833427864981318 - ], - [ - -0.25874901728160354, - 1.6335780097784152, - 0.2923930340328605 - ], - [ - -0.2830392239461499, - 1.6519319586679024, - 0.16456788714055937 - ], - [ - -0.4885536090018366, - 1.6115981375141735, - 0.015204138966055252 - ], - [ - -0.49122469615687303, - 1.5725403136956537, - -0.14007464690003377 - ], - [ - -0.4822701077153274, - 1.5007331115042382, - -0.28096023640178647 - ], - [ - -0.46675578277265456, - 1.40303951163799, - -0.39409351747290594 - ], - [ - -0.4522753792686361, - 1.3002528103251827, - -0.4661988556625707 - ], - [ - -0.44593557376160353, - 1.2218329797255438, - -0.4907306397754312 - ], - [ - -0.448191211580398, - 1.188808842073344, - -0.47387548565056 - ], - [ - -0.4560341663313562, - 1.2161363147767326, - -0.4156629340605353 - ], - [ - -0.46762032373671114, - 1.3023222705149293, - -0.2966303539283299 - ], - [ - -0.4693031872616102, - 1.398341670407877, - -0.10953452054650593 - ], - [ - -0.44194240448021854, - 1.4442877484526102, - 0.10618203212219947 - ], - [ - -0.3945955234256253, - 1.4421993077315292, - 0.287489354500908 - ], - [ - -0.3588103725362344, - 1.4365428139396097, - 0.401318640719705 - ], - [ - -0.35117410215179395, - 1.4512428216388897, - 0.4548578000784213 - ], - [ - -0.3694570678902022, - 1.487539483488743, - 0.45870893137710267 - ], - [ - -0.4051400217565432, - 1.539236603549691, - 0.4090439665994183 - ], - [ - -0.4437529282823074, - 1.5888287489678738, - 0.30734137040969195 - ], - [ - -0.4727103508738113, - 1.6163444436167955, - 0.16979531952817234 - ], - [ - -0.6739545385313982, - 1.5557279848350325, - 0.008055394996668238 - ], - [ - -0.6747956911755091, - 1.522873652060666, - -0.15362341656536058 - ], - [ - -0.6619898621807113, - 1.4558271436177146, - -0.30049632367449663 - ], - [ - -0.6419726920595458, - 1.364103900318963, - -0.4170359355005624 - ], - [ - -0.6228641787322718, - 1.2698633626539875, - -0.4884010643346401 - ], - [ - -0.6122563347160386, - 1.2022599737428727, - -0.5090193438473741 - ], - [ - -0.6110089285443768, - 1.1796937334251338, - -0.48470135297904077 - ], - [ - -0.6168009463273025, - 1.2145557903307105, - -0.41257824179247377 - ], - [ - -0.6266697495780335, - 1.3003226622482607, - -0.27128996335677 - ], - [ - -0.6221515505712095, - 1.3796348591528258, - -0.05948757176482997 - ], - [ - -0.5833033772450396, - 1.3962485384115626, - 0.16912615555426716 - ], - [ - -0.5272873702147435, - 1.3697220167687656, - 0.3454838741444812 - ], - [ - -0.49194214281668025, - 1.3528011631007426, - 0.4470902059091022 - ], - [ - -0.4918513580597592, - 1.36426636438387, - 0.49028096131961485 - ], - [ - -0.5215271525114118, - 1.4020754278371672, - 0.48414562579857334 - ], - [ - -0.5703670672506057, - 1.4590589205674618, - 0.42423366393749534 - ], - [ - -0.62034585223823, - 1.5156755028236684, - 0.3141384303565412 - ], - [ - -0.6561227720034385, - 1.551760041627131, - 0.1694131183392142 - ] - ] - } - }, - "140342738037920": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738037920", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.4396784976662238, - 0.07232256637643669, - -0.0017168784604873716, - -0.00017591785195430736, - -1.4713432097432976e-05, - -6.318454351696858e-05, - 3.9299166971699546e-05, - 0.17655866899125044, - -0.0656036574895566, - 0.0007959457181250228, - 0.0005379381755404229, - -1.984374673756674e-05, - -0.00014203386343491044, - -3.073880724298774e-05, - 0.04439060025501837, - 0.04146943438862737, - 0.010751294094100984, - -0.0014194507660624516, - -0.0001946438745373209, - -3.9321575804151604e-05, - 3.0582923587384204e-05, - -0.013580129107756545, - -0.0061469441447517155, - -0.0023387484100976996, - -0.0005012637408009066, - 0.00033236306330178223, - -2.2780849338490352e-05, - -2.8429337897055636e-06, - 0.0012985766038578564, - 0.004341999021161757, - 0.0011473640768298434, - -0.00011364509312266224, - 0.0003193475479129732, - -4.786873624144241e-06, - -8.446523592593317e-06, - -0.0015720127137336347, - -0.0012881646177589452, - -0.0007869914216321488, - -1.6361133818130227e-05, - 5.55417368277998e-05, - -5.8830169072226763e-05, - 2.535600709221514e-05, - 0.0007135287891833859, - 6.188316596345133e-06, - 0.0002479502659434782, - 0.0001702275636113531, - 3.483517136079659e-05, - -1.0184276958365754e-05, - 4.641598732067948e-06, - 0.14921824094299405, - -0.00043448018286282964, - -0.00044777968407376913, - -0.00016863171812403466, - -4.955111890369024e-06, - -1.982466743665499e-05, - -0.03641559887142441, - -0.009560213725251095, - 0.0018000090155919418, - 7.375262912627103e-06, - 2.221419667767416e-05, - -4.281306228397052e-05, - 0.007045624332852643, - 0.003291725820297764, - 0.0010589601698750434, - -0.000307494722222267, - -1.4825821763999563e-05, - -8.783572537259268e-06, - -0.002246967504088654, - -0.0012551705019901867, - 0.0001851457881549044, - -0.00040514699197309503, - 4.2493466956557895e-05, - 1.3748920703286263e-05, - 0.0006632293691167362, - 0.0008489334566164892, - 0.00014768029719319477, - -1.1851386432420375e-05, - 6.184094152166256e-05, - -2.574660175175791e-05, - 5.212056630362284e-05, - -0.000173023558144979, - -0.0001925083797543852, - -4.1735327622644494e-05, - 1.5088284178548434e-05, - -4.809284814326903e-06, - -0.02235093143565873, - 0.0030434994371424284, - 0.00040606751536435674, - 0.00010550024750185843, - -0.00010660165001437607, - -3.198837110832411e-05, - 0.0303518880046735, - -0.0002009142276002284, - -0.000741235763578501, - 0.00012736212766935548, - -0.00012484420802568642, - 5.670271682412382e-05, - -0.024008822127762747, - -0.0012400158372468768, - 0.000765092358010478, - 7.833148937094587e-05, - -0.00012921782486968535, - -1.78650775845365e-05, - 0.0017345249869115662, - 0.0015692037522975664, - -0.0002900814692255432, - -0.00012945785489652153, - -1.002576783342721e-05, - 4.14555519743603e-05, - -0.0007515407932780015, - 0.00020826078113116375, - -3.513831270613622e-05, - 0.00013764185309997776, - 3.841852596417541e-05, - 1.636904486771199e-05, - 0.0002494907915368058, - 0.00013481094843538125, - -4.038908945904893e-06, - 3.748940901436102e-05, - -1.1361730720758814e-05, - -1.688223957884492e-05, - -1.2171105952534395e-05, - -3.6391622781640864e-05, - -2.2576699946186432e-05, - 3.3100727940570355e-05, - 1.3045548943149944e-05, - 1.236298201798866e-05, - 0.031735068346156525, - 0.05509793324984616, - -0.00348614822378161, - -2.2519602656728635e-05, - 0.00019991951421581347, - 5.553007609817959e-06, - 8.119966536863101e-05, - 0.004507776681422563, - -0.02575250912508862, - -0.0016382048105159314, - 0.0003882011075955719, - 6.966652104884665e-05, - -1.2137417557027789e-06, - 4.525825964309204e-06, - -0.002151242544861001, - 0.0007792694641628402, - 0.0014381981246847078, - -0.0008792840026122963, - -9.755073305400306e-05, - 2.0324023592375216e-06, - 1.934537631903572e-05, - 0.0006273042732522928, - 0.0006327831238223836, - -0.0003218202374152053, - -0.00037923191175175634, - 3.8914781173360224e-05, - 5.5466893929468935e-05, - 1.8395147475562628e-05, - -0.000406465891166161, - -5.288122438744325e-05, - 0.00010848790133383144, - -4.147743366814909e-05, - 5.5381854095208204e-05, - -1.8991926315466896e-05, - -2.356531215480636e-05, - 0.00014990819894626173, - 0.0001586373701189229, - 5.065758976004906e-05, - -5.289712137411078e-05, - 6.851972536623415e-06, - 6.801298353256237e-06, - 1.228674057278291e-05, - 0.04247239411121721, - -0.0027910199321829502, - 0.0010019722065819437, - 3.624429390114166e-05, - -6.39104844849195e-05, - 2.2718420425829372e-05, - -0.08677434343513618, - 0.0005225853305023255, - -0.0002304466580093873, - 0.00010408259469834521, - -1.0234804232440391e-05, - -1.3060654074118569e-05, - 0.017201333270546026, - 0.009273392139903094, - -0.0020198979332276277, - -0.00010695148956120309, - 1.9181308238144256e-05, - -1.0397565889116764e-06, - -0.0031963456552044603, - -0.00336246353538785, - -0.0010864667553729611, - 0.0003608586931257558, - 4.5569477299700553e-05, - 7.1631684158345195e-06, - 0.0031296425527932515, - 0.0016539870377959452, - -0.0004072256120136085, - 0.0003614783204108866, - -5.607672926381748e-05, - -1.6056555976507773e-05, - 4.770079512505175e-05, - -0.0007507135840394342, - -7.524433609752762e-05, - 5.3898778220150815e-05, - -6.185986386908952e-05, - 2.0661889362180527e-05, - -0.0007689122530416373, - 0.00022613790371628083, - 0.0001724335249330347, - 3.1464445850586494e-05, - -2.2528034317789985e-05, - 9.10067681285232e-06, - -0.36446617409781856, - -0.15752133149232983, - -0.0014484688876732568, - 0.00035952931084106733, - -3.3060831216160415e-05, - -6.351752668209927e-05, - 3.640772373529825e-05, - 0.011876472797505084, - 0.016734337277909125, - 0.008892127331055674, - -0.0010795301309463664, - -0.0002388227145048703, - 6.75607551165389e-05, - 3.1225132462668316e-05, - -0.007191917582474914, - -0.006750026752440994, - -0.002551654280575772, - -0.000741805584365676, - 0.0003943781375121578, - 4.6926080059704625e-05, - 1.9802609822934572e-05, - 0.002764559319924977, - 0.004083135092309606, - 0.0015740852024771683, - -0.0003987550330652069, - 0.0002956113427070349, - -2.932816632883742e-05, - -1.8066589184135155e-05, - -0.00035859252346187885, - -0.0006310198447643578, - -0.0008481810436568666, - -7.084926063796922e-06, - 6.790638858448879e-05, - -6.228612421967779e-05, - 1.92880624985156e-05, - 0.0003074895340054883, - -0.0005030654407130155, - 0.00021409083830304754, - 0.00013027445746624053, - 2.5925215374653425e-05, - -1.6398921020322178e-05, - 6.666553143728353e-06 - ] - }, - "names": [ - "x0", - "x1", - "x2", - "x3", - "x4", - "x5", - "x6", - "x7", - "x8", - "x9", - "x10", - "x11", - "x12", - "x13", - "x14", - "x15", - "x16", - "x17", - "x18", - "x19", - "x20", - "x21", - "x22", - "x23", - "x24", - "x25", - "x26", - "x27", - "x28", - "x29", - "x30", - "x31", - "x32", - "x33", - "x34", - "x35", - "x36", - "x37", - "x38", - "x39", - "x40", - "x41", - "x42", - "x43", - "x44", - "x45", - "x46", - "x47", - "x48", - "x49", - "x50", - "x51", - "x52", - "x53", - "x54", - "x55", - "x56", - "x57", - "x58", - "x59", - "x60", - "x61", - "x62", - "x63", - "x64", - "x65", - "x66", - "x67", - "x68", - "x69", - "x70", - "x71", - "x72", - "x73", - "x74", - "x75", - "x76", - "x77", - "x78", - "x79", - "x80", - "x81", - "x82", - "x83", - "x84", - "x85", - "x86", - "x87", - "x88", - "x89", - "x90", - "x91", - "x92", - "x93", - "x94", - "x95", - "x96", - "x97", - "x98", - "x99", - "x100", - "x101", - "x102", - "x103", - "x104", - "x105", - "x106", - "x107", - "x108", - "x109", - "x110", - "x111", - "x112", - "x113", - "x114", - "x115", - "x116", - "x117", - "x118", - "x119", - "x120", - "x121", - "x122", - "x123", - "x124", - "x125", - "x126", - "x127", - "x128", - "x129", - "x130", - "x131", - "x132", - "x133", - "x134", - "x135", - "x136", - "x137", - "x138", - "x139", - "x140", - "x141", - "x142", - "x143", - "x144", - "x145", - "x146", - "x147", - "x148", - "x149", - "x150", - "x151", - "x152", - "x153", - "x154", - "x155", - "x156", - "x157", - "x158", - "x159", - "x160", - "x161", - "x162", - "x163", - "x164", - "x165", - "x166", - "x167", - "x168", - "x169", - "x170", - "x171", - "x172", - "x173", - "x174", - "x175", - "x176", - "x177", - "x178", - "x179", - "x180", - "x181", - "x182", - "x183", - "x184", - "x185", - "x186", - "x187", - "x188", - "x189", - "x190", - "x191", - "x192", - "x193", - "x194", - "x195", - "x196", - "x197", - "x198", - "x199", - "x200", - "x201", - "x202", - "x203", - "x204", - "x205", - "x206", - "x207", - "x208", - "x209", - "x210", - "x211", - "x212", - "x213", - "x214", - "x215", - "x216", - "x217", - "x218", - "x219", - "x220", - "x221", - "x222", - "x223", - "x224", - "x225", - "x226", - "x227", - "x228", - "x229", - "x230", - "x231", - "x232", - "x233", - "x234", - "x235", - "x236", - "x237", - "x238", - "x239", - "x240", - "x241", - "x242", - "x243", - "x244", - "x245", - "x246", - "x247", - "x248", - "x249", - "x250", - "x251", - "x252" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "SurfaceXYZTensorFourier1": { - "@module": "simsopt.geo.surfacexyztensorfourier", - "@class": "SurfaceXYZTensorFourier", - "@name": "SurfaceXYZTensorFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "nfp": 3, - "stellsym": true, - "mpol": 6, - "ntor": 6, - "clamped_dims": [ - false, - false, - false - ], - "quadpoints_phi": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.018518518518518517, - 0.037037037037037035, - 0.05555555555555555, - 0.07407407407407407, - 0.09259259259259259, - 0.1111111111111111, - 0.12962962962962962, - 0.14814814814814814, - 0.16666666666666666, - 0.18518518518518517, - 0.2037037037037037, - 0.2222222222222222, - 0.24074074074074073, - 0.25925925925925924, - 0.2777777777777778, - 0.2962962962962963, - 0.31481481481481477 - ] - }, - "quadpoints_theta": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.05555555555555555, - 0.1111111111111111, - 0.16666666666666666, - 0.2222222222222222, - 0.2777777777777778, - 0.3333333333333333, - 0.38888888888888884, - 0.4444444444444444, - 0.5, - 0.5555555555555556, - 0.611111111111111, - 0.6666666666666666, - 0.7222222222222222, - 0.7777777777777777, - 0.8333333333333333, - 0.8888888888888888, - 0.9444444444444444 - ] - }, - "dofs": { - "$type": "ref", - "value": "140342738037920" - } - }, - "Volume1": { - "@module": "simsopt.geo.surfaceobjectives", - "@class": "Volume", - "@name": "Volume1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "range": null, - "nphi": null, - "ntheta": null - }, - "BoozerSurface4": { - "@module": "simsopt.geo.boozersurface", - "@class": "BoozerSurface", - "@name": "BoozerSurface4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "biotsavart": { - "$type": "ref", - "value": "BiotSavart1" - }, - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "label": { - "$type": "ref", - "value": "Volume1" - }, - "targetlabel": -1.5036269634831068, - "constraint_weight": 1000.0, - "reg": null - } - } -} \ No newline at end of file diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_3.vts b/examples/2_Intermediate/inputs/input_ncsx/surface_3.vts deleted file mode 100644 index 2f016463ff382e028af51bde9390b3a79290bb91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31872 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 WoIjE`I{&{HIRD=pp790a>i-7 diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_4.json b/examples/2_Intermediate/inputs/input_ncsx/surface_4.json deleted file mode 100644 index 8dfa52f87..000000000 --- a/examples/2_Intermediate/inputs/input_ncsx/surface_4.json +++ /dev/null @@ -1,7022 +0,0 @@ -{ - "@module": "simsopt._core.json", - "@class": "SIMSON", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "graph": [ - { - "$type": "ref", - "value": "BoozerSurface5" - }, - { - "iota": -0.43321785577303545, - "G": 13.887479145271556 - } - ], - "simsopt_objs": { - "140342738246336": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738246336", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.506387961733893, - 0.1058930714809362, - 0.7258942274042265, - -0.001249592121112775, - 0.2763105569564668, - 0.01482550301512887, - -0.1280092780227772, - 0.005921392096802394, - 0.01864241438718947, - -0.01034831723350223, - 0.0001022108294955593, - 0.01892666378143068, - -0.007192153616853929, - -0.007355339046239706, - -0.01884714563379878, - -0.002596706082945131, - 0.01131859363705868, - 0.00964754529816095, - -0.0113260687651076, - -0.006628855789771619, - 0.000322284209286623, - 0.001842953924532827, - -0.0004161340928027646, - 0.00176264188836799, - 0.001814459617914206, - -0.001883356200860781, - -0.003584967425237995, - 0.0003165409191237933, - 0.00198839685289703, - 0.0007998064690618334, - 0.0005809753916376526, - 4.996792424044994e-05, - -0.0009656219012175038, - -0.001300735471703214, - -0.0004500391754653399, - 0.002413016477450284, - 0.00190334965179141, - -0.001622873850792805, - -0.001817132111793323, - 0.0005008124937015768, - 0.0009410326413637304, - 0.0005073038161052906, - -0.0001747050570155717, - -0.0004010070348672179, - 0.0002171330554898199, - 0.0001868680753017027, - -0.00049371483741256, - -1.263882515020243e-05, - 0.0005663593123846766, - 0.0001291744509577553, - -0.0002415255915965764, - 0.2855239540187146, - 0.02831674064739627, - 0.1230646086878452, - -0.1881027707999307, - -0.03092022550185042, - 0.07598032813641656, - 0.032842960392996, - -0.02022733960800226, - 0.03368541189764687, - -0.02527069889002642, - 0.03990545352197854, - 0.03266977475756579, - 0.007041509561223136, - -0.01843202758194484, - -0.003255107459418295, - 0.001087406605704745, - 0.02057587403483786, - 0.004332699549632209, - -0.003239348172858322, - -0.008060517809116506, - 0.0008303250764389791, - 0.002593682135814645, - 0.005122620691996364, - 0.002329497971206275, - -0.007021762243403233, - -0.002076255998522319, - 0.005455573755227739, - 0.0004034355313731426, - -0.002121189074115063, - -0.001155709211846629, - 0.0007060503790857225, - 0.001458108819397405, - 0.0007612900914783658, - -0.001579374591052191, - -0.0005648184298353118, - -3.483600030825498e-05, - 0.0006434230018098444, - 0.0002266872576160417, - -0.0005870263149471541, - -0.0004782734366555642, - 0.0004131000234993432, - -0.0002086017812282408, - -0.0002217317708794842, - 0.0004459870616389726, - 0.0002232186481886098, - -0.000550989811641543, - -0.0004679750418668452, - 0.0001971289820931924, - 0.0006305703105299488, - 1.94634036466225e-05, - -0.0005071137243856577, - 0.0009455853398023695, - -1.066704925256128, - 0.01954765252843791, - -0.03091192279856904, - -0.009251669123731003, - 0.03622032973711591, - 0.01289395028459556, - -0.01341289215090563, - -0.01055557464591715, - -0.007044726977866961, - -0.007171173731457627, - 0.01327231838496817, - 0.003220259676106272, - -0.006043809337864334, - -0.006228107449831786, - -0.0004722020937025503, - -0.0007632924616726337, - 0.0002557840887866895, - -0.0008300983337148277, - 0.001290373849098229, - 0.0002249498117545818, - -0.0003276137574950353, - -0.001560853624251917, - -0.003125967131907846, - 0.0007111137798287738, - 0.001688245514976161, - 0.00083638883723687, - -3.216802700299113e-05, - -0.003601309499252412, - -0.003364173533240832, - 0.003283863928203238, - 0.003620244544063828, - -0.001109032285114347, - -0.002277398193829699, - -0.0015519788484098, - 0.0002155015553257128, - 0.002349143532954114, - 0.000703914196138795, - -0.001628934087145739, - -0.0005728748367786014, - 0.000379102967651227, - 3.674770297429017e-05, - 0.0003644795696035227, - 0.0001196573774128766, - -0.0004826910821886253, - 1.895960151025164e-05, - 0.0002282029938596129, - -3.982416558199763e-05, - -0.0001869395233315697, - -0.0002051724761620464, - 0.0001303574263284748 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier1": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738246336" - } - }, - "140342738367104": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367104", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 652271.9419853 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current1": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 652271.9419853, - "dofs": { - "$type": "ref", - "value": "140342738367104" - } - }, - "Coil1": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "140342738247296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738247296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.268960636199869, - 0.2234285580503567, - 0.5468300987692021, - -0.07598922426224614, - 0.2314838962751658, - 0.01035784318060333, - -0.08314304549672957, - -0.04624738986383844, - 0.05377747860630284, - -0.001074456865203822, - -0.02151604922154927, - -0.01446679290684195, - 0.008416712252875694, - -0.009228184118107326, - 0.005277266362275169, - 0.01142201731157229, - 0.01681398796325401, - 0.009993706195866578, - 0.001370286955930781, - -0.008399573830195455, - -0.005099919856215084, - 0.005334309041669094, - -0.001419513324650316, - -0.003333508834690296, - 0.0002887180426140212, - -0.0001690909516323616, - -0.001592036575525169, - -4.507713399549196e-05, - 0.005287560419413426, - 0.001265480827581528, - -0.001229918688675425, - 0.001129035262308468, - -0.002142778995712242, - -0.001748186446934164, - 0.000763477629872682, - 0.0006002693299791978, - -0.0003618301004192371, - 0.000988040168005559, - 0.0007880569343915778, - -0.001135722890360471, - -0.0008706368325040781, - 0.0005507322770281398, - 0.0009555809731928289, - -0.0001476990895937402, - -0.001054028588515068, - -1.482885559572655e-05, - -0.0001592869344899095, - -0.0004579572172035079, - 0.0006274586578504227, - 0.0005393401407410331, - -3.182089243244368e-05, - 0.7629396044020591, - 0.189701305549749, - 0.2946730680990991, - -0.1569360429309221, - -0.08805875862294558, - -0.03077704895086764, - 0.1149783480591024, - 0.1301411562027019, - -0.001461622206151801, - 0.04030157913855995, - 0.0006901390690664732, - -0.02740323125842794, - -0.02323299800745342, - 0.006389595554305861, - 0.003627095782551136, - -0.01015301262258172, - -0.00621023311542419, - -0.003238881121248944, - -0.006852312518149265, - 0.005609446955056436, - 0.004762124576622897, - 0.006665063843140196, - -6.70526269177163e-05, - -0.003587348009623233, - -0.00322170321999071, - -0.004203038352780501, - 0.0006017815497404605, - 0.001489961187320675, - 0.002190828148742953, - -0.001018226063168117, - -0.002311412742654803, - 0.0005349636274747352, - 0.0005836793424641873, - 0.0003330260000362103, - 0.0006191475972028521, - 0.0004562062905476333, - -0.0003998259903290102, - -0.001606870160409875, - -0.0001005634411503442, - 0.0003784623778643909, - 0.0003873441313675419, - 0.0004934685418203405, - 0.0004248568990090018, - -0.0001368925780341768, - -0.0005224641202364183, - 7.402330001924084e-06, - 0.0001942482764948633, - 3.004761739695799e-05, - 0.0001571480542442944, - -1.517325817427362e-05, - -0.0001596571201453762, - -0.004342453367498795, - -0.8322915538683627, - 0.01842619538559772, - -0.1445740110997678, - -0.03919221672360253, - 0.0181885023851906, - 0.007857938792447916, - -0.0008409533080505334, - 0.0679882056193599, - -0.008440199737942872, - -0.05052693032193879, - 0.0111459982531894, - -0.002854468104354866, - -0.01157234174126346, - -0.002254287431014864, - 0.01222589681633306, - 0.007524606302699996, - -0.006381505382857464, - 0.003239076046582923, - 0.00341366498860203, - -0.00384676331619515, - 0.0004019843766106519, - 0.003278371413101953, - -0.001659157168404143, - -0.008498109023400214, - -0.0005869360684358228, - 0.001643969359882166, - -0.001687685453312147, - 0.001913710312578008, - 0.00307704389234268, - -0.001526906838827543, - -0.002096608532065649, - 0.002116359835823416, - 0.0002080593023590777, - -0.001289011271870523, - 0.0003465163727308783, - 0.0003373949660992973, - -0.0005853247790129025, - -0.0007569823284455652, - -3.821511752005806e-05, - 0.0008610335506290439, - 0.0002833895542749826, - -4.205984435378816e-05, - 0.0001112528084110792, - -0.0002379239249443648, - -0.0002104661224579025, - 0.0001263747200842462, - -0.0001533284829536013, - 0.0001522993485716547, - 0.0003185888026784711, - -0.0001603437887349448 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier2": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738247296" - } - }, - "140342738367296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 651868.5693674 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current2": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 651868.5693674, - "dofs": { - "$type": "ref", - "value": "140342738367296" - } - }, - "Coil2": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "140342738366624": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738366624", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.8980851593547453, - 0.1942559921705813, - 0.3889755333770718, - -0.1446923384557668, - 0.2616477438027761, - 0.03731920597998046, - -0.03289705406442186, - 0.02547136484396155, - 0.0532217952204826, - 0.050428478861979, - -0.03624366941253683, - -0.005451626158324006, - -0.01668041626206209, - 0.008182439166261426, - 0.003842296843932926, - 0.01470476196344816, - 0.01901860245900076, - 0.0218942171541043, - -0.00945061997881808, - 0.002564135600286371, - -0.006766476390874592, - -0.001269140258791196, - 0.002139997339095541, - 0.001657675366985779, - 0.0002979912903074711, - 0.006328865782046154, - 0.0004567550240531948, - -0.0008525115686061069, - -0.000977103914377314, - 0.0005522046297053057, - -0.0009600861596635313, - -0.001340814451660981, - -0.001495132545615355, - 0.0006434008787568705, - 0.000495245187218385, - -0.00134743162348104, - 0.0002393656261548005, - 0.0003132890671380592, - 0.0006144326019911972, - -0.0005029044211924421, - -0.000783957033721161, - -0.0004002250154653492, - 0.0002391300413782915, - -0.0003806672575232206, - -0.000145466845504183, - -7.221379723120868e-05, - 0.0006927366534479363, - -0.0001275371930022123, - -0.0001401106599127933, - -0.0002158625680600062, - -7.139828388354475e-05, - 1.129181984052873, - 0.2708936854358476, - 0.468646640557997, - 0.02081652240284051, - -0.1928735276123626, - -0.03518255586981031, - 0.01192001522947444, - -0.06439441858177399, - -0.004172035660790115, - -0.016589458610143, - 0.001628354566592241, - 0.003299047220307412, - 0.02371335634022325, - -0.02489732104888577, - 0.01517053799913132, - -0.007490250276888437, - -0.02121728304870823, - -0.006509759115093021, - 0.002045879344162137, - 0.0002421911767798572, - 0.005286626183968976, - -0.002423351884665077, - 0.003037404376098953, - -0.001045524131070646, - -0.001371894636819662, - 0.0002683048956511064, - 0.0006396825080884871, - 0.0006110891778951719, - -0.001898949452431453, - -0.001413075309279682, - -0.000175565426273192, - 0.00025798969577147, - 0.001643409441239691, - 7.18696208370806e-05, - -0.0001583133254478763, - 0.001580406281910882, - -0.002161287927547965, - -0.0003891297580205399, - 0.0004807171148380796, - -0.0003779554431875909, - -0.000203599914921071, - 0.0002418121495980502, - -0.0001924002563136939, - 0.0004205862222447268, - -0.0003081775538974041, - -1.457104090324735e-05, - -0.0001305465480840895, - -2.931233724533855e-05, - 3.39235991969411e-05, - -8.787891234509293e-05, - -0.0002714497625897205, - 0.01443108431390148, - -0.5884600992390547, - 0.1639153375972931, - -0.02326901782799053, - -0.09503676743509344, - -0.001882227773385535, - -0.1358423641287697, - -0.04946480830906624, - 0.01080325660372903, - -0.004462853204566593, - 0.02204832208587066, - -0.01988057349197482, - 0.006713767349457029, - 0.009816410920710776, - -0.004595941635687146, - 0.01307328931917959, - 0.0183731152740804, - -0.002049019816619709, - -0.009421893063595877, - 0.0003683472428279665, - 0.005559370162880608, - -0.001158799750525409, - 0.002656529580593774, - 0.005458828901239469, - 0.003685058507882478, - 0.005539080181031877, - 0.0003319744004354147, - 0.003297209047830778, - -0.001172958360845208, - -6.403055114502017e-05, - -0.0028127900802783, - -7.412199662635927e-05, - -1.404234804116165e-06, - 0.002212349409834762, - 0.001726905111358576, - 0.0009310945379894919, - -0.0002426222281296402, - 0.0007504861042380895, - -0.001511448440947522, - -0.0002060956498950368, - -0.000206480198377301, - 8.668234567299965e-05, - 0.0001267761162311387, - 1.493158313140079e-05, - 0.0001119337013982711, - 0.0003201242558262467, - 0.00016404919743365, - -0.0002679743018523173, - -0.000169663995881007, - 0.0002693900147788098, - -0.0001731877336642894 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier3": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738366624" - } - }, - "140342738367776": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367776", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 537743.5886473 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current3": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 537743.5886473, - "dofs": { - "$type": "ref", - "value": "140342738367776" - } - }, - "Coil3": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve1": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent1": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil4": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve1" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent1" - } - }, - "RotatedCurve2": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent2": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil5": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve2" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent2" - } - }, - "RotatedCurve3": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent3": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil6": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve3" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent3" - } - }, - "RotatedCurve4": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil7": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve4" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve5": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil8": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve5" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve6": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil9": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve6" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve7": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent4": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil10": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve7" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent4" - } - }, - "RotatedCurve8": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent5": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil11": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve8" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent5" - } - }, - "RotatedCurve9": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent6": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil12": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve9" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent6" - } - }, - "RotatedCurve10": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil13": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve10" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve11": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil14": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve11" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve12": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil15": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve12" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve13": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent7": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil16": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil16", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve13" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent7" - } - }, - "RotatedCurve14": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent8": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil17": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil17", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve14" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent8" - } - }, - "RotatedCurve15": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent9": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil18": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil18", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve15" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent9" - } - }, - "BiotSavart1": { - "@module": "simsopt.field.biotsavart", - "@class": "BiotSavart", - "@name": "BiotSavart1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "coils": [ - { - "$type": "ref", - "value": "Coil1" - }, - { - "$type": "ref", - "value": "Coil2" - }, - { - "$type": "ref", - "value": "Coil3" - }, - { - "$type": "ref", - "value": "Coil4" - }, - { - "$type": "ref", - "value": "Coil5" - }, - { - "$type": "ref", - "value": "Coil6" - }, - { - "$type": "ref", - "value": "Coil7" - }, - { - "$type": "ref", - "value": "Coil8" - }, - { - "$type": "ref", - "value": "Coil9" - }, - { - "$type": "ref", - "value": "Coil10" - }, - { - "$type": "ref", - "value": "Coil11" - }, - { - "$type": "ref", - "value": "Coil12" - }, - { - "$type": "ref", - "value": "Coil13" - }, - { - "$type": "ref", - "value": "Coil14" - }, - { - "$type": "ref", - "value": "Coil15" - }, - { - "$type": "ref", - "value": "Coil16" - }, - { - "$type": "ref", - "value": "Coil17" - }, - { - "$type": "ref", - "value": "Coil18" - } - ], - "points": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - [ - 1.7148017576411465, - 0.0, - 0.0 - ], - [ - 1.6893371389219671, - 0.014405409877117682, - -0.18174471814505588 - ], - [ - 1.6185722718851223, - 0.033297460040003266, - -0.34583710968684167 - ], - [ - 1.5171611685451056, - 0.059178825107246806, - -0.47164543955304256 - ], - [ - 1.4165313199002365, - 0.08656185996101444, - -0.5422756759317021 - ], - [ - 1.3531855838893394, - 0.1058594197509796, - -0.5540386133525302 - ], - [ - 1.3401077660165892, - 0.10837640672328284, - -0.5156869953026777 - ], - [ - 1.3838417331647905, - 0.08761628291486845, - -0.42349790659009473 - ], - [ - 1.470230732483197, - 0.047483863145518584, - -0.25005216825452087 - ], - [ - 1.5186346891690274, - 1.6921195380258708e-17, - -9.356675841712921e-17 - ], - [ - 1.470230732483197, - -0.04748386314551856, - 0.2500521682545207 - ], - [ - 1.3838417331647908, - -0.08761628291486838, - 0.4234979065900944 - ], - [ - 1.3401077660165892, - -0.10837640672328282, - 0.5156869953026775 - ], - [ - 1.3531855838893394, - -0.1058594197509796, - 0.5540386133525304 - ], - [ - 1.4165313199002363, - -0.08656185996101447, - 0.5422756759317023 - ], - [ - 1.5171611685451056, - -0.05917882510724686, - 0.4716454395530429 - ], - [ - 1.6185722718851219, - -0.033297460040003286, - 0.3458371096868418 - ], - [ - 1.6893371389219674, - -0.01440540987711771, - 0.1817447181450562 - ], - [ - 1.6998197175932614, - 0.19697799580259026, - -0.012071085041897921 - ], - [ - 1.683445738798562, - 0.21066443831069714, - -0.19161851725439494 - ], - [ - 1.6221988912248553, - 0.22467580154421415, - -0.3518677159814101 - ], - [ - 1.5302239168809049, - 0.24251326995660005, - -0.4715298583124625 - ], - [ - 1.4409882418934774, - 0.26008588205902994, - -0.5340332134860634 - ], - [ - 1.3876110152937393, - 0.2692783049549639, - -0.5368099565069716 - ], - [ - 1.3795171500890875, - 0.262719217067761, - -0.48802101223247984 - ], - [ - 1.4210872830417567, - 0.2368372076530192, - -0.37978810950023345 - ], - [ - 1.4872861846408505, - 0.19628108230696337, - -0.18874034231471545 - ], - [ - 1.4968407141547067, - 0.1480177912087433, - 0.06408925135334903 - ], - [ - 1.4159950214302073, - 0.09727238568191596, - 0.2963356044249911 - ], - [ - 1.319993350837632, - 0.056739389374177926, - 0.4461422002804904 - ], - [ - 1.2796735059449418, - 0.04167313197503191, - 0.5219778754195742 - ], - [ - 1.3000896515380995, - 0.05364419585315769, - 0.5508364601568314 - ], - [ - 1.3734977668352397, - 0.08346612426374829, - 0.5326085428424946 - ], - [ - 1.4832261346186324, - 0.12042350483248497, - 0.4576429272150495 - ], - [ - 1.5910888856040197, - 0.15395508700120872, - 0.330383874339251 - ], - [ - 1.6675475600919072, - 0.1789886055586195, - 0.16760813053808638 - ], - [ - 1.6558504015286337, - 0.3884918598090443, - -0.022953640307863548 - ], - [ - 1.6486767654877106, - 0.40515247987242997, - -0.19556347761486267 - ], - [ - 1.5990023409877945, - 0.41654496371629446, - -0.34801424444292806 - ], - [ - 1.5201075669481459, - 0.4261960626012216, - -0.4584656879066645 - ], - [ - 1.4444852427038712, - 0.43358182394513134, - -0.5096210749179503 - ], - [ - 1.3997179450797248, - 0.43248083206773774, - -0.5013434980568076 - ], - [ - 1.3929240493382031, - 0.4167707231542857, - -0.4413971527238261 - ], - [ - 1.4246393870225633, - 0.38475003610998415, - -0.3190826850113037 - ], - [ - 1.462055773737041, - 0.3397670288426954, - -0.12102238642033329 - ], - [ - 1.4348938365654385, - 0.286579865949061, - 0.11779780327548729 - ], - [ - 1.3338071044556559, - 0.2323323675163715, - 0.32159839232490767 - ], - [ - 1.2374378064214404, - 0.19282388608243395, - 0.446469420026217 - ], - [ - 1.2039071750202102, - 0.18379438000878284, - 0.5075305395003883 - ], - [ - 1.233062573095451, - 0.2053810355030261, - 0.5286239048609469 - ], - [ - 1.315419557034238, - 0.24595632411565096, - 0.5061962295716291 - ], - [ - 1.4310798887825797, - 0.2926204639072107, - 0.430138284190814 - ], - [ - 1.54161290470994, - 0.33399706167300225, - 0.3063485048699233 - ], - [ - 1.6194487801125284, - 0.3652518706881523, - 0.1500911036901203 - ], - [ - 1.5864015656640158, - 0.5699410837312531, - -0.03137167600564611 - ], - [ - 1.5856218517504053, - 0.5910490474048744, - -0.19300730410516517 - ], - [ - 1.5477578623943136, - 0.6023472305373898, - -0.3355333455979296 - ], - [ - 1.4852995260951807, - 0.6063477439533513, - -0.4343719803127519 - ], - [ - 1.4238509028995474, - 0.6041337407158122, - -0.4707662567394468 - ], - [ - 1.384371827873494, - 0.5911624131221191, - -0.44979443782728684 - ], - [ - 1.373966747246669, - 0.5635904743368646, - -0.37938686660406545 - ], - [ - 1.388817863776166, - 0.5214156830280835, - -0.248790919112712 - ], - [ - 1.3949252486976784, - 0.4682435310116745, - -0.0579747696384829 - ], - [ - 1.3408327014863, - 0.41010115214190296, - 0.1524512423079327 - ], - [ - 1.2335034751693217, - 0.3558270929486938, - 0.32369153702421666 - ], - [ - 1.1441328936026745, - 0.3207772698121725, - 0.4268695581672609 - ], - [ - 1.119716163251638, - 0.31900527335930984, - 0.4768545614774736 - ], - [ - 1.1578390967083003, - 0.34928143814502527, - 0.49260405733647256 - ], - [ - 1.2466547324061068, - 0.39922816504641345, - 0.46736317294967583 - ], - [ - 1.3642461319057038, - 0.45521766944213216, - 0.3923553635034455 - ], - [ - 1.4733006499426642, - 0.5042925842217066, - 0.2759788017659639 - ], - [ - 1.5489154544737307, - 0.5412567588594569, - 0.13053957867456398 - ], - [ - 1.496724035954601, - 0.7397875969431369, - -0.036955319537355376 - ], - [ - 1.4994298472878285, - 0.7639913440674261, - -0.18525775039059694 - ], - [ - 1.4723572474584345, - 0.7777429956332498, - -0.3155641989520872 - ], - [ - 1.4255007083078777, - 0.7795075685816807, - -0.3984350026775887 - ], - [ - 1.3739917016752614, - 0.7662639762183083, - -0.4168218970003704 - ], - [ - 1.3346912259520283, - 0.736473820385731, - -0.3846470224377511 - ], - [ - 1.3168275915672119, - 0.6927121421213083, - -0.30923963418730377 - ], - [ - 1.3125892519657865, - 0.6383369517979727, - -0.18080670878177113 - ], - [ - 1.2923018612360855, - 0.5783377529140005, - -0.010768644385223526 - ], - [ - 1.2243805101661955, - 0.5196299196381602, - 0.16394434216261733 - ], - [ - 1.1230702952356826, - 0.47069634386063597, - 0.30497566823361744 - ], - [ - 1.0467987740275015, - 0.4445180089503004, - 0.39253034567231093 - ], - [ - 1.032931716260483, - 0.4510322708361304, - 0.43639460582151407 - ], - [ - 1.0779860268625592, - 0.487636841850235, - 0.44900766310987045 - ], - [ - 1.1695012380681395, - 0.5447612478989327, - 0.4214227419174349 - ], - [ - 1.2853369016825578, - 0.6093373456682444, - 0.3491868626914112 - ], - [ - 1.389600276100641, - 0.6656170231704361, - 0.24301650815823025 - ], - [ - 1.4605927173042033, - 0.7075195486563874, - 0.11093710071995454 - ], - [ - 1.3905060894461412, - 0.8992959375264421, - -0.04026356463703809 - ], - [ - 1.395274546293489, - 0.9252802438037098, - -0.17301887187024514 - ], - [ - 1.3763648943021491, - 0.9419861376663018, - -0.2859066233245807 - ], - [ - 1.3385992686299897, - 0.9393612378426499, - -0.3478458539167908 - ], - [ - 1.289739952429321, - 0.908605263180637, - -0.35061076001231556 - ], - [ - 1.2476119804476733, - 0.8569427568224133, - -0.31509269802002715 - ], - [ - 1.2223153295907907, - 0.7969562777464713, - -0.2435236340601566 - ], - [ - 1.2023834272369598, - 0.7337814790509094, - -0.12775285844492731 - ], - [ - 1.1655945089674176, - 0.6725603604560196, - 0.01375714675564051 - ], - [ - 1.095931772118045, - 0.6199687279422068, - 0.15395257986748903 - ], - [ - 1.0086266651209275, - 0.5817279133029738, - 0.27160662266223945 - ], - [ - 0.9488107564097968, - 0.5667580523033237, - 0.3502306293009379 - ], - [ - 0.944804605127463, - 0.5809358834013884, - 0.39207672028767465 - ], - [ - 0.9935472843872164, - 0.6220372126655997, - 0.4023488427701436 - ], - [ - 1.0847680193999587, - 0.6848680413991216, - 0.3728900322063846 - ], - [ - 1.1960051680204293, - 0.7568479594885265, - 0.30543237251089606 - ], - [ - 1.2925759329341562, - 0.8194917188744579, - 0.21065016037922787 - ], - [ - 1.357131793774725, - 0.8654498636344744, - 0.09242195805960032 - ], - [ - 1.269776946035242, - 1.0490065142663094, - -0.041398609882023964 - ], - [ - 1.2750861254324322, - 1.0760639763515383, - -0.15529623183677793 - ], - [ - 1.2592010909794868, - 1.0907340477178882, - -0.24549831995268354 - ], - [ - 1.2224206318411746, - 1.0743709907962835, - -0.28820441224864757 - ], - [ - 1.1723669060364246, - 1.0197795879860643, - -0.28598249127176434 - ], - [ - 1.1290411217496885, - 0.9474513911467587, - -0.2567604897618606 - ], - [ - 1.0990448903368308, - 0.8763652352576347, - -0.1952307642492227 - ], - [ - 1.0692671736065362, - 0.8101088854106135, - -0.09827398321614639 - ], - [ - 1.0264689674518317, - 0.7544939433693107, - 0.014065632273292808 - ], - [ - 0.9637472784249353, - 0.714777103139748, - 0.1275373581454164 - ], - [ - 0.8932000231638035, - 0.6906779543607358, - 0.23058926708782873 - ], - [ - 0.8488443933957246, - 0.6869020808166677, - 0.30490488676371474 - ], - [ - 0.8526336218624047, - 0.7081850263807147, - 0.345968229995663 - ], - [ - 0.9035636629363737, - 0.7538402740053344, - 0.35448745655818903 - ], - [ - 0.9932514087361296, - 0.821649727145621, - 0.3256256126543515 - ], - [ - 1.0976906026310314, - 0.899102902198041, - 0.2653634918326017 - ], - [ - 1.1841727909328352, - 0.9659554073842263, - 0.18169252237574476 - ], - [ - 1.2404556555170922, - 1.0142298400035197, - 0.07607300279469709 - ], - [ - 1.1366445589396217, - 1.1887221088048046, - -0.03763680385498749 - ], - [ - 1.1381275660795152, - 1.2135162688463033, - -0.130667173302071 - ], - [ - 1.1190676736051919, - 1.2162511057563123, - -0.2009735568951292 - ], - [ - 1.0800433073931637, - 1.1775366104185854, - -0.23586619627525196 - ], - [ - 1.0309927388519182, - 1.0996340857952454, - -0.2401263276339476 - ], - [ - 0.9897919806220684, - 1.0123258403601465, - -0.22170921514468234 - ], - [ - 0.9578626601107781, - 0.9353595870573335, - -0.1723952139214957 - ], - [ - 0.9238757114266697, - 0.871596114539019, - -0.09557048244810548 - ], - [ - 0.8826524043151226, - 0.8279862157437023, - -0.007042594851245445 - ], - [ - 0.8309643053827412, - 0.8054770532598351, - 0.09010580429206089 - ], - [ - 0.7762290315220867, - 0.7965044062195734, - 0.18545862308830502 - ], - [ - 0.7449141936020176, - 0.803781532569799, - 0.2565739716143911 - ], - [ - 0.7556121548972673, - 0.8329713188780904, - 0.29696973229158863 - ], - [ - 0.8084525334577157, - 0.884005079252962, - 0.30657390897978676 - ], - [ - 0.8952586971592326, - 0.9562328697104419, - 0.28255673583080776 - ], - [ - 0.991402021311683, - 1.0372566437175632, - 0.23189495813738026 - ], - [ - 1.0669031123769115, - 1.1052767253864637, - 0.1589896084976914 - ], - [ - 1.1136514125025534, - 1.1534432803877508, - 0.06446462669807895 - ], - [ - 0.9897288507923936, - 1.3175881536683958, - -0.02380303019605738 - ], - [ - 0.9814565953975646, - 1.3312795021287553, - -0.1010999357983156 - ], - [ - 0.9571787528230166, - 1.3136843760838903, - -0.16453133429405484 - ], - [ - 0.9192048736018438, - 1.2524261264829615, - -0.20443532487208715 - ], - [ - 0.87542761691771, - 1.1567830555938727, - -0.22017225950345243 - ], - [ - 0.8385975116843343, - 1.0591036962772296, - -0.2130951763730983 - ], - [ - 0.8075046443103796, - 0.9800982559349172, - -0.17661585003717017 - ], - [ - 0.7742031901379035, - 0.9238380994131705, - -0.11699107920988214 - ], - [ - 0.7381911395715667, - 0.896165953975269, - -0.04331296578117384 - ], - [ - 0.6973293896121424, - 0.8919297370840727, - 0.04635935346531709 - ], - [ - 0.6566007567844303, - 0.8978712896353938, - 0.13712847856340563 - ], - [ - 0.6378273587833553, - 0.9167833883051008, - 0.20519242463813844 - ], - [ - 0.6556798331863928, - 0.9551390210560056, - 0.24713573399928843 - ], - [ - 0.7094410701270288, - 1.0120734148057677, - 0.26221411102847647 - ], - [ - 0.7914008213772904, - 1.088262828937981, - 0.24683346050143343 - ], - [ - 0.8781129789244222, - 1.1718039752215417, - 0.20744805922720677 - ], - [ - 0.942383432119524, - 1.2394625170693214, - 0.14541440948794432 - ], - [ - 0.9779228796141081, - 1.2858175122364455, - 0.06248421063440795 - ], - [ - 0.8251994884874251, - 1.4292874404400686, - -9.596835853467427e-18 - ], - [ - 0.8068744923335605, - 1.4228397655142564, - -0.07520137112258288 - ], - [ - 0.7814035401280459, - 1.3843079164084577, - -0.14563346543925423 - ], - [ - 0.7488323657015366, - 1.3064474566726083, - -0.19638305501603562 - ], - [ - 0.7124989560970517, - 1.1984535757592736, - -0.22399640156895415 - ], - [ - 0.6813274172701419, - 1.0936776900439082, - -0.22844835879732905 - ], - [ - 0.6538754763373621, - 1.0158127142351907, - -0.20399388952254524 - ], - [ - 0.6246175131513028, - 0.9700038511970867, - -0.1560307110405205 - ], - [ - 0.5942469085117901, - 0.9595192613893544, - -0.08828939152916251 - ], - [ - 0.5619780620544832, - 0.97337455621746, - -1.653764142487148e-17 - ], - [ - 0.5338446015277671, - 0.9943925495862544, - 0.08828939152916249 - ], - [ - 0.5277392203297663, - 1.025936559636232, - 0.15603071104052044 - ], - [ - 0.5527818778462167, - 1.0741791305374013, - 0.20399388952254519 - ], - [ - 0.6064889544952371, - 1.1368856966727374, - 0.22844835879732905 - ], - [ - 0.6816417638153035, - 1.2162689840295768, - 0.22399640156895415 - ], - [ - 0.7570005033372803, - 1.3017315802098333, - 0.19638305501603584 - ], - [ - 0.8081440522056067, - 1.368869274562209, - 0.14563346543925426 - ], - [ - 0.8287781362832601, - 1.4101936907836639, - 0.07520137112258303 - ], - [ - 0.6462003874060691, - 1.515924404478789, - 0.02380303019605732 - ], - [ - 0.6245891904206159, - 1.4898148128060709, - -0.062484210634407754 - ], - [ - 0.6022143107608742, - 1.4358592508557368, - -0.14541440948794418 - ], - [ - 0.5757555213352353, - 1.34637013475215, - -0.20744805922720655 - ], - [ - 0.5467628451659657, - 1.229504630357595, - -0.24683346050143337 - ], - [ - 0.5217607526531464, - 1.1204306966209079, - -0.2622141110284763 - ], - [ - 0.49933473978710463, - 1.045404902816562, - -0.24713573399928832 - ], - [ - 0.47504402464811357, - 1.0107663900876678, - -0.20519242463813842 - ], - [ - 0.4492789677607317, - 1.0175685803371008, - -0.13712847856340551 - ], - [ - 0.4237691158995115, - 1.0498698347516482, - -0.04635935346531698 - ], - [ - 0.40700691236351605, - 1.0873752567051955, - 0.04331296578117393 - ], - [ - 0.4129656680067877, - 1.1323986800569632, - 0.11699107920988211 - ], - [ - 0.44503766568927106, - 1.1893686636141643, - 0.17661585003717017 - ], - [ - 0.49791195037591207, - 1.2557985968076655, - 0.21309517637309838 - ], - [ - 0.5640897043528253, - 1.3365340832221442, - 0.22017225950345243 - ], - [ - 0.6250304050966654, - 1.4222678350631408, - 0.20443532487208724 - ], - [ - 0.6590946658318514, - 1.485783303949383, - 0.16453133429405475 - ], - [ - 0.66219357068222, - 1.515606095390454, - 0.10109993579831575 - ], - [ - 0.4611412647953598, - 1.5787241175174735, - 0.03763680385498749 - ], - [ - 0.44208547638897283, - 1.5411720543815095, - -0.06446462669807868 - ], - [ - 0.423746166207899, - 1.4766035613883217, - -0.15898960849769134 - ], - [ - 0.4025895930477531, - 1.377207657677941, - -0.23189495813738006 - ], - [ - 0.3804926085233218, - 1.2534332095540757, - -0.28255673583080765 - ], - [ - 0.36134458897868343, - 1.1421429713547517, - -0.3065739089797867 - ], - [ - 0.3435682453236211, - 1.070864980988381, - -0.29696973229158863 - ], - [ - 0.3236381294972264, - 1.0470053815838463, - -0.2565739716143912 - ], - [ - 0.3016785342513475, - 1.0704862635629055, - -0.18545862308830502 - ], - [ - 0.28208143759707816, - 1.1223747247294618, - -0.09010580429206094 - ], - [ - 0.2757308946598281, - 1.1783925127201609, - 0.007042594851245393 - ], - [ - 0.29288652131726695, - 1.2358978933044262, - 0.09557048244810538 - ], - [ - 0.33111383400958394, - 1.2972131905211397, - 0.17239521392149557 - ], - [ - 0.38180390434828304, - 1.3633479198608995, - 0.2217092151446823 - ], - [ - 0.43681468374000043, - 1.4426829458606796, - 0.24012632763394762 - ], - [ - 0.479754964812133, - 1.5241132465991378, - 0.23586619627525202 - ], - [ - 0.4937705181632846, - 1.5772665867742044, - 0.2009735568951292 - ], - [ - 0.481872133686848, - 1.5924055193953643, - 0.13066717330207106 - ], - [ - 0.27357781707236634, - 1.6241623495394963, - 0.04139860988202396 - ], - [ - 0.25812097896072883, - 1.58138102994764, - -0.07607300279469678 - ], - [ - 0.2444555262512692, - 1.508501423110268, - -0.18169252237574463 - ], - [ - 0.22980065260430363, - 1.4001793984729438, - -0.2653634918326015 - ], - [ - 0.21494383235259576, - 1.2710058158829802, - -0.32562561265435136 - ], - [ - 0.20106299621625495, - 1.1594292230420868, - -0.354487456558189 - ], - [ - 0.18698941249424966, - 1.0924948898439348, - -0.34596822999566296 - ], - [ - 0.17045245520176372, - 1.0785718489490237, - -0.30490488676371474 - ], - [ - 0.15154464272836468, - 1.1188728879010705, - -0.23058926708782865 - ], - [ - 0.1371414901500041, - 1.1920181775139824, - -0.1275373581454164 - ], - [ - 0.14017643823340498, - 1.2661951736943236, - -0.014065632273292874 - ], - [ - 0.16694128779381995, - 1.3310669784813525, - 0.09827398321614618 - ], - [ - 0.20943211155822206, - 1.3899834125599948, - 0.19523076424922248 - ], - [ - 0.25599641270915574, - 1.451503988925889, - 0.2567604897618605 - ], - [ - 0.2969715764385476, - 1.5251893171767397, - 0.2859824912717643 - ], - [ - 0.3192222551980517, - 1.5958328166828235, - 0.2882044122486475 - ], - [ - 0.3150028486065759, - 1.6358671571202594, - 0.2454983199526835 - ], - [ - 0.29435567690151376, - 1.6422889648133272, - 0.15529623183677807 - ], - [ - 0.08356008269497199, - 1.653861566340536, - 0.040263564637038105 - ], - [ - 0.07093567072187068, - 1.6080355415096927, - -0.09242195805960005 - ], - [ - 0.06341268026917829, - 1.5291494536785795, - -0.2106501603792278 - ], - [ - 0.05744697570926506, - 1.4141948383074314, - -0.30543237251089583 - ], - [ - 0.05072911239175275, - 1.281870682712856, - -0.3728900322063845 - ], - [ - 0.04192638607406468, - 1.1714557944731714, - -0.40234884277014354 - ], - [ - 0.030702930431825592, - 1.1086927313536024, - -0.39207672028767476 - ], - [ - 0.016421492889169616, - 1.1050732445864748, - -0.35023062930093807 - ], - [ - -0.0005221815495766724, - 1.1643602715805896, - -0.27160662266223956 - ], - [ - -0.011057218109147851, - 1.2590891194398286, - -0.15395257986748914 - ], - [ - -0.0003428967503766728, - 1.3457146355054421, - -0.013757146755640638 - ], - [ - 0.03428168806612666, - 1.40818533260206, - 0.12775285844492695 - ], - [ - 0.07902671743853577, - 1.4570342657340092, - 0.24352363406015634 - ], - [ - 0.11832820677344386, - 1.508935047544706, - 0.3150926980200271 - ], - [ - 0.14200526371201685, - 1.5712501946698438, - 0.3506107600123155 - ], - [ - 0.14421106098713635, - 1.6289415910421658, - 0.34784585391679074 - ], - [ - 0.12760147808072847, - 1.6629600321758953, - 0.2859066233245809 - ], - [ - 0.10367892360712735, - 1.6709833242458236, - 0.1730188718702454 - ], - [ - -0.10768716561990054, - 1.666094836063026, - 0.036955319537355376 - ], - [ - -0.11756645584156969, - 1.6186701720961767, - -0.11093710071995415 - ], - [ - -0.11835888679334738, - 1.5362376517942435, - -0.2430165081582301 - ], - [ - -0.11496683001799937, - 1.4178030821127994, - -0.3491868626914109 - ], - [ - -0.11297353935628171, - 1.2851984058738282, - -0.42142274191743473 - ], - [ - -0.11668712056776118, - 1.177381705112748, - -0.44900766310987034 - ], - [ - -0.1258604536595691, - 1.120061242074303, - -0.4363946058215142 - ], - [ - -0.13843549882311187, - 1.1288133354333725, - -0.39253034567231104 - ], - [ - -0.1539001563660748, - 1.2079555778401085, - -0.3049756682336175 - ], - [ - -0.16217754410998447, - 1.3201595855215564, - -0.16394434216261747 - ], - [ - -0.14529574462691053, - 1.4083351176453627, - 0.010768644385223312 - ], - [ - -0.10347860955152614, - 1.4559041128357708, - 0.18080670878177066 - ], - [ - -0.05850748319661647, - 1.4867622177621387, - 0.3092396341873035 - ], - [ - -0.029540575299793218, - 1.5241134180755183, - 0.384647022437751 - ], - [ - -0.02339178142770057, - 1.5730437063489404, - 0.4168218970003703 - ], - [ - -0.03767699731996261, - 1.6242736107981735, - 0.39843500267758875 - ], - [ - -0.06263343189541304, - 1.66397027756176, - 0.3155641989520874 - ], - [ - -0.08807901141010538, - 1.6805400109775948, - 0.1852577503905972 - ], - [ - -0.29961732566030874, - 1.6588345983340713, - 0.03137167600564611 - ], - [ - -0.30571562409454744, - 1.6120285113182982, - -0.13053957867456362 - ], - [ - -0.2999201360952306, - 1.5280620823733255, - -0.2759788017659637 - ], - [ - -0.28789299996441814, - 1.4090806419660618, - -0.3923553635034453 - ], - [ - -0.2775856333666127, - 1.279248750534987, - -0.4673631729496756 - ], - [ - -0.2764329498501952, - 1.177358790316728, - -0.4926040573364726 - ], - [ - -0.28359141095545715, - 1.1292052790836162, - -0.47685456147747374 - ], - [ - -0.2942651821873805, - 1.1512367860714001, - -0.426869558167261 - ], - [ - -0.30859643573632517, - 1.246158891627367, - -0.3236915370242168 - ], - [ - -0.31525833486699484, - 1.366245757783004, - -0.1524512423079328 - ], - [ - -0.29195183133500247, - 1.4421624672583526, - 0.05797476963848278 - ], - [ - -0.24284970445414814, - 1.4634593927738375, - 0.24879091911271167 - ], - [ - -0.19889970551668798, - 1.4716853442391207, - 0.37938686660406523 - ], - [ - -0.18022424641048057, - 1.4944823777830034, - 0.4497944378272868 - ], - [ - -0.18873028470655887, - 1.5351579234703236, - 0.4707662567394469 - ], - [ - -0.21753721325660563, - 1.5894809938040895, - 0.43437198031275204 - ], - [ - -0.25223092765257527, - 1.6415712430092697, - 0.33553334559792974 - ], - [ - -0.28094743593998833, - 1.6687133281140114, - 0.19300730410516548 - ], - [ - -0.4914813810062213, - 1.6282544424949823, - 0.02295364030786359 - ], - [ - -0.49340699126053505, - 1.5851097190492451, - -0.1500911036901198 - ], - [ - -0.48155651215679174, - 1.5020744691172285, - -0.30634850486992304 - ], - [ - -0.4621231889804576, - 1.3856617704843288, - -0.43013828419081357 - ], - [ - -0.4447053536115257, - 1.262164915084349, - -0.5061962295716288 - ], - [ - -0.43866609234655074, - 1.1705540305079798, - -0.5286239048609469 - ], - [ - -0.44278298534968785, - 1.1345113873702517, - -0.5075305395003883 - ], - [ - -0.4517285194068953, - 1.1680645190054746, - -0.44646942002621726 - ], - [ - -0.46569781983726727, - 1.2712770199649477, - -0.3215983923249077 - ], - [ - -0.46926147415769315, - 1.3859444471739168, - -0.1177978032754876 - ], - [ - -0.436781008522386, - 1.4360609562273388, - 0.12102238642033283 - ], - [ - -0.3791163881330551, - 1.4261489184484228, - 0.3190826850113031 - ], - [ - -0.33552799086387863, - 1.414692973846316, - 0.44139715272382574 - ], - [ - -0.3253195853193695, - 1.4284317146058625, - 0.5013434980568074 - ], - [ - -0.3467497471962594, - 1.4677518275458485, - 0.5096210749179503 - ], - [ - -0.39095716626851157, - 1.5295498007626596, - 0.45846568790666453 - ], - [ - -0.43876265009711857, - 1.5930491298643648, - 0.34801424444292817 - ], - [ - -0.47346604276806686, - 1.630372201477732, - 0.195563477614863 - ], - [ - -0.6793219104450424, - 1.5705760551907504, - 0.01207108504189797 - ], - [ - -0.6787651006442356, - 1.5336328518376592, - -0.16760813053808588 - ], - [ - -0.662215426417119, - 1.4549009381127582, - -0.33038387433925076 - ], - [ - -0.6373232529116255, - 1.344723264552976, - -0.45764292721504907 - ], - [ - -0.6144650994497847, - 1.231217020252388, - -0.5326085428424944 - ], - [ - -0.603587589394627, - 1.1527327633558324, - -0.5508364601568314 - ], - [ - -0.603746762026831, - 1.1290663306857323, - -0.5219778754195742 - ], - [ - -0.6108589228255603, - 1.171517469339023, - -0.44614220028049073 - ], - [ - -0.6237571536278459, - 1.2749238530318079, - -0.29633560442499146 - ], - [ - -0.6202331896785201, - 1.3703109794811894, - -0.06408925135334943 - ], - [ - -0.5736586887602902, - 1.3861681597500919, - 0.188740342314715 - ], - [ - -0.5054366031319933, - 1.3491162919356787, - 0.37978810950023273 - ], - [ - -0.4622370590015039, - 1.326056505467341, - 0.48802101223247957 - ], - [ - -0.46060365486785737, - 1.336345542292978, - 0.5368099565069716 - ], - [ - -0.49525313991793457, - 1.3779753650639421, - 0.5340332134860631 - ], - [ - -0.5550893059032025, - 1.4464694204756912, - 0.4715298583124627 - ], - [ - -0.6165244938595064, - 1.5172033505637812, - 0.35186771598141037 - ], - [ - -0.6592821141482372, - 1.5632389948475671, - 0.19161851725439533 - ] - ] - } - }, - "140342738037920": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738037920", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.4294334490674496, - 0.06211623836294424, - -0.0020992167481603064, - 0.00011399265413059905, - 2.3217153058813136e-05, - -9.619722272512663e-05, - 2.9176534572300715e-05, - 0.20197069906136192, - -0.07380648487377739, - 0.0010890856317489028, - 0.000622719937841421, - -8.091808540057688e-05, - -0.00012895435886341525, - -4.019059378974189e-05, - 0.05746624943422227, - 0.048929075457438555, - 0.012975038612487924, - -0.00191574638890013, - -0.0003634626653687531, - 2.1899693595361495e-06, - 4.762249030554052e-05, - -0.017100611698806233, - -0.0062495021935566365, - -0.0024932347558619975, - -0.0008772754184898598, - 0.000454205288844004, - -4.251903298056293e-05, - -1.4351619968203108e-05, - 0.0010571123556512676, - 0.005758322706961897, - 0.0013476566231188443, - -0.0003927185433880054, - 0.0004969202505670528, - 2.649196371230162e-06, - -2.173874933406853e-05, - -0.002194693155191858, - -0.0020211235106914727, - -0.0011231291346698769, - 3.8760896746955706e-05, - 0.00013921520478389542, - -0.00010456754467033983, - 4.6404191450236495e-05, - 0.0010643711004666469, - 2.8335094819775582e-05, - 0.00041649780603789533, - 0.0002549927594735047, - 6.665656935622904e-05, - -3.079761489682612e-05, - 8.33713906622897e-06, - 0.1666658923460983, - -0.0016743904409309365, - -0.0007597184379581217, - -0.00024079314074101338, - 4.242145501578102e-06, - -1.4909087922261948e-05, - -0.04381139061584406, - -0.012131453025855261, - 0.002439815365073662, - 0.00014866856599237655, - 3.225222534814971e-05, - -8.823377299986273e-05, - 0.008024761597249363, - 0.003847950052138041, - 0.001531688441433922, - -0.0004936502391808819, - -2.4944694720048975e-05, - -7.95941347709355e-07, - -0.002819868092720041, - -0.001519290786345621, - 0.0004621366397293514, - -0.0006509552298005272, - 5.9576744363097805e-05, - 2.7774135361468154e-05, - 0.0012558670819094056, - 0.0013251723394530522, - 0.00018425196245982136, - -8.490782665628263e-05, - 0.00010888571108050734, - -5.07042582076298e-05, - -5.295757130336753e-05, - -0.00026975444524519567, - -0.00029065256956523755, - -7.558381740471509e-05, - 3.8748498920870515e-05, - -7.594526396630609e-06, - -0.017748644865295312, - 0.002571801522916167, - 0.00041331336383479287, - 0.00015831343417262614, - -6.591533981519593e-05, - -4.090247189449646e-05, - 0.033965032198327916, - -9.171211719436307e-05, - -0.0007858881324029156, - 0.00015506770995182072, - -0.00016375361772571448, - 4.262193186621419e-05, - -0.028854347347127194, - -0.001452574664224222, - 0.0008317315523530162, - -1.6990871959380407e-05, - -0.00020189689133028897, - -2.306857249367945e-05, - 0.001762225418402025, - 0.0018500895958383902, - -0.0003787459134455493, - -0.00022191976647441646, - 3.398832995672553e-05, - 7.121758707845226e-05, - -0.00102242211010635, - 0.000522385949023877, - -7.14734479217999e-05, - 0.0001501004672682474, - 3.293355806300553e-05, - 2.3649215875639542e-05, - 0.00037550294345433185, - 0.0002324576281904514, - -3.260317437700248e-05, - 6.91769288663947e-05, - -5.848377133179428e-06, - -2.9649381740953362e-05, - -0.0001582554213695247, - -5.601815204500063e-05, - -2.471550365789018e-05, - 4.985710300374838e-05, - 1.9006654718949053e-05, - 1.959218991178331e-05, - 0.036104419221012166, - 0.06369904349251124, - -0.0038568079475752295, - 0.00010489543974493791, - 0.00023998065342247063, - -6.120662206396881e-05, - 0.00010174004047511264, - 0.006167327890200743, - -0.032697269688888614, - -0.001831565180650986, - 0.0007194475542912513, - 0.00013784258813517262, - -3.4410361743442354e-05, - -8.601125706875085e-06, - -0.0028833478941941207, - 0.00031276037930676854, - 0.0018712091780173515, - -0.0010902003193091207, - -0.00012070279919234449, - 1.529923183115449e-05, - 4.3946504792835105e-05, - 0.0008140424612343317, - 0.000922944504182917, - -0.00043640119545139807, - -0.000591899677458796, - 5.253536154973493e-05, - 6.91305261651331e-05, - 2.6656684912319212e-05, - -0.0005039360373165858, - 8.116350913688713e-06, - 0.00014083046294822662, - -0.00011143770180552444, - 0.00011169102553813432, - -1.055224889274651e-05, - -4.0705775344917655e-05, - 0.0002382090472860589, - 0.00013183158363440413, - 6.593727368223074e-05, - -0.000103410064322589, - 1.0037503743138952e-05, - 1.0280079790292349e-05, - 2.1008499699773567e-05, - 0.0383031550743632, - -0.003799569927755617, - 0.0013253099034300953, - 0.00011203718965486363, - -0.0001025849783952083, - 3.0249949567803302e-05, - -0.09813750611647926, - 0.0016968744496200032, - -0.00022387470800981873, - 7.363600381921985e-05, - -3.0062936372532143e-05, - -1.2152805721175476e-05, - 0.017822969566651612, - 0.011830378312698389, - -0.0025388583632048266, - -0.00022784765248132699, - 3.817967115682744e-05, - 1.6694572227457116e-05, - -0.0037605290506282202, - -0.004168845045490884, - -0.0015624751412720438, - 0.0005443562601394128, - 5.923846834888851e-05, - 5.9505627731051e-06, - 0.004379935079795735, - 0.00221612428486899, - -0.0008465358793241793, - 0.0005789183452678994, - -7.182496953286212e-05, - -2.7229994425065062e-05, - -1.7657464258695615e-05, - -0.001066361219454378, - -0.00010937644777879002, - 0.00014116829827342964, - -0.00011214916933250967, - 3.770300354486976e-05, - -0.000875506832094303, - 0.0003616898576756144, - 0.0002519787119243776, - 5.896929481528794e-05, - -5.199168227017997e-05, - 1.7494533776882777e-05, - -0.40140339377999656, - -0.17057080089147952, - -0.000623180962242225, - 0.00014551560431050803, - -0.00014541220213060965, - -0.0001064024511432245, - 5.566767704910102e-05, - 0.010055574612474059, - 0.016307162747713315, - 0.011334576263437502, - -0.0013255748948435811, - -0.00040460828674291575, - 0.00010579710405388799, - 4.982914703007093e-05, - -0.00916120341168678, - -0.007792964903074305, - -0.0027208403783570098, - -0.0011436691998600273, - 0.0005464377929219673, - 7.359207355275956e-05, - 2.6488923887655434e-05, - 0.003520165824759033, - 0.00540947705969704, - 0.0021405374947637465, - -0.000800929694410864, - 0.0004987185210189292, - -3.7805766607881594e-05, - -3.481081367929095e-05, - -0.0005605160312131695, - -0.001004169411481148, - -0.0011408984853994043, - 2.5582319730948182e-05, - 0.00014936041421973473, - -0.00011364547809746048, - 3.292671020669509e-05, - 0.0005189526095239373, - -0.0006054886989537355, - 0.00032941300007991136, - 0.00018709080626324665, - 5.7356221112589885e-05, - -3.704885151638695e-05, - 1.345084587648121e-05 - ] - }, - "names": [ - "x0", - "x1", - "x2", - "x3", - "x4", - "x5", - "x6", - "x7", - "x8", - "x9", - "x10", - "x11", - "x12", - "x13", - "x14", - "x15", - "x16", - "x17", - "x18", - "x19", - "x20", - "x21", - "x22", - "x23", - "x24", - "x25", - "x26", - "x27", - "x28", - "x29", - "x30", - "x31", - "x32", - "x33", - "x34", - "x35", - "x36", - "x37", - "x38", - "x39", - "x40", - "x41", - "x42", - "x43", - "x44", - "x45", - "x46", - "x47", - "x48", - "x49", - "x50", - "x51", - "x52", - "x53", - "x54", - "x55", - "x56", - "x57", - "x58", - "x59", - "x60", - "x61", - "x62", - "x63", - "x64", - "x65", - "x66", - "x67", - "x68", - "x69", - "x70", - "x71", - "x72", - "x73", - "x74", - "x75", - "x76", - "x77", - "x78", - "x79", - "x80", - "x81", - "x82", - "x83", - "x84", - "x85", - "x86", - "x87", - "x88", - "x89", - "x90", - "x91", - "x92", - "x93", - "x94", - "x95", - "x96", - "x97", - "x98", - "x99", - "x100", - "x101", - "x102", - "x103", - "x104", - "x105", - "x106", - "x107", - "x108", - "x109", - "x110", - "x111", - "x112", - "x113", - "x114", - "x115", - "x116", - "x117", - "x118", - "x119", - "x120", - "x121", - "x122", - "x123", - "x124", - "x125", - "x126", - "x127", - "x128", - "x129", - "x130", - "x131", - "x132", - "x133", - "x134", - "x135", - "x136", - "x137", - "x138", - "x139", - "x140", - "x141", - "x142", - "x143", - "x144", - "x145", - "x146", - "x147", - "x148", - "x149", - "x150", - "x151", - "x152", - "x153", - "x154", - "x155", - "x156", - "x157", - "x158", - "x159", - "x160", - "x161", - "x162", - "x163", - "x164", - "x165", - "x166", - "x167", - "x168", - "x169", - "x170", - "x171", - "x172", - "x173", - "x174", - "x175", - "x176", - "x177", - "x178", - "x179", - "x180", - "x181", - "x182", - "x183", - "x184", - "x185", - "x186", - "x187", - "x188", - "x189", - "x190", - "x191", - "x192", - "x193", - "x194", - "x195", - "x196", - "x197", - "x198", - "x199", - "x200", - "x201", - "x202", - "x203", - "x204", - "x205", - "x206", - "x207", - "x208", - "x209", - "x210", - "x211", - "x212", - "x213", - "x214", - "x215", - "x216", - "x217", - "x218", - "x219", - "x220", - "x221", - "x222", - "x223", - "x224", - "x225", - "x226", - "x227", - "x228", - "x229", - "x230", - "x231", - "x232", - "x233", - "x234", - "x235", - "x236", - "x237", - "x238", - "x239", - "x240", - "x241", - "x242", - "x243", - "x244", - "x245", - "x246", - "x247", - "x248", - "x249", - "x250", - "x251", - "x252" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "SurfaceXYZTensorFourier1": { - "@module": "simsopt.geo.surfacexyztensorfourier", - "@class": "SurfaceXYZTensorFourier", - "@name": "SurfaceXYZTensorFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "nfp": 3, - "stellsym": true, - "mpol": 6, - "ntor": 6, - "clamped_dims": [ - false, - false, - false - ], - "quadpoints_phi": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.018518518518518517, - 0.037037037037037035, - 0.05555555555555555, - 0.07407407407407407, - 0.09259259259259259, - 0.1111111111111111, - 0.12962962962962962, - 0.14814814814814814, - 0.16666666666666666, - 0.18518518518518517, - 0.2037037037037037, - 0.2222222222222222, - 0.24074074074074073, - 0.25925925925925924, - 0.2777777777777778, - 0.2962962962962963, - 0.31481481481481477 - ] - }, - "quadpoints_theta": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.05555555555555555, - 0.1111111111111111, - 0.16666666666666666, - 0.2222222222222222, - 0.2777777777777778, - 0.3333333333333333, - 0.38888888888888884, - 0.4444444444444444, - 0.5, - 0.5555555555555556, - 0.611111111111111, - 0.6666666666666666, - 0.7222222222222222, - 0.7777777777777777, - 0.8333333333333333, - 0.8888888888888888, - 0.9444444444444444 - ] - }, - "dofs": { - "$type": "ref", - "value": "140342738037920" - } - }, - "Volume1": { - "@module": "simsopt.geo.surfaceobjectives", - "@class": "Volume", - "@name": "Volume1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "range": null, - "nphi": null, - "ntheta": null - }, - "BoozerSurface5": { - "@module": "simsopt.geo.boozersurface", - "@class": "BoozerSurface", - "@name": "BoozerSurface5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "biotsavart": { - "$type": "ref", - "value": "BiotSavart1" - }, - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "label": { - "$type": "ref", - "value": "Volume1" - }, - "targetlabel": -1.9061691362359223, - "constraint_weight": 1000.0, - "reg": null - } - } -} \ No newline at end of file diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_4.vts b/examples/2_Intermediate/inputs/input_ncsx/surface_4.vts deleted file mode 100644 index adb051c8012b430ec6ce8c661cf661c959f49835..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31872 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 diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_6.json b/examples/2_Intermediate/inputs/input_ncsx/surface_6.json deleted file mode 100644 index 26b82c11b..000000000 --- a/examples/2_Intermediate/inputs/input_ncsx/surface_6.json +++ /dev/null @@ -1,7022 +0,0 @@ -{ - "@module": "simsopt._core.json", - "@class": "SIMSON", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "graph": [ - { - "$type": "ref", - "value": "BoozerSurface7" - }, - { - "iota": -0.4495474245205908, - "G": 13.887480382084156 - } - ], - "simsopt_objs": { - "140342738246336": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738246336", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.506387961733893, - 0.1058930714809362, - 0.7258942274042265, - -0.001249592121112775, - 0.2763105569564668, - 0.01482550301512887, - -0.1280092780227772, - 0.005921392096802394, - 0.01864241438718947, - -0.01034831723350223, - 0.0001022108294955593, - 0.01892666378143068, - -0.007192153616853929, - -0.007355339046239706, - -0.01884714563379878, - -0.002596706082945131, - 0.01131859363705868, - 0.00964754529816095, - -0.0113260687651076, - -0.006628855789771619, - 0.000322284209286623, - 0.001842953924532827, - -0.0004161340928027646, - 0.00176264188836799, - 0.001814459617914206, - -0.001883356200860781, - -0.003584967425237995, - 0.0003165409191237933, - 0.00198839685289703, - 0.0007998064690618334, - 0.0005809753916376526, - 4.996792424044994e-05, - -0.0009656219012175038, - -0.001300735471703214, - -0.0004500391754653399, - 0.002413016477450284, - 0.00190334965179141, - -0.001622873850792805, - -0.001817132111793323, - 0.0005008124937015768, - 0.0009410326413637304, - 0.0005073038161052906, - -0.0001747050570155717, - -0.0004010070348672179, - 0.0002171330554898199, - 0.0001868680753017027, - -0.00049371483741256, - -1.263882515020243e-05, - 0.0005663593123846766, - 0.0001291744509577553, - -0.0002415255915965764, - 0.2855239540187146, - 0.02831674064739627, - 0.1230646086878452, - -0.1881027707999307, - -0.03092022550185042, - 0.07598032813641656, - 0.032842960392996, - -0.02022733960800226, - 0.03368541189764687, - -0.02527069889002642, - 0.03990545352197854, - 0.03266977475756579, - 0.007041509561223136, - -0.01843202758194484, - -0.003255107459418295, - 0.001087406605704745, - 0.02057587403483786, - 0.004332699549632209, - -0.003239348172858322, - -0.008060517809116506, - 0.0008303250764389791, - 0.002593682135814645, - 0.005122620691996364, - 0.002329497971206275, - -0.007021762243403233, - -0.002076255998522319, - 0.005455573755227739, - 0.0004034355313731426, - -0.002121189074115063, - -0.001155709211846629, - 0.0007060503790857225, - 0.001458108819397405, - 0.0007612900914783658, - -0.001579374591052191, - -0.0005648184298353118, - -3.483600030825498e-05, - 0.0006434230018098444, - 0.0002266872576160417, - -0.0005870263149471541, - -0.0004782734366555642, - 0.0004131000234993432, - -0.0002086017812282408, - -0.0002217317708794842, - 0.0004459870616389726, - 0.0002232186481886098, - -0.000550989811641543, - -0.0004679750418668452, - 0.0001971289820931924, - 0.0006305703105299488, - 1.94634036466225e-05, - -0.0005071137243856577, - 0.0009455853398023695, - -1.066704925256128, - 0.01954765252843791, - -0.03091192279856904, - -0.009251669123731003, - 0.03622032973711591, - 0.01289395028459556, - -0.01341289215090563, - -0.01055557464591715, - -0.007044726977866961, - -0.007171173731457627, - 0.01327231838496817, - 0.003220259676106272, - -0.006043809337864334, - -0.006228107449831786, - -0.0004722020937025503, - -0.0007632924616726337, - 0.0002557840887866895, - -0.0008300983337148277, - 0.001290373849098229, - 0.0002249498117545818, - -0.0003276137574950353, - -0.001560853624251917, - -0.003125967131907846, - 0.0007111137798287738, - 0.001688245514976161, - 0.00083638883723687, - -3.216802700299113e-05, - -0.003601309499252412, - -0.003364173533240832, - 0.003283863928203238, - 0.003620244544063828, - -0.001109032285114347, - -0.002277398193829699, - -0.0015519788484098, - 0.0002155015553257128, - 0.002349143532954114, - 0.000703914196138795, - -0.001628934087145739, - -0.0005728748367786014, - 0.000379102967651227, - 3.674770297429017e-05, - 0.0003644795696035227, - 0.0001196573774128766, - -0.0004826910821886253, - 1.895960151025164e-05, - 0.0002282029938596129, - -3.982416558199763e-05, - -0.0001869395233315697, - -0.0002051724761620464, - 0.0001303574263284748 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier1": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738246336" - } - }, - "140342738367104": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367104", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 652271.9419853 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current1": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 652271.9419853, - "dofs": { - "$type": "ref", - "value": "140342738367104" - } - }, - "Coil1": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "140342738247296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738247296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.268960636199869, - 0.2234285580503567, - 0.5468300987692021, - -0.07598922426224614, - 0.2314838962751658, - 0.01035784318060333, - -0.08314304549672957, - -0.04624738986383844, - 0.05377747860630284, - -0.001074456865203822, - -0.02151604922154927, - -0.01446679290684195, - 0.008416712252875694, - -0.009228184118107326, - 0.005277266362275169, - 0.01142201731157229, - 0.01681398796325401, - 0.009993706195866578, - 0.001370286955930781, - -0.008399573830195455, - -0.005099919856215084, - 0.005334309041669094, - -0.001419513324650316, - -0.003333508834690296, - 0.0002887180426140212, - -0.0001690909516323616, - -0.001592036575525169, - -4.507713399549196e-05, - 0.005287560419413426, - 0.001265480827581528, - -0.001229918688675425, - 0.001129035262308468, - -0.002142778995712242, - -0.001748186446934164, - 0.000763477629872682, - 0.0006002693299791978, - -0.0003618301004192371, - 0.000988040168005559, - 0.0007880569343915778, - -0.001135722890360471, - -0.0008706368325040781, - 0.0005507322770281398, - 0.0009555809731928289, - -0.0001476990895937402, - -0.001054028588515068, - -1.482885559572655e-05, - -0.0001592869344899095, - -0.0004579572172035079, - 0.0006274586578504227, - 0.0005393401407410331, - -3.182089243244368e-05, - 0.7629396044020591, - 0.189701305549749, - 0.2946730680990991, - -0.1569360429309221, - -0.08805875862294558, - -0.03077704895086764, - 0.1149783480591024, - 0.1301411562027019, - -0.001461622206151801, - 0.04030157913855995, - 0.0006901390690664732, - -0.02740323125842794, - -0.02323299800745342, - 0.006389595554305861, - 0.003627095782551136, - -0.01015301262258172, - -0.00621023311542419, - -0.003238881121248944, - -0.006852312518149265, - 0.005609446955056436, - 0.004762124576622897, - 0.006665063843140196, - -6.70526269177163e-05, - -0.003587348009623233, - -0.00322170321999071, - -0.004203038352780501, - 0.0006017815497404605, - 0.001489961187320675, - 0.002190828148742953, - -0.001018226063168117, - -0.002311412742654803, - 0.0005349636274747352, - 0.0005836793424641873, - 0.0003330260000362103, - 0.0006191475972028521, - 0.0004562062905476333, - -0.0003998259903290102, - -0.001606870160409875, - -0.0001005634411503442, - 0.0003784623778643909, - 0.0003873441313675419, - 0.0004934685418203405, - 0.0004248568990090018, - -0.0001368925780341768, - -0.0005224641202364183, - 7.402330001924084e-06, - 0.0001942482764948633, - 3.004761739695799e-05, - 0.0001571480542442944, - -1.517325817427362e-05, - -0.0001596571201453762, - -0.004342453367498795, - -0.8322915538683627, - 0.01842619538559772, - -0.1445740110997678, - -0.03919221672360253, - 0.0181885023851906, - 0.007857938792447916, - -0.0008409533080505334, - 0.0679882056193599, - -0.008440199737942872, - -0.05052693032193879, - 0.0111459982531894, - -0.002854468104354866, - -0.01157234174126346, - -0.002254287431014864, - 0.01222589681633306, - 0.007524606302699996, - -0.006381505382857464, - 0.003239076046582923, - 0.00341366498860203, - -0.00384676331619515, - 0.0004019843766106519, - 0.003278371413101953, - -0.001659157168404143, - -0.008498109023400214, - -0.0005869360684358228, - 0.001643969359882166, - -0.001687685453312147, - 0.001913710312578008, - 0.00307704389234268, - -0.001526906838827543, - -0.002096608532065649, - 0.002116359835823416, - 0.0002080593023590777, - -0.001289011271870523, - 0.0003465163727308783, - 0.0003373949660992973, - -0.0005853247790129025, - -0.0007569823284455652, - -3.821511752005806e-05, - 0.0008610335506290439, - 0.0002833895542749826, - -4.205984435378816e-05, - 0.0001112528084110792, - -0.0002379239249443648, - -0.0002104661224579025, - 0.0001263747200842462, - -0.0001533284829536013, - 0.0001522993485716547, - 0.0003185888026784711, - -0.0001603437887349448 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier2": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738247296" - } - }, - "140342738367296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 651868.5693674 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current2": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 651868.5693674, - "dofs": { - "$type": "ref", - "value": "140342738367296" - } - }, - "Coil2": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "140342738366624": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738366624", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.8980851593547453, - 0.1942559921705813, - 0.3889755333770718, - -0.1446923384557668, - 0.2616477438027761, - 0.03731920597998046, - -0.03289705406442186, - 0.02547136484396155, - 0.0532217952204826, - 0.050428478861979, - -0.03624366941253683, - -0.005451626158324006, - -0.01668041626206209, - 0.008182439166261426, - 0.003842296843932926, - 0.01470476196344816, - 0.01901860245900076, - 0.0218942171541043, - -0.00945061997881808, - 0.002564135600286371, - -0.006766476390874592, - -0.001269140258791196, - 0.002139997339095541, - 0.001657675366985779, - 0.0002979912903074711, - 0.006328865782046154, - 0.0004567550240531948, - -0.0008525115686061069, - -0.000977103914377314, - 0.0005522046297053057, - -0.0009600861596635313, - -0.001340814451660981, - -0.001495132545615355, - 0.0006434008787568705, - 0.000495245187218385, - -0.00134743162348104, - 0.0002393656261548005, - 0.0003132890671380592, - 0.0006144326019911972, - -0.0005029044211924421, - -0.000783957033721161, - -0.0004002250154653492, - 0.0002391300413782915, - -0.0003806672575232206, - -0.000145466845504183, - -7.221379723120868e-05, - 0.0006927366534479363, - -0.0001275371930022123, - -0.0001401106599127933, - -0.0002158625680600062, - -7.139828388354475e-05, - 1.129181984052873, - 0.2708936854358476, - 0.468646640557997, - 0.02081652240284051, - -0.1928735276123626, - -0.03518255586981031, - 0.01192001522947444, - -0.06439441858177399, - -0.004172035660790115, - -0.016589458610143, - 0.001628354566592241, - 0.003299047220307412, - 0.02371335634022325, - -0.02489732104888577, - 0.01517053799913132, - -0.007490250276888437, - -0.02121728304870823, - -0.006509759115093021, - 0.002045879344162137, - 0.0002421911767798572, - 0.005286626183968976, - -0.002423351884665077, - 0.003037404376098953, - -0.001045524131070646, - -0.001371894636819662, - 0.0002683048956511064, - 0.0006396825080884871, - 0.0006110891778951719, - -0.001898949452431453, - -0.001413075309279682, - -0.000175565426273192, - 0.00025798969577147, - 0.001643409441239691, - 7.18696208370806e-05, - -0.0001583133254478763, - 0.001580406281910882, - -0.002161287927547965, - -0.0003891297580205399, - 0.0004807171148380796, - -0.0003779554431875909, - -0.000203599914921071, - 0.0002418121495980502, - -0.0001924002563136939, - 0.0004205862222447268, - -0.0003081775538974041, - -1.457104090324735e-05, - -0.0001305465480840895, - -2.931233724533855e-05, - 3.39235991969411e-05, - -8.787891234509293e-05, - -0.0002714497625897205, - 0.01443108431390148, - -0.5884600992390547, - 0.1639153375972931, - -0.02326901782799053, - -0.09503676743509344, - -0.001882227773385535, - -0.1358423641287697, - -0.04946480830906624, - 0.01080325660372903, - -0.004462853204566593, - 0.02204832208587066, - -0.01988057349197482, - 0.006713767349457029, - 0.009816410920710776, - -0.004595941635687146, - 0.01307328931917959, - 0.0183731152740804, - -0.002049019816619709, - -0.009421893063595877, - 0.0003683472428279665, - 0.005559370162880608, - -0.001158799750525409, - 0.002656529580593774, - 0.005458828901239469, - 0.003685058507882478, - 0.005539080181031877, - 0.0003319744004354147, - 0.003297209047830778, - -0.001172958360845208, - -6.403055114502017e-05, - -0.0028127900802783, - -7.412199662635927e-05, - -1.404234804116165e-06, - 0.002212349409834762, - 0.001726905111358576, - 0.0009310945379894919, - -0.0002426222281296402, - 0.0007504861042380895, - -0.001511448440947522, - -0.0002060956498950368, - -0.000206480198377301, - 8.668234567299965e-05, - 0.0001267761162311387, - 1.493158313140079e-05, - 0.0001119337013982711, - 0.0003201242558262467, - 0.00016404919743365, - -0.0002679743018523173, - -0.000169663995881007, - 0.0002693900147788098, - -0.0001731877336642894 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier3": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738366624" - } - }, - "140342738367776": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367776", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 537743.5886473 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current3": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 537743.5886473, - "dofs": { - "$type": "ref", - "value": "140342738367776" - } - }, - "Coil3": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve1": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent1": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil4": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve1" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent1" - } - }, - "RotatedCurve2": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent2": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil5": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve2" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent2" - } - }, - "RotatedCurve3": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent3": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil6": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve3" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent3" - } - }, - "RotatedCurve4": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil7": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve4" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve5": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil8": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve5" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve6": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil9": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve6" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve7": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent4": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil10": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve7" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent4" - } - }, - "RotatedCurve8": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent5": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil11": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve8" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent5" - } - }, - "RotatedCurve9": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent6": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil12": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve9" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent6" - } - }, - "RotatedCurve10": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil13": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve10" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve11": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil14": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve11" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve12": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil15": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve12" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve13": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent7": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil16": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil16", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve13" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent7" - } - }, - "RotatedCurve14": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent8": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil17": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil17", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve14" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent8" - } - }, - "RotatedCurve15": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent9": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil18": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil18", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve15" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent9" - } - }, - "BiotSavart1": { - "@module": "simsopt.field.biotsavart", - "@class": "BiotSavart", - "@name": "BiotSavart1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "coils": [ - { - "$type": "ref", - "value": "Coil1" - }, - { - "$type": "ref", - "value": "Coil2" - }, - { - "$type": "ref", - "value": "Coil3" - }, - { - "$type": "ref", - "value": "Coil4" - }, - { - "$type": "ref", - "value": "Coil5" - }, - { - "$type": "ref", - "value": "Coil6" - }, - { - "$type": "ref", - "value": "Coil7" - }, - { - "$type": "ref", - "value": "Coil8" - }, - { - "$type": "ref", - "value": "Coil9" - }, - { - "$type": "ref", - "value": "Coil10" - }, - { - "$type": "ref", - "value": "Coil11" - }, - { - "$type": "ref", - "value": "Coil12" - }, - { - "$type": "ref", - "value": "Coil13" - }, - { - "$type": "ref", - "value": "Coil14" - }, - { - "$type": "ref", - "value": "Coil15" - }, - { - "$type": "ref", - "value": "Coil16" - }, - { - "$type": "ref", - "value": "Coil17" - }, - { - "$type": "ref", - "value": "Coil18" - } - ], - "points": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - [ - 1.7402302347007024, - 0.0, - 0.0 - ], - [ - 1.7058570041562326, - 0.015574951416036105, - -0.2193798075397688 - ], - [ - 1.6104140498881088, - 0.03756549611469929, - -0.4080067105276916 - ], - [ - 1.4709187504983297, - 0.07287643767952254, - -0.5464582762261487 - ], - [ - 1.3348616585259394, - 0.11240528312761051, - -0.6209214412116206 - ], - [ - 1.2625072382215734, - 0.13774086524011123, - -0.6246545878330929 - ], - [ - 1.2599605289780382, - 0.1382578392998912, - -0.5729727150195244 - ], - [ - 1.3211684968049722, - 0.11011914603684952, - -0.47246202072520826 - ], - [ - 1.4368888565470295, - 0.05933059111366294, - -0.28412841775886427 - ], - [ - 1.5035774432167162, - 2.111505465038396e-17, - -1.0735424551160511e-16 - ], - [ - 1.4368888565470295, - -0.0593305911136629, - 0.2841284177588641 - ], - [ - 1.3211684968049724, - -0.11011914603684944, - 0.47246202072520804 - ], - [ - 1.259960528978038, - -0.13825783929989116, - 0.5729727150195242 - ], - [ - 1.2625072382215734, - -0.13774086524011123, - 0.6246545878330929 - ], - [ - 1.3348616585259392, - -0.11240528312761058, - 0.6209214412116207 - ], - [ - 1.4709187504983294, - -0.07287643767952266, - 0.5464582762261492 - ], - [ - 1.6104140498881085, - -0.03756549611469933, - 0.40800671052769194 - ], - [ - 1.7058570041562322, - -0.01557495141603613, - 0.21937980753976938 - ], - [ - 1.7256376665488444, - 0.2016012300898992, - -0.02090027466329247 - ], - [ - 1.7008254909730414, - 0.2159174352161673, - -0.23726777902971893 - ], - [ - 1.6140375239526754, - 0.23132358742080497, - -0.4197528510582566 - ], - [ - 1.483763956051522, - 0.2564142621684157, - -0.5511234280453176 - ], - [ - 1.3644955506075578, - 0.28362843273312255, - -0.6176993443866384 - ], - [ - 1.3077057972003576, - 0.29661727896712897, - -0.6107876702509323 - ], - [ - 1.3101619621933136, - 0.28617222143336873, - -0.5466802982944274 - ], - [ - 1.3689728770050793, - 0.252059262104719, - -0.42791121851444797 - ], - [ - 1.4623816125018634, - 0.20184425230102127, - -0.21700610344350782 - ], - [ - 1.480574440522177, - 0.14239017923258776, - 0.07209281417258916 - ], - [ - 1.3737088284165382, - 0.07855991704171869, - 0.33337198149113956 - ], - [ - 1.249025822658004, - 0.026522214339931665, - 0.49256752476858623 - ], - [ - 1.1928334118888628, - 0.0048478591487777865, - 0.5747482077572273 - ], - [ - 1.2043512331596042, - 0.016683574015398456, - 0.615557729381082 - ], - [ - 1.2914971053681954, - 0.05572592592991116, - 0.6046919937729073 - ], - [ - 1.439744814078288, - 0.10793020032286406, - 0.5261718572244019 - ], - [ - 1.5850016725600584, - 0.15232987205978096, - 0.38556032083316105 - ], - [ - 1.684790902389834, - 0.1814988917911921, - 0.1970338023020704 - ], - [ - 1.6824290511842894, - 0.3984812114723389, - -0.0401075443383495 - ], - [ - 1.6679481935133171, - 0.4160385548393808, - -0.24812441208369487 - ], - [ - 1.5927656368679763, - 0.42603073057910945, - -0.42036392819148355 - ], - [ - 1.4777071299903843, - 0.4395514328909597, - -0.541978671156464 - ], - [ - 1.3793493488297306, - 0.4544824340664603, - -0.5965567526507904 - ], - [ - 1.33525350362928, - 0.45491400122647374, - -0.5756426680052781 - ], - [ - 1.3369525560988966, - 0.4333284751212648, - -0.4980434321618357 - ], - [ - 1.3841188054845486, - 0.3932031184128618, - -0.3628993542176371 - ], - [ - 1.4439007266878636, - 0.3395544058389125, - -0.14161366666903966 - ], - [ - 1.4154144649857465, - 0.27505447340067063, - 0.1321472383828179 - ], - [ - 1.283497786902354, - 0.20662099606223255, - 0.3583059408519841 - ], - [ - 1.1603626755982182, - 0.15444828979623348, - 0.4879613009337175 - ], - [ - 1.1126883915842478, - 0.13886195324020395, - 0.5542909832443509 - ], - [ - 1.1356536152223764, - 0.16269146433669449, - 0.5865694120697543 - ], - [ - 1.2362060299039181, - 0.2164939999755274, - 0.5709436041428654 - ], - [ - 1.3922841110860231, - 0.28184933885870206, - 0.4911152456242783 - ], - [ - 1.53902508551775, - 0.3355762098690725, - 0.3536964905257767 - ], - [ - 1.6380721140671306, - 0.3716797424631452, - 0.17140360320598433 - ], - [ - 1.6140427661855599, - 0.585647125018574, - -0.05539379781744868 - ], - [ - 1.6065246588366635, - 0.6083587079005164, - -0.25095212495071145 - ], - [ - 1.545463804355573, - 0.6156342127092158, - -0.4122613089410039 - ], - [ - 1.4532364238396036, - 0.620665409534236, - -0.5211460539728151 - ], - [ - 1.3757962351328958, - 0.6242987736845237, - -0.5573538795497162 - ], - [ - 1.3370259803663291, - 0.6100067569224906, - -0.5201882285188424 - ], - [ - 1.3319366849296335, - 0.5739042940319335, - -0.4308196456988431 - ], - [ - 1.3594509452115475, - 0.5234024291000147, - -0.28548277998556965 - ], - [ - 1.3807472567647636, - 0.4619257431236637, - -0.0705923898228142 - ], - [ - 1.3172020986588422, - 0.392277485047036, - 0.17017164278576027 - ], - [ - 1.1776328488327157, - 0.32414986827130615, - 0.35749616899591413 - ], - [ - 1.0628954620435764, - 0.27720009943735924, - 0.4629945490356855 - ], - [ - 1.025390761244579, - 0.26967347591324403, - 0.5183964394305318 - ], - [ - 1.0616075977629063, - 0.303564946726764, - 0.5453024050461416 - ], - [ - 1.1735432269366282, - 0.3691304374827709, - 0.5258724110436973 - ], - [ - 1.332329500760001, - 0.44648618320167976, - 0.4458102358040153 - ], - [ - 1.4753871484342704, - 0.5092080157920826, - 0.3154809945204026 - ], - [ - 1.5696680653371482, - 0.5516099281572171, - 0.14431534691705616 - ], - [ - 1.5259204811764402, - 0.7613436620413225, - -0.06595789602193514 - ], - [ - 1.5221185981947405, - 0.7881064816032654, - -0.2472794142417303 - ], - [ - 1.4774739228954403, - 0.7987167343506226, - -0.3962828228208106 - ], - [ - 1.410182998359604, - 0.8010256401908309, - -0.48491945395813446 - ], - [ - 1.3457395269013355, - 0.7896634328304655, - -0.49575719954976044 - ], - [ - 1.3027601045826078, - 0.7523606803442766, - -0.4454031588797432 - ], - [ - 1.2868251965241788, - 0.6959103095276455, - -0.35279624136077087 - ], - [ - 1.2916685978389075, - 0.6326934766882801, - -0.20930897714010424 - ], - [ - 1.2788718440951823, - 0.5650520981423461, - -0.017222620825935418 - ], - [ - 1.197021852049817, - 0.4957178474155704, - 0.18137339595018268 - ], - [ - 1.0656128236692484, - 0.4359509160852478, - 0.3345404293790567 - ], - [ - 0.9661553399008728, - 0.40182875965171677, - 0.425495699019192 - ], - [ - 0.9405966592507751, - 0.4036786515537175, - 0.4768749240226683 - ], - [ - 0.9875179707844186, - 0.4428895366834234, - 0.5003263205159295 - ], - [ - 1.1053377066470058, - 0.5159748895190525, - 0.4756424482830472 - ], - [ - 1.2616327646360548, - 0.6033620230089682, - 0.39600521025985747 - ], - [ - 1.3969795178917792, - 0.6742624453494092, - 0.2756543022868004 - ], - [ - 1.484299452704361, - 0.7225686938134969, - 0.11840570186691095 - ], - [ - 1.4215532865277005, - 0.9268565931866678, - -0.0723315698221223 - ], - [ - 1.421063761587728, - 0.9577641146584395, - -0.23645544525362477 - ], - [ - 1.3916321778024625, - 0.9766374320042472, - -0.36526698534834584 - ], - [ - 1.3403624455304748, - 0.9739117637976664, - -0.4252864912506175 - ], - [ - 1.2770538349064329, - 0.9350802632905045, - -0.4146145643670294 - ], - [ - 1.2261240747141857, - 0.8661634693739361, - -0.3636095889523993 - ], - [ - 1.2005533162058675, - 0.7904290644028269, - -0.2789297402791997 - ], - [ - 1.18615343548747, - 0.7191861365909772, - -0.149181676993644 - ], - [ - 1.1509996184291396, - 0.6518229653586853, - 0.010291694165370758 - ], - [ - 1.06658869761164, - 0.5914448419406754, - 0.1681066574950465 - ], - [ - 0.9539017334705615, - 0.5471876098923234, - 0.297259035193847 - ], - [ - 0.8743963348421129, - 0.5280189731778528, - 0.3844394812739406 - ], - [ - 0.859557085686704, - 0.5373856860257885, - 0.4372331613292714 - ], - [ - 0.9116901763897614, - 0.5798615172140976, - 0.4553656238445187 - ], - [ - 1.03079954992947, - 0.6589812558262546, - 0.42343921031549914 - ], - [ - 1.1809261420225101, - 0.7542915217511955, - 0.3465166816725625 - ], - [ - 1.3051065534880697, - 0.8324714946708515, - 0.2376967735368004 - ], - [ - 1.383852088260522, - 0.8862100261533068, - 0.09488177288830879 - ], - [ - 1.3034457437615763, - 1.083675972220169, - -0.07444581585190804 - ], - [ - 1.3055812598179881, - 1.1192555248493006, - -0.21408099497190458 - ], - [ - 1.2827296366829364, - 1.1399521370950119, - -0.31299145352454605 - ], - [ - 1.2334848395370597, - 1.1180564955378625, - -0.34861370028154376 - ], - [ - 1.166893047776198, - 1.0424766384747108, - -0.33488456154866825 - ], - [ - 1.1135138471570736, - 0.9453044392612738, - -0.29624761075225237 - ], - [ - 1.0828078256387446, - 0.8584871890149435, - -0.22476120524412738 - ], - [ - 1.055527892768143, - 0.7856022385304074, - -0.11566013589020135 - ], - [ - 1.0109086795702906, - 0.7263688002610805, - 0.009908655472009973 - ], - [ - 0.9348933195028933, - 0.6836893081104073, - 0.13726038371482424 - ], - [ - 0.8435903253439936, - 0.6577510613674155, - 0.2542919239702618 - ], - [ - 0.7813338064317306, - 0.6511321986403572, - 0.34287811617174124 - ], - [ - 0.7740301007455208, - 0.6674700035055989, - 0.39609862572462934 - ], - [ - 0.8304781617358217, - 0.7150143844779059, - 0.4075793793707672 - ], - [ - 0.950211995534766, - 0.7999292566808192, - 0.3719149707920161 - ], - [ - 1.0913811705120164, - 0.9007230844594116, - 0.3019462797450627 - ], - [ - 1.2014756490943759, - 0.9836898736288169, - 0.20463156411619002 - ], - [ - 1.2698987066856737, - 1.0410232583816386, - 0.07470098679936467 - ], - [ - 1.173341785769199, - 1.2331377817383493, - -0.0678506715866868 - ], - [ - 1.1718927345516112, - 1.2680420490111741, - -0.1759374357465704 - ], - [ - 1.1442188961677688, - 1.2728596311772937, - -0.24889536568504442 - ], - [ - 1.0918596260388407, - 1.2198833301720806, - -0.28018406933254525 - ], - [ - 1.0279034705183085, - 1.1124500086435716, - -0.2801027789367992 - ], - [ - 0.978656377197632, - 0.9970723041173372, - -0.2568256028599403 - ], - [ - 0.9459208061635801, - 0.9051217033416749, - -0.19944520725589976 - ], - [ - 0.9119899906533269, - 0.8363433662550539, - -0.11318249922069373 - ], - [ - 0.8673740365144367, - 0.7930937966188915, - -0.015044168169712505 - ], - [ - 0.8045722620788492, - 0.7730099473537863, - 0.09573805517239561 - ], - [ - 0.7318117729503928, - 0.7648279067682047, - 0.20833645160620473 - ], - [ - 0.6828323072324797, - 0.7701257168500281, - 0.29515456111661764 - ], - [ - 0.6836484680508297, - 0.7958781150177584, - 0.3454663012151366 - ], - [ - 0.7455000388829833, - 0.8498646716595732, - 0.3553121164270347 - ], - [ - 0.8634800161752264, - 0.9396132833833367, - 0.32416656283005996 - ], - [ - 0.993364500719075, - 1.0440554248583778, - 0.2655475098211498 - ], - [ - 1.0885371344662567, - 1.1277799140738574, - 0.17961440212123794 - ], - [ - 1.1455685494212022, - 1.186365330485529, - 0.06062289076104869 - ], - [ - 1.0275744396241633, - 1.3724251594190378, - -0.043151157718258816 - ], - [ - 1.0125823603626276, - 1.3920019131859702, - -0.12621229866290176 - ], - [ - 0.977396598158005, - 1.367783132085871, - -0.194947542947465 - ], - [ - 0.9284279364402485, - 1.2867501513386326, - -0.23999626758803197 - ], - [ - 0.8738438170322024, - 1.1582569455746559, - -0.2565579562696111 - ], - [ - 0.8312497737000512, - 1.0302748083322488, - -0.24712756736600594 - ], - [ - 0.7993608464022512, - 0.9369275842696574, - -0.20504421816617951 - ], - [ - 0.7647095456914907, - 0.8784598049924632, - -0.1384099301892158 - ], - [ - 0.7246768287746658, - 0.8555931928647699, - -0.05623789319811258 - ], - [ - 0.6740317941202304, - 0.8581467435706501, - 0.04880011500334062 - ], - [ - 0.617169662514404, - 0.866521060913295, - 0.1579895100202265 - ], - [ - 0.5832397784371627, - 0.8846699056227635, - 0.2390747151792601 - ], - [ - 0.5947873145928388, - 0.9218496222732231, - 0.2882880537116749 - ], - [ - 0.6594660173646497, - 0.9827823490893004, - 0.304201589980261 - ], - [ - 0.7709872184839537, - 1.0770742116563525, - 0.2843499131055834 - ], - [ - 0.8879864980629963, - 1.1843086606161113, - 0.23974773697380766 - ], - [ - 0.9688702233936695, - 1.2669810698709838, - 0.16517590043878475 - ], - [ - 1.012973244796695, - 1.3260176421797045, - 0.05978651564612899 - ], - [ - 0.8604071817241601, - 1.4902689539433929, - -1.7598949661357686e-17 - ], - [ - 0.8307973676825338, - 1.480722212223664, - -0.08190713716927991 - ], - [ - 0.7954545898106665, - 1.4298073238307822, - -0.1672217133352955 - ], - [ - 0.7559380743582361, - 1.3311000452917796, - -0.2289945146899045 - ], - [ - 0.7120665403294911, - 1.187913326687164, - -0.2595881023516155 - ], - [ - 0.6774670270610709, - 1.0504626727306139, - -0.2648033294921933 - ], - [ - 0.6504867607087785, - 0.9597107087735838, - -0.23745139739522442 - ], - [ - 0.6193776393585214, - 0.915534603037563, - -0.18323595855709218 - ], - [ - 0.5837338667895391, - 0.9141382047814168, - -0.10560714264370179 - ], - [ - 0.5415882611442585, - 0.9380583850847367, - -2.2575521202496584e-17 - ], - [ - 0.4997999745158391, - 0.9625974600797705, - 0.10560714264370177 - ], - [ - 0.48318740459497067, - 0.9941640717392971, - 0.18323595855709204 - ], - [ - 0.5058904737275035, - 1.043193413986043, - 0.23745139739522442 - ], - [ - 0.5709938467814754, - 1.111934992026514, - 0.2648033294921934 - ], - [ - 0.6727298482404218, - 1.2106243764538178, - 0.25958810235161556 - ], - [ - 0.7747974170221803, - 1.3202115987280119, - 0.2289945146899047 - ], - [ - 0.8405221700491677, - 1.4037875442483583, - 0.16722171333529565 - ], - [ - 0.8669443678923193, - 1.4598527319221464, - 0.08190713716928008 - ], - [ - 0.6747678330377133, - 1.5761181487036027, - 0.04315115771825871 - ], - [ - 0.6418783415956207, - 1.540269384437743, - -0.059786515646128774 - ], - [ - 0.6128026809254244, - 1.4725567613647137, - -0.16517590043878452 - ], - [ - 0.5816481369839777, - 1.3611731958481916, - -0.23974773697380758 - ], - [ - 0.5472800198135221, - 1.2062316230283836, - -0.2843499131055832 - ], - [ - 0.5213814720199559, - 1.0625054985149864, - -0.3042015899802609 - ], - [ - 0.5009515340612813, - 0.9760257354227373, - -0.2882880537116748 - ], - [ - 0.47452672301431403, - 0.9474354174355721, - -0.2390747151792601 - ], - [ - 0.4418444204079547, - 0.9677451366391898, - -0.15798951002022638 - ], - [ - 0.40616098304695847, - 1.0128020284518469, - -0.04880011500334052 - ], - [ - 0.3786270259385968, - 1.0553851396851912, - 0.05623789319811266 - ], - [ - 0.3784137344812518, - 1.101487795581519, - 0.1384099301892158 - ], - [ - 0.4117226662827829, - 1.1607305919098083, - 0.2050442181661794 - ], - [ - 0.47661927004484556, - 1.2350208250804344, - 0.24712756736600588 - ], - [ - 0.5661580304613207, - 1.3358994172771756, - 0.25655795626961103 - ], - [ - 0.6501443511626027, - 1.4474172542097354, - 0.23999626758803208 - ], - [ - 0.6958366401752086, - 1.530341849620258, - 0.194947542947465 - ], - [ - 0.6992178387542773, - 1.5729230040910294, - 0.12621229866290176 - ], - [ - 0.4812577524672017, - 1.6327126846670994, - 0.0678506715866868 - ], - [ - 0.4546382396589883, - 1.5852741308180152, - -0.06062289076104843 - ], - [ - 0.4324174882326637, - 1.5065907684474245, - -0.17961440212123778 - ], - [ - 0.407496270526773, - 1.3823066052695536, - -0.26554750982114955 - ], - [ - 0.3819889650556633, - 1.2176022713596124, - -0.32416656283005985 - ], - [ - 0.36325437599461985, - 1.0705543080247373, - -0.3553121164270347 - ], - [ - 0.3474264318960376, - 0.9899959980992121, - -0.3454663012151366 - ], - [ - 0.32553228128358624, - 0.9764129830130823, - -0.29515456111661764 - ], - [ - 0.2964545103093453, - 1.016181539547672, - -0.20833645160620481 - ], - [ - 0.267160120747026, - 1.0832849918174878, - -0.09573805517239566 - ], - [ - 0.25315235719859064, - 1.1477148485139992, - 0.015044168169712456 - ], - [ - 0.2682996061368062, - 1.2079781830304404, - 0.11318249922069355 - ], - [ - 0.31089798552874287, - 1.2717522997767532, - 0.1994452072558996 - ], - [ - 0.3741617561766815, - 1.3460774362874637, - 0.2568256028599402 - ], - [ - 0.44945823266639695, - 1.4464155224288295, - 0.2801027789367991 - ], - [ - 0.5105201405627615, - 1.555519838602253, - 0.2801840693325452 - ], - [ - 0.5302193279673434, - 1.6273524471601237, - 0.24889536568504453 - ], - [ - 0.5122102602347435, - 1.648909903137696, - 0.1759374357465706 - ], - [ - 0.2867680495326781, - 1.6706551126623115, - 0.07444581585190803 - ], - [ - 0.26660323434611394, - 1.6202761694136165, - -0.07470098679936434 - ], - [ - 0.2511625954608719, - 1.5323533709585364, - -0.2046315641161898 - ], - [ - 0.234358487660919, - 1.3955253611051084, - -0.3019462797450625 - ], - [ - 0.21765305974860946, - 1.2228723554542227, - -0.37191497079201585 - ], - [ - 0.20398154016124972, - 1.0767223775903763, - -0.4075793793707671 - ], - [ - 0.19103092892717694, - 1.0040647322922494, - -0.39609862572462934 - ], - [ - 0.17323012202869956, - 1.0022210245256504, - -0.34287811617174124 - ], - [ - 0.14783396583836247, - 1.0594461828183857, - -0.25429192397026174 - ], - [ - 0.12464564936797248, - 1.151486018573071, - -0.1372603837148242 - ], - [ - 0.12359949375737533, - 1.238656997544595, - -0.009908655472010091 - ], - [ - 0.15258754945318342, - 1.3069150888054721, - 0.11566013589020108 - ], - [ - 0.20206780169106175, - 1.3669826789272153, - 0.22476120524412718 - ], - [ - 0.2619007351319303, - 1.4369834987344055, - 0.29624761075225226 - ], - [ - 0.3193647278828068, - 1.5317973421109918, - 0.334884561548668 - ], - [ - 0.3515229082334621, - 1.6272574539909974, - 0.34861370028154354 - ], - [ - 0.34586269148117327, - 1.680852520102112, - 0.31299145352454605 - ], - [ - 0.3165130879365854, - 1.6902943001319195, - 0.2140809949719048 - ], - [ - 0.09190471210090319, - 1.6945295555595816, - 0.0723315698221223 - ], - [ - 0.07555435160697468, - 1.6415560765904105, - -0.09488177288830844 - ], - [ - 0.06838818556732464, - 1.5464911773016488, - -0.23769677353680024 - ], - [ - 0.06277254868450298, - 1.3998577998602417, - -0.34651668167256217 - ], - [ - 0.05529473319857377, - 1.2221892243616141, - -0.423439210315499 - ], - [ - 0.04632971638951558, - 1.0794776117412979, - -0.4553656238445186 - ], - [ - 0.03561111288510922, - 1.0130911152204976, - -0.4372331613292714 - ], - [ - 0.020079677031138506, - 1.0212589255382, - -0.3844394812739406 - ], - [ - -0.0030724959324393286, - 1.0996969388456803, - -0.29725903519384705 - ], - [ - -0.021088090747922963, - 1.2194153284913765, - -0.1681066574950466 - ], - [ - -0.01100456244384393, - 1.3227063919851727, - -0.01029169416537087 - ], - [ - 0.029756746593636453, - 1.3868320762138238, - 0.1491816769936436 - ], - [ - 0.08425499155948052, - 1.4349242026333464, - 0.2789297402791995 - ], - [ - 0.13705753095080048, - 1.494936331581142, - 0.3636095889523993 - ], - [ - 0.17127634513380208, - 1.5735011946745616, - 0.4146145643670294 - ], - [ - 0.17325110572805186, - 1.64774381000686, - 0.42528649125061746 - ], - [ - 0.14997673750124438, - 1.693507534702919, - 0.36526698534834595 - ], - [ - 0.11891617333345676, - 1.7095593752616647, - 0.23645544525362513 - ], - [ - -0.10361728825016032, - 1.702157731874433, - 0.06595789602193516 - ], - [ - -0.11638688153035223, - 1.6467253797720636, - -0.11840570186691048 - ], - [ - -0.1145613524554844, - 1.5469509737355234, - -0.27565430228680005 - ], - [ - -0.10828954271348974, - 1.3942870359261017, - -0.39600521025985713 - ], - [ - -0.10582149128513427, - 1.215237978476665, - -0.4756424482830471 - ], - [ - -0.1102053955540444, - 1.0766604177346772, - -0.5003263205159295 - ], - [ - -0.12070236241442137, - 1.0164199274028054, - -0.4768749240226683 - ], - [ - -0.13508375612085802, - 1.0376294481820032, - -0.425495699019192 - ], - [ - -0.15526184370170137, - 1.1408232339386606, - -0.33454042937905665 - ], - [ - -0.1692066770536863, - 1.2845102564680244, - -0.18137339595018273 - ], - [ - -0.15008645059462145, - 1.3900615542422525, - 0.017222620825935234 - ], - [ - -0.09790567529870572, - 1.4349645573432592, - 0.20930897714010366 - ], - [ - -0.040736591455656376, - 1.462378465183664, - 0.3527962413607705 - ], - [ - 0.0001834096953832881, - 1.5044036857775487, - 0.44540315887974313 - ], - [ - 0.010998829820142261, - 1.5602763335886412, - 0.49575719954976033 - ], - [ - -0.01138294569184893, - 1.621767120659742, - 0.48491945395813446 - ], - [ - -0.047027979072333644, - 1.6788883178318137, - 0.3962828228208107 - ], - [ - -0.07853906514176884, - 1.7122466144110362, - 0.24727941424173056 - ], - [ - -0.2998360951733736, - 1.6906256008204885, - 0.05539379781744869 - ], - [ - -0.3071258219047147, - 1.635177384169751, - -0.14431534691705572 - ], - [ - -0.29670649673052396, - 1.5323267588572023, - -0.31548099452040235 - ], - [ - -0.27949637328859284, - 1.3770742854704396, - -0.44581023580401496 - ], - [ - -0.2670952772981708, - 1.2008834657076721, - -0.5258724110436973 - ], - [ - -0.26790884331760556, - 1.0711616218766307, - -0.5453024050461416 - ], - [ - -0.27915129975456915, - 1.0228511860002913, - -0.5183964394305319 - ], - [ - -0.2913854029774625, - 1.0590945214156153, - -0.4629945490356856 - ], - [ - -0.3080944038600273, - 1.1819348975558244, - -0.3574961689959142 - ], - [ - -0.31887878194601754, - 1.3368692218802516, - -0.17017164278576039 - ], - [ - -0.29033420017528394, - 1.426725072125792, - 0.070592389822814 - ], - [ - -0.2264456726026775, - 1.439020268301974, - 0.28548277998556926 - ], - [ - -0.16895264449218828, - 1.440443152397459, - 0.43081964569884296 - ], - [ - -0.14023164220812856, - 1.4629018429782803, - 0.5201882285188424 - ], - [ - -0.1472395200041784, - 1.5036238768983388, - 0.557353879549716 - ], - [ - -0.1891062000128808, - 1.5688723655170638, - 0.5211460539728152 - ], - [ - -0.2395770345327728, - 1.6462280215558778, - 0.41226130894100416 - ], - [ - -0.2764082337630074, - 1.6954705203089369, - 0.25095212495071184 - ], - [ - -0.4961196735262996, - 1.6562669041267137, - 0.040107544338349566 - ], - [ - -0.4971519579884234, - 1.604451935244589, - -0.17140360320598375 - ], - [ - -0.4788950201065597, - 1.5006229260544268, - -0.35369649052577634 - ], - [ - -0.4520533680515267, - 1.346678078915283, - -0.49111524562427794 - ], - [ - -0.4306137112062442, - 1.1788328261960623, - -0.570943604142865 - ], - [ - -0.42693186651672027, - 1.0648506128505633, - -0.5865694120697541 - ], - [ - -0.43608621666698, - 1.0330473902281079, - -0.554290983244351 - ], - [ - -0.4464251952645095, - 1.0821276995694549, - -0.4879613009337176 - ], - [ - -0.4628098619060388, - 1.214852187189661, - -0.35830594085198425 - ], - [ - -0.46950307110334116, - 1.3633121202619518, - -0.13214723838281825 - ], - [ - -0.4278876219205021, - 1.4202319127739578, - 0.14161366666903918 - ], - [ - -0.3515355133494751, - 1.3952836066118224, - 0.36289935421763647 - ], - [ - -0.2932028104112597, - 1.3744991147968169, - 0.4980434321618354 - ], - [ - -0.27365967021528825, - 1.3838204552483708, - 0.575642668005278 - ], - [ - -0.2960813409395241, - 1.4217927938133004, - 0.5965567526507903 - ], - [ - -0.3581908578417697, - 1.4995076303705468, - 0.541978671156464 - ], - [ - -0.42742938295963484, - 1.5923908690921222, - 0.4203639281914838 - ], - [ - -0.4736741393119889, - 1.6525047851985857, - 0.24812441208369534 - ], - [ - -0.6882270465823768, - 1.595246672003549, - 0.02090027466329256 - ], - [ - -0.685212800145021, - 1.549821167430101, - -0.19703380230206982 - ], - [ - -0.6605792973210246, - 1.4488166495077257, - -0.38556032083316066 - ], - [ - -0.6264021117239997, - 1.3008206841201337, - -0.5261718572244014 - ], - [ - -0.5974884851793839, - 1.146332265127881, - -0.6046919937729069 - ], - [ - -0.5877272176565483, - 1.0513405500030322, - -0.6155577293810819 - ], - [ - -0.5922183367676205, - 1.0354479667530112, - -0.5747482077572276 - ], - [ - -0.6015439999460048, - 1.0949491995745544, - -0.49256752476858656 - ], - [ - -0.6188195303309421, - 1.2289467013325397, - -0.33337198149113995 - ], - [ - -0.6169737077962474, - 1.3534101673024315, - -0.07209281417258961 - ], - [ - -0.5563885561503713, - 1.3673817526043759, - 0.21700610344350738 - ], - [ - -0.4661967142606924, - 1.3115949196306285, - 0.42791121851444747 - ], - [ - -0.40724856747793337, - 1.2777196530481614, - 0.546680298294427 - ], - [ - -0.39697479981322903, - 1.280815080535256, - 0.610787670250932 - ], - [ - -0.4366183473213281, - 1.3235020265435415, - 0.6176993443866383 - ], - [ - -0.5198207130952689, - 1.4131844102445232, - 0.551123428045318 - ], - [ - -0.6066866587753692, - 1.5134592921147538, - 0.4197528510582569 - ], - [ - -0.6634227614693381, - 1.580916800194878, - 0.23726777902971946 - ] - ] - } - }, - "140342738037920": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738037920", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.406258963977428, - 0.04295097851840034, - -0.002561310463938891, - 0.0007989227366976135, - 2.2543520945711195e-05, - -0.00028892287799783, - -1.6684013875857696e-05, - 0.24626556604581293, - -0.09038345777288276, - 0.0013962490589759578, - 0.0009726593174076946, - -0.0002633747215592735, - -7.436829921981472e-06, - -4.863800779382658e-05, - 0.08560054473145134, - 0.06276731622862239, - 0.01751176981009032, - -0.002749473185477003, - -0.0007401399414573232, - 0.00022355997237510615, - 0.00011592974625896148, - -0.02311472344042543, - -0.003858202118640215, - -0.002206313785237374, - -0.0021758292232522867, - 0.0007250969391782909, - -0.00014805022711856863, - -9.925340393764767e-05, - -2.0663156544842605e-05, - 0.007170344472513412, - 0.001660080080589182, - -0.0014755034713530746, - 0.0009266432734855827, - 7.212907013801047e-05, - -8.640481700829985e-05, - -0.0028392188734555684, - -0.004611972624183941, - -0.0018146057209778806, - 0.00018086768770647662, - 0.00045983614809892514, - -0.00021484062806856796, - 0.0001120379222678716, - 0.002059028464668953, - 0.00022762062987144232, - 0.0010006701183455553, - 0.0003722233867389176, - 0.00020503925702097187, - -0.00011499743538359502, - 1.3630326104209359e-05, - 0.19897955452616903, - -0.0044659990354148525, - -0.0013596864480935704, - -0.00037765276564353373, - -7.762264018275258e-05, - 2.6504959396566405e-05, - -0.05751346667142594, - -0.017951882197926195, - 0.003711371801445263, - 0.0007023078506876504, - 4.3942141403155366e-05, - -0.00027318904220267296, - 0.007653964046286689, - 0.0043433740406934465, - 0.002679354885711715, - -0.0008722754587014892, - -4.279095217223719e-05, - 6.135307718901577e-05, - -0.0025551202946962376, - -0.001893861063495939, - 0.001356851015248003, - -0.0012663164283912322, - 5.431291116243608e-05, - 9.657396771453867e-05, - 0.0037834357289587635, - 0.0026163095705066587, - 0.000227925254830098, - -0.0003916328932614321, - 0.00025593323292367163, - -0.00014370553946030845, - -0.0006167212871765763, - -0.000538479424186674, - -0.0005023476313143821, - -0.00021684986411474468, - 0.0001290855662294289, - -1.5270750427133104e-05, - -0.009513832700093733, - 0.0013520916796041062, - 0.0006254049585417375, - 0.00023932730940158864, - 9.212419131132556e-05, - -4.14860583944361e-05, - 0.04102255072309463, - 0.0004509465941488149, - -0.0007768357787799466, - 0.00019749727382769257, - -0.0003269223164798194, - -2.4198825193406168e-05, - -0.037799322894848705, - -0.0020174682677388763, - 0.0008272819657541414, - -0.00015201707025305517, - -0.00037323943359663373, - -0.00010086416926990942, - 0.0011703693002562234, - 0.0017978110212705635, - -0.0004822850160628523, - -0.000485861314533565, - 0.00026744335002549656, - 0.00015623893102179414, - -0.0011612315155666564, - 0.0013690142110910294, - -0.000234341920032412, - 0.00012389654419267746, - -2.167962664550075e-06, - 4.2251949329651374e-05, - 0.0009748855204375539, - 0.0006445572933191273, - -0.00018516537452718478, - 9.98101795756474e-05, - 1.574447101771992e-05, - -9.070955871409554e-05, - -0.00039683851818690717, - -8.75827939070776e-05, - 3.061153429706257e-05, - 2.9565996728849588e-05, - 5.1656507749056926e-05, - 4.443454026130757e-05, - 0.044203755873270724, - 0.08230932956725114, - -0.004480356838857705, - 3.006559723220991e-05, - 0.00013249958970657112, - -0.0002539953777435535, - 0.00022371854034226453, - 0.010440489230858031, - -0.04680174396454428, - -0.002008812893606749, - 0.001573901857679378, - 0.00030427083292534527, - -4.6847587167997824e-05, - -9.774951344130324e-05, - -0.0048095057590845265, - -0.0018315349770661193, - 0.0026625985421280863, - -0.0012386364535208216, - -0.00024742706111867955, - 3.524615635376639e-05, - 0.0001261118682532047, - 0.0008893276224414975, - 0.001753671323188433, - -0.0007623289813681504, - -0.0009528818397139852, - 7.774088146081922e-05, - 4.1110676119974126e-05, - 6.483810608870124e-05, - -0.00019225022387033298, - 0.00043241024469760977, - 0.00012249042445684188, - -0.00029338170578360024, - 0.0002711029043287161, - 4.0998036993231005e-05, - -0.00011478437884237744, - 0.0006406084806885246, - 0.00023374055087257495, - -3.0253136803766137e-05, - -0.0002605453188625945, - -3.1077533714312803e-07, - 2.889008663547656e-05, - 5.4214713648939503e-05, - 0.03062977966620271, - -0.006032502395003948, - 0.0019998370621691344, - 0.0003143547726694803, - -0.00019993541082625096, - 4.450222471583974e-05, - -0.11974439280454989, - 0.0045961133213577405, - -0.000326598355237115, - -9.60518978013122e-05, - 4.258848685383921e-06, - -1.3212028571938621e-05, - 0.015736914649712573, - 0.017931879494302815, - -0.003434064274252471, - -0.0006350469136993644, - 7.953593720664445e-05, - 6.366649876647115e-05, - -0.0054169372609551006, - -0.00562341046061577, - -0.002527640511583512, - 0.0010114478483572616, - 5.746935740830996e-06, - -8.831473520271327e-06, - 0.005290176540463956, - 0.003413153349656131, - -0.0022440562877789824, - 0.0011612545008709767, - -5.5855771090187666e-05, - -5.3688027629861904e-05, - -0.0013029251295502116, - -0.0015909347902231773, - -0.0003229535115397038, - 0.00046719039154972887, - -0.0002448113989290334, - 9.240086782869513e-05, - -0.0007335102440339875, - 0.0007065226310007519, - 0.0003660237376009781, - 0.00017798470772705882, - -0.00016689782001723554, - 4.479314533340742e-05, - -0.4611801275190255, - -0.19076693360116903, - 0.000803935588738174, - -0.0006873712763186186, - -0.00013682253772492685, - -0.0001557713447880891, - 6.243444143791703e-05, - 0.00271416813642511, - 0.011373256571074089, - 0.016900127180192757, - -0.0016418274525676153, - -0.0008900962457272901, - 0.00018213441349437237, - 0.00010327795338892219, - -0.012924419959006743, - -0.009803435645321773, - -0.0025938362394300227, - -0.0023306240281902517, - 0.0008488220509905624, - 0.0001232103477872181, - 4.501255578576383e-05, - 0.0041004787113504545, - 0.0069552800404799825, - 0.003649638003106337, - -0.0022285704098195243, - 0.0010652088072614747, - -2.591353283246865e-05, - -8.319943803311588e-05, - -0.001869041289089502, - -0.0029483319183411143, - -0.0012697383304758785, - 0.00010480287293521418, - 0.0004128026285357575, - -0.00026599156179524756, - 7.8625484279717e-05, - 0.0007029116640618813, - -0.0010076760771096215, - 0.0007054167229323628, - 0.0002722708485283385, - 0.00018597853009729237, - -0.00011854785325776304, - 3.453618249531067e-05 - ] - }, - "names": [ - "x0", - "x1", - "x2", - "x3", - "x4", - "x5", - "x6", - "x7", - "x8", - "x9", - "x10", - "x11", - "x12", - "x13", - "x14", - "x15", - "x16", - "x17", - "x18", - "x19", - "x20", - "x21", - "x22", - "x23", - "x24", - "x25", - "x26", - "x27", - "x28", - "x29", - "x30", - "x31", - "x32", - "x33", - "x34", - "x35", - "x36", - "x37", - "x38", - "x39", - "x40", - "x41", - "x42", - "x43", - "x44", - "x45", - "x46", - "x47", - "x48", - "x49", - "x50", - "x51", - "x52", - "x53", - "x54", - "x55", - "x56", - "x57", - "x58", - "x59", - "x60", - "x61", - "x62", - "x63", - "x64", - "x65", - "x66", - "x67", - "x68", - "x69", - "x70", - "x71", - "x72", - "x73", - "x74", - "x75", - "x76", - "x77", - "x78", - "x79", - "x80", - "x81", - "x82", - "x83", - "x84", - "x85", - "x86", - "x87", - "x88", - "x89", - "x90", - "x91", - "x92", - "x93", - "x94", - "x95", - "x96", - "x97", - "x98", - "x99", - "x100", - "x101", - "x102", - "x103", - "x104", - "x105", - "x106", - "x107", - "x108", - "x109", - "x110", - "x111", - "x112", - "x113", - "x114", - "x115", - "x116", - "x117", - "x118", - "x119", - "x120", - "x121", - "x122", - "x123", - "x124", - "x125", - "x126", - "x127", - "x128", - "x129", - "x130", - "x131", - "x132", - "x133", - "x134", - "x135", - "x136", - "x137", - "x138", - "x139", - "x140", - "x141", - "x142", - "x143", - "x144", - "x145", - "x146", - "x147", - "x148", - "x149", - "x150", - "x151", - "x152", - "x153", - "x154", - "x155", - "x156", - "x157", - "x158", - "x159", - "x160", - "x161", - "x162", - "x163", - "x164", - "x165", - "x166", - "x167", - "x168", - "x169", - "x170", - "x171", - "x172", - "x173", - "x174", - "x175", - "x176", - "x177", - "x178", - "x179", - "x180", - "x181", - "x182", - "x183", - "x184", - "x185", - "x186", - "x187", - "x188", - "x189", - "x190", - "x191", - "x192", - "x193", - "x194", - "x195", - "x196", - "x197", - "x198", - "x199", - "x200", - "x201", - "x202", - "x203", - "x204", - "x205", - "x206", - "x207", - "x208", - "x209", - "x210", - "x211", - "x212", - "x213", - "x214", - "x215", - "x216", - "x217", - "x218", - "x219", - "x220", - "x221", - "x222", - "x223", - "x224", - "x225", - "x226", - "x227", - "x228", - "x229", - "x230", - "x231", - "x232", - "x233", - "x234", - "x235", - "x236", - "x237", - "x238", - "x239", - "x240", - "x241", - "x242", - "x243", - "x244", - "x245", - "x246", - "x247", - "x248", - "x249", - "x250", - "x251", - "x252" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "SurfaceXYZTensorFourier1": { - "@module": "simsopt.geo.surfacexyztensorfourier", - "@class": "SurfaceXYZTensorFourier", - "@name": "SurfaceXYZTensorFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "nfp": 3, - "stellsym": true, - "mpol": 6, - "ntor": 6, - "clamped_dims": [ - false, - false, - false - ], - "quadpoints_phi": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.018518518518518517, - 0.037037037037037035, - 0.05555555555555555, - 0.07407407407407407, - 0.09259259259259259, - 0.1111111111111111, - 0.12962962962962962, - 0.14814814814814814, - 0.16666666666666666, - 0.18518518518518517, - 0.2037037037037037, - 0.2222222222222222, - 0.24074074074074073, - 0.25925925925925924, - 0.2777777777777778, - 0.2962962962962963, - 0.31481481481481477 - ] - }, - "quadpoints_theta": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.05555555555555555, - 0.1111111111111111, - 0.16666666666666666, - 0.2222222222222222, - 0.2777777777777778, - 0.3333333333333333, - 0.38888888888888884, - 0.4444444444444444, - 0.5, - 0.5555555555555556, - 0.611111111111111, - 0.6666666666666666, - 0.7222222222222222, - 0.7777777777777777, - 0.8333333333333333, - 0.8888888888888888, - 0.9444444444444444 - ] - }, - "dofs": { - "$type": "ref", - "value": "140342738037920" - } - }, - "Volume1": { - "@module": "simsopt.geo.surfaceobjectives", - "@class": "Volume", - "@name": "Volume1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "range": null, - "nphi": null, - "ntheta": null - }, - "BoozerSurface7": { - "@module": "simsopt.geo.boozersurface", - "@class": "BoozerSurface", - "@name": "BoozerSurface7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "biotsavart": { - "$type": "ref", - "value": "BiotSavart1" - }, - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "label": { - "$type": "ref", - "value": "Volume1" - }, - "targetlabel": -2.7112534817415535, - "constraint_weight": 1000.0, - "reg": null - } - } -} \ No newline at end of file diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_6.vts b/examples/2_Intermediate/inputs/input_ncsx/surface_6.vts deleted file mode 100644 index 50bab7950378033f592f1dbb8b18d3841f33e408..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31872 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�YxBB2J$*ZC6=`pLEt{JdfwP$s-?9t@a+ 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

YY;X+}VgH!xW~mZj zA%-Gn?oU}wj6!qlH`x+>JUv<{=u4s3Y>Or<+JXJ)xAqB}rB5P=SLy3_;9BzISBJN=xQdc1q$wcO0T>ewC9I1T7ARgKPvZ<}H&o z$#mk~5{TxYv_)9p0C6VCaXg7!we+j`|YKl+IIlJEvUgby%3Y{LAI zDq7}~?S3+c_0>`w-X}%mV19MJ_*-j^BO}_sD?1Z`;lLRp$7V|v;(W4K19|)ky+Vu3nJ_;d-d0_jSJF2Ij z2qA$rM~?C&QDTN=gC7o+bY6LBFN!{fSUK~I2oZ9aHy*IDdqK@2f%4_PO8k`IC5~f0 z`GzyS?iR@>ox?8Od+JU{sAHa~{M9!uWKaqE*#2FVCfHMtgr*e)kAwK~k8n>cx93Tx^p>B5^mwKNN5xVVeyeoB7u^)Ph

pCCuk{TzIlqLc=5Iv0Wd$$ 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 diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_8.json b/examples/2_Intermediate/inputs/input_ncsx/surface_8.json deleted file mode 100644 index ea7e85d3f..000000000 --- a/examples/2_Intermediate/inputs/input_ncsx/surface_8.json +++ /dev/null @@ -1,7022 +0,0 @@ -{ - "@module": "simsopt._core.json", - "@class": "SIMSON", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "graph": [ - { - "$type": "ref", - "value": "BoozerSurface9" - }, - { - "iota": -0.48069815477980943, - "G": 13.887479122211442 - } - ], - "simsopt_objs": { - "140342738246336": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738246336", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.506387961733893, - 0.1058930714809362, - 0.7258942274042265, - -0.001249592121112775, - 0.2763105569564668, - 0.01482550301512887, - -0.1280092780227772, - 0.005921392096802394, - 0.01864241438718947, - -0.01034831723350223, - 0.0001022108294955593, - 0.01892666378143068, - -0.007192153616853929, - -0.007355339046239706, - -0.01884714563379878, - -0.002596706082945131, - 0.01131859363705868, - 0.00964754529816095, - -0.0113260687651076, - -0.006628855789771619, - 0.000322284209286623, - 0.001842953924532827, - -0.0004161340928027646, - 0.00176264188836799, - 0.001814459617914206, - -0.001883356200860781, - -0.003584967425237995, - 0.0003165409191237933, - 0.00198839685289703, - 0.0007998064690618334, - 0.0005809753916376526, - 4.996792424044994e-05, - -0.0009656219012175038, - -0.001300735471703214, - -0.0004500391754653399, - 0.002413016477450284, - 0.00190334965179141, - -0.001622873850792805, - -0.001817132111793323, - 0.0005008124937015768, - 0.0009410326413637304, - 0.0005073038161052906, - -0.0001747050570155717, - -0.0004010070348672179, - 0.0002171330554898199, - 0.0001868680753017027, - -0.00049371483741256, - -1.263882515020243e-05, - 0.0005663593123846766, - 0.0001291744509577553, - -0.0002415255915965764, - 0.2855239540187146, - 0.02831674064739627, - 0.1230646086878452, - -0.1881027707999307, - -0.03092022550185042, - 0.07598032813641656, - 0.032842960392996, - -0.02022733960800226, - 0.03368541189764687, - -0.02527069889002642, - 0.03990545352197854, - 0.03266977475756579, - 0.007041509561223136, - -0.01843202758194484, - -0.003255107459418295, - 0.001087406605704745, - 0.02057587403483786, - 0.004332699549632209, - -0.003239348172858322, - -0.008060517809116506, - 0.0008303250764389791, - 0.002593682135814645, - 0.005122620691996364, - 0.002329497971206275, - -0.007021762243403233, - -0.002076255998522319, - 0.005455573755227739, - 0.0004034355313731426, - -0.002121189074115063, - -0.001155709211846629, - 0.0007060503790857225, - 0.001458108819397405, - 0.0007612900914783658, - -0.001579374591052191, - -0.0005648184298353118, - -3.483600030825498e-05, - 0.0006434230018098444, - 0.0002266872576160417, - -0.0005870263149471541, - -0.0004782734366555642, - 0.0004131000234993432, - -0.0002086017812282408, - -0.0002217317708794842, - 0.0004459870616389726, - 0.0002232186481886098, - -0.000550989811641543, - -0.0004679750418668452, - 0.0001971289820931924, - 0.0006305703105299488, - 1.94634036466225e-05, - -0.0005071137243856577, - 0.0009455853398023695, - -1.066704925256128, - 0.01954765252843791, - -0.03091192279856904, - -0.009251669123731003, - 0.03622032973711591, - 0.01289395028459556, - -0.01341289215090563, - -0.01055557464591715, - -0.007044726977866961, - -0.007171173731457627, - 0.01327231838496817, - 0.003220259676106272, - -0.006043809337864334, - -0.006228107449831786, - -0.0004722020937025503, - -0.0007632924616726337, - 0.0002557840887866895, - -0.0008300983337148277, - 0.001290373849098229, - 0.0002249498117545818, - -0.0003276137574950353, - -0.001560853624251917, - -0.003125967131907846, - 0.0007111137798287738, - 0.001688245514976161, - 0.00083638883723687, - -3.216802700299113e-05, - -0.003601309499252412, - -0.003364173533240832, - 0.003283863928203238, - 0.003620244544063828, - -0.001109032285114347, - -0.002277398193829699, - -0.0015519788484098, - 0.0002155015553257128, - 0.002349143532954114, - 0.000703914196138795, - -0.001628934087145739, - -0.0005728748367786014, - 0.000379102967651227, - 3.674770297429017e-05, - 0.0003644795696035227, - 0.0001196573774128766, - -0.0004826910821886253, - 1.895960151025164e-05, - 0.0002282029938596129, - -3.982416558199763e-05, - -0.0001869395233315697, - -0.0002051724761620464, - 0.0001303574263284748 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier1": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738246336" - } - }, - "140342738367104": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367104", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 652271.9419853 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current1": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 652271.9419853, - "dofs": { - "$type": "ref", - "value": "140342738367104" - } - }, - "Coil1": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "140342738247296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738247296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.268960636199869, - 0.2234285580503567, - 0.5468300987692021, - -0.07598922426224614, - 0.2314838962751658, - 0.01035784318060333, - -0.08314304549672957, - -0.04624738986383844, - 0.05377747860630284, - -0.001074456865203822, - -0.02151604922154927, - -0.01446679290684195, - 0.008416712252875694, - -0.009228184118107326, - 0.005277266362275169, - 0.01142201731157229, - 0.01681398796325401, - 0.009993706195866578, - 0.001370286955930781, - -0.008399573830195455, - -0.005099919856215084, - 0.005334309041669094, - -0.001419513324650316, - -0.003333508834690296, - 0.0002887180426140212, - -0.0001690909516323616, - -0.001592036575525169, - -4.507713399549196e-05, - 0.005287560419413426, - 0.001265480827581528, - -0.001229918688675425, - 0.001129035262308468, - -0.002142778995712242, - -0.001748186446934164, - 0.000763477629872682, - 0.0006002693299791978, - -0.0003618301004192371, - 0.000988040168005559, - 0.0007880569343915778, - -0.001135722890360471, - -0.0008706368325040781, - 0.0005507322770281398, - 0.0009555809731928289, - -0.0001476990895937402, - -0.001054028588515068, - -1.482885559572655e-05, - -0.0001592869344899095, - -0.0004579572172035079, - 0.0006274586578504227, - 0.0005393401407410331, - -3.182089243244368e-05, - 0.7629396044020591, - 0.189701305549749, - 0.2946730680990991, - -0.1569360429309221, - -0.08805875862294558, - -0.03077704895086764, - 0.1149783480591024, - 0.1301411562027019, - -0.001461622206151801, - 0.04030157913855995, - 0.0006901390690664732, - -0.02740323125842794, - -0.02323299800745342, - 0.006389595554305861, - 0.003627095782551136, - -0.01015301262258172, - -0.00621023311542419, - -0.003238881121248944, - -0.006852312518149265, - 0.005609446955056436, - 0.004762124576622897, - 0.006665063843140196, - -6.70526269177163e-05, - -0.003587348009623233, - -0.00322170321999071, - -0.004203038352780501, - 0.0006017815497404605, - 0.001489961187320675, - 0.002190828148742953, - -0.001018226063168117, - -0.002311412742654803, - 0.0005349636274747352, - 0.0005836793424641873, - 0.0003330260000362103, - 0.0006191475972028521, - 0.0004562062905476333, - -0.0003998259903290102, - -0.001606870160409875, - -0.0001005634411503442, - 0.0003784623778643909, - 0.0003873441313675419, - 0.0004934685418203405, - 0.0004248568990090018, - -0.0001368925780341768, - -0.0005224641202364183, - 7.402330001924084e-06, - 0.0001942482764948633, - 3.004761739695799e-05, - 0.0001571480542442944, - -1.517325817427362e-05, - -0.0001596571201453762, - -0.004342453367498795, - -0.8322915538683627, - 0.01842619538559772, - -0.1445740110997678, - -0.03919221672360253, - 0.0181885023851906, - 0.007857938792447916, - -0.0008409533080505334, - 0.0679882056193599, - -0.008440199737942872, - -0.05052693032193879, - 0.0111459982531894, - -0.002854468104354866, - -0.01157234174126346, - -0.002254287431014864, - 0.01222589681633306, - 0.007524606302699996, - -0.006381505382857464, - 0.003239076046582923, - 0.00341366498860203, - -0.00384676331619515, - 0.0004019843766106519, - 0.003278371413101953, - -0.001659157168404143, - -0.008498109023400214, - -0.0005869360684358228, - 0.001643969359882166, - -0.001687685453312147, - 0.001913710312578008, - 0.00307704389234268, - -0.001526906838827543, - -0.002096608532065649, - 0.002116359835823416, - 0.0002080593023590777, - -0.001289011271870523, - 0.0003465163727308783, - 0.0003373949660992973, - -0.0005853247790129025, - -0.0007569823284455652, - -3.821511752005806e-05, - 0.0008610335506290439, - 0.0002833895542749826, - -4.205984435378816e-05, - 0.0001112528084110792, - -0.0002379239249443648, - -0.0002104661224579025, - 0.0001263747200842462, - -0.0001533284829536013, - 0.0001522993485716547, - 0.0003185888026784711, - -0.0001603437887349448 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier2": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738247296" - } - }, - "140342738367296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 651868.5693674 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current2": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 651868.5693674, - "dofs": { - "$type": "ref", - "value": "140342738367296" - } - }, - "Coil2": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "140342738366624": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738366624", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.8980851593547453, - 0.1942559921705813, - 0.3889755333770718, - -0.1446923384557668, - 0.2616477438027761, - 0.03731920597998046, - -0.03289705406442186, - 0.02547136484396155, - 0.0532217952204826, - 0.050428478861979, - -0.03624366941253683, - -0.005451626158324006, - -0.01668041626206209, - 0.008182439166261426, - 0.003842296843932926, - 0.01470476196344816, - 0.01901860245900076, - 0.0218942171541043, - -0.00945061997881808, - 0.002564135600286371, - -0.006766476390874592, - -0.001269140258791196, - 0.002139997339095541, - 0.001657675366985779, - 0.0002979912903074711, - 0.006328865782046154, - 0.0004567550240531948, - -0.0008525115686061069, - -0.000977103914377314, - 0.0005522046297053057, - -0.0009600861596635313, - -0.001340814451660981, - -0.001495132545615355, - 0.0006434008787568705, - 0.000495245187218385, - -0.00134743162348104, - 0.0002393656261548005, - 0.0003132890671380592, - 0.0006144326019911972, - -0.0005029044211924421, - -0.000783957033721161, - -0.0004002250154653492, - 0.0002391300413782915, - -0.0003806672575232206, - -0.000145466845504183, - -7.221379723120868e-05, - 0.0006927366534479363, - -0.0001275371930022123, - -0.0001401106599127933, - -0.0002158625680600062, - -7.139828388354475e-05, - 1.129181984052873, - 0.2708936854358476, - 0.468646640557997, - 0.02081652240284051, - -0.1928735276123626, - -0.03518255586981031, - 0.01192001522947444, - -0.06439441858177399, - -0.004172035660790115, - -0.016589458610143, - 0.001628354566592241, - 0.003299047220307412, - 0.02371335634022325, - -0.02489732104888577, - 0.01517053799913132, - -0.007490250276888437, - -0.02121728304870823, - -0.006509759115093021, - 0.002045879344162137, - 0.0002421911767798572, - 0.005286626183968976, - -0.002423351884665077, - 0.003037404376098953, - -0.001045524131070646, - -0.001371894636819662, - 0.0002683048956511064, - 0.0006396825080884871, - 0.0006110891778951719, - -0.001898949452431453, - -0.001413075309279682, - -0.000175565426273192, - 0.00025798969577147, - 0.001643409441239691, - 7.18696208370806e-05, - -0.0001583133254478763, - 0.001580406281910882, - -0.002161287927547965, - -0.0003891297580205399, - 0.0004807171148380796, - -0.0003779554431875909, - -0.000203599914921071, - 0.0002418121495980502, - -0.0001924002563136939, - 0.0004205862222447268, - -0.0003081775538974041, - -1.457104090324735e-05, - -0.0001305465480840895, - -2.931233724533855e-05, - 3.39235991969411e-05, - -8.787891234509293e-05, - -0.0002714497625897205, - 0.01443108431390148, - -0.5884600992390547, - 0.1639153375972931, - -0.02326901782799053, - -0.09503676743509344, - -0.001882227773385535, - -0.1358423641287697, - -0.04946480830906624, - 0.01080325660372903, - -0.004462853204566593, - 0.02204832208587066, - -0.01988057349197482, - 0.006713767349457029, - 0.009816410920710776, - -0.004595941635687146, - 0.01307328931917959, - 0.0183731152740804, - -0.002049019816619709, - -0.009421893063595877, - 0.0003683472428279665, - 0.005559370162880608, - -0.001158799750525409, - 0.002656529580593774, - 0.005458828901239469, - 0.003685058507882478, - 0.005539080181031877, - 0.0003319744004354147, - 0.003297209047830778, - -0.001172958360845208, - -6.403055114502017e-05, - -0.0028127900802783, - -7.412199662635927e-05, - -1.404234804116165e-06, - 0.002212349409834762, - 0.001726905111358576, - 0.0009310945379894919, - -0.0002426222281296402, - 0.0007504861042380895, - -0.001511448440947522, - -0.0002060956498950368, - -0.000206480198377301, - 8.668234567299965e-05, - 0.0001267761162311387, - 1.493158313140079e-05, - 0.0001119337013982711, - 0.0003201242558262467, - 0.00016404919743365, - -0.0002679743018523173, - -0.000169663995881007, - 0.0002693900147788098, - -0.0001731877336642894 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier3": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738366624" - } - }, - "140342738367776": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367776", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 537743.5886473 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current3": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 537743.5886473, - "dofs": { - "$type": "ref", - "value": "140342738367776" - } - }, - "Coil3": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve1": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent1": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil4": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve1" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent1" - } - }, - "RotatedCurve2": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent2": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil5": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve2" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent2" - } - }, - "RotatedCurve3": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent3": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil6": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve3" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent3" - } - }, - "RotatedCurve4": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil7": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve4" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve5": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil8": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve5" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve6": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil9": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve6" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve7": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent4": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil10": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve7" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent4" - } - }, - "RotatedCurve8": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent5": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil11": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve8" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent5" - } - }, - "RotatedCurve9": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent6": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil12": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve9" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent6" - } - }, - "RotatedCurve10": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil13": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve10" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve11": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil14": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve11" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve12": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil15": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve12" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve13": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent7": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil16": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil16", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve13" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent7" - } - }, - "RotatedCurve14": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent8": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil17": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil17", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve14" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent8" - } - }, - "RotatedCurve15": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent9": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil18": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil18", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve15" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent9" - } - }, - "BiotSavart1": { - "@module": "simsopt.field.biotsavart", - "@class": "BiotSavart", - "@name": "BiotSavart1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "coils": [ - { - "$type": "ref", - "value": "Coil1" - }, - { - "$type": "ref", - "value": "Coil2" - }, - { - "$type": "ref", - "value": "Coil3" - }, - { - "$type": "ref", - "value": "Coil4" - }, - { - "$type": "ref", - "value": "Coil5" - }, - { - "$type": "ref", - "value": "Coil6" - }, - { - "$type": "ref", - "value": "Coil7" - }, - { - "$type": "ref", - "value": "Coil8" - }, - { - "$type": "ref", - "value": "Coil9" - }, - { - "$type": "ref", - "value": "Coil10" - }, - { - "$type": "ref", - "value": "Coil11" - }, - { - "$type": "ref", - "value": "Coil12" - }, - { - "$type": "ref", - "value": "Coil13" - }, - { - "$type": "ref", - "value": "Coil14" - }, - { - "$type": "ref", - "value": "Coil15" - }, - { - "$type": "ref", - "value": "Coil16" - }, - { - "$type": "ref", - "value": "Coil17" - }, - { - "$type": "ref", - "value": "Coil18" - } - ], - "points": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - [ - 1.7588414480736, - 0.0, - 0.0 - ], - [ - 1.7155472528969302, - 0.020836225298695343, - -0.26484949139151126 - ], - [ - 1.592461562622708, - 0.04077747547880802, - -0.4697706835013006 - ], - [ - 1.4121835135801513, - 0.08888074002352611, - -0.6103612636113791 - ], - [ - 1.2458916889731118, - 0.14578928433687138, - -0.6824740252302766 - ], - [ - 1.1734600398785981, - 0.1707609297072946, - -0.6740337128048814 - ], - [ - 1.1882822510229625, - 0.16579691402683375, - -0.6104268168611261 - ], - [ - 1.2692795446890817, - 0.13130293268583557, - -0.5021642324846014 - ], - [ - 1.4090561746559793, - 0.06811283133176542, - -0.301260551585781 - ], - [ - 1.489284100533596, - 2.3437677537758572e-17, - -1.1357504956326988e-16 - ], - [ - 1.4090561746559798, - -0.06811283133176538, - 0.30126055158578074 - ], - [ - 1.269279544689082, - -0.13130293268583537, - 0.5021642324846011 - ], - [ - 1.1882822510229625, - -0.16579691402683377, - 0.6104268168611258 - ], - [ - 1.1734600398785981, - -0.1707609297072946, - 0.6740337128048816 - ], - [ - 1.2458916889731115, - -0.14578928433687144, - 0.6824740252302766 - ], - [ - 1.4121835135801506, - -0.08888074002352626, - 0.6103612636113797 - ], - [ - 1.5924615626227079, - -0.04077747547880805, - 0.46977068350130075 - ], - [ - 1.71554725289693, - -0.020836225298695367, - 0.2648494913915118 - ], - [ - 1.7447216394291423, - 0.2064202514326965, - -0.033113672532758605 - ], - [ - 1.7103338265106847, - 0.22355446079141508, - -0.2917701511668801 - ], - [ - 1.5937336784065803, - 0.2352828580264856, - -0.4856431573272354 - ], - [ - 1.4229594232538576, - 0.2727461733017649, - -0.6194975052899334 - ], - [ - 1.281591553331697, - 0.3137247393387758, - -0.6865915235158722 - ], - [ - 1.2323014428631636, - 0.32444447204030846, - -0.6661809663348721 - ], - [ - 1.2508505442827609, - 0.3083955207920205, - -0.5855360174787579 - ], - [ - 1.3264263485680932, - 0.2659257348100183, - -0.45498374095819605 - ], - [ - 1.4412197978244068, - 0.20391041935129886, - -0.22849551863677955 - ], - [ - 1.465089178980134, - 0.13714294136085656, - 0.07875347615938508 - ], - [ - 1.3381166119410817, - 0.062498567749623576, - 0.35430521134845816 - ], - [ - 1.189999133659246, - -0.0020258052299134705, - 0.5212092483975064 - ], - [ - 1.1156591941518887, - -0.02855542044276091, - 0.6078263236853985 - ], - [ - 1.111455652345811, - -0.022313728280998854, - 0.6593386412348754 - ], - [ - 1.2034734020892206, - 0.01990899055789432, - 0.6604305825536602 - ], - [ - 1.3856182983962473, - 0.09380429824961098, - 0.5845727756610063 - ], - [ - 1.571016665827491, - 0.1505813519073939, - 0.441037040765989 - ], - [ - 1.6961997827070288, - 0.17888873167036579, - 0.2327774911592113 - ], - [ - 1.702232995572307, - 0.4092955354634234, - -0.06388001019318085 - ], - [ - 1.6787492090932803, - 0.4270578938416505, - -0.31021831654657195 - ], - [ - 1.5727499519331827, - 0.43033750840985563, - -0.4891098605082969 - ], - [ - 1.420047309186123, - 0.4556185644458015, - -0.615416002840236 - ], - [ - 1.3097007932895712, - 0.4817600947076162, - -0.6739285809181627 - ], - [ - 1.2779618006282984, - 0.476632377462082, - -0.6353152355179483 - ], - [ - 1.2908415998415923, - 0.4480048145826182, - -0.5342066521065756 - ], - [ - 1.3504076217782115, - 0.3994112180728517, - -0.3843855959690518 - ], - [ - 1.427487634399804, - 0.3354034763220363, - -0.14682068165171466 - ], - [ - 1.3966998362984853, - 0.26416164793585406, - 0.14416318827927407 - ], - [ - 1.2402894643233402, - 0.1829777983265331, - 0.3800649626692487 - ], - [ - 1.0955982945388185, - 0.116753195194792, - 0.5126408243001626 - ], - [ - 1.0322528547792673, - 0.09554942883811161, - 0.5820555908634439 - ], - [ - 1.0423127087576194, - 0.11519959177472074, - 0.6251345306405948 - ], - [ - 1.1518822379187321, - 0.17832542612988922, - 0.620678066318622 - ], - [ - 1.3445223368707615, - 0.26987457468850296, - 0.5427673190280521 - ], - [ - 1.5305410164778481, - 0.3354486585717333, - 0.40169452423756946 - ], - [ - 1.6516794313840408, - 0.3723936779355605, - 0.1971766473366787 - ], - [ - 1.6345752776377356, - 0.6025230014204319, - -0.08912168119729112 - ], - [ - 1.6186239282096968, - 0.6231729861447095, - -0.3192739456718181 - ], - [ - 1.5289916981668104, - 0.6211074628296241, - -0.4840768423440807 - ], - [ - 1.4058524066176212, - 0.6378567741204841, - -0.5974983309707099 - ], - [ - 1.3234237445622368, - 0.6513893512961206, - -0.6365016503908328 - ], - [ - 1.295705196812271, - 0.6281125953813773, - -0.5777030117693314 - ], - [ - 1.2966245661691715, - 0.5817767650448361, - -0.4612253517359411 - ], - [ - 1.3335684452254222, - 0.5218634682897358, - -0.300148370622395 - ], - [ - 1.3667701782969273, - 0.45130625012671804, - -0.07013065773095929 - ], - [ - 1.2942389104965908, - 0.3753155047233611, - 0.18488232654949197 - ], - [ - 1.1281888240692206, - 0.29411935796343736, - 0.3775035999024549 - ], - [ - 0.9917042846194166, - 0.2344141272931471, - 0.48233436515068906 - ], - [ - 0.9389909383290257, - 0.22185360914995558, - 0.5406768244746656 - ], - [ - 0.9675336553413606, - 0.2520204318433222, - 0.5798337207712556 - ], - [ - 1.0953878882091872, - 0.3307448097930269, - 0.5711517802104551 - ], - [ - 1.2933467595770562, - 0.43708067344196294, - 0.4913911583496361 - ], - [ - 1.4734879427855987, - 0.5110269154939187, - 0.35578463541863053 - ], - [ - 1.5858674713264718, - 0.5560109618799668, - 0.16024274482028256 - ], - [ - 1.5474185723386207, - 0.7839503561263416, - -0.10747244894286112 - ], - [ - 1.536482609277321, - 0.8075905730294711, - -0.3211908771177854 - ], - [ - 1.4707497952174868, - 0.8097482186460888, - -0.4714248717163822 - ], - [ - 1.3826810991745462, - 0.8231469787271862, - -0.5579623077089879 - ], - [ - 1.3143246957827326, - 0.8179523571812022, - -0.5645928388259167 - ], - [ - 1.2749519472278676, - 0.7670367983672334, - -0.4928380928412976 - ], - [ - 1.2602952270224999, - 0.6954351261559515, - -0.3759941119634386 - ], - [ - 1.2716320002408315, - 0.6216301915689839, - -0.21782440959101387 - ], - [ - 1.2646473989495923, - 0.5474776581627537, - -0.013499419488562966 - ], - [ - 1.1702999080908572, - 0.4729364227177768, - 0.19520099288436332 - ], - [ - 1.0137162433835663, - 0.4034771619920836, - 0.35159062905975264 - ], - [ - 0.8934593904287125, - 0.3630965517298157, - 0.4422953129899749 - ], - [ - 0.8540125161266747, - 0.36069132735460874, - 0.4992323357014795 - ], - [ - 0.8978495748664332, - 0.3936966848288534, - 0.5360254687955043 - ], - [ - 1.0363399064180387, - 0.4808926305257247, - 0.5189836615564327 - ], - [ - 1.2325276271361396, - 0.5971294528894723, - 0.43628943883014665 - ], - [ - 1.4016456245062434, - 0.6783773463993574, - 0.30862647093451934 - ], - [ - 1.5032658233027454, - 0.7317385286853187, - 0.12545388007411865 - ], - [ - 1.4443254850383394, - 0.9549157413540155, - -0.11936367759912278 - ], - [ - 1.4406343007455955, - 0.986150085658442, - -0.31348014090758725 - ], - [ - 1.4009162240617226, - 1.0032730607753655, - -0.43991924838040736 - ], - [ - 1.336734852201346, - 1.0072776861294996, - -0.4879891173011722 - ], - [ - 1.264546951478171, - 0.9627054082404717, - -0.46685054935289105 - ], - [ - 1.207684028834978, - 0.872580362417408, - -0.3992566420075185 - ], - [ - 1.179493902759347, - 0.7787479703081072, - -0.29602314481319075 - ], - [ - 1.168876303560559, - 0.6981269005382225, - -0.1537545483283787 - ], - [ - 1.1351443868935762, - 0.6274574333566467, - 0.014014380728582682 - ], - [ - 1.0381473381089634, - 0.564427373415775, - 0.17818363861040315 - ], - [ - 0.9047161976342234, - 0.5161683720508291, - 0.3123625282217346 - ], - [ - 0.8074343549227753, - 0.4950882882495305, - 0.40670282565973687 - ], - [ - 0.779343812118978, - 0.49744032905691676, - 0.4708503016058371 - ], - [ - 0.8299976710870101, - 0.533011352409624, - 0.49825400634838113 - ], - [ - 0.972374377458581, - 0.6288465955478116, - 0.4654070393570656 - ], - [ - 1.1620675407588583, - 0.7513042771869958, - 0.38203384398092904 - ], - [ - 1.316108919817421, - 0.8396582156530564, - 0.264488455578077 - ], - [ - 1.4053938670402757, - 0.9012468003377239, - 0.09427221929089202 - ], - [ - 1.3292632875034684, - 1.1182189939247134, - -0.12362686855778043 - ], - [ - 1.3317408700581963, - 1.1603777606772916, - -0.2849208563229141 - ], - [ - 1.3034994729509515, - 1.1862946805372188, - -0.37558429485482453 - ], - [ - 1.2428038661424037, - 1.1620571029235027, - -0.3959947494483343 - ], - [ - 1.1632696016244133, - 1.0645215190875448, - -0.3735897978478025 - ], - [ - 1.0997474378647127, - 0.9398678268725477, - -0.32440406952590234 - ], - [ - 1.0654783606967848, - 0.8354896762361277, - -0.23844382940023004 - ], - [ - 1.0403228204816652, - 0.7548150394039034, - -0.11957472092597797 - ], - [ - 0.994417241392628, - 0.6955826321718425, - 0.01024933143283745 - ], - [ - 0.9075340454496398, - 0.6547164028723611, - 0.14293729879959838 - ], - [ - 0.7993447155765937, - 0.6287219175078289, - 0.2704597027822265 - ], - [ - 0.7181381281090307, - 0.619983273169846, - 0.3746678347711377 - ], - [ - 0.6952543288041184, - 0.6270856162647066, - 0.44185725516541274 - ], - [ - 0.7543808201270049, - 0.6709549905945267, - 0.45521865928476063 - ], - [ - 0.9030918110941151, - 0.7760214371147964, - 0.410931588472266 - ], - [ - 1.082762338839584, - 0.9016422185158072, - 0.3335782973251188 - ], - [ - 1.2175528378391507, - 0.9947993772294859, - 0.22642673402530503 - ], - [ - 1.293741330409987, - 1.0623212350444782, - 0.06717212725992378 - ], - [ - 1.2039814721807462, - 1.2779401835296915, - -0.11197948315380311 - ], - [ - 1.2022025237242746, - 1.3195301465655775, - -0.22578995168151444 - ], - [ - 1.1642831208531548, - 1.3267755806774693, - -0.28848017166459355 - ], - [ - 1.1003259892439914, - 1.2632140585755183, - -0.3136562603471165 - ], - [ - 1.0266004195085165, - 1.1245148638368703, - -0.31172940733931853 - ], - [ - 0.9682807962107625, - 0.9787710936681305, - -0.28154473512645095 - ], - [ - 0.9323385492185771, - 0.869995034269605, - -0.21298955774788333 - ], - [ - 0.8994818617636618, - 0.7949169961733259, - -0.12056907700138549 - ], - [ - 0.8519636759992638, - 0.7565354022601487, - -0.020758263998508757 - ], - [ - 0.7802609577376826, - 0.7432947665163755, - 0.09817736516421441 - ], - [ - 0.6912766959142693, - 0.7364400644061118, - 0.22674211799922284 - ], - [ - 0.6195549372771054, - 0.7404937294189927, - 0.32956420382313467 - ], - [ - 0.6054293975115901, - 0.7593951672447923, - 0.3900357717660785 - ], - [ - 0.6769646915696689, - 0.8122508065369644, - 0.3985405207666668 - ], - [ - 0.8283203998180504, - 0.9227157248049099, - 0.3584115647300705 - ], - [ - 0.9943159377091622, - 1.0494890903876566, - 0.2944075408666625 - ], - [ - 1.1084856287963658, - 1.1424073555093759, - 0.19742460469846237 - ], - [ - 1.1712916645642253, - 1.2147586886964337, - 0.04754756882551616 - ], - [ - 1.0622218267742274, - 1.4285892384847478, - -0.07038033900627721 - ], - [ - 1.042348227272043, - 1.4462969865697626, - -0.14639605306376516 - ], - [ - 0.9905544636448262, - 1.4149336522034404, - -0.21467406241067125 - ], - [ - 0.9332431266595307, - 1.32066736973931, - -0.26736066135941233 - ], - [ - 0.8744631885811368, - 1.1590118814955765, - -0.28544678375022126 - ], - [ - 0.823856428774097, - 0.9984031478897047, - -0.2712735848656629 - ], - [ - 0.7893738962377299, - 0.8893135447302586, - -0.22219901932030744 - ], - [ - 0.7555347822224578, - 0.8280095330859067, - -0.15206386699759208 - ], - [ - 0.711777059204575, - 0.8146442703880011, - -0.06797029146516104 - ], - [ - 0.6529559275922944, - 0.8274822417781701, - 0.049537418726818036 - ], - [ - 0.5796620693833904, - 0.8376970089610671, - 0.17633254063955864 - ], - [ - 0.524997216343526, - 0.8561141590700947, - 0.2674207717360207 - ], - [ - 0.5280594387026603, - 0.8898237662739372, - 0.32196250679559824 - ], - [ - 0.6053242262095566, - 0.9515138623091731, - 0.33830431170951336 - ], - [ - 0.7481612322403296, - 1.0666861781249983, - 0.3142433891760898 - ], - [ - 0.8981226277403549, - 1.1944754417780608, - 0.2674232614760669 - ], - [ - 0.992964940930936, - 1.2854659244885625, - 0.1796859575829984 - ], - [ - 1.0408555528859487, - 1.3632027229304033, - 0.04596230087962062 - ], - [ - 0.8959163488682248, - 1.5517726355713684, - -2.8197732111392804e-17 - ], - [ - 0.8558166341852275, - 1.530631777560869, - -0.07818633646918759 - ], - [ - 0.8026749708800681, - 1.4672165246871332, - -0.18014330359439204 - ], - [ - 0.7596365522187756, - 1.3548609333849886, - -0.25610676886056816 - ], - [ - 0.7139027844416573, - 1.1764526752300333, - -0.28779463464562377 - ], - [ - 0.6731551042513766, - 1.0041582705743026, - -0.2918954216267141 - ], - [ - 0.647298078762146, - 0.9002388132396468, - -0.26121482486985925 - ], - [ - 0.6166137341001607, - 0.8582660030520621, - -0.20377118982411094 - ], - [ - 0.5743751357934146, - 0.8699495825051607, - -0.12146593079963343 - ], - [ - 0.5231269042601143, - 0.9060823769847375, - -2.9187410149788376e-17 - ], - [ - 0.46621087056442884, - 0.9323982501518142, - 0.12146593079963337 - ], - [ - 0.434973294797538, - 0.9631361595791528, - 0.2037711898241108 - ], - [ - 0.4559806423572158, - 1.0106959866487013, - 0.2612148248698592 - ], - [ - 0.533049019611906, - 1.0850485562560055, - 0.29189542162671417 - ], - [ - 0.661886510878544, - 1.2064842847739379, - 0.2877946346456237 - ], - [ - 0.7935257107971083, - 1.3352950185571775, - 0.25610676886056827 - ], - [ - 0.8693092977913417, - 1.4287451781076401, - 0.18014330359439223 - ], - [ - 0.8976576861148314, - 1.506474834966135, - 0.07818633646918778 - ], - [ - 0.7060836587137441, - 1.6342057056831683, - 0.070380339006277 - ], - [ - 0.6601404121228749, - 1.58300871193453, - -0.04596230087962038 - ], - [ - 0.6167636758408763, - 1.5026658261577863, - -0.17968595758299824 - ], - [ - 0.5853847629062642, - 1.3750347322258134, - -0.26742326147606665 - ], - [ - 0.5496967120018169, - 1.181269722309294, - -0.3142433891760896 - ], - [ - 0.5213730637080144, - 0.9999830885782208, - -0.33830431170951325 - ], - [ - 0.5065802671330468, - 0.9022247717616244, - -0.321962506795598 - ], - [ - 0.47891800212249147, - 0.8827180058046562, - -0.2674207717360206 - ], - [ - 0.43563585574283004, - 0.9208505821768077, - -0.17633254063955855 - ], - [ - 0.3901426787642454, - 0.9792175417356445, - -0.049537418726817946 - ], - [ - 0.34961410360116074, - 1.0237391502961426, - 0.06797029146516113 - ], - [ - 0.3393098991168581, - 1.068317081390345, - 0.15206386699759208 - ], - [ - 0.37548117354712746, - 1.128274619591304, - 0.22219901932030744 - ], - [ - 0.4527142749037878, - 1.212682170334345, - 0.27127358486566294 - ], - [ - 0.5665021383726002, - 1.3368132767333945, - 0.2854467837502213 - ], - [ - 0.6771099288136528, - 1.4685459404640255, - 0.2673606613594123 - ], - [ - 0.730091255655262, - 1.5653121554502083, - 0.2146740624106711 - ], - [ - 0.7313558181502745, - 1.6258485376921463, - 0.14639605306376516 - ], - [ - 0.5047379273632878, - 1.6816486323591595, - 0.11197948315380311 - ], - [ - 0.46636605159687183, - 1.6217476811017972, - -0.04754756882551578 - ], - [ - 0.4351109769431375, - 1.5311803920223082, - -0.19742460469846224 - ], - [ - 0.4117262444157529, - 1.3858474066377093, - -0.29440754086666227 - ], - [ - 0.38493505824339824, - 1.1787043711177707, - -0.35841156473007046 - ], - [ - 0.36494748692057627, - 0.9923940236329131, - -0.3985405207666667 - ], - [ - 0.3549408075893278, - 0.9040148220653408, - -0.39003577176607857 - ], - [ - 0.3315089123813756, - 0.9067971794315441, - -0.32956420382313484 - ], - [ - 0.29213745618320647, - 0.9668832119089835, - -0.2267421179992228 - ], - [ - 0.25358167143436305, - 1.0473731942401971, - -0.09817736516421442 - ], - [ - 0.22919703921993623, - 1.1160898876470116, - 0.020758263998508747 - ], - [ - 0.23867738170428676, - 1.1764326406173167, - 0.12056907700138533 - ], - [ - 0.2872685262345025, - 1.2424263856856177, - 0.2129895577478832 - ], - [ - 0.36350023350109817, - 1.327941314349208, - 0.281544735126451 - ], - [ - 0.4605582292616702, - 1.451319474748572, - 0.31172940733931853 - ], - [ - 0.5438124705220471, - 1.5845172884172982, - 0.31365626034711647 - ], - [ - 0.5668797975609612, - 1.6716865501949945, - 0.28848017166459344 - ], - [ - 0.5416453661230568, - 1.7009029993217752, - 0.22578995168151458 - ], - [ - 0.30377441198134464, - 1.7102852722583786, - 0.12362686855778043 - ], - [ - 0.27312651132318444, - 1.6515734755831648, - -0.06717212725992326 - ], - [ - 0.2527451134300985, - 1.5518313766332827, - -0.2264267340253048 - ], - [ - 0.23946389693945727, - 1.388520800954038, - -0.3335782973251184 - ], - [ - 0.22050837287566452, - 1.1701111689145993, - -0.4109315884722658 - ], - [ - 0.20387365658730697, - 0.9887904496549886, - -0.4552186592847606 - ], - [ - 0.1954449096309972, - 0.9156507189678194, - -0.44185725516541274 - ], - [ - 0.17785220043199884, - 0.9319174989535475, - -0.3746678347711376 - ], - [ - 0.14481679468954733, - 1.0066137888240911, - -0.2704597027822264 - ], - [ - 0.11323401443701195, - 1.1133057395948298, - -0.14293729879959846 - ], - [ - 0.10518360919574876, - 1.2089819090931795, - -0.010249331432837502 - ], - [ - 0.1335275890414998, - 1.2783535103757517, - 0.11957472092597765 - ], - [ - 0.19081610387172987, - 1.340476165664078, - 0.2384438294002297 - ], - [ - 0.26407569533894476, - 1.4223431323739637, - 0.3244040695259023 - ], - [ - 0.34026787759280824, - 1.5396817860007177, - 0.3735897978478023 - ], - [ - 0.3849690387086998, - 1.6573282714625872, - 0.39599474944833396 - ], - [ - 0.37561159324410115, - 1.7220109976637603, - 0.3755842948548245 - ], - [ - 0.3390461837039364, - 1.7335103050670353, - 0.28492085632291425 - ], - [ - 0.10481854796705836, - 1.7282804320534906, - 0.1193636775991228 - ], - [ - 0.07780569065177306, - 1.66773019134859, - -0.09427221929089154 - ], - [ - 0.06911088534314917, - 1.5596128665357119, - -0.26448845557807676 - ], - [ - 0.06961481963641486, - 1.3820321498039785, - -0.38203384398092877 - ], - [ - 0.05840993809847283, - 1.1565242106421159, - -0.46540703935706557 - ], - [ - 0.04660253614872955, - 0.9853047444480838, - -0.4982540063483811 - ], - [ - 0.041124055770691566, - 0.9236517041057005, - -0.47085030160583713 - ], - [ - 0.025041857278858767, - 0.9468028073761893, - -0.40670282565973687 - ], - [ - -0.005343175991035946, - 1.0415913963919146, - -0.3123625282217347 - ], - [ - -0.0302652250850948, - 1.1812756543814424, - -0.1781836386104033 - ], - [ - -0.02417811636655054, - 1.2967925926914718, - -0.01401438072858279 - ], - [ - 0.02015747915111328, - 1.3613400230342056, - 0.1537545483283782 - ], - [ - 0.08466857405271709, - 1.4108456685525, - 0.2960231448131904 - ], - [ - 0.15183474627941873, - 1.4821752299245337, - 0.39925664200751854 - ], - [ - 0.20145386415783195, - 1.5764824883784998, - 0.46685054935289094 - ], - [ - 0.20396063875268206, - 1.661285183195152, - 0.4879891173011722 - ], - [ - 0.16840184553317444, - 1.7148655689989072, - 0.43991924838040747 - ], - [ - 0.13371387575161353, - 1.7407009448381372, - 0.3134801409075876 - ], - [ - -0.0947883624580406, - 1.732078971996264, - 0.10747244894286113 - ], - [ - -0.11792875688203816, - 1.6677356559637657, - -0.1254538800741181 - ], - [ - -0.11333079691940198, - 1.5530493911253902, - -0.30862647093451906 - ], - [ - -0.09913453801788344, - 1.3659649624107886, - -0.4362894388301463 - ], - [ - -0.1017047186810176, - 1.1379430011764722, - -0.5189836615564326 - ], - [ - -0.10797345698571378, - 0.9744088830258163, - -0.5360254687955042 - ], - [ - -0.11463840564951705, - 0.919942197792873, - -0.49923233570147973 - ], - [ - -0.13227885738980508, - 0.9553068052259317, - -0.442295312989975 - ], - [ - -0.1574366495597894, - 1.0796425999951387, - -0.3515906290597527 - ], - [ - -0.17557499759689782, - 1.2499776618121643, - -0.1952009928843635 - ], - [ - -0.15819413950143837, - 1.368955603401638, - 0.013499419488562724 - ], - [ - -0.09746846246228862, - 1.4120807122582708, - 0.21782440959101335 - ], - [ - -0.027883127576160037, - 1.4391652459477364, - 0.3759941119634382 - ], - [ - 0.02679737940957251, - 1.4876591740873872, - 0.4928380928412976 - ], - [ - 0.05120517251291788, - 1.5472147539597014, - 0.5645928388259166 - ], - [ - 0.02152564503887945, - 1.6090104465813404, - 0.5579623077089878 - ], - [ - -0.034112369592034175, - 1.678580794592149, - 0.4714248717163824 - ], - [ - -0.06884735253830625, - 1.7344282586218949, - 0.32119087711778577 - ], - [ - -0.29548741322432615, - 1.7168452155424967, - 0.08912168119729112 - ], - [ - -0.31141411789256335, - 1.6514069981440977, - -0.16024274482028197 - ], - [ - -0.2941816805574621, - 1.5315914483693591, - -0.35578463541863037 - ], - [ - -0.26815041308457765, - 1.3386114864169971, - -0.4913911583496358 - ], - [ - -0.2612605366539801, - 1.1140061430834585, - -0.571151780210455 - ], - [ - -0.2655107314216385, - 0.9639189404636964, - -0.5798337207712556 - ], - [ - -0.27736460771938753, - 0.9241168110913018, - -0.5406768244746659 - ], - [ - -0.2928435530678837, - 0.9760481671688616, - -0.48233436515068917 - ], - [ - -0.30937957629350443, - 1.124099860891356, - -0.377503599902455 - ], - [ - -0.32208669372368615, - 1.3085015274180225, - -0.18488232654949205 - ], - [ - -0.2925424116520317, - 1.4093108206034848, - 0.0701306577309591 - ], - [ - -0.21483720176674492, - 1.4158358853954, - 0.3001483706223947 - ], - [ - -0.1444788252242269, - 1.4137981959958965, - 0.46122535173594087 - ], - [ - -0.10389113436888645, - 1.4361699139456314, - 0.5777030117693314 - ], - [ - -0.0975921463040118, - 1.4718132584104848, - 0.6365016503908328 - ], - [ - -0.15052603294447847, - 1.5364322851625918, - 0.59749833097071 - ], - [ - -0.22660100779285158, - 1.6346993842027788, - 0.4840768423440809 - ], - [ - -0.2696283271513219, - 1.7133559340753117, - 0.3192739456718186 - ], - [ - -0.49665616641927374, - 1.6788247850574136, - 0.06388001019318096 - ], - [ - -0.503337330391104, - 1.6165931854545963, - -0.19717664733667806 - ], - [ - -0.47476344825038996, - 1.4932117310897404, - -0.4016945242375691 - ], - [ - -0.438542930919616, - 1.2993277870299507, - -0.5427673190280514 - ], - [ - -0.4215067697901963, - 1.086721993270638, - -0.6206780663186218 - ], - [ - -0.42139058139630403, - 0.9602690803588292, - -0.6251345306405945 - ], - [ - -0.4333781946987351, - 0.9417319097869105, - -0.5820555908634444 - ], - [ - -0.4466879142577158, - 1.0071925530109183, - -0.5126408243001628 - ], - [ - -0.4616813104823462, - 1.1656110833134719, - -0.38006496266924894 - ], - [ - -0.46957922033123173, - 1.3416583636639823, - -0.14416318827927446 - ], - [ - -0.4232758861874059, - 1.4039422931394017, - 0.14682068165171416 - ], - [ - -0.32930354948152984, - 1.369192914960485, - 0.3843855959690511 - ], - [ - -0.2574372494745114, - 1.3419040250158751, - 0.534206652106575 - ], - [ - -0.22620515316581238, - 1.3450635731412517, - 0.6353152355179481 - ], - [ - -0.23763391609839257, - 1.3751142056992092, - 0.6739285809181627 - ], - [ - -0.3154464033471995, - 1.4576063265538188, - 0.6154160028402362 - ], - [ - -0.41369176148235637, - 1.577210166379819, - 0.4891098605082971 - ], - [ - -0.4695316195930924, - 1.6673684085786409, - 0.3102183165465726 - ], - [ - -0.693595638118284, - 1.614183387994419, - 0.033113672532758744 - ], - [ - -0.6931777052761988, - 1.5583964675531148, - -0.2327774911592106 - ], - [ - -0.6551010568257375, - 1.435831018329033, - -0.44103704076598854 - ], - [ - -0.6115722439297878, - 1.2468827954845232, - -0.584572775661006 - ], - [ - -0.5844950094577686, - 1.0521930342670969, - -0.66043058255366 - ], - [ - -0.575052081717393, - 0.9513919659707781, - -0.6593386412348755 - ], - [ - -0.5825593165951204, - 0.951911493879831, - -0.6078263236853988 - ], - [ - -0.5967539656218468, - 1.0295565776154234, - -0.5212092483975067 - ], - [ - -0.6149329585992234, - 1.1900922630417519, - -0.3543052113484586 - ], - [ - -0.613775318321845, - 1.3373759184869103, - -0.07875347615938563 - ], - [ - -0.5440182956576401, - 1.3500881670286586, - 0.22849551863677905 - ], - [ - -0.4329147324185267, - 1.2816817815140111, - 0.45498374095819544 - ], - [ - -0.35834691672215824, - 1.2374661080824731, - 0.5855360174787573 - ], - [ - -0.3351735665272444, - 1.2294265906598727, - 0.6661809663348722 - ], - [ - -0.3691021826028168, - 1.2667532121301974, - 0.6865915235158722 - ], - [ - -0.47527459676260636, - 1.3686920957431765, - 0.6194975052899337 - ], - [ - -0.5931059070773452, - 1.4978552813801602, - 0.4856431573272357 - ], - [ - -0.6615630710806435, - 1.5929697731058068, - 0.29177015116688076 - ] - ] - } - }, - "140342738037920": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738037920", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.3811326661850898, - 0.02448244356343087, - -0.002830447249048559, - 0.0016098629516795799, - -0.00012693769295465338, - -0.0008081108512745523, - -0.00010116550435315649, - 0.2844601632312015, - -0.11064835168998781, - 0.0013289062044977928, - 0.001769896721364001, - -0.000623385312415337, - 0.00027389994449362223, - 8.0231441521585e-05, - 0.11353806443952061, - 0.07613485613812707, - 0.02264537258153299, - -0.0031668335274072893, - -0.0011157211797280862, - 0.0007035294449001908, - 0.00035054236552418467, - -0.027153509541833258, - 0.002900077467060187, - -0.001402887083933869, - -0.004400920182544234, - 0.0012112055924743946, - -0.0005039058676451317, - -0.00035758997930735955, - -0.0007355745307802166, - 0.007166015481108517, - 0.002379910200932624, - -0.0034019391938605505, - 0.0014123568052263526, - 0.0002334153042404234, - -0.00025739966130925953, - -0.0028966262041676535, - -0.008322861648202173, - -0.002048930338260883, - 0.00020855358642181903, - 0.000971434007877387, - -0.0002817737500145236, - 0.00021504717140184652, - 0.0032306824543586994, - -0.0004232272225387029, - 0.0015224514551124976, - 0.00020908444286002004, - 0.0005262543243252864, - -0.00022933594363605878, - -1.804127748026717e-05, - 0.2300486034921893, - -0.007859593284410169, - -0.0016990523241952648, - -0.00037841557716980024, - -0.0005389954382825479, - 0.0002532270866895827, - -0.06988970835272597, - -0.025102631410956994, - 0.004756882044005857, - 0.0017665579136541423, - -1.1406237394592485e-06, - -0.0006720143875246866, - 0.0034580648327663293, - 0.004183111222119428, - 0.003966255358872766, - -0.0011128295924487134, - -0.0001472099178421518, - 0.0002261775183119312, - -0.0013006936515008224, - -0.0024863836478352056, - 0.0026535092591935525, - -0.0018170655191923515, - -0.00013773917337013666, - 0.00029830374531614667, - 0.007565497635764069, - 0.00404715668989351, - 0.00014020938960207982, - -0.0008051899677703314, - 0.0004970388844870179, - -0.0003367232954883513, - -0.0006308508652569744, - -0.00040333650397185076, - -0.0007461787010372589, - -0.0004525254651366259, - 0.00025266737855478695, - -3.012045040843106e-05, - -0.0020416197292635148, - -0.0003495317985105897, - 0.0011663722608696813, - 9.278140933081674e-05, - 0.00041754997080649484, - 0.00013545466709419894, - 0.049429341194476686, - 0.0014312780073575328, - -0.0006030257532588873, - 0.00019494965177286323, - -0.0007584066856589742, - -9.252930724318059e-05, - -0.04624601389097408, - -0.002851105255080838, - 0.0007480969839141016, - 1.9227126003597117e-05, - -0.0007025375410129719, - -0.0004126187595215216, - -0.00039978335699845317, - 0.0005791070117796877, - -0.0003044058853432315, - -0.0007826211780843478, - 0.0008247258844624956, - 0.00028142442622312207, - -0.00044490951053858185, - 0.0020866493519219047, - -0.0006415743825804805, - 0.00010395065945623699, - -7.948266440632746e-05, - 4.3495451140307386e-05, - 0.0033562270379838724, - 0.0011918760524910524, - -0.0005607233284846007, - 1.919539842301449e-06, - 4.485370055190845e-05, - -0.0002625320986599554, - 0.001635277705803326, - 0.00019266236961042543, - 0.00024039714896450894, - -0.00021135395787220292, - 0.00017233063594159265, - 9.105249317051247e-05, - 0.05250363998920236, - 0.10285196575967044, - -0.005173641928745492, - -0.0004991210581259668, - -0.00021287241704597142, - -0.0004573223170278472, - 0.0006166734226666022, - 0.016715470013882787, - -0.06070866890882583, - -0.001991260468037734, - 0.0024527610709208746, - 0.00036863070510259794, - 0.00030902105569256995, - -0.000410654594509358, - -0.007673892311640518, - -0.005158232879871336, - 0.0033992277420724273, - -0.0008513108810175304, - -0.0007097190875179632, - 6.744425613779714e-05, - 0.0002415099869852849, - 0.0004909764346481123, - 0.002776402315315485, - -0.001350326841518264, - -0.0007916257428287475, - 1.8381201314918053e-05, - -0.00019344397456574916, - 0.00019250924770593508, - 0.0006532901225544868, - 0.0022333353079212926, - -0.00032530149832245335, - -0.0002844503734357783, - 0.0004046657509103282, - 0.00018948508431952207, - -0.00027991506591093317, - 0.0014276636365315799, - 0.0026530836598983158, - -0.0002690023682302062, - -0.00042193616278779695, - -9.163899538739768e-05, - 9.31128946151891e-05, - 0.00012616723226187656, - 0.02236051962756462, - -0.00863176292606751, - 0.0027495175272335744, - 0.0006455608092370358, - -0.0002677925753307976, - 7.010546569205235e-05, - -0.14386803873968534, - 0.008342280513282447, - -0.0007037475816376946, - -0.0005850756426881015, - 0.00036684969176461595, - -4.852651470927419e-05, - 0.009670042594392534, - 0.026324961691259884, - -0.0041362262999389, - -0.0015204787162155342, - 0.00011729867137330496, - 6.74864870675413e-05, - -0.008941371188522979, - -0.006840028276305798, - -0.0032636083512546997, - 0.001599973650381018, - -0.0003600551876431872, - -5.6100628872548886e-05, - 0.0016885289098471866, - 0.004908140372480334, - -0.004212685136955856, - 0.0019083439904902001, - 9.832820691762187e-05, - -7.448456393358958e-05, - -0.003561339351190498, - -0.001606692070174365, - -0.0008212059808706245, - 0.0010283590848846056, - -0.00032895307765388955, - 0.0001826496409730601, - -0.000920111811764803, - 0.0008970326725869421, - 0.0002809816487367133, - 0.00039566958995572297, - -0.0003670132179938746, - 6.256355520928102e-05, - -0.5080577506953411, - -0.20661009635990735, - 0.0024736635706574064, - -0.001967670697636021, - 0.0006519511703533562, - -3.8244803146363185e-05, - -0.0001188715670170747, - -0.010100794868308094, - 0.0009174831646416852, - 0.023713092773250843, - -0.001648236934550094, - -0.0015725442134146678, - 0.00023755820276267673, - 0.00011477753092802907, - -0.016544477238294338, - -0.012803232231848136, - -0.0024051727889748474, - -0.004418921641916007, - 0.0010544930179243338, - 0.0001267627015678787, - 5.369372462833654e-05, - 0.0027789391551945168, - 0.005650788763831649, - 0.00620618122044694, - -0.004792183212916292, - 0.0018271508925651382, - 0.0001038440447451111, - -0.00015123239494420986, - -0.004253475216029981, - -0.005316051806309542, - -1.6686249389078527e-05, - 0.00020210327316631867, - 0.0007899403901454753, - -0.00042878058433706086, - 0.00017825769500408572, - 0.00012932051172802805, - -0.002704919646583892, - 0.0012798733816245468, - 0.00023839100771304436, - 0.00039741168658185454, - -0.00024464051131811476, - 5.3395079680768744e-05 - ] - }, - "names": [ - "x0", - "x1", - "x2", - "x3", - "x4", - "x5", - "x6", - "x7", - "x8", - "x9", - "x10", - "x11", - "x12", - "x13", - "x14", - "x15", - "x16", - "x17", - "x18", - "x19", - "x20", - "x21", - "x22", - "x23", - "x24", - "x25", - "x26", - "x27", - "x28", - "x29", - "x30", - "x31", - "x32", - "x33", - "x34", - "x35", - "x36", - "x37", - "x38", - "x39", - "x40", - "x41", - "x42", - "x43", - "x44", - "x45", - "x46", - "x47", - "x48", - "x49", - "x50", - "x51", - "x52", - "x53", - "x54", - "x55", - "x56", - "x57", - "x58", - "x59", - "x60", - "x61", - "x62", - "x63", - "x64", - "x65", - "x66", - "x67", - "x68", - "x69", - "x70", - "x71", - "x72", - "x73", - "x74", - "x75", - "x76", - "x77", - "x78", - "x79", - "x80", - "x81", - "x82", - "x83", - "x84", - "x85", - "x86", - "x87", - "x88", - "x89", - "x90", - "x91", - "x92", - "x93", - "x94", - "x95", - "x96", - "x97", - "x98", - "x99", - "x100", - "x101", - "x102", - "x103", - "x104", - "x105", - "x106", - "x107", - "x108", - "x109", - "x110", - "x111", - "x112", - "x113", - "x114", - "x115", - "x116", - "x117", - "x118", - "x119", - "x120", - "x121", - "x122", - "x123", - "x124", - "x125", - "x126", - "x127", - "x128", - "x129", - "x130", - "x131", - "x132", - "x133", - "x134", - "x135", - "x136", - "x137", - "x138", - "x139", - "x140", - "x141", - "x142", - "x143", - "x144", - "x145", - "x146", - "x147", - "x148", - "x149", - "x150", - "x151", - "x152", - "x153", - "x154", - "x155", - "x156", - "x157", - "x158", - "x159", - "x160", - "x161", - "x162", - "x163", - "x164", - "x165", - "x166", - "x167", - "x168", - "x169", - "x170", - "x171", - "x172", - "x173", - "x174", - "x175", - "x176", - "x177", - "x178", - "x179", - "x180", - "x181", - "x182", - "x183", - "x184", - "x185", - "x186", - "x187", - "x188", - "x189", - "x190", - "x191", - "x192", - "x193", - "x194", - "x195", - "x196", - "x197", - "x198", - "x199", - "x200", - "x201", - "x202", - "x203", - "x204", - "x205", - "x206", - "x207", - "x208", - "x209", - "x210", - "x211", - "x212", - "x213", - "x214", - "x215", - "x216", - "x217", - "x218", - "x219", - "x220", - "x221", - "x222", - "x223", - "x224", - "x225", - "x226", - "x227", - "x228", - "x229", - "x230", - "x231", - "x232", - "x233", - "x234", - "x235", - "x236", - "x237", - "x238", - "x239", - "x240", - "x241", - "x242", - "x243", - "x244", - "x245", - "x246", - "x247", - "x248", - "x249", - "x250", - "x251", - "x252" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "SurfaceXYZTensorFourier1": { - "@module": "simsopt.geo.surfacexyztensorfourier", - "@class": "SurfaceXYZTensorFourier", - "@name": "SurfaceXYZTensorFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "nfp": 3, - "stellsym": true, - "mpol": 6, - "ntor": 6, - "clamped_dims": [ - false, - false, - false - ], - "quadpoints_phi": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.018518518518518517, - 0.037037037037037035, - 0.05555555555555555, - 0.07407407407407407, - 0.09259259259259259, - 0.1111111111111111, - 0.12962962962962962, - 0.14814814814814814, - 0.16666666666666666, - 0.18518518518518517, - 0.2037037037037037, - 0.2222222222222222, - 0.24074074074074073, - 0.25925925925925924, - 0.2777777777777778, - 0.2962962962962963, - 0.31481481481481477 - ] - }, - "quadpoints_theta": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.05555555555555555, - 0.1111111111111111, - 0.16666666666666666, - 0.2222222222222222, - 0.2777777777777778, - 0.3333333333333333, - 0.38888888888888884, - 0.4444444444444444, - 0.5, - 0.5555555555555556, - 0.611111111111111, - 0.6666666666666666, - 0.7222222222222222, - 0.7777777777777777, - 0.8333333333333333, - 0.8888888888888888, - 0.9444444444444444 - ] - }, - "dofs": { - "$type": "ref", - "value": "140342738037920" - } - }, - "Volume1": { - "@module": "simsopt.geo.surfaceobjectives", - "@class": "Volume", - "@name": "Volume1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "range": null, - "nphi": null, - "ntheta": null - }, - "BoozerSurface9": { - "@module": "simsopt.geo.boozersurface", - "@class": "BoozerSurface", - "@name": "BoozerSurface9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "biotsavart": { - "$type": "ref", - "value": "BiotSavart1" - }, - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "label": { - "$type": "ref", - "value": "Volume1" - }, - "targetlabel": -3.5163378272471846, - "constraint_weight": 1000.0, - "reg": null - } - } -} \ No newline at end of file diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_8.vts b/examples/2_Intermediate/inputs/input_ncsx/surface_8.vts deleted file mode 100644 index 7f80bf98d09d67e47e526b36117d09adb3d43663..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31872 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 H@tywzYY7=k diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_9.json b/examples/2_Intermediate/inputs/input_ncsx/surface_9.json deleted file mode 100644 index b53e34c2b..000000000 --- a/examples/2_Intermediate/inputs/input_ncsx/surface_9.json +++ /dev/null @@ -1,7022 +0,0 @@ -{ - "@module": "simsopt._core.json", - "@class": "SIMSON", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "graph": [ - { - "$type": "ref", - "value": "BoozerSurface10" - }, - { - "iota": -0.5014295841164587, - "G": 13.88748188997289 - } - ], - "simsopt_objs": { - "140342738246336": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738246336", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.506387961733893, - 0.1058930714809362, - 0.7258942274042265, - -0.001249592121112775, - 0.2763105569564668, - 0.01482550301512887, - -0.1280092780227772, - 0.005921392096802394, - 0.01864241438718947, - -0.01034831723350223, - 0.0001022108294955593, - 0.01892666378143068, - -0.007192153616853929, - -0.007355339046239706, - -0.01884714563379878, - -0.002596706082945131, - 0.01131859363705868, - 0.00964754529816095, - -0.0113260687651076, - -0.006628855789771619, - 0.000322284209286623, - 0.001842953924532827, - -0.0004161340928027646, - 0.00176264188836799, - 0.001814459617914206, - -0.001883356200860781, - -0.003584967425237995, - 0.0003165409191237933, - 0.00198839685289703, - 0.0007998064690618334, - 0.0005809753916376526, - 4.996792424044994e-05, - -0.0009656219012175038, - -0.001300735471703214, - -0.0004500391754653399, - 0.002413016477450284, - 0.00190334965179141, - -0.001622873850792805, - -0.001817132111793323, - 0.0005008124937015768, - 0.0009410326413637304, - 0.0005073038161052906, - -0.0001747050570155717, - -0.0004010070348672179, - 0.0002171330554898199, - 0.0001868680753017027, - -0.00049371483741256, - -1.263882515020243e-05, - 0.0005663593123846766, - 0.0001291744509577553, - -0.0002415255915965764, - 0.2855239540187146, - 0.02831674064739627, - 0.1230646086878452, - -0.1881027707999307, - -0.03092022550185042, - 0.07598032813641656, - 0.032842960392996, - -0.02022733960800226, - 0.03368541189764687, - -0.02527069889002642, - 0.03990545352197854, - 0.03266977475756579, - 0.007041509561223136, - -0.01843202758194484, - -0.003255107459418295, - 0.001087406605704745, - 0.02057587403483786, - 0.004332699549632209, - -0.003239348172858322, - -0.008060517809116506, - 0.0008303250764389791, - 0.002593682135814645, - 0.005122620691996364, - 0.002329497971206275, - -0.007021762243403233, - -0.002076255998522319, - 0.005455573755227739, - 0.0004034355313731426, - -0.002121189074115063, - -0.001155709211846629, - 0.0007060503790857225, - 0.001458108819397405, - 0.0007612900914783658, - -0.001579374591052191, - -0.0005648184298353118, - -3.483600030825498e-05, - 0.0006434230018098444, - 0.0002266872576160417, - -0.0005870263149471541, - -0.0004782734366555642, - 0.0004131000234993432, - -0.0002086017812282408, - -0.0002217317708794842, - 0.0004459870616389726, - 0.0002232186481886098, - -0.000550989811641543, - -0.0004679750418668452, - 0.0001971289820931924, - 0.0006305703105299488, - 1.94634036466225e-05, - -0.0005071137243856577, - 0.0009455853398023695, - -1.066704925256128, - 0.01954765252843791, - -0.03091192279856904, - -0.009251669123731003, - 0.03622032973711591, - 0.01289395028459556, - -0.01341289215090563, - -0.01055557464591715, - -0.007044726977866961, - -0.007171173731457627, - 0.01327231838496817, - 0.003220259676106272, - -0.006043809337864334, - -0.006228107449831786, - -0.0004722020937025503, - -0.0007632924616726337, - 0.0002557840887866895, - -0.0008300983337148277, - 0.001290373849098229, - 0.0002249498117545818, - -0.0003276137574950353, - -0.001560853624251917, - -0.003125967131907846, - 0.0007111137798287738, - 0.001688245514976161, - 0.00083638883723687, - -3.216802700299113e-05, - -0.003601309499252412, - -0.003364173533240832, - 0.003283863928203238, - 0.003620244544063828, - -0.001109032285114347, - -0.002277398193829699, - -0.0015519788484098, - 0.0002155015553257128, - 0.002349143532954114, - 0.000703914196138795, - -0.001628934087145739, - -0.0005728748367786014, - 0.000379102967651227, - 3.674770297429017e-05, - 0.0003644795696035227, - 0.0001196573774128766, - -0.0004826910821886253, - 1.895960151025164e-05, - 0.0002282029938596129, - -3.982416558199763e-05, - -0.0001869395233315697, - -0.0002051724761620464, - 0.0001303574263284748 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier1": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738246336" - } - }, - "140342738367104": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367104", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 652271.9419853 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current1": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 652271.9419853, - "dofs": { - "$type": "ref", - "value": "140342738367104" - } - }, - "Coil1": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "140342738247296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738247296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.268960636199869, - 0.2234285580503567, - 0.5468300987692021, - -0.07598922426224614, - 0.2314838962751658, - 0.01035784318060333, - -0.08314304549672957, - -0.04624738986383844, - 0.05377747860630284, - -0.001074456865203822, - -0.02151604922154927, - -0.01446679290684195, - 0.008416712252875694, - -0.009228184118107326, - 0.005277266362275169, - 0.01142201731157229, - 0.01681398796325401, - 0.009993706195866578, - 0.001370286955930781, - -0.008399573830195455, - -0.005099919856215084, - 0.005334309041669094, - -0.001419513324650316, - -0.003333508834690296, - 0.0002887180426140212, - -0.0001690909516323616, - -0.001592036575525169, - -4.507713399549196e-05, - 0.005287560419413426, - 0.001265480827581528, - -0.001229918688675425, - 0.001129035262308468, - -0.002142778995712242, - -0.001748186446934164, - 0.000763477629872682, - 0.0006002693299791978, - -0.0003618301004192371, - 0.000988040168005559, - 0.0007880569343915778, - -0.001135722890360471, - -0.0008706368325040781, - 0.0005507322770281398, - 0.0009555809731928289, - -0.0001476990895937402, - -0.001054028588515068, - -1.482885559572655e-05, - -0.0001592869344899095, - -0.0004579572172035079, - 0.0006274586578504227, - 0.0005393401407410331, - -3.182089243244368e-05, - 0.7629396044020591, - 0.189701305549749, - 0.2946730680990991, - -0.1569360429309221, - -0.08805875862294558, - -0.03077704895086764, - 0.1149783480591024, - 0.1301411562027019, - -0.001461622206151801, - 0.04030157913855995, - 0.0006901390690664732, - -0.02740323125842794, - -0.02323299800745342, - 0.006389595554305861, - 0.003627095782551136, - -0.01015301262258172, - -0.00621023311542419, - -0.003238881121248944, - -0.006852312518149265, - 0.005609446955056436, - 0.004762124576622897, - 0.006665063843140196, - -6.70526269177163e-05, - -0.003587348009623233, - -0.00322170321999071, - -0.004203038352780501, - 0.0006017815497404605, - 0.001489961187320675, - 0.002190828148742953, - -0.001018226063168117, - -0.002311412742654803, - 0.0005349636274747352, - 0.0005836793424641873, - 0.0003330260000362103, - 0.0006191475972028521, - 0.0004562062905476333, - -0.0003998259903290102, - -0.001606870160409875, - -0.0001005634411503442, - 0.0003784623778643909, - 0.0003873441313675419, - 0.0004934685418203405, - 0.0004248568990090018, - -0.0001368925780341768, - -0.0005224641202364183, - 7.402330001924084e-06, - 0.0001942482764948633, - 3.004761739695799e-05, - 0.0001571480542442944, - -1.517325817427362e-05, - -0.0001596571201453762, - -0.004342453367498795, - -0.8322915538683627, - 0.01842619538559772, - -0.1445740110997678, - -0.03919221672360253, - 0.0181885023851906, - 0.007857938792447916, - -0.0008409533080505334, - 0.0679882056193599, - -0.008440199737942872, - -0.05052693032193879, - 0.0111459982531894, - -0.002854468104354866, - -0.01157234174126346, - -0.002254287431014864, - 0.01222589681633306, - 0.007524606302699996, - -0.006381505382857464, - 0.003239076046582923, - 0.00341366498860203, - -0.00384676331619515, - 0.0004019843766106519, - 0.003278371413101953, - -0.001659157168404143, - -0.008498109023400214, - -0.0005869360684358228, - 0.001643969359882166, - -0.001687685453312147, - 0.001913710312578008, - 0.00307704389234268, - -0.001526906838827543, - -0.002096608532065649, - 0.002116359835823416, - 0.0002080593023590777, - -0.001289011271870523, - 0.0003465163727308783, - 0.0003373949660992973, - -0.0005853247790129025, - -0.0007569823284455652, - -3.821511752005806e-05, - 0.0008610335506290439, - 0.0002833895542749826, - -4.205984435378816e-05, - 0.0001112528084110792, - -0.0002379239249443648, - -0.0002104661224579025, - 0.0001263747200842462, - -0.0001533284829536013, - 0.0001522993485716547, - 0.0003185888026784711, - -0.0001603437887349448 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier2": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738247296" - } - }, - "140342738367296": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367296", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 651868.5693674 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current2": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 651868.5693674, - "dofs": { - "$type": "ref", - "value": "140342738367296" - } - }, - "Coil2": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "140342738366624": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738366624", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.8980851593547453, - 0.1942559921705813, - 0.3889755333770718, - -0.1446923384557668, - 0.2616477438027761, - 0.03731920597998046, - -0.03289705406442186, - 0.02547136484396155, - 0.0532217952204826, - 0.050428478861979, - -0.03624366941253683, - -0.005451626158324006, - -0.01668041626206209, - 0.008182439166261426, - 0.003842296843932926, - 0.01470476196344816, - 0.01901860245900076, - 0.0218942171541043, - -0.00945061997881808, - 0.002564135600286371, - -0.006766476390874592, - -0.001269140258791196, - 0.002139997339095541, - 0.001657675366985779, - 0.0002979912903074711, - 0.006328865782046154, - 0.0004567550240531948, - -0.0008525115686061069, - -0.000977103914377314, - 0.0005522046297053057, - -0.0009600861596635313, - -0.001340814451660981, - -0.001495132545615355, - 0.0006434008787568705, - 0.000495245187218385, - -0.00134743162348104, - 0.0002393656261548005, - 0.0003132890671380592, - 0.0006144326019911972, - -0.0005029044211924421, - -0.000783957033721161, - -0.0004002250154653492, - 0.0002391300413782915, - -0.0003806672575232206, - -0.000145466845504183, - -7.221379723120868e-05, - 0.0006927366534479363, - -0.0001275371930022123, - -0.0001401106599127933, - -0.0002158625680600062, - -7.139828388354475e-05, - 1.129181984052873, - 0.2708936854358476, - 0.468646640557997, - 0.02081652240284051, - -0.1928735276123626, - -0.03518255586981031, - 0.01192001522947444, - -0.06439441858177399, - -0.004172035660790115, - -0.016589458610143, - 0.001628354566592241, - 0.003299047220307412, - 0.02371335634022325, - -0.02489732104888577, - 0.01517053799913132, - -0.007490250276888437, - -0.02121728304870823, - -0.006509759115093021, - 0.002045879344162137, - 0.0002421911767798572, - 0.005286626183968976, - -0.002423351884665077, - 0.003037404376098953, - -0.001045524131070646, - -0.001371894636819662, - 0.0002683048956511064, - 0.0006396825080884871, - 0.0006110891778951719, - -0.001898949452431453, - -0.001413075309279682, - -0.000175565426273192, - 0.00025798969577147, - 0.001643409441239691, - 7.18696208370806e-05, - -0.0001583133254478763, - 0.001580406281910882, - -0.002161287927547965, - -0.0003891297580205399, - 0.0004807171148380796, - -0.0003779554431875909, - -0.000203599914921071, - 0.0002418121495980502, - -0.0001924002563136939, - 0.0004205862222447268, - -0.0003081775538974041, - -1.457104090324735e-05, - -0.0001305465480840895, - -2.931233724533855e-05, - 3.39235991969411e-05, - -8.787891234509293e-05, - -0.0002714497625897205, - 0.01443108431390148, - -0.5884600992390547, - 0.1639153375972931, - -0.02326901782799053, - -0.09503676743509344, - -0.001882227773385535, - -0.1358423641287697, - -0.04946480830906624, - 0.01080325660372903, - -0.004462853204566593, - 0.02204832208587066, - -0.01988057349197482, - 0.006713767349457029, - 0.009816410920710776, - -0.004595941635687146, - 0.01307328931917959, - 0.0183731152740804, - -0.002049019816619709, - -0.009421893063595877, - 0.0003683472428279665, - 0.005559370162880608, - -0.001158799750525409, - 0.002656529580593774, - 0.005458828901239469, - 0.003685058507882478, - 0.005539080181031877, - 0.0003319744004354147, - 0.003297209047830778, - -0.001172958360845208, - -6.403055114502017e-05, - -0.0028127900802783, - -7.412199662635927e-05, - -1.404234804116165e-06, - 0.002212349409834762, - 0.001726905111358576, - 0.0009310945379894919, - -0.0002426222281296402, - 0.0007504861042380895, - -0.001511448440947522, - -0.0002060956498950368, - -0.000206480198377301, - 8.668234567299965e-05, - 0.0001267761162311387, - 1.493158313140079e-05, - 0.0001119337013982711, - 0.0003201242558262467, - 0.00016404919743365, - -0.0002679743018523173, - -0.000169663995881007, - 0.0002693900147788098, - -0.0001731877336642894 - ] - }, - "names": [ - "xc(0)", - "xs(1)", - "xc(1)", - "xs(2)", - "xc(2)", - "xs(3)", - "xc(3)", - "xs(4)", - "xc(4)", - "xs(5)", - "xc(5)", - "xs(6)", - "xc(6)", - "xs(7)", - "xc(7)", - "xs(8)", - "xc(8)", - "xs(9)", - "xc(9)", - "xs(10)", - "xc(10)", - "xs(11)", - "xc(11)", - "xs(12)", - "xc(12)", - "xs(13)", - "xc(13)", - "xs(14)", - "xc(14)", - "xs(15)", - "xc(15)", - "xs(16)", - "xc(16)", - "xs(17)", - "xc(17)", - "xs(18)", - "xc(18)", - "xs(19)", - "xc(19)", - "xs(20)", - "xc(20)", - "xs(21)", - "xc(21)", - "xs(22)", - "xc(22)", - "xs(23)", - "xc(23)", - "xs(24)", - "xc(24)", - "xs(25)", - "xc(25)", - "yc(0)", - "ys(1)", - "yc(1)", - "ys(2)", - "yc(2)", - "ys(3)", - "yc(3)", - "ys(4)", - "yc(4)", - "ys(5)", - "yc(5)", - "ys(6)", - "yc(6)", - "ys(7)", - "yc(7)", - "ys(8)", - "yc(8)", - "ys(9)", - "yc(9)", - "ys(10)", - "yc(10)", - "ys(11)", - "yc(11)", - "ys(12)", - "yc(12)", - "ys(13)", - "yc(13)", - "ys(14)", - "yc(14)", - "ys(15)", - "yc(15)", - "ys(16)", - "yc(16)", - "ys(17)", - "yc(17)", - "ys(18)", - "yc(18)", - "ys(19)", - "yc(19)", - "ys(20)", - "yc(20)", - "ys(21)", - "yc(21)", - "ys(22)", - "yc(22)", - "ys(23)", - "yc(23)", - "ys(24)", - "yc(24)", - "ys(25)", - "yc(25)", - "zc(0)", - "zs(1)", - "zc(1)", - "zs(2)", - "zc(2)", - "zs(3)", - "zc(3)", - "zs(4)", - "zc(4)", - "zs(5)", - "zc(5)", - "zs(6)", - "zc(6)", - "zs(7)", - "zc(7)", - "zs(8)", - "zc(8)", - "zs(9)", - "zc(9)", - "zs(10)", - "zc(10)", - "zs(11)", - "zc(11)", - "zs(12)", - "zc(12)", - "zs(13)", - "zc(13)", - "zs(14)", - "zc(14)", - "zs(15)", - "zc(15)", - "zs(16)", - "zc(16)", - "zs(17)", - "zc(17)", - "zs(18)", - "zc(18)", - "zs(19)", - "zc(19)", - "zs(20)", - "zc(20)", - "zs(21)", - "zc(21)", - "zs(22)", - "zc(22)", - "zs(23)", - "zc(23)", - "zs(24)", - "zc(24)", - "zs(25)", - "zc(25)" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "CurveXYZFourier3": { - "@module": "simsopt.geo.curvexyzfourier", - "@class": "CurveXYZFourier", - "@name": "CurveXYZFourier3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "quadpoints": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.004, - 0.008, - 0.012, - 0.016, - 0.02, - 0.024, - 0.028, - 0.032, - 0.036000000000000004, - 0.04, - 0.044, - 0.048, - 0.052000000000000005, - 0.056, - 0.06, - 0.064, - 0.068, - 0.07200000000000001, - 0.076, - 0.08, - 0.084, - 0.088, - 0.092, - 0.096, - 0.1, - 0.10400000000000001, - 0.108, - 0.112, - 0.116, - 0.12, - 0.124, - 0.128, - 0.132, - 0.136, - 0.14, - 0.14400000000000002, - 0.148, - 0.152, - 0.156, - 0.16, - 0.164, - 0.168, - 0.17200000000000001, - 0.176, - 0.18, - 0.184, - 0.188, - 0.192, - 0.196, - 0.2, - 0.20400000000000001, - 0.20800000000000002, - 0.212, - 0.216, - 0.22, - 0.224, - 0.228, - 0.232, - 0.23600000000000002, - 0.24, - 0.244, - 0.248, - 0.252, - 0.256, - 0.26, - 0.264, - 0.268, - 0.272, - 0.276, - 0.28, - 0.28400000000000003, - 0.28800000000000003, - 0.292, - 0.296, - 0.3, - 0.304, - 0.308, - 0.312, - 0.316, - 0.32, - 0.324, - 0.328, - 0.332, - 0.336, - 0.34, - 0.34400000000000003, - 0.34800000000000003, - 0.352, - 0.356, - 0.36, - 0.364, - 0.368, - 0.372, - 0.376, - 0.38, - 0.384, - 0.388, - 0.392, - 0.396, - 0.4, - 0.404, - 0.40800000000000003, - 0.41200000000000003, - 0.41600000000000004, - 0.42, - 0.424, - 0.428, - 0.432, - 0.436, - 0.44, - 0.444, - 0.448, - 0.452, - 0.456, - 0.46, - 0.464, - 0.468, - 0.47200000000000003, - 0.47600000000000003, - 0.48, - 0.484, - 0.488, - 0.492, - 0.496, - 0.5, - 0.504, - 0.508, - 0.512, - 0.516, - 0.52, - 0.524, - 0.528, - 0.532, - 0.536, - 0.54, - 0.544, - 0.548, - 0.552, - 0.556, - 0.56, - 0.5640000000000001, - 0.5680000000000001, - 0.5720000000000001, - 0.5760000000000001, - 0.58, - 0.584, - 0.588, - 0.592, - 0.596, - 0.6, - 0.604, - 0.608, - 0.612, - 0.616, - 0.62, - 0.624, - 0.628, - 0.632, - 0.636, - 0.64, - 0.644, - 0.648, - 0.652, - 0.656, - 0.66, - 0.664, - 0.668, - 0.672, - 0.676, - 0.68, - 0.684, - 0.6880000000000001, - 0.6920000000000001, - 0.6960000000000001, - 0.7000000000000001, - 0.704, - 0.708, - 0.712, - 0.716, - 0.72, - 0.724, - 0.728, - 0.732, - 0.736, - 0.74, - 0.744, - 0.748, - 0.752, - 0.756, - 0.76, - 0.764, - 0.768, - 0.772, - 0.776, - 0.78, - 0.784, - 0.788, - 0.792, - 0.796, - 0.8, - 0.804, - 0.808, - 0.812, - 0.8160000000000001, - 0.8200000000000001, - 0.8240000000000001, - 0.8280000000000001, - 0.8320000000000001, - 0.836, - 0.84, - 0.844, - 0.848, - 0.852, - 0.856, - 0.86, - 0.864, - 0.868, - 0.872, - 0.876, - 0.88, - 0.884, - 0.888, - 0.892, - 0.896, - 0.9, - 0.904, - 0.908, - 0.912, - 0.916, - 0.92, - 0.924, - 0.928, - 0.932, - 0.936, - 0.9400000000000001, - 0.9440000000000001, - 0.9480000000000001, - 0.9520000000000001, - 0.9560000000000001, - 0.96, - 0.964, - 0.968, - 0.972, - 0.976, - 0.98, - 0.984, - 0.988, - 0.992, - 0.996 - ] - }, - "order": 25, - "dofs": { - "$type": "ref", - "value": "140342738366624" - } - }, - "140342738367776": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738367776", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 537743.5886473 - ] - }, - "names": [ - "x0" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity - ] - } - }, - "Current3": { - "@module": "simsopt.field.coil", - "@class": "Current", - "@name": "Current3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current": 537743.5886473, - "dofs": { - "$type": "ref", - "value": "140342738367776" - } - }, - "Coil3": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve1": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent1": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil4": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve1" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent1" - } - }, - "RotatedCurve2": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent2": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent2", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil5": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve2" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent2" - } - }, - "RotatedCurve3": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 0.0, - "flip": true - }, - "ScaledCurrent3": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent3", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil6": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve3" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent3" - } - }, - "RotatedCurve4": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil7": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve4" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve5": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil8": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve5" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve6": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": false - }, - "Coil9": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve6" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve7": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent4": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent4", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil10": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve7" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent4" - } - }, - "RotatedCurve8": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent5": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent5", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil11": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve8" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent5" - } - }, - "RotatedCurve9": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 2.0943951023931953, - "flip": true - }, - "ScaledCurrent6": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent6", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil12": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve9" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent6" - } - }, - "RotatedCurve10": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil13": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve10" - }, - "current": { - "$type": "ref", - "value": "Current1" - } - }, - "RotatedCurve11": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve11", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil14": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve11" - }, - "current": { - "$type": "ref", - "value": "Current2" - } - }, - "RotatedCurve12": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve12", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": false - }, - "Coil15": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve12" - }, - "current": { - "$type": "ref", - "value": "Current3" - } - }, - "RotatedCurve13": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve13", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier1" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent7": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent7", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current1" - }, - "scale": -1.0 - }, - "Coil16": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil16", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve13" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent7" - } - }, - "RotatedCurve14": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve14", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier2" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent8": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent8", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current2" - }, - "scale": -1.0 - }, - "Coil17": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil17", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve14" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent8" - } - }, - "RotatedCurve15": { - "@module": "simsopt.geo.curve", - "@class": "RotatedCurve", - "@name": "RotatedCurve15", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "CurveXYZFourier3" - }, - "phi": 4.1887902047863905, - "flip": true - }, - "ScaledCurrent9": { - "@module": "simsopt.field.coil", - "@class": "ScaledCurrent", - "@name": "ScaledCurrent9", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "current_to_scale": { - "$type": "ref", - "value": "Current3" - }, - "scale": -1.0 - }, - "Coil18": { - "@module": "simsopt.field.coil", - "@class": "Coil", - "@name": "Coil18", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "curve": { - "$type": "ref", - "value": "RotatedCurve15" - }, - "current": { - "$type": "ref", - "value": "ScaledCurrent9" - } - }, - "BiotSavart1": { - "@module": "simsopt.field.biotsavart", - "@class": "BiotSavart", - "@name": "BiotSavart1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "coils": [ - { - "$type": "ref", - "value": "Coil1" - }, - { - "$type": "ref", - "value": "Coil2" - }, - { - "$type": "ref", - "value": "Coil3" - }, - { - "$type": "ref", - "value": "Coil4" - }, - { - "$type": "ref", - "value": "Coil5" - }, - { - "$type": "ref", - "value": "Coil6" - }, - { - "$type": "ref", - "value": "Coil7" - }, - { - "$type": "ref", - "value": "Coil8" - }, - { - "$type": "ref", - "value": "Coil9" - }, - { - "$type": "ref", - "value": "Coil10" - }, - { - "$type": "ref", - "value": "Coil11" - }, - { - "$type": "ref", - "value": "Coil12" - }, - { - "$type": "ref", - "value": "Coil13" - }, - { - "$type": "ref", - "value": "Coil14" - }, - { - "$type": "ref", - "value": "Coil15" - }, - { - "$type": "ref", - "value": "Coil16" - }, - { - "$type": "ref", - "value": "Coil17" - }, - { - "$type": "ref", - "value": "Coil18" - } - ], - "points": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - [ - 1.7680722478252928, - 0.0, - 0.0 - ], - [ - 1.7209247675770682, - 0.024695920948230445, - -0.2871985408189701 - ], - [ - 1.58001575500593, - 0.04268423059962205, - -0.5012545980793669 - ], - [ - 1.3784170338245367, - 0.09779852889333147, - -0.6405105274688647 - ], - [ - 1.2086808867601821, - 0.1628599872097202, - -0.7054517324786512 - ], - [ - 1.1401684171288364, - 0.18460450609915924, - -0.6898775248859494 - ], - [ - 1.155580070148073, - 0.17754120361731043, - -0.6251104565576596 - ], - [ - 1.2444770704753965, - 0.14237632072469178, - -0.5146683947981974 - ], - [ - 1.3964584856126678, - 0.07275107017858914, - -0.30655843731572224 - ], - [ - 1.4815680648673304, - 2.4529231771759414e-17, - -1.1499982286092568e-16 - ], - [ - 1.3964584856126678, - -0.07275107017858909, - 0.3065584373157221 - ], - [ - 1.2444770704753965, - -0.14237632072469167, - 0.5146683947981968 - ], - [ - 1.1555800701480732, - -0.17754120361731043, - 0.6251104565576593 - ], - [ - 1.1401684171288364, - -0.1846045060991593, - 0.6898775248859494 - ], - [ - 1.2086808867601817, - -0.16285998720972023, - 0.7054517324786513 - ], - [ - 1.3784170338245363, - -0.09779852889333168, - 0.6405105274688649 - ], - [ - 1.5800157550059295, - -0.042684230599622106, - 0.5012545980793671 - ], - [ - 1.7209247675770678, - -0.02469592094823047, - 0.2871985408189706 - ], - [ - 1.754051856520195, - 0.20918923172603887, - -0.04009835568961519 - ], - [ - 1.7141608064493685, - 0.22830829434705927, - -0.3191823551708279 - ], - [ - 1.578190392445102, - 0.23721674838593013, - -0.5191125631376396 - ], - [ - 1.3887201148795254, - 0.281824232268786, - -0.6515943590208377 - ], - [ - 1.2481128032491002, - 0.3289502458789051, - -0.7135596327733066 - ], - [ - 1.2044887913637978, - 0.3361149974607934, - -0.6863937660022384 - ], - [ - 1.2242081254228512, - 0.31862947417230175, - -0.6019190791090401 - ], - [ - 1.3072015319851868, - 0.27364597192709195, - -0.46576140290372475 - ], - [ - 1.4317108031629406, - 0.20480990826641646, - -0.23058262246625574 - ], - [ - 1.4567694760801877, - 0.1342308206031571, - 0.08202421637710015 - ], - [ - 1.321523209720005, - 0.05383991948111207, - 0.3619548738904281 - ], - [ - 1.1614329844567277, - -0.016355218276540767, - 0.5332177308882257 - ], - [ - 1.0823415420451266, - -0.041706039535744574, - 0.61974340755493 - ], - [ - 1.0779841411036202, - -0.03806549241065234, - 0.6730776682164475 - ], - [ - 1.1656180936984921, - 0.0020483168654304505, - 0.6819813064037555 - ], - [ - 1.354049160893743, - 0.08618528316207082, - 0.6122844417584006 - ], - [ - 1.5621781037696407, - 0.14946971349728325, - 0.46881799944766206 - ], - [ - 1.7031279228212948, - 0.17655862965590785, - 0.24955315997837343 - ], - [ - 1.7116676006639935, - 0.41537276166518167, - -0.07742800132185333 - ], - [ - 1.681802689990416, - 0.43261707498031865, - -0.3420283374297781 - ], - [ - 1.5564864526116695, - 0.43160367048376863, - -0.5241698352379243 - ], - [ - 1.388371036911217, - 0.4651591154285038, - -0.6507625046159534 - ], - [ - 1.2820848378593281, - 0.4962451104250306, - -0.7075662105198588 - ], - [ - 1.2569705210219697, - 0.4853629003433239, - -0.6603996766695123 - ], - [ - 1.270791867692402, - 0.4546651589682246, - -0.5498992397654674 - ], - [ - 1.3359073501901473, - 0.4032263596062831, - -0.3917173059818337 - ], - [ - 1.419660716141146, - 0.3328322187836187, - -0.14568836126282997 - ], - [ - 1.386770201635739, - 0.2580928010043199, - 0.15009337272599313 - ], - [ - 1.2193953258160606, - 0.1699147426808685, - 0.3883556059396122 - ], - [ - 1.064233975858743, - 0.09751899249402102, - 0.5224135569949871 - ], - [ - 0.9999716888030086, - 0.07784036334279866, - 0.5914745582505492 - ], - [ - 1.009811912963917, - 0.09550838437283843, - 0.6376765883025264 - ], - [ - 1.1145336313512793, - 0.15936582508439334, - 0.6404322025750467 - ], - [ - 1.3166447381785107, - 0.26331454840536767, - 0.5670798336352831 - ], - [ - 1.5261845351670618, - 0.3348670314623818, - 0.425190904863415 - ], - [ - 1.660264229355289, - 0.37190670626128974, - 0.20834609655897782 - ], - [ - 1.64368304037421, - 0.6118132485611744, - -0.10843861002741617 - ], - [ - 1.6211911854876186, - 0.6295560740683873, - -0.35505529541965036 - ], - [ - 1.514531056638536, - 0.6224615584496106, - -0.5204847509951354 - ], - [ - 1.379851854810507, - 0.6495309627730746, - -0.6334105919498286 - ], - [ - 1.302218840560934, - 0.667712868096011, - -0.6718144357371896 - ], - [ - 1.2798325833253084, - 0.6361637449049504, - -0.6034632004907471 - ], - [ - 1.281446654149259, - 0.5856872140414803, - -0.47423094393890725 - ], - [ - 1.3225600927033563, - 0.521913546302192, - -0.30364342234017 - ], - [ - 1.3595205859751085, - 0.44520477347884996, - -0.06642207221812069 - ], - [ - 1.2821682152221385, - 0.365757477079884, - 0.19212002656798796 - ], - [ - 1.1031002295008714, - 0.2774961217863611, - 0.3847907200338494 - ], - [ - 0.9565944669364895, - 0.21309940844474146, - 0.48867414627408207 - ], - [ - 0.9049055009942245, - 0.20269232679134633, - 0.5472133620270453 - ], - [ - 0.9339359188953229, - 0.23032108659614134, - 0.5912270501902529 - ], - [ - 1.0593497998564867, - 0.3115485981004461, - 0.5895900924652928 - ], - [ - 1.2707758728561056, - 0.43200911071499076, - 0.5130346716810242 - ], - [ - 1.4740535950609974, - 0.5115294223116441, - 0.3751012410189239 - ], - [ - 1.5958991128737805, - 0.5577947207325618, - 0.1658212181153926 - ], - [ - 1.5559408540770292, - 0.7957380130712147, - -0.13154938099716484 - ], - [ - 1.5398798542593344, - 0.8149905752646446, - -0.361113214679157 - ], - [ - 1.4625386175552766, - 0.8127792053676645, - -0.5085317153853542 - ], - [ - 1.3677043074899553, - 0.8367589743886225, - -0.5892134229914564 - ], - [ - 1.3020441738251485, - 0.8350495814355556, - -0.5934925755901909 - ], - [ - 1.264129516008067, - 0.7743753577953667, - -0.5140029374361951 - ], - [ - 1.2492266387459874, - 0.6959427536889674, - -0.3853106960493632 - ], - [ - 1.2629367738602766, - 0.6169229409461704, - -0.2181861725957825 - ], - [ - 1.2568571287952393, - 0.5375396324123799, - -0.008681130327320987 - ], - [ - 1.1562908297728687, - 0.4600322166010081, - 0.20169800381803343 - ], - [ - 0.9866011411546383, - 0.3862570483974544, - 0.3572249217057805 - ], - [ - 0.8579987419384898, - 0.3457385457662895, - 0.4469514679738313 - ], - [ - 0.8210423406728821, - 0.3451317242171014, - 0.505466286584031 - ], - [ - 0.8650885466363889, - 0.37323718897574937, - 0.5483128445552922 - ], - [ - 1.0031622317169981, - 0.46371467657119103, - 0.5373715193713036 - ], - [ - 1.215910581856729, - 0.5940146203994715, - 0.45547226947116326 - ], - [ - 1.4065941223119867, - 0.68008745002744, - 0.323455452607952 - ], - [ - 1.5140680970330784, - 0.7361696650516472, - 0.1260338438039452 - ], - [ - 1.4527691866755628, - 0.9690610568548097, - -0.1473912621348829 - ], - [ - 1.448174931011679, - 0.9987000095929328, - -0.35699422223079585 - ], - [ - 1.4046887822237273, - 1.014872020921697, - -0.4771601195468688 - ], - [ - 1.3365564770089529, - 1.0253627789925666, - -0.5134270873349986 - ], - [ - 1.261555954473149, - 0.9782467163485575, - -0.48769798852027096 - ], - [ - 1.200837601102099, - 0.8761031957375435, - -0.4149329224009639 - ], - [ - 1.170750357390383, - 0.7742346578050538, - -0.3021740314901848 - ], - [ - 1.1606848560256202, - 0.6885817944457319, - -0.1523200809575562 - ], - [ - 1.1262513031272277, - 0.6138344662214583, - 0.018088485529077186 - ], - [ - 1.0234070285169812, - 0.5492294198539395, - 0.1822477214008732 - ], - [ - 0.8790706750621735, - 0.5007151250306213, - 0.31758490272433815 - ], - [ - 0.7762535324180768, - 0.4813466807840149, - 0.41536402425551433 - ], - [ - 0.7505717896659181, - 0.4822386023036034, - 0.48355814119332957 - ], - [ - 0.799656713843975, - 0.5127483802885304, - 0.5150123483423211 - ], - [ - 0.9433884948889466, - 0.6143430779188004, - 0.4841787560175849 - ], - [ - 1.1519771763973745, - 0.7499438696728989, - 0.3987418464229427 - ], - [ - 1.3253478985445515, - 0.8430490472705313, - 0.2755729153169847 - ], - [ - 1.4168461257268834, - 0.9085786413069763, - 0.09086817159177078 - ], - [ - 1.3385386475195313, - 1.135451191726052, - -0.15348216581811622 - ], - [ - 1.3431069157206852, - 1.1816279856151182, - -0.3257405583944725 - ], - [ - 1.315007660973004, - 1.211599121307774, - -0.4073853980747419 - ], - [ - 1.2504165945114365, - 1.1873282223304962, - -0.41541009827917613 - ], - [ - 1.16423967730412, - 1.0773406707215134, - -0.389161410581851 - ], - [ - 1.0946326414560064, - 0.9380243357904737, - -0.3366577673034683 - ], - [ - 1.0581147325750313, - 0.8263850061564209, - -0.24269631108473716 - ], - [ - 1.0325260254413866, - 0.7408471779878933, - -0.11808814329922007 - ], - [ - 0.9854012798244418, - 0.6785297005433786, - 0.01166175700653285 - ], - [ - 0.8937489890122365, - 0.6386541616015479, - 0.14448861207601063 - ], - [ - 0.7761292763287888, - 0.6147115361000631, - 0.27755103484909316 - ], - [ - 0.6886723382157068, - 0.60627772536458, - 0.38966131559533074 - ], - [ - 0.665393993438627, - 0.6096222008686576, - 0.4616866647665 - ], - [ - 0.7237563206695984, - 0.6510392250916778, - 0.4757149461228547 - ], - [ - 0.8790035125749528, - 0.764803875775301, - 0.42912393966438317 - ], - [ - 1.07906306229287, - 0.9026168526729031, - 0.3479980448536496 - ], - [ - 1.2294655611830145, - 1.0005771712783673, - 0.23452518387938867 - ], - [ - 1.3053714544015873, - 1.0726047880228389, - 0.0598569432349431 - ], - [ - 1.215452745775397, - 1.299532943880838, - -0.13798771244674438 - ], - [ - 1.2144588010254316, - 1.344775275291624, - -0.25286314130723037 - ], - [ - 1.1733747987151142, - 1.3567043234111271, - -0.30664003145239926 - ], - [ - 1.1058096405530404, - 1.2899085971804438, - -0.32632565593620977 - ], - [ - 1.0277872797832526, - 1.1327392783139016, - -0.3244926425709145 - ], - [ - 0.9645393567303252, - 0.9710406873889953, - -0.29206371844146384 - ], - [ - 0.9264342986025836, - 0.8559399700940715, - -0.2168306849823443 - ], - [ - 0.8928160527037219, - 0.775618719994372, - -0.12131501592080657 - ], - [ - 0.8441713349470346, - 0.7362799482289287, - -0.023406334758914217 - ], - [ - 0.7682837175535356, - 0.7271103651541142, - 0.09839080279846833 - ], - [ - 0.6691527368702893, - 0.7227133372720203, - 0.23594600205806765 - ], - [ - 0.5887950454091017, - 0.7274355570741424, - 0.34559443998804756 - ], - [ - 0.5730886732911219, - 0.7440170558907081, - 0.40877371579057675 - ], - [ - 0.6469580730325103, - 0.7957660352946686, - 0.41722168012921845 - ], - [ - 0.8099873338952917, - 0.9155409035860799, - 0.3741997049833415 - ], - [ - 0.9966089501204827, - 1.0529546231470763, - 0.306744689186155 - ], - [ - 1.1217811776149107, - 1.14965470936722, - 0.20275828232814458 - ], - [ - 1.1829607423668453, - 1.2285126095194567, - 0.03693621845263564 - ], - [ - 1.076944801169051, - 1.4551475105413565, - -0.08547397474399784 - ], - [ - 1.055519742004532, - 1.4698386740002358, - -0.15475299575659204 - ], - [ - 0.9953065117417849, - 1.4390579378749127, - -0.2203846875534553 - ], - [ - 0.9353930104751851, - 1.341939097790177, - -0.2768224729358256 - ], - [ - 0.8761926892926568, - 1.1611215285093817, - -0.2974778161096089 - ], - [ - 0.8213356899748697, - 0.9844617648980184, - -0.2813332370887146 - ], - [ - 0.7842930594607062, - 0.8702441587938653, - -0.22740964387439155 - ], - [ - 0.7502897919985411, - 0.8042677099579103, - -0.15648873252961748 - ], - [ - 0.7059104437374021, - 0.7920225578603564, - -0.07419445952873198 - ], - [ - 0.6424091640183707, - 0.8110719436508862, - 0.04945728863852943 - ], - [ - 0.5585158801786818, - 0.8235950577408283, - 0.18571175669907405 - ], - [ - 0.4969671050361561, - 0.8436952515813781, - 0.2793921560473084 - ], - [ - 0.5008553825113218, - 0.8772232621355395, - 0.33442825510717367 - ], - [ - 0.5812603219216935, - 0.9385174035323885, - 0.35223022689965194 - ], - [ - 0.7365969270562933, - 1.0631610911842186, - 0.3275617663342745 - ], - [ - 0.9062599714309366, - 1.2003736265598748, - 0.2787444474867998 - ], - [ - 1.0076717017945591, - 1.2944116526898963, - 0.18290793490410737 - ], - [ - 1.052852600082172, - 1.3818192853594857, - 0.03524245047290434 - ], - [ - 0.9125663698545683, - 1.5806113178668033, - -3.338663530972138e-17 - ], - [ - 0.869113927810831, - 1.552315187114308, - -0.0730391988830628 - ], - [ - 0.8050922446292604, - 1.4865577073137994, - -0.1821578073419472 - ], - [ - 0.7607447042748242, - 1.3703268801756467, - -0.2664502784477747 - ], - [ - 0.7161939046876921, - 1.1719848280815819, - -0.30012461375351196 - ], - [ - 0.6718532945207347, - 0.9841099726290903, - -0.3028133950505102 - ], - [ - 0.6450973122416518, - 0.876888728596458, - -0.26903874595351446 - ], - [ - 0.615084928235879, - 0.8316634352990808, - -0.21167698228798143 - ], - [ - 0.5708233416635586, - 0.8457791366426325, - -0.12970490800073575 - ], - [ - 0.513422675094356, - 0.8892741590213524, - -3.300827316471772e-17 - ], - [ - 0.44705454749161067, - 0.917237083275082, - 0.1297049080007357 - ], - [ - 0.4126991982497006, - 0.9485108909867399, - 0.21167698228798135 - ], - [ - 0.4368592591359447, - 0.9971150246125614, - 0.2690387459535143 - ], - [ - 0.5163375891540336, - 1.0738970069857696, - 0.3028133950505102 - ], - [ - 0.656871681624742, - 1.2062345295359032, - 0.30012461375351196 - ], - [ - 0.8063655375833723, - 1.3439876797843004, - 0.2664502784477749 - ], - [ - 0.8848506164106728, - 1.4405091898956748, - 0.18215780734194728 - ], - [ - 0.9097874228159699, - 1.528832333824208, - 0.07303919888306297 - ], - [ - 0.7217223097979737, - 1.6602353115566573, - 0.08547397474399765 - ], - [ - 0.6702643045194876, - 1.6027067407914022, - -0.03524245047290406 - ], - [ - 0.6171575232867713, - 1.5198751187737345, - -0.18290793490410723 - ], - [ - 0.5864240689182385, - 1.3850309709720885, - -0.27874444748679955 - ], - [ - 0.5524260497525711, - 1.169492196772413, - -0.3275617663342746 - ], - [ - 0.5221497523920133, - 0.972644906762302, - -0.3522302268996516 - ], - [ - 0.5092699385443726, - 0.8723651159447469, - -0.3344282551071734 - ], - [ - 0.482177968403699, - 0.8522337635972099, - -0.2793921560473083 - ], - [ - 0.43399630234552855, - 0.8954864695221786, - -0.18571175669907378 - ], - [ - 0.3812043254893032, - 0.9618786274892761, - -0.049457288638529315 - ], - [ - 0.3329564336086983, - 1.007347656003514, - 0.0741944595287321 - ], - [ - 0.32137137226781454, - 1.0519038750498335, - 0.1564887325296175 - ], - [ - 0.3615070192801532, - 1.1143397929017231, - 0.2274096438743915 - ], - [ - 0.4419010524687128, - 1.2035284550020662, - 0.28133323708871444 - ], - [ - 0.5674643959238133, - 1.3393658917923366, - 0.29747781610960883 - ], - [ - 0.6944568437802707, - 1.4810436584890019, - 0.27682247293582585 - ], - [ - 0.7486074758464304, - 1.581489692657916, - 0.2203846875534552 - ], - [ - 0.7451577601467724, - 1.6490262477720388, - 0.1547529957565919 - ], - [ - 0.5177021695678847, - 1.702379426881462, - 0.13798771244674438 - ], - [ - 0.47244275752993964, - 1.6387303593291151, - -0.03693621845263522 - ], - [ - 0.43473959508497306, - 1.5463183519853465, - -0.2027582823281444 - ], - [ - 0.41358097761739715, - 1.3895659800168152, - -0.30674468918615466 - ], - [ - 0.38788801376165916, - 1.1592400596899914, - -0.37419970498334154 - ], - [ - 0.3656745655177523, - 0.9581651440769164, - -0.41722168012921834 - ], - [ - 0.3577933346046991, - 0.8683178776365865, - -0.40877371579057686 - ], - [ - 0.3355801493377417, - 0.8736292454837653, - -0.34559443998804756 - ], - [ - 0.29131174129625614, - 0.9408599377775649, - -0.23594600205806768 - ], - [ - 0.2455541888016748, - 1.0289083992923675, - -0.09839080279846844 - ], - [ - 0.2155514719898264, - 1.0992137953252183, - 0.023406334758914158 - ], - [ - 0.2252974888140346, - 1.1610107425451552, - 0.12131501592080639 - ], - [ - 0.27804860891466676, - 1.2302856225740915, - 0.21683068498234412 - ], - [ - 0.35867622502201096, - 1.3208359295728602, - 0.29206371844146384 - ], - [ - 0.46708735099266385, - 1.456459533135752, - 0.32449264257091437 - ], - [ - 0.5641887934416925, - 1.6026135390588934, - 0.32632565593620994 - ], - [ - 0.5882530101406579, - 1.6945245455533047, - 0.30664003145239926 - ], - [ - 0.5573801502710428, - 1.724139811183426, - 0.2528631413072303 - ], - [ - 0.3140602530323106, - 1.7269340685622043, - 0.1534821658181162 - ], - [ - 0.2762172674478079, - 1.6667872348982344, - -0.05985694323494258 - ], - [ - 0.25179246818233225, - 1.5650369947017657, - -0.23452518387938837 - ], - [ - 0.24215759315225516, - 1.3858044505675073, - -0.34799804485364927 - ], - [ - 0.22283782904673244, - 1.143641309793314, - -0.4291239396643829 - ], - [ - 0.20193834745472922, - 0.9523109723952671, - -0.47571494612285464 - ], - [ - 0.19525131594392406, - 0.8810592022777558, - -0.46168666476649994 - ], - [ - 0.1807157428065183, - 0.8995466024607207, - -0.38966131559533085 - ], - [ - 0.14429116809761539, - 0.9795034379715943, - -0.2775510348490932 - ], - [ - 0.10621623367347442, - 1.0933364098920297, - -0.14448861207601063 - ], - [ - 0.09492331798059271, - 1.1926473915213534, - -0.011661757006532934 - ], - [ - 0.1253294637388338, - 1.264617357094764, - 0.11808814329921967 - ], - [ - 0.18661304235050435, - 1.329546741606765, - 0.24269631108473685 - ], - [ - 0.26503658343457165, - 1.416991843207801, - 0.3366577673034682 - ], - [ - 0.35088455072293656, - 1.546931471999921, - 0.38916141058185094 - ], - [ - 0.4030481059127095, - 1.6765566473257771, - 0.41541009827917597 - ], - [ - 0.39177178776893423, - 1.744629601227663, - 0.40738539807474183 - ], - [ - 0.3517663955049831, - 1.7539787018202373, - 0.3257405583944725 - ], - [ - 0.11284689971668031, - 1.7426655499236994, - 0.14739126213488293 - ], - [ - 0.07842912184434947, - 1.68131405878653, - -0.09086817159177023 - ], - [ - 0.06742794230027274, - 1.5693094726271684, - -0.2755729153169845 - ], - [ - 0.07348185435044971, - 1.3726134341764438, - -0.3987418464229423 - ], - [ - 0.06034246467233084, - 1.124169941171194, - -0.4841787560175849 - ], - [ - 0.044224766157204116, - 0.9488972186399309, - -0.5150123483423211 - ], - [ - 0.04234498544746258, - 0.8911335383664374, - -0.48355814119332974 - ], - [ - 0.02873168737723759, - 0.9129286192434686, - -0.41536402425551444 - ], - [ - -0.005903319195467008, - 1.0116550988410884, - -0.31758490272433815 - ], - [ - -0.036056884159189534, - 1.1609111950342208, - -0.18224772140087325 - ], - [ - -0.03152941009736973, - 1.2822794726642366, - -0.01808848552907728 - ], - [ - 0.01598689856066813, - 1.3494734683289362, - 0.1523200809575559 - ], - [ - 0.0851317034543369, - 1.4010168798923086, - 0.3021740314901844 - ], - [ - 0.15830882329439386, - 1.4780074662427536, - 0.4149329224009639 - ], - [ - 0.2164085302899863, - 1.5816628630435503, - 0.48769798852027085 - ], - [ - 0.21971197619809535, - 1.6701732521786685, - 0.5134270873349985 - ], - [ - 0.17656056059637865, - 1.7239321802776228, - 0.4771601195468688 - ], - [ - 0.14081211356140313, - 1.7535062841763571, - 0.3569942222307963 - ], - [ - -0.08884109296188875, - 1.745353312952371, - 0.13154938099716493 - ], - [ - -0.11949241708633121, - 1.6793062676160324, - -0.12603384380394453 - ], - [ - -0.11432405263725025, - 1.5581899677497768, - -0.3234554526079517 - ], - [ - -0.09352353944305204, - 1.350016762817982, - -0.4554722694711628 - ], - [ - -0.09999242584016277, - 1.1006213150696078, - -0.5373715193713033 - ], - [ - -0.10931138602810207, - 0.9358072523979467, - -0.5483128445552922 - ], - [ - -0.11162832951250609, - 0.8836093867139043, - -0.5054662865840311 - ], - [ - -0.12958100726814917, - 0.9159179798169653, - -0.4469514679738314 - ], - [ - -0.15879215427432808, - 1.0475501758413608, - -0.3572249217057805 - ], - [ - -0.17974582875069584, - 1.2313933410467963, - -0.20169800381803354 - ], - [ - -0.16290558718754963, - 1.3572400186704374, - 0.00868113032732074 - ], - [ - -0.09719744789334772, - 1.402196800009647, - 0.2181861725957819 - ], - [ - -0.021909215098651576, - 1.4298333810827542, - 0.38531069604936274 - ], - [ - 0.03856397391141826, - 1.4819559534343967, - 0.5140029374361949 - ], - [ - 0.07215206403017953, - 1.5451281220998778, - 0.5934925755901906 - ], - [ - 0.040802374920182224, - 1.602846162346016, - 0.5892134229914563 - ], - [ - -0.027381869261511274, - 1.6729851995024754, - 0.5085317153853545 - ], - [ - -0.0641373851055912, - 1.7410703601967847, - 0.3611132146791575 - ], - [ - -0.2919957045612447, - 1.729377893014296, - 0.10843861002741617 - ], - [ - -0.3148851581856451, - 1.660986533992024, - -0.16582121811539202 - ], - [ - -0.2940293230254364, - 1.5323325710184257, - -0.37510124101892367 - ], - [ - -0.26125707188254665, - 1.3165287437672275, - -0.513034671681024 - ], - [ - -0.25986589945982863, - 1.0731981372199013, - -0.5895900924652929 - ], - [ - -0.26750404742816736, - 0.9239727745681834, - -0.5912270501902529 - ], - [ - -0.276916046343629, - 0.8850173152809562, - -0.5472133620270455 - ], - [ - -0.29374773222366246, - 0.9349848137090038, - -0.4886741462740822 - ], - [ - -0.3112314238317865, - 1.0940608825613796, - -0.3847907200338496 - ], - [ - -0.32432884083578517, - 1.2932689848472676, - -0.19212002656798807 - ], - [ - -0.29420164926877357, - 1.3999817511617747, - 0.06642207221812052 - ], - [ - -0.20928965667475394, - 1.4063274114637043, - 0.3036434223401696 - ], - [ - -0.13350332104297372, - 1.40260896310857, - 0.47423094393890686 - ], - [ - -0.0889823276083237, - 1.4264494022032566, - 0.6034632004907471 - ], - [ - -0.07285311407555328, - 1.461611031260492, - 0.6718144357371895 - ], - [ - -0.12741561309920602, - 1.5197522411115127, - 0.6334105919498287 - ], - [ - -0.21819800582265275, - 1.6228531490942657, - 0.5204847509951355 - ], - [ - -0.2653840394937881, - 1.7187707880578815, - 0.3550552954196508 - ], - [ - -0.49611043668984994, - 1.6900340058423673, - 0.0774280013218535 - ], - [ - -0.5080514592175702, - 1.6237843527469202, - -0.20834609655897707 - ], - [ - -0.4730889114472251, - 1.489148094048812, - -0.4251909048634147 - ], - [ - -0.4302852809841794, - 1.271905065224386, - -0.5670798336352828 - ], - [ - -0.4192519626574873, - 1.0448973506645258, - -0.6404322025750464 - ], - [ - -0.42219326934067125, - 0.9222769618573319, - -0.637676588302526 - ], - [ - -0.4325741123068293, - 0.9049210672400321, - -0.591474558250549 - ], - [ - -0.4476630630780849, - 0.9704131549111967, - -0.5224135569949873 - ], - [ - -0.4625471792689019, - 1.1409847007531448, - -0.3883556059396124 - ], - [ - -0.4698701786142465, - 1.3300246243299785, - -0.15009337272599355 - ], - [ - -0.4215892014060189, - 1.395878354324851, - 0.1456883612628295 - ], - [ - -0.318749404200513, - 1.3585428821701635, - 0.3917173059818329 - ], - [ - -0.2416443559640283, - 1.3278706198284065, - 0.5498992397654667 - ], - [ - -0.20814865875917135, - 1.33124985318485, - 0.6603996766695122 - ], - [ - -0.21128154679777358, - 1.3584405946055476, - 0.7075662105198587 - ], - [ - -0.2913459076926256, - 1.4349441455579086, - 0.6507625046159535 - ], - [ - -0.4044634833002827, - 1.5637586438499143, - 0.5241698352379246 - ], - [ - -0.46624396795133416, - 1.6727923911748646, - 0.3420283374297787 - ], - [ - -0.6958627393871972, - 1.6236480831647655, - 0.040098355689615374 - ], - [ - -0.6986597028712619, - 1.5632313618858185, - -0.24955315997837266 - ], - [ - -0.6516444828997909, - 1.4276207798489546, - -0.4688179994476616 - ], - [ - -0.6023859357961623, - 1.2157336128880203, - -0.6122844417584001 - ], - [ - -0.5810351524087823, - 1.0104790386863998, - -0.6819813064037552 - ], - [ - -0.571957753986998, - 0.9145289048671577, - -0.6730776682164473 - ], - [ - -0.5772892607517555, - 0.9164822512144299, - -0.6197434075549298 - ], - [ - -0.594880526740287, - 0.9976528601944324, - -0.5332177308882261 - ], - [ - -0.6141348668516501, - 1.1713926310488303, - -0.36195487389042846 - ], - [ - -0.6121374374269277, - 1.3287147840447684, - -0.0820242163771007 - ], - [ - -0.5384848180759927, - 1.3423028805449368, - 0.2305826224662552 - ], - [ - -0.4166164026604487, - 1.2688927205286555, - 0.46576140290372403 - ], - [ - -0.3361628436837344, - 1.219510073221667, - 0.6019190791090397 - ], - [ - -0.3111602692879093, - 1.2111753906250606, - 0.6863937660022382 - ], - [ - -0.3391771321122803, - 1.2453725173417827, - 0.7135596327733067 - ], - [ - -0.45029311289294693, - 1.3435790143665063, - 0.6515943590208383 - ], - [ - -0.5836594659171932, - 1.485361346058956, - 0.51911256313764 - ], - [ - -0.6593596204254351, - 1.5986609517303034, - 0.3191823551708286 - ] - ] - } - }, - "140342738037920": { - "@module": "simsopt._core.optimizable", - "@class": "DOFs", - "@name": "140342738037920", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "x": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 1.370099855687832, - 0.015612104788396806, - -0.0030179159583515573, - 0.0022063231165241233, - -0.0002734200030295804, - -0.0012226452716094548, - -0.00012178648431735264, - 0.302178979912302, - -0.12156392591290117, - 0.0012148068343540656, - 0.0024845973069276355, - -0.0009487053589635161, - 0.0004469862881796634, - 0.0002992063541037181, - 0.1241420996623515, - 0.08220801224462833, - 0.025309097692454787, - -0.0031679568382928184, - -0.0013474404453579255, - 0.0009710588963599626, - 0.0005845501908979165, - -0.02737035264952027, - 0.007743839909994162, - -0.0013009390202269758, - -0.005854489156318461, - 0.0016323167346173676, - -0.0008185001665246053, - -0.0005601663845150453, - -0.00041703968348957377, - 0.009715551251600117, - 0.0034738909595454425, - -0.004628805893661069, - 0.001721825690142954, - 0.0003574623490250821, - -0.00037456983620028675, - -0.003736833065050284, - -0.01016814768720632, - -0.0017419346739122477, - 8.708763937825734e-05, - 0.0012876399842537878, - -0.0003032498621445788, - 0.0002438744521539715, - 0.003652537623916706, - -0.0022177509081757166, - 0.0013410346476269732, - -0.00016191436665664405, - 0.0007036290317634967, - -0.0002558836694448717, - -7.17481281678613e-05, - 0.24380061368439773, - -0.010071642778727529, - -0.0016413303536336132, - -0.00020008214586538937, - -0.000977543126554361, - 0.0005227777071488129, - -0.07532560018495471, - -0.029234761183654038, - 0.005149253916889585, - 0.0025866007924868245, - -0.0001237964826232096, - -0.0009387954093402702, - 0.0008358444806667871, - 0.004131411992662826, - 0.004561235738609085, - -0.0011363027830899508, - -0.00036748515008869806, - 0.000363271160005206, - -0.0032611172270354915, - -0.0033784135399489105, - 0.003345765376819986, - -0.0018953074691629482, - -0.0003644439218137425, - 0.000446852131551194, - 0.009407172358681739, - 0.004643726438496215, - -1.364165151881822e-05, - -0.0009393275408625786, - 0.0006568500390140209, - -0.00043863298497605146, - 0.000666509713260929, - 0.00016454371967560447, - -0.000839294819472734, - -0.0005309840083991336, - 0.00028118212419470773, - -2.2543594072121704e-05, - 0.0016005424841288197, - -0.0013167858251726071, - 0.0015837852943506104, - -0.00014551651703067006, - 0.0006088991759239378, - 0.00038090445854628357, - 0.05411995175479992, - 0.0019028436139005983, - -0.00031689636950124394, - 0.00014140201140625986, - -0.001171734282778547, - -4.695552401219802e-05, - -0.050185506265380264, - -0.0035356767910498317, - 0.0007677138370074986, - 0.0003301685139897476, - -0.0009514214980598781, - -0.0006549569679681475, - -0.0012673984853303494, - -0.00013167230908013553, - -0.0001298201636444754, - -0.0008681585906736584, - 0.001223799781827021, - 0.00034502885311922754, - -0.00042650206758509853, - 0.002121814701090765, - -0.000977955837388021, - 0.000128627762124797, - -0.00015421976933677287, - -1.1665717889056904e-05, - 0.005664897925133099, - 0.0011231455211457417, - -0.0008794922303261419, - -0.00010517917170814688, - 8.523817163794135e-05, - -0.00038164229933544675, - 0.0031885447442114687, - 0.000829944975154068, - 0.0003906218182780436, - -0.00041242411159952877, - 0.0002635215060608244, - 0.00013075266274608068, - 0.05704950067130263, - 0.11220000845768416, - -0.005613396564839782, - -0.0008240667339965433, - -0.00046797669484346233, - -0.0004538894102919448, - 0.00098101877217381, - 0.02030435442281452, - -0.06722620471295754, - -0.0018973232126689187, - 0.0027854299923622725, - 0.00024726719780385426, - 0.0007812902562423288, - -0.0006754902369012465, - -0.008809283098389178, - -0.0063800263981638565, - 0.00400257435845095, - -0.0004745582480581115, - -0.001232673003785594, - 9.769518797490552e-05, - 0.0002953001808185349, - 0.0003914211957151875, - 0.0023686618423507813, - -0.001883144164243817, - -0.000298665520308543, - -8.611335457180634e-05, - -0.000399939025124226, - 0.0002665574506677008, - 0.0005486001062539296, - 0.004125035999562045, - -0.0010305402562355407, - -0.00011085384281944096, - 0.0004221189570385646, - 0.0003212658486506654, - -0.0003718969988800435, - 0.0018727911828621494, - 0.004415287227056264, - -0.00019890675976168027, - -0.00047637387336616844, - -0.00018687675562060067, - 0.00013239353304179193, - 0.00019448474294613542, - 0.0175675766383604, - -0.009875661448489406, - 0.0031092216570921915, - 0.0008065176224734124, - -0.00021018625813556578, - 9.767400469461835e-05, - -0.15699810147530688, - 0.010542112770075144, - -0.0009778732920278038, - -0.0010665830996924525, - 0.0008076979618913867, - -9.558224834579981e-05, - 0.005507988349817701, - 0.031164894454736115, - -0.004337126740459847, - -0.002189475702997216, - 0.00012222177543344588, - 1.8701403892307008e-06, - -0.012155652521718045, - -0.007307663714583059, - -0.003496836786738803, - 0.001894522794969929, - -0.0007271320162097899, - -0.00011309139004382258, - -0.0008203454995776989, - 0.005901570605144783, - -0.005177967958134056, - 0.002274563799914917, - 0.00021692204657530121, - -6.005266463510737e-05, - -0.0038755797133734043, - -0.001736609933790854, - -0.0011128238951791224, - 0.001416949885327378, - -0.00032934036935998434, - 0.00024169315081806641, - -0.0009920572988003178, - 0.0009188383324148919, - 5.2379111989037965e-05, - 0.0004650767044931138, - -0.0004263242200192872, - 5.4080572130627756e-05, - -0.5277395180216956, - -0.21374199990615314, - 0.003688150207258406, - -0.002646015924012413, - 0.0014927176517076598, - 0.0001357116524985605, - -0.0003647241855285567, - -0.01721757933817644, - -0.005424390529843613, - 0.027461991686469317, - -0.0017157228405142476, - -0.0018674306686356156, - 0.0002884181715804734, - 2.8217353950113614e-05, - -0.018692141898086215, - -0.015351256146304566, - -0.0024519249779179596, - -0.006007666179938757, - 0.0011177211558422253, - 0.00012110942323144351, - 1.2344548019734355e-05, - 0.0019332259380344435, - 0.004465561443084816, - 0.008183032304722553, - -0.006333298313922966, - 0.0021692008087801735, - 0.00020888542073621628, - -0.00018186868048159936, - -0.00520572306839542, - -0.005246404590234969, - 0.0009477592515354704, - 0.00024395982816618396, - 0.0010133539694583613, - -0.00047891769880890943, - 0.0002569096021071273, - -0.00019681207193257658, - -0.003623535740686089, - 0.001599108044503654, - 7.012928016346378e-05, - 0.0004852460112548447, - -0.00024396321544820784, - 5.689747926156211e-05 - ] - }, - "names": [ - "x0", - "x1", - "x2", - "x3", - "x4", - "x5", - "x6", - "x7", - "x8", - "x9", - "x10", - "x11", - "x12", - "x13", - "x14", - "x15", - "x16", - "x17", - "x18", - "x19", - "x20", - "x21", - "x22", - "x23", - "x24", - "x25", - "x26", - "x27", - "x28", - "x29", - "x30", - "x31", - "x32", - "x33", - "x34", - "x35", - "x36", - "x37", - "x38", - "x39", - "x40", - "x41", - "x42", - "x43", - "x44", - "x45", - "x46", - "x47", - "x48", - "x49", - "x50", - "x51", - "x52", - "x53", - "x54", - "x55", - "x56", - "x57", - "x58", - "x59", - "x60", - "x61", - "x62", - "x63", - "x64", - "x65", - "x66", - "x67", - "x68", - "x69", - "x70", - "x71", - "x72", - "x73", - "x74", - "x75", - "x76", - "x77", - "x78", - "x79", - "x80", - "x81", - "x82", - "x83", - "x84", - "x85", - "x86", - "x87", - "x88", - "x89", - "x90", - "x91", - "x92", - "x93", - "x94", - "x95", - "x96", - "x97", - "x98", - "x99", - "x100", - "x101", - "x102", - "x103", - "x104", - "x105", - "x106", - "x107", - "x108", - "x109", - "x110", - "x111", - "x112", - "x113", - "x114", - "x115", - "x116", - "x117", - "x118", - "x119", - "x120", - "x121", - "x122", - "x123", - "x124", - "x125", - "x126", - "x127", - "x128", - "x129", - "x130", - "x131", - "x132", - "x133", - "x134", - "x135", - "x136", - "x137", - "x138", - "x139", - "x140", - "x141", - "x142", - "x143", - "x144", - "x145", - "x146", - "x147", - "x148", - "x149", - "x150", - "x151", - "x152", - "x153", - "x154", - "x155", - "x156", - "x157", - "x158", - "x159", - "x160", - "x161", - "x162", - "x163", - "x164", - "x165", - "x166", - "x167", - "x168", - "x169", - "x170", - "x171", - "x172", - "x173", - "x174", - "x175", - "x176", - "x177", - "x178", - "x179", - "x180", - "x181", - "x182", - "x183", - "x184", - "x185", - "x186", - "x187", - "x188", - "x189", - "x190", - "x191", - "x192", - "x193", - "x194", - "x195", - "x196", - "x197", - "x198", - "x199", - "x200", - "x201", - "x202", - "x203", - "x204", - "x205", - "x206", - "x207", - "x208", - "x209", - "x210", - "x211", - "x212", - "x213", - "x214", - "x215", - "x216", - "x217", - "x218", - "x219", - "x220", - "x221", - "x222", - "x223", - "x224", - "x225", - "x226", - "x227", - "x228", - "x229", - "x230", - "x231", - "x232", - "x233", - "x234", - "x235", - "x236", - "x237", - "x238", - "x239", - "x240", - "x241", - "x242", - "x243", - "x244", - "x245", - "x246", - "x247", - "x248", - "x249", - "x250", - "x251", - "x252" - ], - "free": { - "@module": "numpy", - "@class": "array", - "dtype": "bool", - "data": [ - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true, - true - ] - }, - "lower_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity - ] - }, - "upper_bounds": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity, - Infinity - ] - } - }, - "SurfaceXYZTensorFourier1": { - "@module": "simsopt.geo.surfacexyztensorfourier", - "@class": "SurfaceXYZTensorFourier", - "@name": "SurfaceXYZTensorFourier1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "nfp": 3, - "stellsym": true, - "mpol": 6, - "ntor": 6, - "clamped_dims": [ - false, - false, - false - ], - "quadpoints_phi": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.018518518518518517, - 0.037037037037037035, - 0.05555555555555555, - 0.07407407407407407, - 0.09259259259259259, - 0.1111111111111111, - 0.12962962962962962, - 0.14814814814814814, - 0.16666666666666666, - 0.18518518518518517, - 0.2037037037037037, - 0.2222222222222222, - 0.24074074074074073, - 0.25925925925925924, - 0.2777777777777778, - 0.2962962962962963, - 0.31481481481481477 - ] - }, - "quadpoints_theta": { - "@module": "numpy", - "@class": "array", - "dtype": "float64", - "data": [ - 0.0, - 0.05555555555555555, - 0.1111111111111111, - 0.16666666666666666, - 0.2222222222222222, - 0.2777777777777778, - 0.3333333333333333, - 0.38888888888888884, - 0.4444444444444444, - 0.5, - 0.5555555555555556, - 0.611111111111111, - 0.6666666666666666, - 0.7222222222222222, - 0.7777777777777777, - 0.8333333333333333, - 0.8888888888888888, - 0.9444444444444444 - ] - }, - "dofs": { - "$type": "ref", - "value": "140342738037920" - } - }, - "Volume1": { - "@module": "simsopt.geo.surfaceobjectives", - "@class": "Volume", - "@name": "Volume1", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "range": null, - "nphi": null, - "ntheta": null - }, - "BoozerSurface10": { - "@module": "simsopt.geo.boozersurface", - "@class": "BoozerSurface", - "@name": "BoozerSurface10", - "@version": "0.13.0.post3+g0f8c1278.d20230501.dirty", - "biotsavart": { - "$type": "ref", - "value": "BiotSavart1" - }, - "surface": { - "$type": "ref", - "value": "SurfaceXYZTensorFourier1" - }, - "label": { - "$type": "ref", - "value": "Volume1" - }, - "targetlabel": -3.91888, - "constraint_weight": 1000.0, - "reg": null - } - } -} \ No newline at end of file diff --git a/examples/2_Intermediate/inputs/input_ncsx/surface_9.vts b/examples/2_Intermediate/inputs/input_ncsx/surface_9.vts deleted file mode 100644 index fa28e6e8a9aeb72a2f1f71a54fa87c128d85efed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31872 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 From 291b0a02644c683302f6a1c5e3f0e805cedfc4aa Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 5 Apr 2024 14:21:05 -0400 Subject: [PATCH 016/131] cleaning up [skip ci] --- examples/2_Intermediate/boozerQA_ls_mpi.py | 12 ++++++------ src/simsopt/geo/boozersurface.py | 10 +--------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index b984b28c7..88404c521 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -139,12 +139,12 @@ def callback(x): outstr += f"{'nonQS ratio':{width}}" + ", ".join([f'{np.sqrt(nonqs.J()):.6e}' for nonqs in nonQSs]) + "\n" outstr += f"{'Boozer Residual':{width}}" + ", ".join([f'{br.J():.6e}' for br in brs]) + "\n" outstr += f"{'<ι>':{width}} {mean_iota.J():.6f} \n" - outstr += f"{'ι on surfaces':{width}}" + ", ".join([f"{boozer_surface.res['iota']:.6f}" for boozer_surface in boozer_surfaces]) + "\n" - outstr += f"{'major radius on surfaces':{width}}" + ', '.join([f'{surface.major_radius():.6f}' for surface in surfaces]) + "\n" - outstr += f"{'minor radius on surfaces':{width}}" + ', '.join([f'{surface.minor_radius():.6f}' for surface in surfaces]) + "\n" - outstr += f"{'aspect ratio radius on surfaces':{width}}" + ', '.join([f'{surface.aspect_ratio():.6f}' for surface in surfaces]) + "\n" - outstr += f"{'volume':{width}}" + ', '.join([f'{surface.volume():.6f}' for surface in surfaces]) + "\n" - outstr += f"{'surfaces are self-intersecting':{width}}" + ', '.join([f'{surface.is_self_intersecting()}' for surface in surfaces]) + "\n" + outstr += f"{'ι on surfaces':{width}}" + ", ".join([f"{boozer_surface.res['iota']:.6f}" for boozer_surface in mpi_boozer_surfaces]) + "\n" + outstr += f"{'major radius on surfaces':{width}}" + ', '.join([f'{surface.major_radius():.6f}' for surface in mpi_surfaces]) + "\n" + outstr += f"{'minor radius on surfaces':{width}}" + ', '.join([f'{surface.minor_radius():.6f}' for surface in mpi_surfaces]) + "\n" + outstr += f"{'aspect ratio radius on surfaces':{width}}" + ', '.join([f'{surface.aspect_ratio():.6f}' for surface in mpi_surfaces]) + "\n" + outstr += f"{'volume':{width}}" + ', '.join([f'{surface.volume():.6f}' for surface in mpi_surfaces]) + "\n" + outstr += f"{'surfaces are self-intersecting':{width}}" + ', '.join([f'{surface.is_self_intersecting()}' for surface in mpi_surfaces]) + "\n" outstr += f"{'shortest coil to coil distance':{width}} {Jccdist.shortest_distance():.3f} \n" outstr += f"{'coil lengths':{width}}" + ', '.join([f'{J.J():5.6f}' for J in ls]) + "\n" outstr += f"{'coil length sum':{width}} {sum(J.J() for J in ls):.3f} \n" diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 0f3126167..4278cc5f8 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -41,14 +41,13 @@ class BoozerSurface(Optimizable): where Newton is used to solve the first order necessary conditions for optimality. """ - def __init__(self, biotsavart, surface, label, targetlabel, constraint_weight=None, reg=None): + def __init__(self, biotsavart, surface, label, targetlabel, constraint_weight=None): super().__init__(depends_on=[biotsavart]) self.biotsavart = biotsavart self.surface = surface self.label = label self.targetlabel = targetlabel self.constraint_weight = constraint_weight - self.reg = reg self.need_to_run_code = True def recompute_bell(self, parent=None): @@ -683,9 +682,6 @@ def boozerls_penalty(self, dofs, derivatives=0, constraint_weight=1., optimize_G rz = np.sqrt(constraint_weight) * (s.gamma()[0, 0, 2] - 0.) r = rnl + 0.5*rl**2 + 0.5*rz**2 - if self.reg is not None: - r += self.reg.J() - if derivatives == 0: return r @@ -701,8 +697,6 @@ def boozerls_penalty(self, dofs, derivatives=0, constraint_weight=1., optimize_G drl = np.sqrt(constraint_weight) * dl drz = np.sqrt(constraint_weight) * drz J = Jnl + rl * drl + rz * drz - if self.reg is not None: - J[:nsurfdofs] += self.reg.dJ() if derivatives == 1: return r, J @@ -714,8 +708,6 @@ def boozerls_penalty(self, dofs, derivatives=0, constraint_weight=1., optimize_G d2rl = np.zeros((dofs.shape[0], dofs.shape[0])) d2rl[:nsurfdofs, :nsurfdofs] = np.sqrt(constraint_weight)*self.label.d2J_by_dsurfacecoefficientsdsurfacecoefficients() H = Hnl + drl[:, None] @ drl[None, :] + drz[:, None] @ drz[None, :] + rl * d2rl - if self.reg is not None: - H[:nsurfdofs, :nsurfdofs] += self.reg.d2J() return r, J, H From 63bfaf98ad2fce92de7bcd0d67d6b8165bd59082 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 5 Apr 2024 14:37:32 -0400 Subject: [PATCH 017/131] docstring [skip ci] --- examples/2_Intermediate/boozerQA_ls_mpi.py | 23 +++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index 88404c521..104f09764 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -25,12 +25,33 @@ def pprint(*args, **kwargs): size = 1 pprint = print +""" +This example optimizes the NCSX coils and currents for QA on potentially multiple surfaces using the BoozerLS approach. +For a single surface, the objective is: + + J = ( \int_S B_nonQA**2 dS )/(\int_S B_QA dS) + + 0.5*(iota - iota_0)**2 + + 0.5*(major_radius - target_major_radius)**2 + + 0.5*max(\sum_{coils} CurveLength - CurveLengthTarget, 0)**2 + +We first load a surface close to the magnetic axis, then optimize for QA on that surface. +The objective also includes penalty terms on the rotational transform, major radius, +and total coil length. The rotational transform and major radius penalty ensures that the surface's +rotational transform and aspect ratio do not stray too far from the value in the initial configuration. +There is also a penalty on the total coil length as a regularizer to prevent the coils from becoming +too complex. The BFGS optimizer is used, and quasisymmetry is improved substantially on the surface. +Surface solves using the BoozerLS approach can be costly, so this script supports distributing the solves +across multiple MPI ranks. + +More details on this work can be found at or doi:10.1063/5.0129716 arxiv:2210.03248. +""" + # Directory for output IN_DIR = "./inputs/input_ncsx/" OUT_DIR = "./output/" os.makedirs(OUT_DIR, exist_ok=True) -pprint("Running 2_Intermediate/boozerQA.py") +pprint("Running 2_Intermediate/boozerQA_ls_mpi.py") pprint("================================") base_curves, base_currents, coils, curves, surfaces, boozer_surfaces, ress = load(IN_DIR + f"ncsx_init.json") From 9cd851431a23bef6b1eb6da53b51f30f223b39ef Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Thu, 11 Apr 2024 15:44:21 -0400 Subject: [PATCH 018/131] cleaning up [skip ci] --- src/simsopt/geo/surfacexyztensorfourier.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/simsopt/geo/surfacexyztensorfourier.py b/src/simsopt/geo/surfacexyztensorfourier.py index 7f4eeac20..a6e2197aa 100644 --- a/src/simsopt/geo/surfacexyztensorfourier.py +++ b/src/simsopt/geo/surfacexyztensorfourier.py @@ -165,8 +165,4 @@ def npsame(a, b): if npsame(phis, np.linspace(0, 1/(2*self.nfp), ntor+1, endpoint=False)) and \ npsame(thetas, np.linspace(0, 1, 2*mpol+1, endpoint=False)): mask[0, mpol+1:] = False - if npsame(phis, np.linspace(0, 1/self.nfp, 2*ntor+1, endpoint=False)[:ntor+1]) and \ - npsame(thetas, np.linspace(0, 1, 2*mpol+1, endpoint=False)): - mask[0, mpol+1:] = False - return mask From bd9c09128bc171c3d9bb703fbc37c612bb7b8f71 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 15 Apr 2024 16:38:38 -0400 Subject: [PATCH 019/131] initial commit --- CMakeLists.txt | 1 + src/simsopt/geo/boozersurface.py | 235 +++++++++++++++- src/simsopt/geo/surfaceobjectives.py | 138 +++++++--- src/simsoptpp/boozerresidual.cpp | 382 +++++++++++++++++++++++++++ src/simsoptpp/boozerresidual.h | 11 + src/simsoptpp/python.cpp | 7 + tests/geo/test_boozersurface.py | 73 +++++ 7 files changed, 802 insertions(+), 45 deletions(-) create mode 100644 src/simsoptpp/boozerresidual.cpp create mode 100644 src/simsoptpp/boozerresidual.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e6e63ec9b..2d0a93f54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,6 +119,7 @@ set(XTENSOR_USE_TBB 0) pybind11_add_module(${PROJECT_NAME} src/simsoptpp/python.cpp src/simsoptpp/python_surfaces.cpp src/simsoptpp/python_curves.cpp + src/simsoptpp/boozerresidual.cpp src/simsoptpp/python_magneticfield.cpp src/simsoptpp/python_tracing.cpp src/simsoptpp/python_distance.cpp src/simsoptpp/biot_savart_py.cpp src/simsoptpp/biot_savart_vjp_py.cpp diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index e8d564e40..74ad2ac5a 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -2,6 +2,7 @@ from scipy.linalg import lu from scipy.optimize import minimize, least_squares +import simsoptpp as sopp from .surfaceobjectives import boozer_surface_residual from .._core.optimizable import Optimizable @@ -39,19 +40,42 @@ class BoozerSurface(Optimizable): where Newton is used to solve the first order necessary conditions for optimality. """ - - def __init__(self, biotsavart, surface, label, targetlabel): + + def __init__(self, biotsavart, surface, label, targetlabel, constraint_weight=None): super().__init__(depends_on=[biotsavart]) self.biotsavart = biotsavart self.surface = surface self.label = label self.targetlabel = targetlabel + self.constraint_weight = constraint_weight self.need_to_run_code = True def recompute_bell(self, parent=None): self.need_to_run_code = True + + def run_code(self, boozer_type, iota, G=None, verbose=True): + """ + Run the default solvers. + """ + if not self.need_to_run_code: + return + + if boozer_type == 'exact': + res = self.solve_residual_equation_exactly_newton(tol=1e-13, maxiter=40, iota=iota, G=G, verbose=verbose) + return res + elif boozer_type == 'ls': + # first try BFGS + res = self.minimize_boozer_penalty_constraints_BFGS(tol=1e-10, maxiter=1500, constraint_weight=self.constraint_weight, iota=iota, G=G, verbose=verbose) + iota, G = res['iota'], res['G'] + + ## polish off using Newton's method + self.need_to_run_code = True + res = self.minimize_boozer_penalty_constraints_newton(tol=1e-11, maxiter=40, constraint_weight=self.constraint_weight, iota=iota, G=G, verbose=verbose) + return res + else: + raise Exception(f"boozer_type not supported: {boozer_type}") - def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., scalarize=True, optimize_G=False): + def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., scalarize=True, optimize_G=False, weight_inv_modB=False): r""" Define the residual @@ -89,7 +113,7 @@ def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., sca s.set_dofs(sdofs) - boozer = boozer_surface_residual(s, iota, G, biotsavart, derivatives=derivatives) + boozer = boozer_surface_residual(s, iota, G, biotsavart, derivatives=derivatives, weight_inv_modB=weight_inv_modB) r = boozer[0] @@ -133,7 +157,7 @@ def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., sca d2l = np.zeros((x.shape[0], x.shape[0])) d2l[:nsurfdofs, :nsurfdofs] = self.label.d2J_by_dsurfacecoefficientsdsurfacecoefficients() - + H = np.concatenate(( H, np.sqrt(constraint_weight) * d2l[None, :, :], @@ -141,6 +165,99 @@ def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., sca d2val = J.T @ J + np.sum(r[:, None, None] * H, axis=0) return val, dval, d2val + def boozer_penalty_constraints_vectorized(self, dofs, derivatives=0, constraint_weight=1., optimize_G=False): + """ + This function returns the same thing as `boozer_penalty_constraints` when `scalarized=True` and `weight_inv_modB=True`. It + is much faster since it calls a vectorized implementation in cpp. + """ + + # this is essentially the scalarize option in previous implementation. This should be merged in that case... + assert derivatives in [0, 1, 2] + if optimize_G: + sdofs = dofs[:-2] + iota = dofs[-2] + G = dofs[-1] + else: + sdofs = dofs[:-1] + iota = dofs[-1] + G = 2. * np.pi * np.sum(np.abs([coil.current.get_value() for coil in self.biotsavart._coils])) * (4 * np.pi * 10**(-7) / (2 * np.pi)) + + s = self.surface + nphi = s.quadpoints_phi.size + ntheta = s.quadpoints_theta.size + nsurfdofs = sdofs.size + + s.set_dofs(sdofs) + + surface = self.surface + biotsavart = self.biotsavart + x = surface.gamma() + xphi = surface.gammadash1() + xtheta = surface.gammadash2() + nphi = x.shape[0] + ntheta = x.shape[1] + + xsemiflat = x.reshape((x.size//3, 3)).copy() + biotsavart.set_points(xsemiflat) + biotsavart.compute(derivatives) + B = biotsavart.B().reshape((nphi, ntheta, 3)) + + if derivatives >= 1: + dx_dc = surface.dgamma_by_dcoeff() + dxphi_dc = surface.dgammadash1_by_dcoeff() + dxtheta_dc = surface.dgammadash2_by_dcoeff() + dB_dx = biotsavart.dB_by_dX().reshape((nphi, ntheta, 3, 3)) + + if derivatives == 2: + d2B_by_dXdX = biotsavart.d2B_by_dXdX().reshape((nphi, ntheta, 3, 3, 3)) + + if derivatives == 0: + val = sopp.boozer_residual(G, iota, xphi, xtheta, B) + boozer = val, + elif derivatives == 1: + val, dval = sopp.boozer_residual_ds(G, iota, B, dB_dx, xphi, xtheta, dx_dc, dxphi_dc, dxtheta_dc) + boozer = val, dval + elif derivatives == 2: + val, dval, d2val = sopp.boozer_residual_ds2(G, iota, B, dB_dx, d2B_by_dXdX, xphi, xtheta, dx_dc, dxphi_dc, dxtheta_dc) + boozer = val, dval, d2val + + lab = self.label.J() + + rnl = boozer[0] + rl = np.sqrt(constraint_weight) * (lab-self.targetlabel) + rz = np.sqrt(constraint_weight) * (s.gamma()[0, 0, 2] - 0.) + r = rnl + 0.5*rl**2 + 0.5*rz**2 + + if derivatives == 0: + return r + + dl = np.zeros(dofs.shape) + drz = np.zeros(dofs.shape) + dl[:nsurfdofs] = self.label.dJ(partials=True)(s) + drz[:nsurfdofs] = s.dgamma_by_dcoeff()[0, 0, 2, :] + + Jnl = boozer[1] + if not optimize_G: + Jnl = Jnl[:-1] + + drl = np.sqrt(constraint_weight) * dl + drz = np.sqrt(constraint_weight) * drz + J = Jnl + rl * drl + rz * drz + + if derivatives == 1: + return r, J + + Hnl = boozer[2] + if not optimize_G: + Hnl = Hnl[:-1, :-1] + + d2rl = np.zeros((dofs.shape[0], dofs.shape[0])) + d2rl[:nsurfdofs, :nsurfdofs] = np.sqrt(constraint_weight)*self.label.d2J_by_dsurfacecoefficientsdsurfacecoefficients() + H = Hnl + drl[:, None] @ drl[None, :] + drz[:, None] @ drz[None, :] + rl * d2rl + + return r, J, H + + def boozer_exact_constraints(self, xl, derivatives=0, optimize_G=True): r""" This function returns the optimality conditions corresponding to the minimization problem @@ -252,6 +369,106 @@ def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, cons self.need_to_run_code = False return resdict + def minimize_boozer_penalty_constraints_BFGS(self, tol=1e-3, maxiter=1000, constraint_weight=1., iota=0., G=None, hessian=False, verbose=False): + r""" + """ + if not self.need_to_run_code: + return self.res + + s = self.surface + if G is None: + x = np.concatenate((s.get_dofs(), [iota])) + else: + x = np.concatenate((s.get_dofs(), [iota, G])) + + fun = lambda x: self.boozer_penalty_constraints_vectorized( + x, derivatives=1, constraint_weight=constraint_weight, optimize_G=G is not None) + res = minimize( + fun, x, jac=True, method='BFGS', + options={'maxiter': maxiter, 'gtol': tol}) + + resdict = { + "residual": res.fun, "gradient": res.jac, "iter": res.nit, "info": res, "success": res.success, "G": None, 'type': 'ls', 'solver': 'BFGS', + "firstorderop": res.jac, "constraint_weight": constraint_weight, "labelerr": np.abs((self.label.J()-self.targetlabel)/self.targetlabel) + } + + if G is None: + s.set_dofs(res.x[:-1]) + iota = res.x[-1] + else: + s.set_dofs(res.x[:-2]) + iota = res.x[-2] + G = res.x[-1] + resdict['G'] = G + resdict['s'] = s + resdict['iota'] = iota + + if hessian: + val, dval, d2val = self.boozer_penalty_constraints_vectorized( + x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) + P, L, U = lu(d2val) + resdict["PLU"] = (P, L, U) + + self.res = resdict + self.need_to_run_code = False + + if verbose: + print(f"BFGS solve - {resdict['success']} iter={resdict['iter']}, iota={resdict['iota']:.16f}, ||grad||_inf = {np.linalg.norm(resdict['firstorderop'], ord=np.inf):.3e}", flush=True) + return resdict + + def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, stab=0., verbose=False): + """ + """ + if not self.need_to_run_code: + return self.res + + s = self.surface + if G is None: + x = np.concatenate((s.get_dofs(), [iota])) + else: + x = np.concatenate((s.get_dofs(), [iota, G])) + i = 0 + + val, dval, d2val = self.boozer_penalty_constraints_vectorized( + x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) + norm = np.linalg.norm(dval, ord=np.inf) + + while i < maxiter and norm > tol: + d2val += stab*np.identity(d2val.shape[0]) + dx = np.linalg.solve(d2val, dval) + if norm < 1e-9: + dx += np.linalg.solve(d2val, dval - d2val@dx) + x = x - dx + val, dval, d2val = self.boozer_penalty_constraints_vectorized( + x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) + norm = np.linalg.norm(dval, ord=np.inf) + + if norm > 1e1: + break + + i = i+1 + + P, L, U = lu(d2val) + if G is None: + s.set_dofs(x[:-1]) + iota = x[-1] + else: + s.set_dofs(x[:-2]) + iota = x[-2] + G = x[-1] + + res = { + "residual": val, "jacobian": dval, "hessian": d2val, "iter": i, "success": norm <= tol, "firstorderop": dval, + "PLU": (P, L, U), 'iota': iota, "G": G, "type": "ls" + } + + self.res = res + self.need_to_run_code = False + + if verbose: + print(f"NEWTON solve - {res['success']} iter={res['iter']}, iota={res['iota']:.16f}, ||grad||_inf = {np.linalg.norm(res['firstorderop'], ord=np.inf):.3e}", flush=True) + return res + def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, stab=0.): """ This function does the same as :mod:`minimize_boozer_penalty_constraints_LBFGS`, but instead of LBFGS it uses @@ -445,7 +662,7 @@ def minimize_boozer_exact_constraints_newton(self, tol=1e-12, maxiter=10, iota=0 self.need_to_run_code = False return res - def solve_residual_equation_exactly_newton(self, tol=1e-10, maxiter=10, iota=0., G=None): + def solve_residual_equation_exactly_newton(self, tol=1e-10, maxiter=10, iota=0., G=None, verbose=False): """ This function solves the Boozer Surface residual equation exactly. For this to work, we need the right balance of quadrature points, degrees @@ -582,9 +799,13 @@ def solve_residual_equation_exactly_newton(self, tol=1e-10, maxiter=10, iota=0., P, L, U = lu(J) res = { - "residual": r, "jacobian": J, "iter": i, "success": norm <= tol, "G": G, "s": s, "iota": iota, "PLU": (P, L, U), + "residual": r, "jacobian": J, "iter": i, "success": norm <= tol, "G": G, "iota": iota, "PLU": (P, L, U), "mask": mask, 'type': 'exact' } + + if verbose: + print(f"NEWTON solve - {res['success']} iter={res['iter']}, iota={res['iota']:.16f}, ||residual||_inf = {np.linalg.norm(res['residual'], ord=np.inf):.3e}", flush=True) + self.res = res self.need_to_run_code = False return res diff --git a/src/simsopt/geo/surfaceobjectives.py b/src/simsopt/geo/surfaceobjectives.py index bfe3ebf21..bd3f73e76 100644 --- a/src/simsopt/geo/surfaceobjectives.py +++ b/src/simsopt/geo/surfaceobjectives.py @@ -287,21 +287,40 @@ def dJ(self): return Derivative({self.surface: deriv}) -def boozer_surface_residual(surface, iota, G, biotsavart, derivatives=0): +def boozer_surface_residual(surface, iota, G, biotsavart, derivatives=0, weight_inv_modB=False): r""" For a given surface, this function computes the residual .. math:: - G\mathbf B(\mathbf x) - \|\mathbf B(\mathbf x)\|^2 (\mathbf x_\varphi + \iota \mathbf x_\theta) + G\mathbf B_\text{BS}(\mathbf x) - ||\mathbf B_\text{BS}(\mathbf x)||^2 (\mathbf x_\varphi + \iota \mathbf x_\theta) as well as the derivatives of this residual with respect to surface dofs, iota, and G. In the above, :math:`\mathbf x` are points on the surface, :math:`\iota` is the - rotational transform on that surface, and :math:`\mathbf B` is the magnetic field. + rotational transform on that surface, and :math:`\mathbf B_{\text{BS}}` is the magnetic field + computed using the Biot-Savart law. :math:`G` is known for exact boozer surfaces, so if ``G=None`` is passed, then that value is used instead. + + Args: + surface: The surface to use for the computation + iota: the surface rotational transform + G: a constant that is a function of the coil currents in vacuum field + biotsavart: the Biot-Savart magnetic field + derivatives: how many spatial derivatives of the residual to compute + weight_inv_modB: whether or not to weight the residual by :math:`\|\mathbf B\|`. This + is useful to activate so that the residual does not scale with the + coil currents. + + Returns: + the residual at the surface quadrature points and optionally the spatial derivatives + of the residual. + + """ + + assert derivatives in [0, 1, 2] user_provided_G = G is not None if not user_provided_G: @@ -324,8 +343,15 @@ def boozer_surface_residual(surface, iota, G, biotsavart, derivatives=0): B2 = np.sum(B**2, axis=2) residual = G*B - B2[..., None] * tang - residual_flattened = residual.reshape((nphi*ntheta*3, )) - r = residual_flattened + if weight_inv_modB: + modB = np.sqrt(B2) + w = 1./modB + rtil = w[:, :, None] * residual + else: + rtil = residual.copy() + + rtil_flattened = rtil.reshape((nphi*ntheta*3, )) + r = rtil_flattened if derivatives == 0: return r, @@ -341,24 +367,41 @@ def boozer_surface_residual(surface, iota, G, biotsavart, derivatives=0): dresidual_dc = sopp.boozer_dresidual_dc(G, dB_dc, B, tang, B2, dxphi_dc, iota, dxtheta_dc) dresidual_diota = -B2[..., None] * xtheta - dresidual_dc_flattened = dresidual_dc.reshape((nphi*ntheta*3, nsurfdofs)) - dresidual_diota_flattened = dresidual_diota.reshape((nphi*ntheta*3, 1)) + if weight_inv_modB: + dB2_dc = 2*np.einsum('ijk,ijkl->ijl', B, dB_dc, optimize=True) + dmodB_dc = 0.5*dB2_dc/np.sqrt(B2[:, :, None]) + dw_dc = -dmodB_dc/modB[:, :, None]**2 + drtil_dc = residual[..., None] * dw_dc[:, :, None, :] + w[:, :, None, None] * dresidual_dc + drtil_diota = w[:, :, None] * dresidual_diota + else: + drtil_dc = dresidual_dc.copy() + drtil_diota = dresidual_diota.copy() + + drtil_dc_flattened = drtil_dc.reshape((nphi*ntheta*3, nsurfdofs)) + drtil_diota_flattened = drtil_diota.reshape((nphi*ntheta*3, 1)) if user_provided_G: dresidual_dG = B - dresidual_dG_flattened = dresidual_dG.reshape((nphi*ntheta*3, 1)) - J = np.concatenate((dresidual_dc_flattened, dresidual_diota_flattened, dresidual_dG_flattened), axis=1) + + if weight_inv_modB: + drtil_dG = w[:, :, None] * dresidual_dG + else: + drtil_dG = dresidual_dG.copy() + + drtil_dG_flattened = drtil_dG.reshape((nphi*ntheta*3, 1)) + J = np.concatenate((drtil_dc_flattened, drtil_diota_flattened, drtil_dG_flattened), axis=1) else: - J = np.concatenate((dresidual_dc_flattened, dresidual_diota_flattened), axis=1) + J = np.concatenate((drtil_dc_flattened, drtil_diota_flattened), axis=1) + if derivatives == 1: return r, J d2B_by_dXdX = biotsavart.d2B_by_dXdX().reshape((nphi, ntheta, 3, 3, 3)) - d2B_dcdc = np.einsum('ijkpl,ijpn,ijkm->ijlmn', d2B_by_dXdX, dx_dc, dx_dc) - dB2_dc = 2. * np.einsum('ijl,ijlm->ijm', B, dB_dc) + d2B_dcdc = np.einsum('ijkpl,ijpn,ijkm->ijlmn', d2B_by_dXdX, dx_dc, dx_dc, optimize=True) + dB2_dc = 2. * np.einsum('ijl,ijlm->ijm', B, dB_dc, optimize=True) - term1 = np.einsum('ijlm,ijln->ijmn', dB_dc, dB_dc) - term2 = np.einsum('ijlmn,ijl->ijmn', d2B_dcdc, B) + term1 = np.einsum('ijlm,ijln->ijmn', dB_dc, dB_dc, optimize=True) + term2 = np.einsum('ijlmn,ijl->ijmn', d2B_dcdc, B, optimize=True) d2B2_dcdc = 2*(term1 + term2) term1 = -(dxphi_dc[..., None, :] + iota * dxtheta_dc[..., None, :]) * dB2_dc[..., None, :, None] @@ -368,39 +411,58 @@ def boozer_surface_residual(surface, iota, G, biotsavart, derivatives=0): d2residual_by_dcdiota = -(dB2_dc[..., None, :] * xtheta[..., :, None] + B2[..., None, None] * dxtheta_dc) d2residual_by_diotadiota = np.zeros(dresidual_diota.shape) - d2residual_by_dcdc_flattened = d2residual_by_dcdc.reshape((nphi*ntheta*3, nsurfdofs, nsurfdofs)) - d2residual_by_dcdiota_flattened = d2residual_by_dcdiota.reshape((nphi*ntheta*3, nsurfdofs)) - d2residual_by_diotadiota_flattened = d2residual_by_diotadiota.reshape((nphi*ntheta*3,)) - + if weight_inv_modB: + d2B2_dcdc = 2*(np.einsum('ijlm,ijln->ijmn', dB_dc, dB_dc, optimize=True)+np.einsum('ijkpl,ijpn,ijkm,ijl->ijmn', d2B_by_dXdX, dx_dc, dx_dc, B, optimize=True)) + d2modB_dc2 = (2*B2[:, :, None, None] * d2B2_dcdc - dB2_dc[:, :, :, None]*dB2_dc[:, :, None, :])*(1/(4*B2[:, :, None, None]**1.5)) + d2w_dc2 = (2*dmodB_dc[:, :, :, None] * dmodB_dc[:, :, None, :] - modB[:, :, None, None] * d2modB_dc2)/modB[:, :, None, None]**3. + + d2rtil_dcdc = residual[..., None, None] * d2w_dc2[:, :, None, ...] \ + + dw_dc[:, :, None, :, None] * dresidual_dc[:, :, :, None, :] \ + + dw_dc[:, :, None, None, :] * dresidual_dc[:, :, :, :, None] \ + + w[:, :, None, None, None] * d2residual_by_dcdc + d2rtil_dcdiota = w[:, :, None, None] * d2residual_by_dcdiota + dw_dc[:, :, None, :] * dresidual_diota[..., None] + d2rtil_diotadiota = np.zeros(dresidual_diota.shape) + else: + d2rtil_dcdc = d2residual_by_dcdc.copy() + d2rtil_dcdiota = d2residual_by_dcdiota.copy() + d2rtil_diotadiota = d2residual_by_diotadiota.copy() + + d2rtil_dcdc_flattened = d2rtil_dcdc.reshape((nphi*ntheta*3, nsurfdofs, nsurfdofs)) + d2rtil_dcdiota_flattened = d2rtil_dcdiota.reshape((nphi*ntheta*3, nsurfdofs)) + d2rtil_diotadiota_flattened = d2rtil_diotadiota.reshape((nphi*ntheta*3,)) + if user_provided_G: d2residual_by_dcdG = dB_dc - d2residual_by_diotadG = np.zeros(dresidual_diota.shape) - d2residual_by_dGdG = np.zeros(dresidual_dG.shape) - d2residual_by_dcdG_flattened = d2residual_by_dcdG.reshape((nphi*ntheta*3, nsurfdofs)) - d2residual_by_diotadG_flattened = d2residual_by_diotadG.reshape((nphi*ntheta*3,)) - d2residual_by_dGdG_flattened = d2residual_by_dGdG.reshape((nphi*ntheta*3,)) + if weight_inv_modB: + d2rtil_dcdG = dw_dc[:, :, None, :] * dresidual_dG[..., None] + w[:, :, None, None] * d2residual_by_dcdG + else: + d2rtil_dcdG = d2residual_by_dcdG.copy() + + d2rtil_dGdG = np.zeros(dresidual_dG.shape) + d2rtil_dcdG_flattened = d2rtil_dcdG.reshape((nphi*ntheta*3, nsurfdofs)) + d2rtil_diotadG_flattened = np.zeros((nphi*ntheta*3,)) + d2rtil_dGdG_flattened = d2rtil_dGdG.reshape((nphi*ntheta*3,)) + H = np.zeros((nphi*ntheta*3, nsurfdofs + 2, nsurfdofs + 2)) # noqa turns out linting so that we can align everything neatly - H[:, :nsurfdofs, :nsurfdofs] = d2residual_by_dcdc_flattened # noqa (0, 0) dcdc - H[:, :nsurfdofs, nsurfdofs] = d2residual_by_dcdiota_flattened # noqa (0, 1) dcdiota - H[:, :nsurfdofs, nsurfdofs+1] = d2residual_by_dcdG_flattened # noqa (0, 2) dcdG - H[:, nsurfdofs, :nsurfdofs] = d2residual_by_dcdiota_flattened # noqa (1, 0) diotadc - H[:, nsurfdofs, nsurfdofs] = d2residual_by_diotadiota_flattened # noqa (1, 1) diotadiota - H[:, nsurfdofs, nsurfdofs+1] = d2residual_by_diotadiota_flattened # noqa (1, 2) diotadG - H[:, nsurfdofs+1, :nsurfdofs] = d2residual_by_dcdG_flattened # noqa (2, 0) dGdc - H[:, nsurfdofs+1, nsurfdofs] = d2residual_by_diotadG_flattened # noqa (2, 1) dGdiota - H[:, nsurfdofs+1, nsurfdofs+1] = d2residual_by_dGdG_flattened # noqa (2, 2) dGdG + H[:, :nsurfdofs, :nsurfdofs] = d2rtil_dcdc_flattened # noqa (0, 0) dcdc + H[:, :nsurfdofs, nsurfdofs] = d2rtil_dcdiota_flattened # noqa (0, 1) dcdiota + H[:, :nsurfdofs, nsurfdofs+1] = d2rtil_dcdG_flattened # noqa (0, 2) dcdG + H[:, nsurfdofs, :nsurfdofs] = d2rtil_dcdiota_flattened # noqa (1, 0) diotadc + H[:, nsurfdofs, nsurfdofs] = d2rtil_diotadiota_flattened # noqa (1, 1) diotadiota + H[:, nsurfdofs, nsurfdofs+1] = d2rtil_diotadiota_flattened # noqa (1, 2) diotadG + H[:, nsurfdofs+1, :nsurfdofs] = d2rtil_dcdG_flattened # noqa (2, 0) dGdc + H[:, nsurfdofs+1, nsurfdofs] = d2rtil_diotadG_flattened # noqa (2, 1) dGdiota + H[:, nsurfdofs+1, nsurfdofs+1] = d2rtil_dGdG_flattened # noqa (2, 2) dGdG else: H = np.zeros((nphi*ntheta*3, nsurfdofs + 1, nsurfdofs + 1)) - - H[:, :nsurfdofs, :nsurfdofs] = d2residual_by_dcdc_flattened # noqa (0, 0) dcdc - H[:, :nsurfdofs, nsurfdofs] = d2residual_by_dcdiota_flattened # noqa (0, 1) dcdiota - H[:, nsurfdofs, :nsurfdofs] = d2residual_by_dcdiota_flattened # noqa (1, 0) diotadc - H[:, nsurfdofs, nsurfdofs] = d2residual_by_diotadiota_flattened # noqa (1, 1) diotadiota + H[:, :nsurfdofs, :nsurfdofs] = d2rtil_dcdc_flattened # noqa (0, 0) dcdc + H[:, :nsurfdofs, nsurfdofs] = d2rtil_dcdiota_flattened # noqa (0, 1) dcdiota + H[:, nsurfdofs, :nsurfdofs] = d2rtil_dcdiota_flattened # noqa (1, 0) diotadc + H[:, nsurfdofs, nsurfdofs] = d2rtil_diotadiota_flattened # noqa (1, 1) diotadiota return r, J, H - def parameter_derivatives(surface: Surface, shape_gradient: NDArray[Any, Float] ) -> NDArray[Any, Float]: diff --git a/src/simsoptpp/boozerresidual.cpp b/src/simsoptpp/boozerresidual.cpp new file mode 100644 index 000000000..340cdfd65 --- /dev/null +++ b/src/simsoptpp/boozerresidual.cpp @@ -0,0 +1,382 @@ +#include "boozerresidual.h" + +#include "xsimd/xsimd.hpp" +#include "simdhelpers.h" +#include "vec3dsimd.h" +#include "xtensor/xarray.hpp" +#include +#include "xtensor/xadapt.hpp" + +#if __cplusplus >= 201703L +#define MYIF(c) if constexpr(c) +#else +#define MYIF(c) if(c) +#endif + +#if defined(USE_XSIMD) +template void boozer_residual_impl(double G, double iota, T& B, T& dB_dx, T& d2B_dx2, T& xphi, T& xtheta, T& dx_ds, T& dxphi_ds, T& dxtheta_ds, double& res, T& dres, T& d2res, size_t ndofs){ + int nphi = xphi.shape(0); + int ntheta = xtheta.shape(1); + int num_points = 3 * nphi * ntheta; + + constexpr size_t simd_size = xsimd::simd_type::size; + auto dx_ds_ij0 = AlignedPaddedVec(ndofs, 0); + auto dx_ds_ij1 = AlignedPaddedVec(ndofs, 0); + auto dx_ds_ij2 = AlignedPaddedVec(ndofs, 0); + auto dxphi_ds_ij0 = AlignedPaddedVec(ndofs, 0); + auto dxphi_ds_ij1 = AlignedPaddedVec(ndofs, 0); + auto dxphi_ds_ij2 = AlignedPaddedVec(ndofs, 0); + auto dxtheta_ds_ij0 = AlignedPaddedVec(ndofs, 0); + auto dxtheta_ds_ij1 = AlignedPaddedVec(ndofs, 0); + auto dxtheta_ds_ij2 = AlignedPaddedVec(ndofs, 0); + + auto drtilij0 = AlignedPaddedVec(ndofs+2, 0); + auto drtilij1 = AlignedPaddedVec(ndofs+2, 0); + auto drtilij2 = AlignedPaddedVec(ndofs+2, 0); + + auto dresij0 = AlignedPaddedVec(ndofs+2, 0); + auto dresij1 = AlignedPaddedVec(ndofs+2, 0); + auto dresij2 = AlignedPaddedVec(ndofs+2, 0); + + auto dw_ij = AlignedPaddedVec(ndofs+2, 0); + + auto dtang_ij0 = AlignedPaddedVec(ndofs+2, 0); + auto dtang_ij1 = AlignedPaddedVec(ndofs+2, 0); + auto dtang_ij2 = AlignedPaddedVec(ndofs+2, 0); + + auto dB2_ij = AlignedPaddedVec(ndofs+2, 0); + auto dBij0 = AlignedPaddedVec(ndofs+2, 0); + auto dBij1 = AlignedPaddedVec(ndofs+2, 0); + auto dBij2 = AlignedPaddedVec(ndofs+2, 0); + auto dmodB_ij = AlignedPaddedVec(ndofs+2, 0); + + simd_t it(iota); + simd_t GG(G); + + for(int i=0; i0){ + simd_t Bij0(B(i, j, 0)); + simd_t Bij1(B(i, j, 1)); + simd_t Bij2(B(i, j, 2)); + + simd_t dB_dxij00(dB_dx(i, j, 0, 0)); + simd_t dB_dxij10(dB_dx(i, j, 1, 0)); + simd_t dB_dxij20(dB_dx(i, j, 2, 0)); + simd_t dB_dxij01(dB_dx(i, j, 0, 1)); + simd_t dB_dxij11(dB_dx(i, j, 1, 1)); + simd_t dB_dxij21(dB_dx(i, j, 2, 1)); + simd_t dB_dxij02(dB_dx(i, j, 0, 2)); + simd_t dB_dxij12(dB_dx(i, j, 1, 2)); + simd_t dB_dxij22(dB_dx(i, j, 2, 2)); + + simd_t bw_ij(wij); + simd_t btang_ij0(tang_ij0); + simd_t btang_ij1(tang_ij1); + simd_t btang_ij2(tang_ij2); + + simd_t brtil_ij0(rtil_ij0); + simd_t brtil_ij1(rtil_ij1); + simd_t brtil_ij2(rtil_ij2); + + for (int m = 0; m < ndofs; ++m) { + dx_ds_ij0[m] = dx_ds(i,j,0,m); + dx_ds_ij1[m] = dx_ds(i,j,1,m); + dx_ds_ij2[m] = dx_ds(i,j,2,m); + + dxphi_ds_ij0[m] = dxphi_ds(i,j,0,m); + dxphi_ds_ij1[m] = dxphi_ds(i,j,1,m); + dxphi_ds_ij2[m] = dxphi_ds(i,j,2,m); + + dxtheta_ds_ij0[m] = dxtheta_ds(i,j,0,m); + dxtheta_ds_ij1[m] = dxtheta_ds(i,j,1,m); + dxtheta_ds_ij2[m] = dxtheta_ds(i,j,2,m); + + } + + for (int m = 0; m < ndofs; m+=simd_size) { + simd_t dx_ds_ij0m = xs::load_aligned(&dx_ds_ij0[m]); + simd_t dx_ds_ij1m = xs::load_aligned(&dx_ds_ij1[m]); + simd_t dx_ds_ij2m = xs::load_aligned(&dx_ds_ij2[m]); + + simd_t dxphi_ds_ij0m = xs::load_aligned(&dxphi_ds_ij0[m]); + simd_t dxphi_ds_ij1m = xs::load_aligned(&dxphi_ds_ij1[m]); + simd_t dxphi_ds_ij2m = xs::load_aligned(&dxphi_ds_ij2[m]); + + simd_t dxtheta_ds_ij0m = xs::load_aligned(&dxtheta_ds_ij0[m]); + simd_t dxtheta_ds_ij1m = xs::load_aligned(&dxtheta_ds_ij1[m]); + simd_t dxtheta_ds_ij2m = xs::load_aligned(&dxtheta_ds_ij2[m]); + + auto dBij0m = xsimd::fma(dB_dxij00,dx_ds_ij0m,xsimd::fma(dB_dxij10,dx_ds_ij1m,dB_dxij20*dx_ds_ij2m)); + auto dBij1m = xsimd::fma(dB_dxij01,dx_ds_ij0m,xsimd::fma(dB_dxij11,dx_ds_ij1m,dB_dxij21*dx_ds_ij2m)); + auto dBij2m = xsimd::fma(dB_dxij02,dx_ds_ij0m,xsimd::fma(dB_dxij12,dx_ds_ij1m,dB_dxij22*dx_ds_ij2m)); + + auto dB2_ijm = 2*(Bij0 * dBij0m + Bij1 * dBij1m + Bij2 * dBij2m); + auto tang_ij0m = xsimd::fma(it, dxtheta_ds_ij0m , dxphi_ds_ij0m); + auto tang_ij1m = xsimd::fma(it, dxtheta_ds_ij1m , dxphi_ds_ij1m); + auto tang_ij2m = xsimd::fma(it, dxtheta_ds_ij2m , dxphi_ds_ij2m); + + auto dresij0m = xsimd::fms(GG , dBij0m , xsimd::fma(dB2_ijm , btang_ij0 , B2ij * tang_ij0m)); + auto dresij1m = xsimd::fms(GG , dBij1m , xsimd::fma(dB2_ijm , btang_ij1 , B2ij * tang_ij1m)); + auto dresij2m = xsimd::fms(GG , dBij2m , xsimd::fma(dB2_ijm , btang_ij2 , B2ij * tang_ij2m)); + + auto dmodB_ijm = 0.5 * dB2_ijm * wij; + auto dw_ijm = -dmodB_ijm * rB2ij; + auto drtil_ij0m = xsimd::fma(dresij0m , bw_ij , dw_ijm * resij0); + auto drtil_ij1m = xsimd::fma(dresij1m , bw_ij , dw_ijm * resij1); + auto drtil_ij2m = xsimd::fma(dresij2m , bw_ij , dw_ijm * resij2); + + // sum_k (r_k grad r_k) + auto dresm = xsimd::fma(brtil_ij0, drtil_ij0m, xsimd::fma(brtil_ij1, drtil_ij1m , brtil_ij2 * drtil_ij2m)); + + int jjlimit = std::min(simd_size, ndofs-m); + for(int jj = 0; jj < jjlimit; jj++){ + dres(m+jj) += dresm[jj]; + + drtilij0[m+jj] = drtil_ij0m[jj]; + drtilij1[m+jj] = drtil_ij1m[jj]; + drtilij2[m+jj] = drtil_ij2m[jj]; + + dB2_ij[m+jj] = dB2_ijm[jj]; + dtang_ij0[m+jj] = tang_ij0m[jj]; + dtang_ij1[m+jj] = tang_ij1m[jj]; + dtang_ij2[m+jj] = tang_ij2m[jj]; + dresij0[m+jj] = dresij0m[jj]; + dresij1[m+jj] = dresij1m[jj]; + dresij2[m+jj] = dresij2m[jj]; + + dBij0[m+jj] = dBij0m[jj]; + dBij1[m+jj] = dBij1m[jj]; + dBij2[m+jj] = dBij2m[jj]; + + dw_ij[m+jj] = dw_ijm[jj]; + + dmodB_ij[m+jj] = dmodB_ijm[jj]; + } + } + + double dres_ij0iota = -B2ij * xtheta(i, j, 0); + double dres_ij1iota = -B2ij * xtheta(i, j, 1); + double dres_ij2iota = -B2ij * xtheta(i, j, 2); + + double drtil_ij0iota = dres_ij0iota * wij; + double drtil_ij1iota = dres_ij1iota * wij; + double drtil_ij2iota = dres_ij2iota * wij; + dres(ndofs + 0) += rtil_ij0 * drtil_ij0iota + rtil_ij1 * drtil_ij1iota + rtil_ij2 * drtil_ij2iota; + + drtilij0[ndofs + 0] = drtil_ij0iota; + drtilij1[ndofs + 0] = drtil_ij1iota; + drtilij2[ndofs + 0] = drtil_ij2iota; + + + double dres_ij0_dG = B(i, j, 0); + double dres_ij1_dG = B(i, j, 1); + double dres_ij2_dG = B(i, j, 2); + + double drtil_ij0_dG = wij * dres_ij0_dG; + double drtil_ij1_dG = wij * dres_ij1_dG; + double drtil_ij2_dG = wij * dres_ij2_dG; + dres(ndofs + 1) += rtil_ij0 * drtil_ij0_dG + rtil_ij1 * drtil_ij1_dG + rtil_ij2 * drtil_ij2_dG; + + drtilij0[ndofs + 1] = drtil_ij0_dG; + drtilij1[ndofs + 1] = drtil_ij1_dG; + drtilij2[ndofs + 1] = drtil_ij2_dG; + + MYIF(deriv > 1) { + // outer product d_rij0_dm (x) d_rij0_dm + for(int m = 0; m < ndofs + 2; m++){ + simd_t drtilij0_dm(drtilij0[m]); + simd_t drtilij1_dm(drtilij1[m]); + simd_t drtilij2_dm(drtilij2[m]); + for(int n = m; n < ndofs + 2; n+=simd_size){ + simd_t drtilij0_dn = xs::load_aligned(&drtilij0[n]); + simd_t drtilij1_dn = xs::load_aligned(&drtilij1[n]); + simd_t drtilij2_dn = xs::load_aligned(&drtilij2[n]); + simd_t d2res_mn = drtilij0_dm * drtilij0_dn + drtilij1_dm * drtilij1_dn + drtilij2_dm * drtilij2_dn; + + int jjlimit = std::min(simd_size, ndofs+2-n); + for(int jj = 0; jj < jjlimit; jj++){ + d2res(m, n+jj) += d2res_mn[jj]; + } + } + } + + // rij * d2rij_dmn + for(int m = 0; m < ndofs; m+=simd_size){ + simd_t dx_ds_ij0m = xsimd::load_aligned(&dx_ds_ij0[m]); + simd_t dx_ds_ij1m = xsimd::load_aligned(&dx_ds_ij1[m]); + simd_t dx_ds_ij2m = xsimd::load_aligned(&dx_ds_ij2[m]); + + simd_t dxphi_ds_ij0m = xsimd::load_aligned(&dxphi_ds_ij0[m]); + simd_t dxphi_ds_ij1m = xsimd::load_aligned(&dxphi_ds_ij1[m]); + simd_t dxphi_ds_ij2m = xsimd::load_aligned(&dxphi_ds_ij2[m]); + + simd_t dxtheta_ds_ij0m = xsimd::load_aligned(&dxtheta_ds_ij0[m]); + simd_t dxtheta_ds_ij1m = xsimd::load_aligned(&dxtheta_ds_ij1[m]); + simd_t dxtheta_ds_ij2m = xsimd::load_aligned(&dxtheta_ds_ij2[m]); + + simd_t dBij0m = xsimd::load_aligned(&dBij0[m]); + simd_t dBij1m = xsimd::load_aligned(&dBij1[m]); + simd_t dBij2m = xsimd::load_aligned(&dBij2[m]); + + simd_t dB2_ijm = xsimd::load_aligned(&dB2_ij[m]); + simd_t dmodB_ijm = xsimd::load_aligned(&dmodB_ij[m]); + simd_t dw_ijm = xsimd::load_aligned(&dw_ij[m]); + + simd_t dresij0m = xsimd::load_aligned(&dresij0[m]); + simd_t dresij1m = xsimd::load_aligned(&dresij1[m]); + simd_t dresij2m = xsimd::load_aligned(&dresij2[m]); + + simd_t dtang_ij0m = xsimd::load_aligned(&dtang_ij0[m]); + simd_t dtang_ij1m = xsimd::load_aligned(&dtang_ij1[m]); + simd_t dtang_ij2m = xsimd::load_aligned(&dtang_ij2[m]); + + for(int n = m; n < ndofs; n++){ + simd_t d2Bij0_mn(0.); + simd_t d2Bij1_mn(0.); + simd_t d2Bij2_mn(0.); + for(int l = 0; l < 3; l++){ + simd_t dx_ds_ijln(dx_ds(i, j, l, n)); + + d2Bij0_mn = d2B_dx2(i, j, 0, l, 0) * dx_ds_ij0m * dx_ds_ijln+ d2Bij0_mn; + d2Bij1_mn = d2B_dx2(i, j, 0, l, 1) * dx_ds_ij0m * dx_ds_ijln+ d2Bij1_mn; + d2Bij2_mn = d2B_dx2(i, j, 0, l, 2) * dx_ds_ij0m * dx_ds_ijln+ d2Bij2_mn; + d2Bij0_mn = d2B_dx2(i, j, 1, l, 0) * dx_ds_ij1m * dx_ds_ijln+ d2Bij0_mn; + d2Bij1_mn = d2B_dx2(i, j, 1, l, 1) * dx_ds_ij1m * dx_ds_ijln+ d2Bij1_mn; + d2Bij2_mn = d2B_dx2(i, j, 1, l, 2) * dx_ds_ij1m * dx_ds_ijln+ d2Bij2_mn; + d2Bij0_mn = d2B_dx2(i, j, 2, l, 0) * dx_ds_ij2m * dx_ds_ijln+ d2Bij0_mn; + d2Bij1_mn = d2B_dx2(i, j, 2, l, 1) * dx_ds_ij2m * dx_ds_ijln+ d2Bij1_mn; + d2Bij2_mn = d2B_dx2(i, j, 2, l, 2) * dx_ds_ij2m * dx_ds_ijln+ d2Bij2_mn; + } + + auto d2B2_ijmn = 2*(dBij0m*dBij0[n] + dBij1m*dBij1[n] + dBij2m*dBij2[n]+ B(i,j,0) * d2Bij0_mn + B(i,j,1) * d2Bij1_mn + B(i,j,2) * d2Bij2_mn); + auto term1_0 = -dtang_ij0[n] * dB2_ijm; + auto term1_1 = -dtang_ij1[n] * dB2_ijm; + auto term1_2 = -dtang_ij2[n] * dB2_ijm; + + auto term2_0 = -dtang_ij0m * dB2_ij[n]; + auto term2_1 = -dtang_ij1m * dB2_ij[n]; + auto term2_2 = -dtang_ij2m * dB2_ij[n]; + + auto term3_0 = -tang_ij0 * d2B2_ijmn; + auto term3_1 = -tang_ij1 * d2B2_ijmn; + auto term3_2 = -tang_ij2 * d2B2_ijmn; + + auto d2res_ij0mn = xsimd::fma(GG , d2Bij0_mn , term1_0) + term2_0 + term3_0; + auto d2res_ij1mn = xsimd::fma(GG , d2Bij1_mn , term1_1) + term2_1 + term3_1; + auto d2res_ij2mn = xsimd::fma(GG , d2Bij2_mn , term1_2) + term2_2 + term3_2; + + auto d2modB_ijmn = (2 * B2ij * d2B2_ijmn - dB2_ijm*dB2_ij[n]) * powrmodBijthree / 4. ; + auto d2wij_mn = (2. * dmodB_ijm * dmodB_ij[n] - modB_ij * d2modB_ijmn) * powrmodBijthree; + + auto d2rtil_0mn = dresij0m *dw_ij[n] + dresij0[n] * dw_ijm + d2res_ij0mn * wij + resij0 * d2wij_mn; + auto d2rtil_1mn = dresij1m *dw_ij[n] + dresij1[n] * dw_ijm + d2res_ij1mn * wij + resij1 * d2wij_mn; + auto d2rtil_2mn = dresij2m *dw_ij[n] + dresij2[n] * dw_ijm + d2res_ij2mn * wij + resij2 * d2wij_mn; + + auto d2res_mn = rtil_ij0 * d2rtil_0mn + rtil_ij1 * d2rtil_1mn +rtil_ij2 * d2rtil_2mn; + + int jjlimit = std::min(simd_size, ndofs-m); + for(int jj = 0; jj < jjlimit; jj++){ + d2res(m+jj, n) += d2res_mn[jj]; + } + } + auto d2res_ij0miota = -(dB2_ijm * xtheta(i, j, 0) + B2ij * dxtheta_ds_ij0m); + auto d2res_ij1miota = -(dB2_ijm * xtheta(i, j, 1) + B2ij * dxtheta_ds_ij1m); + auto d2res_ij2miota = -(dB2_ijm * xtheta(i, j, 2) + B2ij * dxtheta_ds_ij2m); + + + auto d2rtil_ij0miota = d2res_ij0miota * wij + dres_ij0iota * dw_ijm ; + auto d2rtil_ij1miota = d2res_ij1miota * wij + dres_ij1iota * dw_ijm ; + auto d2rtil_ij2miota = d2res_ij2miota * wij + dres_ij2iota * dw_ijm ; + auto d2res_miota = rtil_ij0*d2rtil_ij0miota+rtil_ij1*d2rtil_ij1miota+rtil_ij2*d2rtil_ij2miota; + + int jjlimit = std::min(simd_size, ndofs-m); + for(int jj = 0; jj < jjlimit; jj++){ + d2res(m+jj, ndofs) += d2res_miota[jj]; + } + + auto d2res_ij0mG = dBij0m; + auto d2res_ij1mG = dBij1m; + auto d2res_ij2mG = dBij2m; + + auto d2rtil_ij0mG = d2res_ij0mG * wij + dres_ij0_dG * dw_ijm; + auto d2rtil_ij1mG = d2res_ij1mG * wij + dres_ij1_dG * dw_ijm; + auto d2rtil_ij2mG = d2res_ij2mG * wij + dres_ij2_dG * dw_ijm; + auto d2res_mG = rtil_ij0*d2rtil_ij0mG+rtil_ij1*d2rtil_ij1mG+rtil_ij2*d2rtil_ij2mG; + + for(int jj = 0; jj < jjlimit; jj++){ + d2res(m+jj, ndofs+1) += d2res_mG[jj]; + } + + } + } + } + } + } + + res/=num_points; + dres/=num_points; + d2res/=num_points; + + // symmetrize the Hessian + for(int m = 0; m < ndofs+2; m++){ + for(int n = m+1; n < ndofs+2; n++){ + d2res(n, m) = d2res(m, n); + } + } +} + +#else +#endif + +double boozer_residual(double G, double iota, Array& xphi, Array& xtheta, Array& B){ + double res = 0.; + Array dummy = xt::zeros({1}); + boozer_residual_impl(G, iota, B, dummy, dummy, xphi, xtheta, dummy, dummy, dummy, res, dummy, dummy, 0); + return res; +} + +std::tuple boozer_residual_ds(double G, double iota, Array& B, Array& dB_dx, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds){ + size_t ndofs = dx_ds.shape(3); + + double res = 0.; + Array dres = xt::zeros({ndofs+2}); + Array dummy = xt::zeros({1}); + boozer_residual_impl(G, iota, B, dB_dx, dummy, xphi, xtheta, dx_ds, dxphi_ds, dxtheta_ds, res, dres, dummy, ndofs); + auto tup = std::make_tuple(res, dres); + return tup; +} + +std::tuple boozer_residual_ds2(double G, double iota, Array& B, Array& dB_dx, Array& d2B_dx2, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds){ + size_t ndofs = dx_ds.shape(3); + + double res = 0.; + Array dres = xt::zeros({ndofs+2}); + Array d2res = xt::zeros({ndofs+2, ndofs+2}); + boozer_residual_impl(G, iota, B, dB_dx, d2B_dx2, xphi, xtheta, dx_ds, dxphi_ds, dxtheta_ds, res, dres, d2res, ndofs); + auto tup = std::make_tuple(res, dres, d2res); + return tup; +} + diff --git a/src/simsoptpp/boozerresidual.h b/src/simsoptpp/boozerresidual.h new file mode 100644 index 000000000..a30558c46 --- /dev/null +++ b/src/simsoptpp/boozerresidual.h @@ -0,0 +1,11 @@ +#pragma once + +#include "xtensor/xarray.hpp" +#include "xtensor/xmath.hpp" +#include "xtensor-python/pyarray.hpp" // Numpy bindings +typedef xt::pyarray Array; +using std::vector; + +double boozer_residual(double G, double iota, Array& xphi, Array& xtheta, Array& B); +std::tuple boozer_residual_ds(double G, double iota, Array& B, Array& dB_dx, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds); +std::tuple boozer_residual_ds2(double G, double iota, Array& B, Array& dB_dx, Array& d2B_dx2, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds); diff --git a/src/simsoptpp/python.cpp b/src/simsoptpp/python.cpp index 83a1c93f2..f965ec567 100644 --- a/src/simsoptpp/python.cpp +++ b/src/simsoptpp/python.cpp @@ -12,6 +12,8 @@ typedef xt::pytensor PyTensor; #include + + #include "biot_savart_py.h" #include "biot_savart_vjp_py.h" #include "boozerradialinterpolant.h" @@ -21,6 +23,7 @@ typedef xt::pytensor PyTensor; #include "permanent_magnet_optimization.h" #include "reiman.h" #include "simdhelpers.h" +#include "boozerresidual.h" namespace py = pybind11; @@ -123,6 +126,10 @@ PYBIND11_MODULE(simsoptpp, m) { return res; }); + m.def("boozer_residual", &boozer_residual); + m.def("boozer_residual_ds", &boozer_residual_ds); + m.def("boozer_residual_ds2", &boozer_residual_ds2); + m.def("matmult", [](PyArray& A, PyArray&B) { // Product of an lxm matrix with an mxn matrix, results in an l x n matrix int l = A.shape(0); diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 06ae8aeff..8b82fbd9b 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -349,6 +349,79 @@ def subtest_boozer_serialization(self, label): # check that BoozerSurface.surface and label.surface are the same surfaces assert bs_regen.label.surface is bs_regen.surface + def test_boozer_penalty_constraints_cpp_notcpp(self): + """ + Test to verify cpp and python implementations of the BoozerLS objective return the same thing. + """ + for surfacetype in surfacetypes_list: + for stellsym in stellsym_list: + for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 10, 17), (False, 13, 21)]: + with self.subTest(surfacetype=surfacetype, + stellsym=stellsym, + optimize_G=optimize_G): + self.subtest_boozer_penalty_constraints_cpp_notcpp(surfacetype, stellsym, optimize_G, nphi, ntheta) + + def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, optimize_G, nphi, ntheta): + + np.random.seed(1) + curves, currents, ma = get_ncsx_data() + coils = coils_via_symmetries(curves, currents, 3, stellsym) + bs = BiotSavart(coils) + bs_tf = BiotSavart(coils) + current_sum = sum(abs(c.current.get_value()) for c in coils) + + s = get_surface(surfacetype, stellsym, nphi=nphi, ntheta=ntheta) + s.fit_to_curve(ma, 0.1) + s.x = s.x + np.random.rand(s.x.size)*1e-6 + + tf = ToroidalFlux(s, bs_tf, nphi=51, ntheta=51) + + tf_target = 0.1 + boozer_surface = BoozerSurface(bs, s, tf, tf_target) + + iota = -0.3 + x = np.concatenate((s.get_dofs(), [iota])) + if optimize_G: + x = np.concatenate( + (x, [2.*np.pi*current_sum*(4*np.pi*10**(-7)/(2 * np.pi))])) + + w = 1e2 + f0, J0, H0 = boozer_surface.boozer_penalty_constraints( + x, derivatives=2, constraint_weight=w, optimize_G=optimize_G, weight_inv_modB=True) + f1, J1, H1 = boozer_surface.boozer_penalty_constraints_vectorized( + x, derivatives=2, constraint_weight=w, optimize_G=optimize_G) + + # f1, and J1 scale the quadratic residual terms by 1/(number of residuals), while f0 and J0 do not. + # rescale below so that both quantities are comparable. + diff1 = (boozer_surface.label.J() - boozer_surface.targetlabel) + diff2 = s.gamma()[0, 0, 2] + f1 -= 0.5 * w * (diff1**2 + diff2**2) + f1 *= (3 * len(s.quadpoints_phi)*len(s.quadpoints_theta)) + f1 += 0.5 * w * (diff1**2 + diff2**2) + + to_add = [0] + if optimize_G: + to_add = [0, 0] + + dl = np.append(boozer_surface.label.dJ(partials=True)(s), to_add) + drz = np.append(s.dgamma_by_dcoeff()[0, 0, 2, :], to_add) + J1 -= w * (diff1 * dl + diff2 * drz) + J1 *= (3*len(s.quadpoints_phi)*len(s.quadpoints_theta)) + J1 += w * (diff1 * dl + diff2 * drz) + + nsurfdofs = s.x.size + d2l = np.zeros((x.size, x.size)) + d2l[:nsurfdofs, :nsurfdofs] = boozer_surface.label.d2J_by_dsurfacecoefficientsdsurfacecoefficients() + H1 -= w * dl[:, None] * dl[None, :] + w * diff1 * d2l + H1 -= w * drz[:, None] * drz[None, :] + H1 *= (3*len(s.quadpoints_phi)*len(s.quadpoints_theta)) + H1 += w * dl[:, None] * dl[None, :] + w * diff1 * d2l + H1 += w * drz[:, None] * drz[None, :] + + self.assertAlmostEqual(f0, f1) + np.testing.assert_allclose(J0, J1) + norm = np.max(np.abs(H0)) + assert np.all(np.abs((H0-H1)/norm) < 1e-13) if __name__ == "__main__": unittest.main() From 290dab1dcd43ad03e781abbb05a939f7f3447062 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 15 Apr 2024 18:32:57 -0400 Subject: [PATCH 020/131] cleaning up unit tests --- src/simsopt/geo/boozersurface.py | 19 +++++-- src/simsoptpp/boozerresidual.cpp | 23 ++++----- src/simsoptpp/boozerresidual.h | 6 +-- tests/geo/test_boozersurface.py | 85 +++++++++++++++----------------- 4 files changed, 66 insertions(+), 67 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 74ad2ac5a..81fdc6635 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -165,9 +165,9 @@ def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., sca d2val = J.T @ J + np.sum(r[:, None, None] * H, axis=0) return val, dval, d2val - def boozer_penalty_constraints_vectorized(self, dofs, derivatives=0, constraint_weight=1., optimize_G=False): + def boozer_penalty_constraints_vectorized(self, dofs, derivatives=0, constraint_weight=1., optimize_G=False, weight_inv_modB=False): """ - This function returns the same thing as `boozer_penalty_constraints` when `scalarized=True` and `weight_inv_modB=True`. It + This function returns the same thing as `boozer_penalty_constraints` when `scalarized=True`. It is much faster since it calls a vectorized implementation in cpp. """ @@ -212,13 +212,13 @@ def boozer_penalty_constraints_vectorized(self, dofs, derivatives=0, constraint_ d2B_by_dXdX = biotsavart.d2B_by_dXdX().reshape((nphi, ntheta, 3, 3, 3)) if derivatives == 0: - val = sopp.boozer_residual(G, iota, xphi, xtheta, B) + val = sopp.boozer_residual(G, iota, xphi, xtheta, B, weight_inv_modB) boozer = val, elif derivatives == 1: - val, dval = sopp.boozer_residual_ds(G, iota, B, dB_dx, xphi, xtheta, dx_dc, dxphi_dc, dxtheta_dc) + val, dval = sopp.boozer_residual_ds(G, iota, B, dB_dx, xphi, xtheta, dx_dc, dxphi_dc, dxtheta_dc, weight_inv_modB) boozer = val, dval elif derivatives == 2: - val, dval, d2val = sopp.boozer_residual_ds2(G, iota, B, dB_dx, d2B_by_dXdX, xphi, xtheta, dx_dc, dxphi_dc, dxtheta_dc) + val, dval, d2val = sopp.boozer_residual_ds2(G, iota, B, dB_dx, d2B_by_dXdX, xphi, xtheta, dx_dc, dxphi_dc, dxtheta_dc, weight_inv_modB) boozer = val, dval, d2val lab = self.label.J() @@ -371,6 +371,15 @@ def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, cons def minimize_boozer_penalty_constraints_BFGS(self, tol=1e-3, maxiter=1000, constraint_weight=1., iota=0., G=None, hessian=False, verbose=False): r""" + This function tries to find the surface that approximately solves + + .. math:: + \text{min}_x ~J(x) + \frac{1}{2} w_c (l - l_0)^2 + + \frac{1}{2} w_c (z(\varphi=0, \theta=0) - 0)^2 + + where :math:`J(x) = \frac{1}{2}\mathbf r(x)^T \mathbf r(x)`, and :math:`\mathbf r(x)` contains + the Boozer residuals at quadrature points :math:`1,\dots,n`. + This is done using BFGS. """ if not self.need_to_run_code: return self.res diff --git a/src/simsoptpp/boozerresidual.cpp b/src/simsoptpp/boozerresidual.cpp index 340cdfd65..c64f32a34 100644 --- a/src/simsoptpp/boozerresidual.cpp +++ b/src/simsoptpp/boozerresidual.cpp @@ -14,7 +14,7 @@ #endif #if defined(USE_XSIMD) -template void boozer_residual_impl(double G, double iota, T& B, T& dB_dx, T& d2B_dx2, T& xphi, T& xtheta, T& dx_ds, T& dxphi_ds, T& dxtheta_ds, double& res, T& dres, T& d2res, size_t ndofs){ +template void boozer_residual_impl(double G, double iota, T& B, T& dB_dx, T& d2B_dx2, T& xphi, T& xtheta, T& dx_ds, T& dxphi_ds, T& dxtheta_ds, double& res, T& dres, T& d2res, size_t ndofs, bool weight_inv_modB){ int nphi = xphi.shape(0); int ntheta = xtheta.shape(1); int num_points = 3 * nphi * ntheta; @@ -57,7 +57,7 @@ template void boozer_residual_impl(double G, double iota, T& for(int j=0; j void boozer_residual_impl(double G, double iota, T& auto dresij2m = xsimd::fms(GG , dBij2m , xsimd::fma(dB2_ijm , btang_ij2 , B2ij * tang_ij2m)); auto dmodB_ijm = 0.5 * dB2_ijm * wij; - auto dw_ijm = -dmodB_ijm * rB2ij; + auto dw_ijm = weight_inv_modB ? -dmodB_ijm * rB2ij : simd_t(0.); auto drtil_ij0m = xsimd::fma(dresij0m , bw_ij , dw_ijm * resij0); auto drtil_ij1m = xsimd::fma(dresij1m , bw_ij , dw_ijm * resij1); auto drtil_ij2m = xsimd::fma(dresij2m , bw_ij , dw_ijm * resij2); @@ -289,7 +289,7 @@ template void boozer_residual_impl(double G, double iota, T& auto d2res_ij2mn = xsimd::fma(GG , d2Bij2_mn , term1_2) + term2_2 + term3_2; auto d2modB_ijmn = (2 * B2ij * d2B2_ijmn - dB2_ijm*dB2_ij[n]) * powrmodBijthree / 4. ; - auto d2wij_mn = (2. * dmodB_ijm * dmodB_ij[n] - modB_ij * d2modB_ijmn) * powrmodBijthree; + auto d2wij_mn = weight_inv_modB ? (2. * dmodB_ijm * dmodB_ij[n] - modB_ij * d2modB_ijmn) * powrmodBijthree : simd_t(0.); auto d2rtil_0mn = dresij0m *dw_ij[n] + dresij0[n] * dw_ijm + d2res_ij0mn * wij + resij0 * d2wij_mn; auto d2rtil_1mn = dresij1m *dw_ij[n] + dresij1[n] * dw_ijm + d2res_ij1mn * wij + resij1 * d2wij_mn; @@ -336,9 +336,6 @@ template void boozer_residual_impl(double G, double iota, T& } } - res/=num_points; - dres/=num_points; - d2res/=num_points; // symmetrize the Hessian for(int m = 0; m < ndofs+2; m++){ @@ -351,31 +348,31 @@ template void boozer_residual_impl(double G, double iota, T& #else #endif -double boozer_residual(double G, double iota, Array& xphi, Array& xtheta, Array& B){ +double boozer_residual(double G, double iota, Array& xphi, Array& xtheta, Array& B, bool weight_inv_modB){ double res = 0.; Array dummy = xt::zeros({1}); - boozer_residual_impl(G, iota, B, dummy, dummy, xphi, xtheta, dummy, dummy, dummy, res, dummy, dummy, 0); + boozer_residual_impl(G, iota, B, dummy, dummy, xphi, xtheta, dummy, dummy, dummy, res, dummy, dummy, 0, weight_inv_modB); return res; } -std::tuple boozer_residual_ds(double G, double iota, Array& B, Array& dB_dx, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds){ +std::tuple boozer_residual_ds(double G, double iota, Array& B, Array& dB_dx, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds, bool weight_inv_modB){ size_t ndofs = dx_ds.shape(3); double res = 0.; Array dres = xt::zeros({ndofs+2}); Array dummy = xt::zeros({1}); - boozer_residual_impl(G, iota, B, dB_dx, dummy, xphi, xtheta, dx_ds, dxphi_ds, dxtheta_ds, res, dres, dummy, ndofs); + boozer_residual_impl(G, iota, B, dB_dx, dummy, xphi, xtheta, dx_ds, dxphi_ds, dxtheta_ds, res, dres, dummy, ndofs, weight_inv_modB); auto tup = std::make_tuple(res, dres); return tup; } -std::tuple boozer_residual_ds2(double G, double iota, Array& B, Array& dB_dx, Array& d2B_dx2, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds){ +std::tuple boozer_residual_ds2(double G, double iota, Array& B, Array& dB_dx, Array& d2B_dx2, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds, bool weight_inv_modB){ size_t ndofs = dx_ds.shape(3); double res = 0.; Array dres = xt::zeros({ndofs+2}); Array d2res = xt::zeros({ndofs+2, ndofs+2}); - boozer_residual_impl(G, iota, B, dB_dx, d2B_dx2, xphi, xtheta, dx_ds, dxphi_ds, dxtheta_ds, res, dres, d2res, ndofs); + boozer_residual_impl(G, iota, B, dB_dx, d2B_dx2, xphi, xtheta, dx_ds, dxphi_ds, dxtheta_ds, res, dres, d2res, ndofs, weight_inv_modB); auto tup = std::make_tuple(res, dres, d2res); return tup; } diff --git a/src/simsoptpp/boozerresidual.h b/src/simsoptpp/boozerresidual.h index a30558c46..2c11650a4 100644 --- a/src/simsoptpp/boozerresidual.h +++ b/src/simsoptpp/boozerresidual.h @@ -6,6 +6,6 @@ typedef xt::pyarray Array; using std::vector; -double boozer_residual(double G, double iota, Array& xphi, Array& xtheta, Array& B); -std::tuple boozer_residual_ds(double G, double iota, Array& B, Array& dB_dx, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds); -std::tuple boozer_residual_ds2(double G, double iota, Array& B, Array& dB_dx, Array& d2B_dx2, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds); +double boozer_residual(double G, double iota, Array& xphi, Array& xtheta, Array& B, bool weight_inv_modB); +std::tuple boozer_residual_ds(double G, double iota, Array& B, Array& dB_dx, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds, bool weight_inv_modB); +std::tuple boozer_residual_ds2(double G, double iota, Array& B, Array& dB_dx, Array& d2B_dx2, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds, bool weight_inv_modB); diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 8b82fbd9b..e897f48e6 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -355,13 +355,15 @@ def test_boozer_penalty_constraints_cpp_notcpp(self): """ for surfacetype in surfacetypes_list: for stellsym in stellsym_list: - for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 10, 17), (False, 13, 21)]: - with self.subTest(surfacetype=surfacetype, - stellsym=stellsym, - optimize_G=optimize_G): - self.subtest_boozer_penalty_constraints_cpp_notcpp(surfacetype, stellsym, optimize_G, nphi, ntheta) + for weight_inv_modB in [False, True]: + for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 2, 2), (False, 2, 1), (True, 10, 17), (False, 13, 21),(True, 3, 3), (False, 3, 3)]: + with self.subTest(surfacetype=surfacetype, + stellsym=stellsym, + optimize_G=optimize_G, + weight_inv_modB=weight_inv_modB): + self.subtest_boozer_penalty_constraints_cpp_notcpp(surfacetype, stellsym, optimize_G, nphi, ntheta, weight_inv_modB) - def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, optimize_G, nphi, ntheta): + def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, optimize_G, nphi, ntheta, weight_inv_modB): np.random.seed(1) curves, currents, ma = get_ncsx_data() @@ -369,59 +371,50 @@ def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, o bs = BiotSavart(coils) bs_tf = BiotSavart(coils) current_sum = sum(abs(c.current.get_value()) for c in coils) - - s = get_surface(surfacetype, stellsym, nphi=nphi, ntheta=ntheta) + + phis = None + thetas = None + if nphi == 1: + phis = [0.2234567989] + elif nphi == 2: + phis = [0.2234567989, 0.432123451] + + if ntheta == 1: + thetas = [0.2432101234] + elif ntheta == 2: + thetas = [0.2432101234, 0.9832134] + + + s = get_surface(surfacetype, stellsym, nphi=nphi, ntheta=ntheta, thetas=thetas, phis=phis) s.fit_to_curve(ma, 0.1) s.x = s.x + np.random.rand(s.x.size)*1e-6 tf = ToroidalFlux(s, bs_tf, nphi=51, ntheta=51) - + tf_target = 0.1 boozer_surface = BoozerSurface(bs, s, tf, tf_target) iota = -0.3 x = np.concatenate((s.get_dofs(), [iota])) if optimize_G: - x = np.concatenate( - (x, [2.*np.pi*current_sum*(4*np.pi*10**(-7)/(2 * np.pi))])) + x = np.concatenate((x, [2.*np.pi*current_sum*(4*np.pi*10**(-7)/(2 * np.pi))])) - w = 1e2 + w = 0. f0, J0, H0 = boozer_surface.boozer_penalty_constraints( - x, derivatives=2, constraint_weight=w, optimize_G=optimize_G, weight_inv_modB=True) + x, derivatives=2, constraint_weight=w, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) f1, J1, H1 = boozer_surface.boozer_penalty_constraints_vectorized( - x, derivatives=2, constraint_weight=w, optimize_G=optimize_G) - - # f1, and J1 scale the quadratic residual terms by 1/(number of residuals), while f0 and J0 do not. - # rescale below so that both quantities are comparable. - diff1 = (boozer_surface.label.J() - boozer_surface.targetlabel) - diff2 = s.gamma()[0, 0, 2] - f1 -= 0.5 * w * (diff1**2 + diff2**2) - f1 *= (3 * len(s.quadpoints_phi)*len(s.quadpoints_theta)) - f1 += 0.5 * w * (diff1**2 + diff2**2) - - to_add = [0] - if optimize_G: - to_add = [0, 0] - - dl = np.append(boozer_surface.label.dJ(partials=True)(s), to_add) - drz = np.append(s.dgamma_by_dcoeff()[0, 0, 2, :], to_add) - J1 -= w * (diff1 * dl + diff2 * drz) - J1 *= (3*len(s.quadpoints_phi)*len(s.quadpoints_theta)) - J1 += w * (diff1 * dl + diff2 * drz) - - nsurfdofs = s.x.size - d2l = np.zeros((x.size, x.size)) - d2l[:nsurfdofs, :nsurfdofs] = boozer_surface.label.d2J_by_dsurfacecoefficientsdsurfacecoefficients() - H1 -= w * dl[:, None] * dl[None, :] + w * diff1 * d2l - H1 -= w * drz[:, None] * drz[None, :] - H1 *= (3*len(s.quadpoints_phi)*len(s.quadpoints_theta)) - H1 += w * dl[:, None] * dl[None, :] + w * diff1 * d2l - H1 += w * drz[:, None] * drz[None, :] - - self.assertAlmostEqual(f0, f1) - np.testing.assert_allclose(J0, J1) - norm = np.max(np.abs(H0)) - assert np.all(np.abs((H0-H1)/norm) < 1e-13) + x, derivatives=2, constraint_weight=w, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) + + np.testing.assert_allclose(f0, f1, atol=1e-13, rtol=1e-13) + np.testing.assert_allclose(J0, J1, atol=1e-11, rtol=1e-11) + np.testing.assert_allclose(H0, H1, atol=1e-10, rtol=1e-10) + + h1 = np.random.rand(J0.size)-0.5 + h2 = np.random.rand(J0.size)-0.5 + np.testing.assert_allclose(f0, f1, atol=1e-13, rtol=1e-13) + np.testing.assert_allclose(J0@h1, J1@h1, atol=1e-13, rtol=1e-13) + np.testing.assert_allclose((H0@h1)@h2, (H1@h1)@h2, atol=1e-13, rtol=1e-13) + print(np.abs(f0-f1)/np.abs(f0), np.abs(J0@h1-J1@h1)/np.abs(J0@h1), np.abs((H0@h1)@h2-(H1@h1)@h2)/np.abs((H0@h1)@h2)) if __name__ == "__main__": unittest.main() From fd33c3d46f74f0ef7c735f9bf73669111ea92f01 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 15 Apr 2024 22:07:42 -0400 Subject: [PATCH 021/131] added non-xsimd implementation --- src/simsoptpp/boozerresidual.cpp | 242 +++++++++++++++++++++++++++++-- tests/geo/test_boozersurface.py | 11 +- 2 files changed, 234 insertions(+), 19 deletions(-) diff --git a/src/simsoptpp/boozerresidual.cpp b/src/simsoptpp/boozerresidual.cpp index c64f32a34..3da78ee52 100644 --- a/src/simsoptpp/boozerresidual.cpp +++ b/src/simsoptpp/boozerresidual.cpp @@ -13,6 +13,7 @@ #define MYIF(c) if(c) #endif +//#if false #if defined(USE_XSIMD) template void boozer_residual_impl(double G, double iota, T& B, T& dB_dx, T& d2B_dx2, T& xphi, T& xtheta, T& dx_ds, T& dxphi_ds, T& dxtheta_ds, double& res, T& dres, T& d2res, size_t ndofs, bool weight_inv_modB){ int nphi = xphi.shape(0); @@ -260,15 +261,15 @@ template void boozer_residual_impl(double G, double iota, T& for(int l = 0; l < 3; l++){ simd_t dx_ds_ijln(dx_ds(i, j, l, n)); - d2Bij0_mn = d2B_dx2(i, j, 0, l, 0) * dx_ds_ij0m * dx_ds_ijln+ d2Bij0_mn; - d2Bij1_mn = d2B_dx2(i, j, 0, l, 1) * dx_ds_ij0m * dx_ds_ijln+ d2Bij1_mn; - d2Bij2_mn = d2B_dx2(i, j, 0, l, 2) * dx_ds_ij0m * dx_ds_ijln+ d2Bij2_mn; - d2Bij0_mn = d2B_dx2(i, j, 1, l, 0) * dx_ds_ij1m * dx_ds_ijln+ d2Bij0_mn; - d2Bij1_mn = d2B_dx2(i, j, 1, l, 1) * dx_ds_ij1m * dx_ds_ijln+ d2Bij1_mn; - d2Bij2_mn = d2B_dx2(i, j, 1, l, 2) * dx_ds_ij1m * dx_ds_ijln+ d2Bij2_mn; - d2Bij0_mn = d2B_dx2(i, j, 2, l, 0) * dx_ds_ij2m * dx_ds_ijln+ d2Bij0_mn; - d2Bij1_mn = d2B_dx2(i, j, 2, l, 1) * dx_ds_ij2m * dx_ds_ijln+ d2Bij1_mn; - d2Bij2_mn = d2B_dx2(i, j, 2, l, 2) * dx_ds_ij2m * dx_ds_ijln+ d2Bij2_mn; + d2Bij0_mn += d2B_dx2(i, j, 0, l, 0) * dx_ds_ij0m * dx_ds_ijln; + d2Bij1_mn += d2B_dx2(i, j, 0, l, 1) * dx_ds_ij0m * dx_ds_ijln; + d2Bij2_mn += d2B_dx2(i, j, 0, l, 2) * dx_ds_ij0m * dx_ds_ijln; + d2Bij0_mn += d2B_dx2(i, j, 1, l, 0) * dx_ds_ij1m * dx_ds_ijln; + d2Bij1_mn += d2B_dx2(i, j, 1, l, 1) * dx_ds_ij1m * dx_ds_ijln; + d2Bij2_mn += d2B_dx2(i, j, 1, l, 2) * dx_ds_ij1m * dx_ds_ijln; + d2Bij0_mn += d2B_dx2(i, j, 2, l, 0) * dx_ds_ij2m * dx_ds_ijln; + d2Bij1_mn += d2B_dx2(i, j, 2, l, 1) * dx_ds_ij2m * dx_ds_ijln; + d2Bij2_mn += d2B_dx2(i, j, 2, l, 2) * dx_ds_ij2m * dx_ds_ijln; } auto d2B2_ijmn = 2*(dBij0m*dBij0[n] + dBij1m*dBij1[n] + dBij2m*dBij2[n]+ B(i,j,0) * d2Bij0_mn + B(i,j,1) * d2Bij1_mn + B(i,j,2) * d2Bij2_mn); @@ -336,16 +337,229 @@ template void boozer_residual_impl(double G, double iota, T& } } - - // symmetrize the Hessian - for(int m = 0; m < ndofs+2; m++){ - for(int n = m+1; n < ndofs+2; n++){ - d2res(n, m) = d2res(m, n); + MYIF(deriv > 1){ + // symmetrize the Hessian + for(int m = 0; m < ndofs+2; m++){ + for(int n = m+1; n < ndofs+2; n++){ + d2res(n, m) = d2res(m, n); + } } } } #else +template void boozer_residual_impl(double G, double iota, T& B, T& dB_dx, T& d2B_dx2, T& xphi, T& xtheta, T& dx_ds, T& dxphi_ds, T& dxtheta_ds, double& res, T& dres, T& d2res, size_t ndofs, bool weight_inv_modB){ + int nphi = xphi.shape(0); + int ntheta = xtheta.shape(1); + + for(int i=0; i0){ + auto drtilij0 = AlignedPaddedVec(ndofs+2, 0); + auto drtilij1 = AlignedPaddedVec(ndofs+2, 0); + auto drtilij2 = AlignedPaddedVec(ndofs+2, 0); + + auto dresij0 = AlignedPaddedVec(ndofs+2, 0); + auto dresij1 = AlignedPaddedVec(ndofs+2, 0); + auto dresij2 = AlignedPaddedVec(ndofs+2, 0); + + auto dw_ij = AlignedPaddedVec(ndofs+2, 0); + + auto dtang_ij0 = AlignedPaddedVec(ndofs+2, 0); + auto dtang_ij1 = AlignedPaddedVec(ndofs+2, 0); + auto dtang_ij2 = AlignedPaddedVec(ndofs+2, 0); + + auto dB2_ij = AlignedPaddedVec(ndofs+2, 0); + auto dBij0 = AlignedPaddedVec(ndofs+2, 0); + auto dBij1 = AlignedPaddedVec(ndofs+2, 0); + auto dBij2 = AlignedPaddedVec(ndofs+2, 0); + auto dmodB_ij = AlignedPaddedVec(ndofs+2, 0); + + for (int m = 0; m < ndofs; m++) { + double dBij0m = dB_dx(i,j,0,0)*dx_ds(i,j,0,m)+dB_dx(i,j,1,0)*dx_ds(i,j,1,m)+dB_dx(i,j,2,0)*dx_ds(i,j,2,m); + double dBij1m = dB_dx(i,j,0,1)*dx_ds(i,j,0,m)+dB_dx(i,j,1,1)*dx_ds(i,j,1,m)+dB_dx(i,j,2,1)*dx_ds(i,j,2,m); + double dBij2m = dB_dx(i,j,0,2)*dx_ds(i,j,0,m)+dB_dx(i,j,1,2)*dx_ds(i,j,1,m)+dB_dx(i,j,2,2)*dx_ds(i,j,2,m); + + double dB2_ijm = 2*(B(i,j,0) * dBij0m + B(i,j,1) * dBij1m + B(i,j,2) * dBij2m); + double tang_ij0m = iota*dxtheta_ds(i,j,0,m) + dxphi_ds(i,j,0,m); + double tang_ij1m = iota*dxtheta_ds(i,j,1,m) + dxphi_ds(i,j,1,m); + double tang_ij2m = iota*dxtheta_ds(i,j,2,m) + dxphi_ds(i,j,2,m); + + double dresij0m = G * dBij0m - (dB2_ijm * tang_ij0 + B2ij * tang_ij0m); + double dresij1m = G * dBij1m - (dB2_ijm * tang_ij1 + B2ij * tang_ij1m); + double dresij2m = G * dBij2m - (dB2_ijm * tang_ij2 + B2ij * tang_ij2m); + + double dmodB_ijm = 0.5 * dB2_ijm * wij; + double dw_ijm = weight_inv_modB ? -dmodB_ijm * rB2ij : 0.; + double drtil_ij0m = dresij0m * wij + dw_ijm * resij0; + double drtil_ij1m = dresij1m * wij + dw_ijm * resij1; + double drtil_ij2m = dresij2m * wij + dw_ijm * resij2; + + // sum_k (r_k grad r_k) + dres(m) += rtil_ij0 * drtil_ij0m + rtil_ij1 * drtil_ij1m + rtil_ij2 * drtil_ij2m; + + drtilij0[m] = drtil_ij0m; + drtilij1[m] = drtil_ij1m; + drtilij2[m] = drtil_ij2m; + + dB2_ij[m] = dB2_ijm; + dtang_ij0[m] = tang_ij0m; + dtang_ij1[m] = tang_ij1m; + dtang_ij2[m] = tang_ij2m; + dresij0[m] = dresij0m; + dresij1[m] = dresij1m; + dresij2[m] = dresij2m; + + dBij0[m] = dBij0m; + dBij1[m] = dBij1m; + dBij2[m] = dBij2m; + + dw_ij[m] = dw_ijm; + + dmodB_ij[m] = dmodB_ijm; + } + + double dres_ij0iota = -B2ij * xtheta(i, j, 0); + double dres_ij1iota = -B2ij * xtheta(i, j, 1); + double dres_ij2iota = -B2ij * xtheta(i, j, 2); + + double drtil_ij0iota = dres_ij0iota * wij; + double drtil_ij1iota = dres_ij1iota * wij; + double drtil_ij2iota = dres_ij2iota * wij; + dres(ndofs + 0) += rtil_ij0 * drtil_ij0iota + rtil_ij1 * drtil_ij1iota + rtil_ij2 * drtil_ij2iota; + + drtilij0[ndofs + 0] = drtil_ij0iota; + drtilij1[ndofs + 0] = drtil_ij1iota; + drtilij2[ndofs + 0] = drtil_ij2iota; + + + double dres_ij0_dG = B(i, j, 0); + double dres_ij1_dG = B(i, j, 1); + double dres_ij2_dG = B(i, j, 2); + + double drtil_ij0_dG = wij * dres_ij0_dG; + double drtil_ij1_dG = wij * dres_ij1_dG; + double drtil_ij2_dG = wij * dres_ij2_dG; + dres(ndofs + 1) += rtil_ij0 * drtil_ij0_dG + rtil_ij1 * drtil_ij1_dG + rtil_ij2 * drtil_ij2_dG; + + drtilij0[ndofs + 1] = drtil_ij0_dG; + drtilij1[ndofs + 1] = drtil_ij1_dG; + drtilij2[ndofs + 1] = drtil_ij2_dG; + MYIF(deriv > 1) { + // outer product d_rij0_dm (x) d_rij0_dm + for(int m = 0; m < ndofs + 2; m++){ + for(int n = m; n < ndofs + 2; n++){ + d2res(m, n) += drtilij0[m] * drtilij0[n] + drtilij1[m] * drtilij1[n] + drtilij2[m] * drtilij2[n]; + } + } + + // rij * d2rij_dmn + for(int m = 0; m < ndofs; m++){ + for(int n = m; n < ndofs; n++){ + double d2Bij0_mn = 0.; + double d2Bij1_mn = 0.; + double d2Bij2_mn = 0.; + for(int l = 0; l < 3; l++){ + d2Bij0_mn += d2B_dx2(i, j, 0, l, 0) * dx_ds(i,j,0,m) * dx_ds(i, j, l, n); + d2Bij1_mn += d2B_dx2(i, j, 0, l, 1) * dx_ds(i,j,0,m) * dx_ds(i, j, l, n); + d2Bij2_mn += d2B_dx2(i, j, 0, l, 2) * dx_ds(i,j,0,m) * dx_ds(i, j, l, n); + d2Bij0_mn += d2B_dx2(i, j, 1, l, 0) * dx_ds(i,j,1,m) * dx_ds(i, j, l, n); + d2Bij1_mn += d2B_dx2(i, j, 1, l, 1) * dx_ds(i,j,1,m) * dx_ds(i, j, l, n); + d2Bij2_mn += d2B_dx2(i, j, 1, l, 2) * dx_ds(i,j,1,m) * dx_ds(i, j, l, n); + d2Bij0_mn += d2B_dx2(i, j, 2, l, 0) * dx_ds(i,j,2,m) * dx_ds(i, j, l, n); + d2Bij1_mn += d2B_dx2(i, j, 2, l, 1) * dx_ds(i,j,2,m) * dx_ds(i, j, l, n); + d2Bij2_mn += d2B_dx2(i, j, 2, l, 2) * dx_ds(i,j,2,m) * dx_ds(i, j, l, n); + } + + auto d2B2_ijmn = 2*(dBij0[m]*dBij0[n] + dBij1[m]*dBij1[n] + dBij2[m]*dBij2[n]+ B(i,j,0) * d2Bij0_mn + B(i,j,1) * d2Bij1_mn + B(i,j,2) * d2Bij2_mn); + auto term1_0 = -dtang_ij0[n] * dB2_ij[m]; + auto term1_1 = -dtang_ij1[n] * dB2_ij[m]; + auto term1_2 = -dtang_ij2[n] * dB2_ij[m]; + + auto term2_0 = -dtang_ij0[m] * dB2_ij[n]; + auto term2_1 = -dtang_ij1[m] * dB2_ij[n]; + auto term2_2 = -dtang_ij2[m] * dB2_ij[n]; + + auto term3_0 = -tang_ij0 * d2B2_ijmn; + auto term3_1 = -tang_ij1 * d2B2_ijmn; + auto term3_2 = -tang_ij2 * d2B2_ijmn; + + auto d2res_ij0mn = G * d2Bij0_mn + term1_0 + term2_0 + term3_0; + auto d2res_ij1mn = G * d2Bij1_mn + term1_1 + term2_1 + term3_1; + auto d2res_ij2mn = G * d2Bij2_mn + term1_2 + term2_2 + term3_2; + + auto d2modB_ijmn = (2 * B2ij * d2B2_ijmn - dB2_ij[m]*dB2_ij[n]) * powrmodBijthree / 4. ; + auto d2wij_mn = weight_inv_modB ? (2. * dmodB_ij[m] * dmodB_ij[n] - modB_ij * d2modB_ijmn) * powrmodBijthree : 0.; + + auto d2rtil_0mn = dresij0[m] *dw_ij[n] + dresij0[n] * dw_ij[m] + d2res_ij0mn * wij + resij0 * d2wij_mn; + auto d2rtil_1mn = dresij1[m] *dw_ij[n] + dresij1[n] * dw_ij[m] + d2res_ij1mn * wij + resij1 * d2wij_mn; + auto d2rtil_2mn = dresij2[m] *dw_ij[n] + dresij2[n] * dw_ij[m] + d2res_ij2mn * wij + resij2 * d2wij_mn; + + auto d2res_mn = rtil_ij0 * d2rtil_0mn + rtil_ij1 * d2rtil_1mn +rtil_ij2 * d2rtil_2mn; + + d2res(m, n) += d2res_mn; + } + auto d2res_ij0miota = -(dB2_ij[m] * xtheta(i, j, 0) + B2ij * dxtheta_ds(i,j,0,m)); + auto d2res_ij1miota = -(dB2_ij[m] * xtheta(i, j, 1) + B2ij * dxtheta_ds(i,j,1,m)); + auto d2res_ij2miota = -(dB2_ij[m] * xtheta(i, j, 2) + B2ij * dxtheta_ds(i,j,2,m)); + + + auto d2rtil_ij0miota = d2res_ij0miota * wij + dres_ij0iota * dw_ij[m] ; + auto d2rtil_ij1miota = d2res_ij1miota * wij + dres_ij1iota * dw_ij[m] ; + auto d2rtil_ij2miota = d2res_ij2miota * wij + dres_ij2iota * dw_ij[m] ; + auto d2res_miota = rtil_ij0*d2rtil_ij0miota+rtil_ij1*d2rtil_ij1miota+rtil_ij2*d2rtil_ij2miota; + + d2res(m, ndofs) += d2res_miota; + + auto d2res_ij0mG = dBij0[m]; + auto d2res_ij1mG = dBij1[m]; + auto d2res_ij2mG = dBij2[m]; + + auto d2rtil_ij0mG = d2res_ij0mG * wij + dres_ij0_dG * dw_ij[m]; + auto d2rtil_ij1mG = d2res_ij1mG * wij + dres_ij1_dG * dw_ij[m]; + auto d2rtil_ij2mG = d2res_ij2mG * wij + dres_ij2_dG * dw_ij[m]; + auto d2res_mG = rtil_ij0*d2rtil_ij0mG+rtil_ij1*d2rtil_ij1mG+rtil_ij2*d2rtil_ij2mG; + + d2res(m, ndofs+1) += d2res_mG; + + } + } + } + } + } + + MYIF(deriv > 1){ + // symmetrize the Hessian + for(int m = 0; m < ndofs+2; m++){ + for(int n = m+1; n < ndofs+2; n++){ + d2res(n, m) = d2res(m, n); + } + } + } +} + #endif double boozer_residual(double G, double iota, Array& xphi, Array& xtheta, Array& B, bool weight_inv_modB){ diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index e897f48e6..43f65a603 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -231,11 +231,12 @@ def test_boozer_surface_optimisation_convergence(self): ] for surfacetype, stellsym, optimize_G, second_stage in configs: for get_data in [get_hsx_data, get_ncsx_data, get_giuliani_data]: - with self.subTest( - surfacetype=surfacetype, stellsym=stellsym, - optimize_G=optimize_G, second_stage=second_stage, get_data=get_data): - self.subtest_boozer_surface_optimisation_convergence( - surfacetype, stellsym, optimize_G, second_stage, get_data) + for vectorize in [True, False]: + with self.subTest( + surfacetype=surfacetype, stellsym=stellsym, + optimize_G=optimize_G, second_stage=second_stage, get_data=get_data, vectorize=vectorize): + self.subtest_boozer_surface_optimisation_convergence( + surfacetype, stellsym, optimize_G, second_stage, get_data) def subtest_boozer_surface_optimisation_convergence(self, surfacetype, stellsym, optimize_G, From ad73f7c9e601cf6ec79130af54e58697adb5cd62 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 16 Apr 2024 15:32:47 -0400 Subject: [PATCH 022/131] removing some changes to make this PR simpler [skip ci] --- src/simsopt/geo/boozersurface.py | 173 ++++++------------------------- tests/geo/test_boozersurface.py | 57 ++++++++-- 2 files changed, 79 insertions(+), 151 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 81fdc6635..904d4dbbf 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -53,28 +53,6 @@ def __init__(self, biotsavart, surface, label, targetlabel, constraint_weight=No def recompute_bell(self, parent=None): self.need_to_run_code = True - def run_code(self, boozer_type, iota, G=None, verbose=True): - """ - Run the default solvers. - """ - if not self.need_to_run_code: - return - - if boozer_type == 'exact': - res = self.solve_residual_equation_exactly_newton(tol=1e-13, maxiter=40, iota=iota, G=G, verbose=verbose) - return res - elif boozer_type == 'ls': - # first try BFGS - res = self.minimize_boozer_penalty_constraints_BFGS(tol=1e-10, maxiter=1500, constraint_weight=self.constraint_weight, iota=iota, G=G, verbose=verbose) - iota, G = res['iota'], res['G'] - - ## polish off using Newton's method - self.need_to_run_code = True - res = self.minimize_boozer_penalty_constraints_newton(tol=1e-11, maxiter=40, constraint_weight=self.constraint_weight, iota=iota, G=G, verbose=verbose) - return res - else: - raise Exception(f"boozer_type not supported: {boozer_type}") - def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., scalarize=True, optimize_G=False, weight_inv_modB=False): r""" Define the residual @@ -95,6 +73,8 @@ def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., sca J(x) = \frac{1}{2}\mathbf r(x)^T \mathbf r(x), i.e. the least squares residual and optionally the gradient and the Hessian of :math:`J(x)`. + + For ``weight_inv_modB=False``, the residuals are unweighted, and they are multiplied by 1/ """ assert derivatives in [0, 1, 2] @@ -324,7 +304,7 @@ def boozer_exact_constraints(self, xl, derivatives=0, optimize_G=True): dres[-1, :-2] = drz return res, dres - def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, constraint_weight=1., iota=0., G=None): + def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, constraint_weight=1., iota=0., G=None, vectorize=False): r""" This function tries to find the surface that approximately solves @@ -345,8 +325,13 @@ def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, cons x = np.concatenate((s.get_dofs(), [iota])) else: x = np.concatenate((s.get_dofs(), [iota, G])) - fun = lambda x: self.boozer_penalty_constraints( - x, derivatives=1, constraint_weight=constraint_weight, optimize_G=G is not None) + + if vectorize: + fun = lambda x: self.boozer_penalty_constraints_vectorized( + x, derivatives=1, constraint_weight=constraint_weight, optimize_G=G is not None) + else: + fun = lambda x: self.boozer_penalty_constraints( + x, derivatives=1, constraint_weight=constraint_weight, optimize_G=G is not None) res = minimize( fun, x, jac=True, method='L-BFGS-B', options={'maxiter': maxiter, 'ftol': tol, 'gtol': tol, 'maxcor': 200}) @@ -369,132 +354,27 @@ def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, cons self.need_to_run_code = False return resdict - def minimize_boozer_penalty_constraints_BFGS(self, tol=1e-3, maxiter=1000, constraint_weight=1., iota=0., G=None, hessian=False, verbose=False): - r""" - This function tries to find the surface that approximately solves - - .. math:: - \text{min}_x ~J(x) + \frac{1}{2} w_c (l - l_0)^2 - + \frac{1}{2} w_c (z(\varphi=0, \theta=0) - 0)^2 - - where :math:`J(x) = \frac{1}{2}\mathbf r(x)^T \mathbf r(x)`, and :math:`\mathbf r(x)` contains - the Boozer residuals at quadrature points :math:`1,\dots,n`. - This is done using BFGS. - """ - if not self.need_to_run_code: - return self.res - - s = self.surface - if G is None: - x = np.concatenate((s.get_dofs(), [iota])) - else: - x = np.concatenate((s.get_dofs(), [iota, G])) - - fun = lambda x: self.boozer_penalty_constraints_vectorized( - x, derivatives=1, constraint_weight=constraint_weight, optimize_G=G is not None) - res = minimize( - fun, x, jac=True, method='BFGS', - options={'maxiter': maxiter, 'gtol': tol}) - - resdict = { - "residual": res.fun, "gradient": res.jac, "iter": res.nit, "info": res, "success": res.success, "G": None, 'type': 'ls', 'solver': 'BFGS', - "firstorderop": res.jac, "constraint_weight": constraint_weight, "labelerr": np.abs((self.label.J()-self.targetlabel)/self.targetlabel) - } - - if G is None: - s.set_dofs(res.x[:-1]) - iota = res.x[-1] - else: - s.set_dofs(res.x[:-2]) - iota = res.x[-2] - G = res.x[-1] - resdict['G'] = G - resdict['s'] = s - resdict['iota'] = iota - - if hessian: - val, dval, d2val = self.boozer_penalty_constraints_vectorized( - x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) - P, L, U = lu(d2val) - resdict["PLU"] = (P, L, U) - - self.res = resdict - self.need_to_run_code = False - - if verbose: - print(f"BFGS solve - {resdict['success']} iter={resdict['iter']}, iota={resdict['iota']:.16f}, ||grad||_inf = {np.linalg.norm(resdict['firstorderop'], ord=np.inf):.3e}", flush=True) - return resdict - - def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, stab=0., verbose=False): + def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, stab=0., vectorize=False): """ + This function does the same as :mod:`minimize_boozer_penalty_constraints_LBFGS`, but instead of LBFGS it uses + Newton's method. """ if not self.need_to_run_code: return self.res - + s = self.surface if G is None: x = np.concatenate((s.get_dofs(), [iota])) else: x = np.concatenate((s.get_dofs(), [iota, G])) i = 0 - - val, dval, d2val = self.boozer_penalty_constraints_vectorized( - x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) - norm = np.linalg.norm(dval, ord=np.inf) - while i < maxiter and norm > tol: - d2val += stab*np.identity(d2val.shape[0]) - dx = np.linalg.solve(d2val, dval) - if norm < 1e-9: - dx += np.linalg.solve(d2val, dval - d2val@dx) - x = x - dx + if vectorize: val, dval, d2val = self.boozer_penalty_constraints_vectorized( x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) - norm = np.linalg.norm(dval, ord=np.inf) - - if norm > 1e1: - break - - i = i+1 - - P, L, U = lu(d2val) - if G is None: - s.set_dofs(x[:-1]) - iota = x[-1] - else: - s.set_dofs(x[:-2]) - iota = x[-2] - G = x[-1] - - res = { - "residual": val, "jacobian": dval, "hessian": d2val, "iter": i, "success": norm <= tol, "firstorderop": dval, - "PLU": (P, L, U), 'iota': iota, "G": G, "type": "ls" - } - - self.res = res - self.need_to_run_code = False - - if verbose: - print(f"NEWTON solve - {res['success']} iter={res['iter']}, iota={res['iota']:.16f}, ||grad||_inf = {np.linalg.norm(res['firstorderop'], ord=np.inf):.3e}", flush=True) - return res - - def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, stab=0.): - """ - This function does the same as :mod:`minimize_boozer_penalty_constraints_LBFGS`, but instead of LBFGS it uses - Newton's method. - """ - if not self.need_to_run_code: - return self.res - - s = self.surface - if G is None: - x = np.concatenate((s.get_dofs(), [iota])) else: - x = np.concatenate((s.get_dofs(), [iota, G])) - i = 0 - - val, dval, d2val = self.boozer_penalty_constraints( - x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) + val, dval, d2val = self.boozer_penalty_constraints( + x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) norm = np.linalg.norm(dval) while i < maxiter and norm > tol: d2val += stab*np.identity(d2val.shape[0]) @@ -527,7 +407,7 @@ def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, cons self.need_to_run_code = False return res - def minimize_boozer_penalty_constraints_ls(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, method='lm'): + def minimize_boozer_penalty_constraints_ls(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, method='lm', vectorize=False): """ This function does the same as :mod:`minimize_boozer_penalty_constraints_LBFGS`, but instead of LBFGS it uses a nonlinear least squares algorithm when ``method='lm'``. Options for the method @@ -547,15 +427,24 @@ def minimize_boozer_penalty_constraints_ls(self, tol=1e-12, maxiter=10, constrai if method == 'manual': i = 0 lam = 1. - r, J = self.boozer_penalty_constraints( - x, derivatives=1, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) + if vectorize: + r, J = self.boozer_penalty_constraints_vectorized( + x, derivatives=1, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) + else: + r, J = self.boozer_penalty_constraints( + x, derivatives=1, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) b = J.T@r JTJ = J.T@J while i < maxiter and norm > tol: dx = np.linalg.solve(JTJ + lam * np.diag(np.diag(JTJ)), b) x -= dx - r, J = self.boozer_penalty_constraints( - x, derivatives=1, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) + + if vectorize: + r, J = self.boozer_penalty_constraints_vectorized( + x, derivatives=1, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) + else: + r, J = self.boozer_penalty_constraints( + x, derivatives=1, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) b = J.T@r JTJ = J.T@J norm = np.linalg.norm(b) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 43f65a603..30c986909 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -236,11 +236,12 @@ def test_boozer_surface_optimisation_convergence(self): surfacetype=surfacetype, stellsym=stellsym, optimize_G=optimize_G, second_stage=second_stage, get_data=get_data, vectorize=vectorize): self.subtest_boozer_surface_optimisation_convergence( - surfacetype, stellsym, optimize_G, second_stage, get_data) + surfacetype, stellsym, optimize_G, second_stage, get_data, vectorize) def subtest_boozer_surface_optimisation_convergence(self, surfacetype, stellsym, optimize_G, - second_stage, get_data): + second_stage, get_data, + vectorize): curves, currents, ma = get_data() if stellsym: coils = coils_via_symmetries(curves, currents, ma.nfp, True) @@ -284,18 +285,19 @@ def subtest_boozer_surface_optimisation_convergence(self, surfacetype, # compute surface first using LBFGS exact and an area constraint res = boozer_surface.minimize_boozer_penalty_constraints_LBFGS( - tol=1e-9, maxiter=500, constraint_weight=100., iota=iota, G=G) + tol=1e-9, maxiter=500, constraint_weight=100., iota=iota, G=G, + vectorize=vectorize) print('Residual norm after LBFGS', np.sqrt(2*res['fun'])) boozer_surface.recompute_bell() if second_stage == 'ls': res = boozer_surface.minimize_boozer_penalty_constraints_ls( tol=1e-11, maxiter=100, constraint_weight=1000., - iota=res['iota'], G=res['G']) + iota=res['iota'], G=res['G'], vectorize=vectorize) elif second_stage == 'newton': res = boozer_surface.minimize_boozer_penalty_constraints_newton( tol=1e-9, maxiter=15, constraint_weight=100., - iota=res['iota'], G=res['G'], stab=1e-4) + iota=res['iota'], G=res['G'], stab=1e-4, vectorize=vectorize) elif second_stage == 'newton_exact': res = boozer_surface.minimize_boozer_exact_constraints_newton( tol=1e-9, maxiter=15, iota=res['iota'], G=res['G']) @@ -399,8 +401,31 @@ def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, o x = np.concatenate((s.get_dofs(), [iota])) if optimize_G: x = np.concatenate((x, [2.*np.pi*current_sum*(4*np.pi*10**(-7)/(2 * np.pi))])) - + + # deriv = 0 w = 0. + f0 = boozer_surface.boozer_penalty_constraints( + x, derivatives=0, constraint_weight=w, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) + f1 = boozer_surface.boozer_penalty_constraints_vectorized( + x, derivatives=0, constraint_weight=w, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) + np.testing.assert_allclose(f0, f1, atol=1e-13, rtol=1e-13) + #print(np.abs(f0-f1)/np.abs(f0)) + + + # deriv = 1 + f0, J0 = boozer_surface.boozer_penalty_constraints( + x, derivatives=1, constraint_weight=w, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) + f1, J1 = boozer_surface.boozer_penalty_constraints_vectorized( + x, derivatives=1, constraint_weight=w, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) + np.testing.assert_allclose(f0, f1, atol=1e-13, rtol=1e-13) + np.testing.assert_allclose(J0, J1, atol=1e-11, rtol=1e-11) + + # check directional derivative + h1 = np.random.rand(J0.size)-0.5 + np.testing.assert_allclose(J0@h1, J1@h1, atol=1e-13, rtol=1e-13) + #print(np.abs(f0-f1)/np.abs(f0), np.abs(J0@h1-J1@h1)/np.abs(J0@h1)) + + f0, J0, H0 = boozer_surface.boozer_penalty_constraints( x, derivatives=2, constraint_weight=w, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) f1, J1, H1 = boozer_surface.boozer_penalty_constraints_vectorized( @@ -409,13 +434,27 @@ def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, o np.testing.assert_allclose(f0, f1, atol=1e-13, rtol=1e-13) np.testing.assert_allclose(J0, J1, atol=1e-11, rtol=1e-11) np.testing.assert_allclose(H0, H1, atol=1e-10, rtol=1e-10) - - h1 = np.random.rand(J0.size)-0.5 h2 = np.random.rand(J0.size)-0.5 + np.testing.assert_allclose(f0, f1, atol=1e-13, rtol=1e-13) np.testing.assert_allclose(J0@h1, J1@h1, atol=1e-13, rtol=1e-13) np.testing.assert_allclose((H0@h1)@h2, (H1@h1)@h2, atol=1e-13, rtol=1e-13) - print(np.abs(f0-f1)/np.abs(f0), np.abs(J0@h1-J1@h1)/np.abs(J0@h1), np.abs((H0@h1)@h2-(H1@h1)@h2)/np.abs((H0@h1)@h2)) + #print(np.abs(f0-f1)/np.abs(f0), np.abs(J0@h1-J1@h1)/np.abs(J0@h1), np.abs((H0@h1)@h2-(H1@h1)@h2)/np.abs((H0@h1)@h2)) + + + def compute_differences(Ha, Hb): + diff = np.abs(Ha.flatten() - Hb.flatten()) + rel_diff = diff/np.abs(Ha.flatten()) + ij1 = np.where(diff.reshape(Ha.shape) == np.max(diff)) + i1 = ij1[0][0] + j1 = ij1[1][0] + + + ij2 = np.where(rel_diff.reshape(Ha.shape) == np.max(rel_diff)) + i2 = ij2[0][0] + j2 = ij2[1][0] + print(f'max err ({i1:03}, {j1:03}): {np.max(diff):.6e}, {Ha[i1, j1]:.6e}\nmax rel err ({i2:03}, {j2:03}): {np.max(rel_diff):.6e}, {Ha[i2,j2]:.6e}\n') + compute_differences(H0, H1) if __name__ == "__main__": unittest.main() From cc77bd79bc2a97d0e2680c6051ab7a4b8c41d44e Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 16 Apr 2024 15:50:11 -0400 Subject: [PATCH 023/131] more unit tests --- tests/geo/test_boozersurface.py | 65 +++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 30c986909..8e5a4d12a 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -55,11 +55,13 @@ def test_boozer_penalty_constraints_gradient(self): for surfacetype in surfacetypes_list: for stellsym in stellsym_list: for optimize_G in [True, False]: - with self.subTest(surfacetype=surfacetype, - stellsym=stellsym, - optimize_G=optimize_G): - self.subtest_boozer_penalty_constraints_gradient( - surfacetype, stellsym, optimize_G) + for vectorize in [True, False]: + with self.subTest(surfacetype=surfacetype, + stellsym=stellsym, + optimize_G=optimize_G, + vectorize=vectorize): + self.subtest_boozer_penalty_constraints_gradient( + surfacetype, stellsym, optimize_G, vectorize) def test_boozer_penalty_constraints_hessian(self): """ @@ -69,14 +71,16 @@ def test_boozer_penalty_constraints_hessian(self): for surfacetype in surfacetypes_list: for stellsym in stellsym_list: for optimize_G in [True, False]: - with self.subTest(surfacetype=surfacetype, - stellsym=stellsym, - optimize_G=optimize_G): - self.subtest_boozer_penalty_constraints_hessian( - surfacetype, stellsym, optimize_G) + for vectorize in [True, False]: + with self.subTest(surfacetype=surfacetype, + stellsym=stellsym, + optimize_G=optimize_G, + vectorize=vectorize): + self.subtest_boozer_penalty_constraints_hessian( + surfacetype, stellsym, optimize_G, vectorize) def subtest_boozer_penalty_constraints_gradient(self, surfacetype, stellsym, - optimize_G=False): + optimize_G=False, vectorize=False): np.random.seed(1) curves, currents, ma = get_ncsx_data() coils = coils_via_symmetries(curves, currents, 3, True) @@ -98,9 +102,12 @@ def subtest_boozer_penalty_constraints_gradient(self, surfacetype, stellsym, x = np.concatenate((s.get_dofs(), [iota])) if optimize_G: x = np.concatenate((x, [2.*np.pi*current_sum*(4*np.pi*10**(-7)/(2 * np.pi))])) - f0, J0 = boozer_surface.boozer_penalty_constraints( - x, derivatives=1, constraint_weight=weight, optimize_G=optimize_G) - + if vectorize: + f0, J0 = boozer_surface.boozer_penalty_constraints_vectorized( + x, derivatives=1, constraint_weight=weight, optimize_G=optimize_G) + else: + f0, J0 = boozer_surface.boozer_penalty_constraints( + x, derivatives=1, constraint_weight=weight, optimize_G=optimize_G) h = np.random.uniform(size=x.shape)-0.5 Jex = J0@h @@ -108,9 +115,14 @@ def subtest_boozer_penalty_constraints_gradient(self, surfacetype, stellsym, epsilons = np.power(2., -np.asarray(range(7, 20))) print("###############################################################") for eps in epsilons: - f1 = boozer_surface.boozer_penalty_constraints( - x + eps*h, derivatives=0, constraint_weight=weight, - optimize_G=optimize_G) + if vectorize: + f1 = boozer_surface.boozer_penalty_constraints_vectorized( + x + eps*h, derivatives=0, constraint_weight=weight, + optimize_G=optimize_G) + else: + f1 = boozer_surface.boozer_penalty_constraints( + x + eps*h, derivatives=0, constraint_weight=weight, + optimize_G=optimize_G) Jfd = (f1-f0)/eps err = np.linalg.norm(Jfd-Jex)/np.linalg.norm(Jex) print(err/err_old, f0, f1) @@ -119,7 +131,7 @@ def subtest_boozer_penalty_constraints_gradient(self, surfacetype, stellsym, print("###############################################################") def subtest_boozer_penalty_constraints_hessian(self, surfacetype, stellsym, - optimize_G=False): + optimize_G=False, vectorize=False): np.random.seed(1) curves, currents, ma = get_ncsx_data() coils = coils_via_symmetries(curves, currents, 3, True) @@ -140,9 +152,12 @@ def subtest_boozer_penalty_constraints_hessian(self, surfacetype, stellsym, if optimize_G: x = np.concatenate( (x, [2.*np.pi*current_sum*(4*np.pi*10**(-7)/(2 * np.pi))])) - f0, J0, H0 = boozer_surface.boozer_penalty_constraints( - x, derivatives=2, optimize_G=optimize_G) - + if vectorize: + f0, J0, H0 = boozer_surface.boozer_penalty_constraints_vectorized( + x, derivatives=2, optimize_G=optimize_G) + else: + f0, J0, H0 = boozer_surface.boozer_penalty_constraints( + x, derivatives=2, optimize_G=optimize_G) h1 = np.random.uniform(size=x.shape)-0.5 h2 = np.random.uniform(size=x.shape)-0.5 d2f = h1 @ H0 @ h2 @@ -151,8 +166,12 @@ def subtest_boozer_penalty_constraints_hessian(self, surfacetype, stellsym, epsilons = np.power(2., -np.asarray(range(10, 20))) print("###############################################################") for eps in epsilons: - fp, Jp = boozer_surface.boozer_penalty_constraints( - x + eps*h1, derivatives=1, optimize_G=optimize_G) + if vectorize: + fp, Jp = boozer_surface.boozer_penalty_constraints_vectorized( + x + eps*h1, derivatives=1, optimize_G=optimize_G) + else: + fp, Jp = boozer_surface.boozer_penalty_constraints( + x + eps*h1, derivatives=1, optimize_G=optimize_G) d2f_fd = (Jp@h2-J0@h2)/eps err = np.abs(d2f_fd-d2f)/np.abs(d2f) print(err/err_old) From 9e5f6216c4c317149696dd16c0541eec51a05321 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 16 Apr 2024 16:05:23 -0400 Subject: [PATCH 024/131] remove unused header --- src/simsoptpp/boozerresidual.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/simsoptpp/boozerresidual.cpp b/src/simsoptpp/boozerresidual.cpp index 3da78ee52..1a1b55782 100644 --- a/src/simsoptpp/boozerresidual.cpp +++ b/src/simsoptpp/boozerresidual.cpp @@ -4,7 +4,6 @@ #include "simdhelpers.h" #include "vec3dsimd.h" #include "xtensor/xarray.hpp" -#include #include "xtensor/xadapt.hpp" #if __cplusplus >= 201703L @@ -13,7 +12,6 @@ #define MYIF(c) if(c) #endif -//#if false #if defined(USE_XSIMD) template void boozer_residual_impl(double G, double iota, T& B, T& dB_dx, T& d2B_dx2, T& xphi, T& xtheta, T& dx_ds, T& dxphi_ds, T& dxtheta_ds, double& res, T& dres, T& d2res, size_t ndofs, bool weight_inv_modB){ int nphi = xphi.shape(0); From 09c17c244b37a434c5747bfbff09e8e30fac254f Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 16 Apr 2024 16:29:44 -0400 Subject: [PATCH 025/131] removing vectorization option in the boozer_surface.minimize_boozer_penalty_constraints_ls function [skip ci] --- src/simsopt/geo/boozersurface.py | 21 ++++++--------------- tests/geo/test_boozersurface.py | 2 +- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 904d4dbbf..22d05836d 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -407,7 +407,7 @@ def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, cons self.need_to_run_code = False return res - def minimize_boozer_penalty_constraints_ls(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, method='lm', vectorize=False): + def minimize_boozer_penalty_constraints_ls(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, method='lm'): """ This function does the same as :mod:`minimize_boozer_penalty_constraints_LBFGS`, but instead of LBFGS it uses a nonlinear least squares algorithm when ``method='lm'``. Options for the method @@ -417,7 +417,7 @@ def minimize_boozer_penalty_constraints_ls(self, tol=1e-12, maxiter=10, constrai if not self.need_to_run_code: return self.res - + s = self.surface if G is None: x = np.concatenate((s.get_dofs(), [iota])) @@ -427,24 +427,15 @@ def minimize_boozer_penalty_constraints_ls(self, tol=1e-12, maxiter=10, constrai if method == 'manual': i = 0 lam = 1. - if vectorize: - r, J = self.boozer_penalty_constraints_vectorized( - x, derivatives=1, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) - else: - r, J = self.boozer_penalty_constraints( - x, derivatives=1, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) + r, J = self.boozer_penalty_constraints( + x, derivatives=1, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) b = J.T@r JTJ = J.T@J while i < maxiter and norm > tol: dx = np.linalg.solve(JTJ + lam * np.diag(np.diag(JTJ)), b) x -= dx - - if vectorize: - r, J = self.boozer_penalty_constraints_vectorized( - x, derivatives=1, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) - else: - r, J = self.boozer_penalty_constraints( - x, derivatives=1, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) + r, J = self.boozer_penalty_constraints( + x, derivatives=1, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) b = J.T@r JTJ = J.T@J norm = np.linalg.norm(b) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 8e5a4d12a..84dd49e76 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -312,7 +312,7 @@ def subtest_boozer_surface_optimisation_convergence(self, surfacetype, if second_stage == 'ls': res = boozer_surface.minimize_boozer_penalty_constraints_ls( tol=1e-11, maxiter=100, constraint_weight=1000., - iota=res['iota'], G=res['G'], vectorize=vectorize) + iota=res['iota'], G=res['G']) elif second_stage == 'newton': res = boozer_surface.minimize_boozer_penalty_constraints_newton( tol=1e-9, maxiter=15, constraint_weight=100., From 0e2c3926a3a1daade57d6db2ea9f4d7925ff7f8b Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 16 Apr 2024 16:31:42 -0400 Subject: [PATCH 026/131] removed constraint_weight [skip ci] --- src/simsopt/geo/boozersurface.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 22d05836d..49f83bdcb 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -41,13 +41,12 @@ class BoozerSurface(Optimizable): where Newton is used to solve the first order necessary conditions for optimality. """ - def __init__(self, biotsavart, surface, label, targetlabel, constraint_weight=None): + def __init__(self, biotsavart, surface, label, targetlabel): super().__init__(depends_on=[biotsavart]) self.biotsavart = biotsavart self.surface = surface self.label = label self.targetlabel = targetlabel - self.constraint_weight = constraint_weight self.need_to_run_code = True def recompute_bell(self, parent=None): From 005b0e0363807dac368ba32917bf05faf5177507 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 16 Apr 2024 16:45:18 -0400 Subject: [PATCH 027/131] increasing maxiter in one of the unit tests [skip ci] --- tests/geo/test_boozersurface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 84dd49e76..80171186c 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -304,7 +304,7 @@ def subtest_boozer_surface_optimisation_convergence(self, surfacetype, # compute surface first using LBFGS exact and an area constraint res = boozer_surface.minimize_boozer_penalty_constraints_LBFGS( - tol=1e-9, maxiter=500, constraint_weight=100., iota=iota, G=G, + tol=1e-9, maxiter=600, constraint_weight=100., iota=iota, G=G, vectorize=vectorize) print('Residual norm after LBFGS', np.sqrt(2*res['fun'])) From d1e71db13de4852833664b6a67945f62d4f7e90a Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 16 Apr 2024 16:50:03 -0400 Subject: [PATCH 028/131] removing a verbose optional argument --- src/simsopt/geo/boozersurface.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 49f83bdcb..58acc02e4 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -550,7 +550,7 @@ def minimize_boozer_exact_constraints_newton(self, tol=1e-12, maxiter=10, iota=0 self.need_to_run_code = False return res - def solve_residual_equation_exactly_newton(self, tol=1e-10, maxiter=10, iota=0., G=None, verbose=False): + def solve_residual_equation_exactly_newton(self, tol=1e-10, maxiter=10, iota=0., G=None): """ This function solves the Boozer Surface residual equation exactly. For this to work, we need the right balance of quadrature points, degrees @@ -691,8 +691,6 @@ def solve_residual_equation_exactly_newton(self, tol=1e-10, maxiter=10, iota=0., "mask": mask, 'type': 'exact' } - if verbose: - print(f"NEWTON solve - {res['success']} iter={res['iter']}, iota={res['iota']:.16f}, ||residual||_inf = {np.linalg.norm(res['residual'], ord=np.inf):.3e}", flush=True) self.res = res self.need_to_run_code = False From 464b3e5237e7f8dc724a115495caba8ceb0b2a7e Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 16 Apr 2024 17:04:26 -0400 Subject: [PATCH 029/131] added another unit test for self-intersecting surfaces --- tests/geo/test_boozersurface.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 80171186c..d17d4663a 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -285,7 +285,7 @@ def subtest_boozer_surface_optimisation_convergence(self, surfacetype, s = get_surface(surfacetype, stellsym, nfp=ma.nfp) s.fit_to_curve(ma, 0.1) if get_data is get_ncsx_data: - iota = -0.3 + iota = -0.4 elif get_data is get_giuliani_data: iota = 0.4 elif get_data is get_hsx_data: @@ -326,6 +326,8 @@ def subtest_boozer_surface_optimisation_convergence(self, surfacetype, print('Residual norm after second stage', np.linalg.norm(res['residual'])) assert res['success'] + assert boozer_surface.surface.is_self_intersecting(thetas=100) + # For the stellsym case we have z(0, 0) = y(0, 0) = 0. For the not # stellsym case, we enforce z(0, 0) = 0, but expect y(0, 0) \neq 0 gammazero = s.gamma()[0, 0, :] From 4c418f59468a11361ee957e3a847f4d5b10785df Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 16 Apr 2024 17:30:20 -0400 Subject: [PATCH 030/131] making problem smaller to avoid issues with CI --- tests/geo/test_boozersurface.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index d17d4663a..23152767e 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -380,7 +380,7 @@ def test_boozer_penalty_constraints_cpp_notcpp(self): for surfacetype in surfacetypes_list: for stellsym in stellsym_list: for weight_inv_modB in [False, True]: - for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 2, 2), (False, 2, 1), (True, 10, 17), (False, 13, 21),(True, 3, 3), (False, 3, 3)]: + for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 2, 2), (False, 2, 1), (True, 6, 13), (False, 7, 13),(True, 3, 3), (False, 3, 3)]: with self.subTest(surfacetype=surfacetype, stellsym=stellsym, optimize_G=optimize_G, @@ -447,6 +447,7 @@ def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, o #print(np.abs(f0-f1)/np.abs(f0), np.abs(J0@h1-J1@h1)/np.abs(J0@h1)) + # deriv = 2 f0, J0, H0 = boozer_surface.boozer_penalty_constraints( x, derivatives=2, constraint_weight=w, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) f1, J1, H1 = boozer_surface.boozer_penalty_constraints_vectorized( From 80e23bc67a2b8d6adebc4509b27a4656558651fa Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 16 Apr 2024 18:04:13 -0400 Subject: [PATCH 031/131] making problem smaller to avoid issues with CI --- tests/geo/test_boozersurface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 23152767e..635415dad 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -380,7 +380,7 @@ def test_boozer_penalty_constraints_cpp_notcpp(self): for surfacetype in surfacetypes_list: for stellsym in stellsym_list: for weight_inv_modB in [False, True]: - for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 2, 2), (False, 2, 1), (True, 6, 13), (False, 7, 13),(True, 3, 3), (False, 3, 3)]: + for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 2, 2), (False, 2, 1), (True, 6, 9), (False, 7, 8),(True, 3, 3), (False, 3, 3)]: with self.subTest(surfacetype=surfacetype, stellsym=stellsym, optimize_G=optimize_G, From 56f67be059643d3a226faf5a21aeb8d28dde86ab Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 17 Apr 2024 10:06:34 -0400 Subject: [PATCH 032/131] trying to avoid segfault in unit tests --- tests/geo/test_boozersurface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 635415dad..7580f4df7 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -409,7 +409,7 @@ def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, o thetas = [0.2432101234, 0.9832134] - s = get_surface(surfacetype, stellsym, nphi=nphi, ntheta=ntheta, thetas=thetas, phis=phis) + s = get_surface(surfacetype, stellsym, nphi=nphi, ntheta=ntheta, thetas=thetas, phis=phis, mpol=3, ntor=3) s.fit_to_curve(ma, 0.1) s.x = s.x + np.random.rand(s.x.size)*1e-6 From 77ca9148b055dca3504de1d5546d6c2154cb8ec0 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 17 Apr 2024 13:07:12 -0400 Subject: [PATCH 033/131] made unit test even easier, minor changes to file naming --- CMakeLists.txt | 4 +-- ...ozerresidual.cpp => boozerresidual_impl.h} | 33 ------------------- src/simsoptpp/boozerresidual_py.cpp | 32 ++++++++++++++++++ .../{boozerresidual.h => boozerresidual_py.h} | 4 +-- src/simsoptpp/python.cpp | 2 +- tests/geo/test_boozersurface.py | 3 +- 6 files changed, 37 insertions(+), 41 deletions(-) rename src/simsoptpp/{boozerresidual.cpp => boozerresidual_impl.h} (94%) create mode 100644 src/simsoptpp/boozerresidual_py.cpp rename src/simsoptpp/{boozerresidual.h => boozerresidual_py.h} (95%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d0a93f54..046f45db4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,7 +119,7 @@ set(XTENSOR_USE_TBB 0) pybind11_add_module(${PROJECT_NAME} src/simsoptpp/python.cpp src/simsoptpp/python_surfaces.cpp src/simsoptpp/python_curves.cpp - src/simsoptpp/boozerresidual.cpp + src/simsoptpp/boozerresidual_py.cpp src/simsoptpp/python_magneticfield.cpp src/simsoptpp/python_tracing.cpp src/simsoptpp/python_distance.cpp src/simsoptpp/biot_savart_py.cpp src/simsoptpp/biot_savart_vjp_py.cpp @@ -159,8 +159,6 @@ set_target_properties(profiling target_include_directories(profiling PRIVATE "thirdparty/xtensor/include" "thirdparty/xsimd/include" "thirdparty/xtl/include" "thirdparty/eigen" "src/simsoptpp/") target_link_libraries(profiling PRIVATE fmt::fmt-header-only) - - #get_cmake_property(_variableNames VARIABLES) #list (SORT _variableNames) #foreach (_variableName ${_variableNames}) diff --git a/src/simsoptpp/boozerresidual.cpp b/src/simsoptpp/boozerresidual_impl.h similarity index 94% rename from src/simsoptpp/boozerresidual.cpp rename to src/simsoptpp/boozerresidual_impl.h index 1a1b55782..c432e275d 100644 --- a/src/simsoptpp/boozerresidual.cpp +++ b/src/simsoptpp/boozerresidual_impl.h @@ -1,10 +1,7 @@ -#include "boozerresidual.h" - #include "xsimd/xsimd.hpp" #include "simdhelpers.h" #include "vec3dsimd.h" #include "xtensor/xarray.hpp" -#include "xtensor/xadapt.hpp" #if __cplusplus >= 201703L #define MYIF(c) if constexpr(c) @@ -559,33 +556,3 @@ template void boozer_residual_impl(double G, double iota, T& } #endif - -double boozer_residual(double G, double iota, Array& xphi, Array& xtheta, Array& B, bool weight_inv_modB){ - double res = 0.; - Array dummy = xt::zeros({1}); - boozer_residual_impl(G, iota, B, dummy, dummy, xphi, xtheta, dummy, dummy, dummy, res, dummy, dummy, 0, weight_inv_modB); - return res; -} - -std::tuple boozer_residual_ds(double G, double iota, Array& B, Array& dB_dx, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds, bool weight_inv_modB){ - size_t ndofs = dx_ds.shape(3); - - double res = 0.; - Array dres = xt::zeros({ndofs+2}); - Array dummy = xt::zeros({1}); - boozer_residual_impl(G, iota, B, dB_dx, dummy, xphi, xtheta, dx_ds, dxphi_ds, dxtheta_ds, res, dres, dummy, ndofs, weight_inv_modB); - auto tup = std::make_tuple(res, dres); - return tup; -} - -std::tuple boozer_residual_ds2(double G, double iota, Array& B, Array& dB_dx, Array& d2B_dx2, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds, bool weight_inv_modB){ - size_t ndofs = dx_ds.shape(3); - - double res = 0.; - Array dres = xt::zeros({ndofs+2}); - Array d2res = xt::zeros({ndofs+2, ndofs+2}); - boozer_residual_impl(G, iota, B, dB_dx, d2B_dx2, xphi, xtheta, dx_ds, dxphi_ds, dxtheta_ds, res, dres, d2res, ndofs, weight_inv_modB); - auto tup = std::make_tuple(res, dres, d2res); - return tup; -} - diff --git a/src/simsoptpp/boozerresidual_py.cpp b/src/simsoptpp/boozerresidual_py.cpp new file mode 100644 index 000000000..d8d41e85b --- /dev/null +++ b/src/simsoptpp/boozerresidual_py.cpp @@ -0,0 +1,32 @@ +#include "boozerresidual_impl.h" +#include "boozerresidual_py.h" + +double boozer_residual(double G, double iota, Array& xphi, Array& xtheta, Array& B, bool weight_inv_modB){ + double res = 0.; + Array dummy = xt::zeros({1}); + boozer_residual_impl(G, iota, B, dummy, dummy, xphi, xtheta, dummy, dummy, dummy, res, dummy, dummy, 0, weight_inv_modB); + return res; +} + +std::tuple boozer_residual_ds(double G, double iota, Array& B, Array& dB_dx, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds, bool weight_inv_modB){ + size_t ndofs = dx_ds.shape(3); + + double res = 0.; + Array dres = xt::zeros({ndofs+2}); + Array dummy = xt::zeros({1}); + boozer_residual_impl(G, iota, B, dB_dx, dummy, xphi, xtheta, dx_ds, dxphi_ds, dxtheta_ds, res, dres, dummy, ndofs, weight_inv_modB); + auto tup = std::make_tuple(res, dres); + return tup; +} + +std::tuple boozer_residual_ds2(double G, double iota, Array& B, Array& dB_dx, Array& d2B_dx2, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds, bool weight_inv_modB){ + size_t ndofs = dx_ds.shape(3); + + double res = 0.; + Array dres = xt::zeros({ndofs+2}); + Array d2res = xt::zeros({ndofs+2, ndofs+2}); + boozer_residual_impl(G, iota, B, dB_dx, d2B_dx2, xphi, xtheta, dx_ds, dxphi_ds, dxtheta_ds, res, dres, d2res, ndofs, weight_inv_modB); + auto tup = std::make_tuple(res, dres, d2res); + return tup; +} + diff --git a/src/simsoptpp/boozerresidual.h b/src/simsoptpp/boozerresidual_py.h similarity index 95% rename from src/simsoptpp/boozerresidual.h rename to src/simsoptpp/boozerresidual_py.h index 2c11650a4..8b5fc5f9b 100644 --- a/src/simsoptpp/boozerresidual.h +++ b/src/simsoptpp/boozerresidual_py.h @@ -1,10 +1,8 @@ -#pragma once - #include "xtensor/xarray.hpp" #include "xtensor/xmath.hpp" #include "xtensor-python/pyarray.hpp" // Numpy bindings + typedef xt::pyarray Array; -using std::vector; double boozer_residual(double G, double iota, Array& xphi, Array& xtheta, Array& B, bool weight_inv_modB); std::tuple boozer_residual_ds(double G, double iota, Array& B, Array& dB_dx, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds, bool weight_inv_modB); diff --git a/src/simsoptpp/python.cpp b/src/simsoptpp/python.cpp index f965ec567..2f153c5a3 100644 --- a/src/simsoptpp/python.cpp +++ b/src/simsoptpp/python.cpp @@ -23,7 +23,7 @@ typedef xt::pytensor PyTensor; #include "permanent_magnet_optimization.h" #include "reiman.h" #include "simdhelpers.h" -#include "boozerresidual.h" +#include "boozerresidual_py.h" namespace py = pybind11; diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 7580f4df7..2be3bfa95 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -380,7 +380,8 @@ def test_boozer_penalty_constraints_cpp_notcpp(self): for surfacetype in surfacetypes_list: for stellsym in stellsym_list: for weight_inv_modB in [False, True]: - for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 2, 2), (False, 2, 1), (True, 6, 9), (False, 7, 8),(True, 3, 3), (False, 3, 3)]: + for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1)]: + #for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 2, 2), (False, 2, 1), (True, 6, 9), (False, 7, 8),(True, 3, 3), (False, 3, 3)]: with self.subTest(surfacetype=surfacetype, stellsym=stellsym, optimize_G=optimize_G, From 71db8b9faf1852924b5a665d044232947277192d Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 17 Apr 2024 20:11:35 -0400 Subject: [PATCH 034/131] initial commit --- src/simsopt/geo/curvexyzhelical.py | 120 +++++++++++++++++++++++++++++ tests/geo/test_curve.py | 50 +++++++++++- 2 files changed, 166 insertions(+), 4 deletions(-) create mode 100644 src/simsopt/geo/curvexyzhelical.py diff --git a/src/simsopt/geo/curvexyzhelical.py b/src/simsopt/geo/curvexyzhelical.py new file mode 100644 index 000000000..bc9d190d7 --- /dev/null +++ b/src/simsopt/geo/curvexyzhelical.py @@ -0,0 +1,120 @@ +import jax.numpy as jnp +from math import pi +import numpy as np +from .curve import JaxCurve + +__all__ = ['CurveXYZHelical'] + + +def jaxXYZHelicalFouriercurve_pure(dofs, quadpoints, order, nfp, stellsym): + + if stellsym: + xc = dofs[:order+1] + ys = dofs[order+1:2*order+1] + zs = dofs[2*order+1:] + + theta, m = jnp.meshgrid(quadpoints, jnp.arange(order+1), indexing='ij') + xhat = np.sum(xc[None, :] * jnp.cos(2 * jnp.pi * nfp*m*theta), axis=1) + yhat = np.sum(ys[None, :] * jnp.sin(2 * jnp.pi * nfp*m[:, 1:]*theta[:, 1:]), axis=1) + + x = jnp.cos(2*jnp.pi*quadpoints) * xhat - jnp.sin(2*jnp.pi*quadpoints) * yhat + y = jnp.sin(2*jnp.pi*quadpoints) * xhat + jnp.cos(2*jnp.pi*quadpoints) * yhat + z = jnp.sum(zs[None, :] * jnp.sin(2*jnp.pi*nfp * m[:, 1:]*theta[:, 1:]), axis=1) + else: + xc = dofs[0 : order+1] + xs = dofs[order+1 : 2*order+1] + yc = dofs[2*order+1: 3*order+2] + ys = dofs[3*order+2: 4*order+2] + zc = dofs[4*order+2: 5*order+3] + zs = dofs[5*order+3: ] + + theta, m = jnp.meshgrid(quadpoints, jnp.arange(order+1), indexing='ij') + xhat = np.sum(xc[None, :] * jnp.cos(2*jnp.pi*nfp*m*theta), axis=1) + np.sum(xs[None, :] * jnp.sin(2*jnp.pi*nfp*m[:, 1:]*theta[:, 1:]), axis=1) + yhat = np.sum(yc[None, :] * jnp.cos(2*jnp.pi*nfp*m*theta), axis=1) + np.sum(ys[None, :] * jnp.sin(2*jnp.pi*nfp*m[:, 1:]*theta[:, 1:]), axis=1) + + x = jnp.cos(2*jnp.pi*quadpoints) * xhat - jnp.sin(2*jnp.pi*quadpoints) * yhat + y = jnp.sin(2*jnp.pi*quadpoints) * xhat + jnp.cos(2*jnp.pi*quadpoints) * yhat + z = np.sum(zc[None, :] * jnp.cos(2*jnp.pi*nfp*m*theta), axis=1) + np.sum(zs[None, :] * jnp.sin(2*jnp.pi*nfp*m[:, 1:]*theta[:, 1:]), axis=1) + + gamma = jnp.zeros((len(quadpoints),3)) + gamma = gamma.at[:, 0].add(x) + gamma = gamma.at[:, 1].add(y) + gamma = gamma.at[:, 2].add(z) + return gamma + + +class CurveXYZHelical(JaxCurve): + r'''A curve representation for a helical coil that does not lie on a torus. The coordinates of the curve are given by: + .. math:: + \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} x_{c,m} cos(2pi n_{\text{fp}} m \theta)\\ + \hat y(\theta) &= \sum_{m=1}^{\text{order}} y_{s,m} sin(2pi n_{\text{fp}} m \theta)\\ + x(\theta) &= \hat x(\theta) \cos(2pi \theta) - \hat y(\theta) \sin(2pi \theta)\\ + y(\theta) &= \hat x(\theta) \sin(2pi \theta) + \hat y(\theta) \cos(2pi \theta)\\ + z(\theta) &= \sum_{i=0}^{\text{order}} z_{s,m} sin(2pi n_{\text{fp}} \theta) + if the coil is stellarator symmetric. When the coil is not stellarator symmetric, the formulas above + become + .. math:: + \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} x_{c, m} cos(2pi m \theta) + x_{s, m} sin(2pi m \theta)\\ + \hat y(\theta) &= y_{c, 0} + \sum_{m=1}^{\text{order}} y_{c, m} cos(2pi m \theta) + y_{s, m} sin(2pi m \theta)\\ + x(\theta) &= \hat x(\theta) \cos(2pi \theta) - \hat y(\theta) \sin(2pi \theta)\\ + y(\theta) &= \hat x(\theta) \sin(2pi \theta) + \hat y(\theta) \cos(2pi \theta)\\ + z(\theta) &= z_{c, 0} + \sum_{m=1}^{\text{order}} z_{c, m} cos(2pi \theta) + z_{s, m} sin(2pi \theta) + + Args: + quadpoints: number of grid points/resolution along the curve, + order: how many Fourier harmonics to include in the Fourier representation, + nfp: discrete rotational symmetry number, + stellsym: stellaratory symmetry if True, not stellarator symmetric otherwise. + ''' + + def __init__(self, quadpoints, order, nfp, stellsym, **kwargs): + if isinstance(quadpoints, int): + quadpoints = np.linspace(0, 1, quadpoints, endpoint=False) + pure = lambda dofs, points: jaxXYZHelicalFouriercurve_pure( + dofs, points, order, nfp, stellsym) + + self.order = order + self.nfp = nfp + self.stellsym = stellsym + self.coefficients = np.zeros(self.num_dofs()) + if "dofs" not in kwargs: + if "x0" not in kwargs: + kwargs["x0"] = self.coefficients + else: + self.set_dofs_impl(kwargs["x0"]) + + super().__init__(quadpoints, pure, names=self._make_names(order), **kwargs) + + def _make_names(self, order): + if self.stellsym: + x_cos_names = [f'xc({i})' for i in range(0, order + 1)] + x_names = x_cos_names + y_sin_names = [f'ys({i})' for i in range(1, order + 1)] + y_names = y_sin_names + z_sin_names = [f'zs({i})' for i in range(1, order + 1)] + z_names = z_sin_names + else: + x_names = ['xc(0)'] + x_cos_names = [f'xc({i})' for i in range(1, order + 1)] + x_sin_names = [f'xs({i})' for i in range(1, order + 1)] + x_names += x_cos_names + x_sin_names + y_names = ['yc(0)'] + y_cos_names = [f'yc({i})' for i in range(1, order + 1)] + y_sin_names = [f'ys({i})' for i in range(1, order + 1)] + y_names += y_cos_names + y_sin_names + z_names = ['zc(0)'] + z_cos_names = [f'zc({i})' for i in range(1, order + 1)] + z_sin_names = [f'zs({i})' for i in range(1, order + 1)] + z_names += z_cos_names + z_sin_names + + return x_names + y_names + z_names + + def num_dofs(self): + return (self.order+1) + self.order + self.order if self.stellsym else 3*(2*self.order+1) + + def get_dofs(self): + return self.coefficients + + def set_dofs_impl(self, dofs): + self.coefficients[:] = dofs[:] + diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index acf3314bf..979359e27 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -11,6 +11,7 @@ from simsopt.geo.curverzfourier import CurveRZFourier from simsopt.geo.curveplanarfourier import CurvePlanarFourier from simsopt.geo.curvehelical import CurveHelical +from simsopt.geo.curvexyzhelical import CurveXYZHelical from simsopt.geo.curve import RotatedCurve, curves_to_vtk from simsopt.geo import parameters from simsopt.configs.zoo import get_ncsx_data, get_w7x_data @@ -36,7 +37,7 @@ def taylor_test(f, df, x, epsilons=None, direction=None): dfx = df(x)@direction if epsilons is None: epsilons = np.power(2., -np.asarray(range(7, 20))) - # print("################################################################################") + print("################################################################################") err_old = 1e9 counter = 0 for eps in epsilons: @@ -46,6 +47,8 @@ def taylor_test(f, df, x, epsilons=None, direction=None): fminuseps = f(x - eps * direction) dfest = (fpluseps-fminuseps)/(2*eps) err = np.linalg.norm(dfest - dfx) + print(err, err/err_old) + assert err < 1e-9 or err < 0.3 * err_old if err < 1e-9: break @@ -53,9 +56,10 @@ def taylor_test(f, df, x, epsilons=None, direction=None): counter += 1 if err > 1e-10: assert counter > 3 - # print("################################################################################") + print("################################################################################") +#def get_curve(curvetype, rotated, x=np.linspace(0, 1, 100, endpoint=False)): def get_curve(curvetype, rotated, x=np.asarray([0.5])): np.random.seed(2) rand_scale = 0.01 @@ -73,9 +77,13 @@ def get_curve(curvetype, rotated, x=np.asarray([0.5])): curve = CurveHelical(x, order, 5, 2, 1.0, 0.3, x0=np.ones((2*order,))) elif curvetype == "CurvePlanarFourier": curve = CurvePlanarFourier(x, order, 2, True) + elif curvetype == "CurveXYZHelical1": + curve = CurveXYZHelical(x, order, 2, True) + elif curvetype == "CurveXYZHelical2": + curve = CurveXYZHelical(x, order, 2, False) else: assert False - + dofs = np.zeros((curve.dof_size, )) if curvetype in ["CurveXYZFourier", "JaxCurveXYZFourier"]: dofs[1] = 1. @@ -87,10 +95,28 @@ def get_curve(curvetype, rotated, x=np.asarray([0.5])): dofs[order+1] = 0.1 elif curvetype in ["CurveHelical", "CurveHelicalInitx0"]: dofs[0] = np.pi/2 + elif curvetype == "CurveXYZHelical1": + R = 1 + r = 0.5 + curve.set('xc(0)', R) + curve.set('xc(1)', -r) + curve.set('zs(1)', -r) + dofs = curve.get_dofs() + elif curvetype == "CurveXYZHelical2": + R = 1 + r = 0.5 + curve.set('xc(0)', R) + curve.set('xs(1)', -0.1*r) + curve.set('xc(1)', -r) + curve.set('zs(1)', -r) + curve.set('zc(0)', 1) + curve.set('zs(1)', r) + dofs = curve.get_dofs() else: assert False curve.x = dofs + rand_scale * np.random.rand(len(dofs)).reshape(dofs.shape) + if rotated: curve = RotatedCurve(curve, 0.5, flip=False) return curve @@ -98,7 +124,23 @@ def get_curve(curvetype, rotated, x=np.asarray([0.5])): class Testing(unittest.TestCase): - curvetypes = ["CurveXYZFourier", "JaxCurveXYZFourier", "CurveRZFourier", "CurvePlanarFourier", "CurveHelical", "CurveHelicalInitx0"] + curvetypes = ["CurveXYZFourier", "JaxCurveXYZFourier", "CurveRZFourier", "CurvePlanarFourier", "CurveHelical", "CurveXYZHelical1","CurveXYZHelical2", "CurveHelicalInitx0"] + + def test_curve_xyzhelical_xyzfourier(self): + # this test checks that both helical coil representations can produce the same helical curve on a torus + + order = 1 + nfp = 2 + x = np.linspace(0, 1, 100, endpoint=False) + curve1 = CurveXYZHelical(x, 10, nfp, True) + R = 1 + r = 0.5 + curve1.set('xc(0)', R) + curve1.set('xc(1)', r) + curve1.set('zs(1)', -r) + dofs = curve1.get_dofs() + curve2 = CurveHelical(x, order, nfp, 1, R, r, x0=np.zeros((2*order,))) + assert np.mean(np.linalg.norm(curve1.gamma()-curve2.gamma(), axis=-1)) == 0 def test_curve_helical_xyzfourier(self): x = np.asarray([0.6]) From c03467852f7bc5f06c25b95b22932253b839aa61 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 17 Apr 2024 20:19:31 -0400 Subject: [PATCH 035/131] linting --- tests/geo/test_curve.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 979359e27..e1d5210dc 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -128,7 +128,7 @@ class Testing(unittest.TestCase): def test_curve_xyzhelical_xyzfourier(self): # this test checks that both helical coil representations can produce the same helical curve on a torus - + order = 1 nfp = 2 x = np.linspace(0, 1, 100, endpoint=False) @@ -138,7 +138,6 @@ def test_curve_xyzhelical_xyzfourier(self): curve1.set('xc(0)', R) curve1.set('xc(1)', r) curve1.set('zs(1)', -r) - dofs = curve1.get_dofs() curve2 = CurveHelical(x, order, nfp, 1, R, r, x0=np.zeros((2*order,))) assert np.mean(np.linalg.norm(curve1.gamma()-curve2.gamma(), axis=-1)) == 0 From 9ef07b1011cf7eb38255c02aa072d16572afc37a Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 17 Apr 2024 20:23:41 -0400 Subject: [PATCH 036/131] more linting --- src/simsopt/geo/curvexyzhelical.py | 1 - tests/geo/test_curve.py | 1 - 2 files changed, 2 deletions(-) diff --git a/src/simsopt/geo/curvexyzhelical.py b/src/simsopt/geo/curvexyzhelical.py index bc9d190d7..e78ba9ca8 100644 --- a/src/simsopt/geo/curvexyzhelical.py +++ b/src/simsopt/geo/curvexyzhelical.py @@ -1,5 +1,4 @@ import jax.numpy as jnp -from math import pi import numpy as np from .curve import JaxCurve diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index e1d5210dc..c3301e2e4 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -128,7 +128,6 @@ class Testing(unittest.TestCase): def test_curve_xyzhelical_xyzfourier(self): # this test checks that both helical coil representations can produce the same helical curve on a torus - order = 1 nfp = 2 x = np.linspace(0, 1, 100, endpoint=False) From c74f81b3b77514b4c1dad2ba222c651899c85f42 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 17 Apr 2024 21:21:43 -0400 Subject: [PATCH 037/131] added more unit tests --- src/simsopt/geo/curvexyzhelical.py | 2 +- tests/geo/test_curve.py | 91 +++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/simsopt/geo/curvexyzhelical.py b/src/simsopt/geo/curvexyzhelical.py index e78ba9ca8..6fcc83690 100644 --- a/src/simsopt/geo/curvexyzhelical.py +++ b/src/simsopt/geo/curvexyzhelical.py @@ -46,7 +46,7 @@ class CurveXYZHelical(JaxCurve): r'''A curve representation for a helical coil that does not lie on a torus. The coordinates of the curve are given by: .. math:: \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} x_{c,m} cos(2pi n_{\text{fp}} m \theta)\\ - \hat y(\theta) &= \sum_{m=1}^{\text{order}} y_{s,m} sin(2pi n_{\text{fp}} m \theta)\\ + \hat y(\theta) &= \sum_{m=1}^{\text{order}} y_{s,m} sin(2pi n_{\text{fp}} m \theta)\\ x(\theta) &= \hat x(\theta) \cos(2pi \theta) - \hat y(\theta) \sin(2pi \theta)\\ y(\theta) &= \hat x(\theta) \sin(2pi \theta) + \hat y(\theta) \cos(2pi \theta)\\ z(\theta) &= \sum_{i=0}^{\text{order}} z_{s,m} sin(2pi n_{\text{fp}} \theta) diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index c3301e2e4..1bf8be5ef 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -131,7 +131,7 @@ def test_curve_xyzhelical_xyzfourier(self): order = 1 nfp = 2 x = np.linspace(0, 1, 100, endpoint=False) - curve1 = CurveXYZHelical(x, 10, nfp, True) + curve1 = CurveXYZHelical(x, order, nfp, True) R = 1 r = 0.5 curve1.set('xc(0)', R) @@ -140,6 +140,95 @@ def test_curve_xyzhelical_xyzfourier(self): curve2 = CurveHelical(x, order, nfp, 1, R, r, x0=np.zeros((2*order,))) assert np.mean(np.linalg.norm(curve1.gamma()-curve2.gamma(), axis=-1)) == 0 + def test_xyzhelical_symmetries(self): + # does the stellarator symmetric curve have rotational symmetry? + np.random.seed(1) + rand_scale = 1e-2 + order = 2 + nfp = 3 + x = np.array([0.123, 0.123+1/nfp]) + curve = CurveXYZHelical(x, order, nfp, True) + R = 1 + r = 0.25 + curve.set('xc(0)', R) + curve.set('xc(2)', r) + curve.set('ys(2)', -r) + curve.set('zs(1)', -2*r) + curve.set('zs(2)', r) + dofs = curve.x.copy() + curve.x = dofs + rand_scale * np.random.rand(len(dofs)).reshape(dofs.shape) + + out = curve.gamma() + alpha = -2*np.pi/nfp + R = np.array([[np.cos(alpha), np.sin(alpha), 0], [-np.sin(alpha), np.cos(alpha), 0], [0, 0, 1]]) + print(R@out[0], out[1]) + assert np.linalg.norm(out[1]-R@out[0])<1e-15 + + # is the stellarator symmetric curve actually stellarator symmetric? + order = 2 + nfp = 3 + x = np.array([0.123, -0.123]) + curve = CurveXYZHelical(x, order, nfp, True) + R = 1 + r = 0.25 + curve.set('xc(0)', R) + curve.set('xc(2)', r) + curve.set('ys(2)', -r) + curve.set('zs(1)', -2*r) + curve.set('zs(2)', r) + dofs = curve.x.copy() + curve.x = dofs + rand_scale * np.random.rand(len(dofs)).reshape(dofs.shape) + pts = curve.gamma() + assert np.abs(pts[0, 0]-pts[1, 0]) <1e-15 + assert np.abs(pts[0, 1]+pts[1, 1]) <1e-15 + assert np.abs(pts[0, 2]+pts[1, 2]) <1e-15 + + + # is the field from the stellarator symmetric curve actually stellarator symmetric? + order = 2 + nfp = 3 + x = np.array([0.123, -0.123]) + curve = CurveXYZHelical(100, order, nfp, True) + R = 1 + r = 0.25 + curve.set('xc(0)', R) + curve.set('xc(2)', r) + curve.set('ys(2)', -r) + curve.set('zs(1)', -2*r) + curve.set('zs(2)', r) + dofs = curve.x.copy() + curve.x = dofs + rand_scale * np.random.rand(len(dofs)).reshape(dofs.shape) + from simsopt.field import BiotSavart, Current, Coil + current = Current(1e5) + coil = Coil(curve, current) + bs = BiotSavart([coil]) + bs.set_points([[1, 1, 1], [1, -1, -1]]) + B=bs.B_cyl() + assert np.abs(B[0, 0]+B[1, 0]) <1e-15 + assert np.abs(B[0, 1]-B[1, 1]) <1e-15 + assert np.abs(B[0, 2]-B[1, 2]) <1e-15 + + # does the non-stellarator symmetric curve have rotational symmetry still? + order = 2 + nfp = 5 + x = np.array([0.123, 0.123+1/nfp]) + curve = CurveXYZHelical(x, order, nfp, False) + R = 1 + r = 0.25 + curve.set('xc(0)', R) + curve.set('xc(2)', r) + curve.set('ys(2)', -r) + curve.set('zs(1)', -2*r) + curve.set('zs(2)', r) + dofs = curve.x.copy() + curve.x = dofs + rand_scale * np.random.rand(len(dofs)).reshape(dofs.shape) + + out = curve.gamma() + alpha = -2*np.pi/nfp + R = np.array([[np.cos(alpha), np.sin(alpha), 0], [-np.sin(alpha), np.cos(alpha), 0], [0, 0, 1]]) + print(R@out[0], out[1]) + assert np.linalg.norm(out[1]-R@out[0])<1e-15 + def test_curve_helical_xyzfourier(self): x = np.asarray([0.6]) curve1 = CurveHelical(x, 2, 5, 2, 1.0, 0.3) From a5b97523ce614a198230ec22799713fb8dafcbbb Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 17 Apr 2024 22:03:37 -0400 Subject: [PATCH 038/131] fixing typo in docstring --- src/simsopt/geo/curvexyzhelical.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simsopt/geo/curvexyzhelical.py b/src/simsopt/geo/curvexyzhelical.py index 6fcc83690..3d690dc1d 100644 --- a/src/simsopt/geo/curvexyzhelical.py +++ b/src/simsopt/geo/curvexyzhelical.py @@ -49,7 +49,7 @@ class CurveXYZHelical(JaxCurve): \hat y(\theta) &= \sum_{m=1}^{\text{order}} y_{s,m} sin(2pi n_{\text{fp}} m \theta)\\ x(\theta) &= \hat x(\theta) \cos(2pi \theta) - \hat y(\theta) \sin(2pi \theta)\\ y(\theta) &= \hat x(\theta) \sin(2pi \theta) + \hat y(\theta) \cos(2pi \theta)\\ - z(\theta) &= \sum_{i=0}^{\text{order}} z_{s,m} sin(2pi n_{\text{fp}} \theta) + z(\theta) &= \sum_{i=1}^{\text{order}} z_{s,m} sin(2pi n_{\text{fp}} \theta) if the coil is stellarator symmetric. When the coil is not stellarator symmetric, the formulas above become .. math:: From cdebaf33f153aa3cb213ded5801a58f284569253 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Thu, 18 Apr 2024 12:15:59 -0400 Subject: [PATCH 039/131] cleaning up unit tests --- tests/geo/test_curve.py | 113 ++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 57 deletions(-) diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 1bf8be5ef..53340a933 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -126,7 +126,32 @@ class Testing(unittest.TestCase): curvetypes = ["CurveXYZFourier", "JaxCurveXYZFourier", "CurveRZFourier", "CurvePlanarFourier", "CurveHelical", "CurveXYZHelical1","CurveXYZHelical2", "CurveHelicalInitx0"] - def test_curve_xyzhelical_xyzfourier(self): + def get_curvexyzhelical(self, stellsym=True, x=None, nfp=None): + # returns a CurveXYZHelical that is randomly perturbed + + np.random.seed(1) + rand_scale = 1e-2 + + if nfp is None: + nfp = 3 + if x is None: + x = np.linspace(0, 1, 200, endpoint=False) + + order = 2 + curve = CurveXYZHelical(x, order, nfp, stellsym) + R = 1 + r = 0.25 + curve.set('xc(0)', R) + curve.set('xc(2)', r) + curve.set('ys(2)', -r) + curve.set('zs(1)', -2*r) + curve.set('zs(2)', r) + dofs = curve.x.copy() + curve.x = dofs + rand_scale * np.random.rand(len(dofs)).reshape(dofs.shape) + + return curve + + def test_curvehelical_is_curvexyzhelical(self): # this test checks that both helical coil representations can produce the same helical curve on a torus order = 1 nfp = 2 @@ -140,24 +165,35 @@ def test_curve_xyzhelical_xyzfourier(self): curve2 = CurveHelical(x, order, nfp, 1, R, r, x0=np.zeros((2*order,))) assert np.mean(np.linalg.norm(curve1.gamma()-curve2.gamma(), axis=-1)) == 0 - def test_xyzhelical_symmetries(self): - # does the stellarator symmetric curve have rotational symmetry? - np.random.seed(1) - rand_scale = 1e-2 - order = 2 + def test_nonstellsym(self): + # this test checks that you can obtain a stellarator symmetric magnetic field from two non-stellarator symmetric + # CurveXYZHelical curves. nfp = 3 - x = np.array([0.123, 0.123+1/nfp]) - curve = CurveXYZHelical(x, order, nfp, True) - R = 1 - r = 0.25 - curve.set('xc(0)', R) - curve.set('xc(2)', r) - curve.set('ys(2)', -r) - curve.set('zs(1)', -2*r) - curve.set('zs(2)', r) - dofs = curve.x.copy() - curve.x = dofs + rand_scale * np.random.rand(len(dofs)).reshape(dofs.shape) + curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp) + from simsopt.field import BiotSavart, Current, coils_via_symmetries, Coil + current = Current(1e5) + coils = coils_via_symmetries([curve], [current], 1, True) + bs = BiotSavart(coils) + bs.set_points([[1, 1, 1], [1, -1, -1]]) + B=bs.B_cyl() + assert np.abs(B[0, 0]+B[1, 0]) <1e-15 + assert np.abs(B[0, 1]-B[1, 1]) <1e-15 + assert np.abs(B[0, 2]-B[1, 2]) <1e-15 + + # sanity check that a nonstellarator symmetric CurveXYZHelical produces a non-stellsym magnetic field + bs = BiotSavart([Coil(curve, Current(1e5))]) + bs.set_points([[1, 1, 1], [1, -1, -1]]) + B=bs.B_cyl() + assert not np.abs(B[0, 0]+B[1, 0]) <1e-15 + assert not np.abs(B[0, 1]-B[1, 1]) <1e-15 + assert not np.abs(B[0, 2]-B[1, 2]) <1e-15 + + def test_xyzhelical_symmetries(self): + + nfp = 3 + # does the stellarator symmetric curve have rotational symmetry? + curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x = np.array([0.123, 0.123+1/nfp])) out = curve.gamma() alpha = -2*np.pi/nfp R = np.array([[np.cos(alpha), np.sin(alpha), 0], [-np.sin(alpha), np.cos(alpha), 0], [0, 0, 1]]) @@ -165,19 +201,7 @@ def test_xyzhelical_symmetries(self): assert np.linalg.norm(out[1]-R@out[0])<1e-15 # is the stellarator symmetric curve actually stellarator symmetric? - order = 2 - nfp = 3 - x = np.array([0.123, -0.123]) - curve = CurveXYZHelical(x, order, nfp, True) - R = 1 - r = 0.25 - curve.set('xc(0)', R) - curve.set('xc(2)', r) - curve.set('ys(2)', -r) - curve.set('zs(1)', -2*r) - curve.set('zs(2)', r) - dofs = curve.x.copy() - curve.x = dofs + rand_scale * np.random.rand(len(dofs)).reshape(dofs.shape) + curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x = np.array([0.123, -0.123])) pts = curve.gamma() assert np.abs(pts[0, 0]-pts[1, 0]) <1e-15 assert np.abs(pts[0, 1]+pts[1, 1]) <1e-15 @@ -185,20 +209,8 @@ def test_xyzhelical_symmetries(self): # is the field from the stellarator symmetric curve actually stellarator symmetric? - order = 2 - nfp = 3 - x = np.array([0.123, -0.123]) - curve = CurveXYZHelical(100, order, nfp, True) - R = 1 - r = 0.25 - curve.set('xc(0)', R) - curve.set('xc(2)', r) - curve.set('ys(2)', -r) - curve.set('zs(1)', -2*r) - curve.set('zs(2)', r) - dofs = curve.x.copy() - curve.x = dofs + rand_scale * np.random.rand(len(dofs)).reshape(dofs.shape) from simsopt.field import BiotSavart, Current, Coil + curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x=np.linspace(0, 1, 200, endpoint=False)) current = Current(1e5) coil = Coil(curve, current) bs = BiotSavart([coil]) @@ -209,20 +221,7 @@ def test_xyzhelical_symmetries(self): assert np.abs(B[0, 2]-B[1, 2]) <1e-15 # does the non-stellarator symmetric curve have rotational symmetry still? - order = 2 - nfp = 5 - x = np.array([0.123, 0.123+1/nfp]) - curve = CurveXYZHelical(x, order, nfp, False) - R = 1 - r = 0.25 - curve.set('xc(0)', R) - curve.set('xc(2)', r) - curve.set('ys(2)', -r) - curve.set('zs(1)', -2*r) - curve.set('zs(2)', r) - dofs = curve.x.copy() - curve.x = dofs + rand_scale * np.random.rand(len(dofs)).reshape(dofs.shape) - + curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp, x = np.array([0.123, 0.123+1/nfp])) out = curve.gamma() alpha = -2*np.pi/nfp R = np.array([[np.cos(alpha), np.sin(alpha), 0], [-np.sin(alpha), np.cos(alpha), 0], [0, 0, 1]]) From fddc130f346282434bf5b8947f7f09d68b81c32b Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Thu, 18 Apr 2024 12:18:58 -0400 Subject: [PATCH 040/131] added a couple more unit tests --- tests/geo/test_curve.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 53340a933..72ca22fea 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -200,6 +200,21 @@ def test_xyzhelical_symmetries(self): print(R@out[0], out[1]) assert np.linalg.norm(out[1]-R@out[0])<1e-15 + # does the stellarator symmetric curve indeed pass through (x0, 0, 0)? + curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x = np.array([0])) + out = curve.gamma() + assert out[0, 0] !=0 + assert out[0, 1] == 0 + assert out[0, 2] == 0 + + + # does the non-stellarator symmetric curve not pass through (x0, 0, 0)? + curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp, x = np.array([0])) + out = curve.gamma() + assert out[0, 0] !=0 + assert out[0, 1] != 0 + assert out[0, 2] != 0 + # is the stellarator symmetric curve actually stellarator symmetric? curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x = np.array([0.123, -0.123])) pts = curve.gamma() @@ -207,7 +222,6 @@ def test_xyzhelical_symmetries(self): assert np.abs(pts[0, 1]+pts[1, 1]) <1e-15 assert np.abs(pts[0, 2]+pts[1, 2]) <1e-15 - # is the field from the stellarator symmetric curve actually stellarator symmetric? from simsopt.field import BiotSavart, Current, Coil curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x=np.linspace(0, 1, 200, endpoint=False)) From 12f0ad23222123b25c1c85d2c97dae3867f924b8 Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Fri, 19 Apr 2024 07:42:39 -0400 Subject: [PATCH 041/131] Add CurveXYZHelical to docs and fix typos in docs --- docs/source/simsopt.geo.rst | 8 ++++++++ src/simsopt/geo/__init__.py | 2 ++ src/simsopt/geo/curvexyzhelical.py | 26 +++++++++++++++----------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/docs/source/simsopt.geo.rst b/docs/source/simsopt.geo.rst index 0a1bf5c32..d3da40ea2 100644 --- a/docs/source/simsopt.geo.rst +++ b/docs/source/simsopt.geo.rst @@ -76,6 +76,14 @@ simsopt.geo.curvexyzfourier module :undoc-members: :show-inheritance: +simsopt.geo.curvexyzhelical module +---------------------------------- + +.. automodule:: simsopt.geo.curvexyzhelical + :members: + :undoc-members: + :show-inheritance: + simsopt.geo.finitebuild module ------------------------------ diff --git a/src/simsopt/geo/__init__.py b/src/simsopt/geo/__init__.py index 2270653fb..d0c7116bc 100644 --- a/src/simsopt/geo/__init__.py +++ b/src/simsopt/geo/__init__.py @@ -6,6 +6,7 @@ from .curvehelical import * from .curverzfourier import * from .curvexyzfourier import * +from .curvexyzhelical import * from .curveperturbed import * from .curveobjectives import * from .curveplanarfourier import * @@ -28,6 +29,7 @@ __all__ = (curve.__all__ + curvehelical.__all__ + curverzfourier.__all__ + curvexyzfourier.__all__ + + curvexyzhelical.__all__ + curveperturbed.__all__ + curveobjectives.__all__ + curveplanarfourier.__all__ + finitebuild.__all__ + plotting.__all__ + diff --git a/src/simsopt/geo/curvexyzhelical.py b/src/simsopt/geo/curvexyzhelical.py index 3d690dc1d..77f68c6b6 100644 --- a/src/simsopt/geo/curvexyzhelical.py +++ b/src/simsopt/geo/curvexyzhelical.py @@ -43,21 +43,25 @@ def jaxXYZHelicalFouriercurve_pure(dofs, quadpoints, order, nfp, stellsym): class CurveXYZHelical(JaxCurve): - r'''A curve representation for a helical coil that does not lie on a torus. The coordinates of the curve are given by: + r'''A curve representation for a helical coil that does not lie on a torus. + The coordinates of the curve are given by: + .. math:: - \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} x_{c,m} cos(2pi n_{\text{fp}} m \theta)\\ - \hat y(\theta) &= \sum_{m=1}^{\text{order}} y_{s,m} sin(2pi n_{\text{fp}} m \theta)\\ - x(\theta) &= \hat x(\theta) \cos(2pi \theta) - \hat y(\theta) \sin(2pi \theta)\\ - y(\theta) &= \hat x(\theta) \sin(2pi \theta) + \hat y(\theta) \cos(2pi \theta)\\ - z(\theta) &= \sum_{i=1}^{\text{order}} z_{s,m} sin(2pi n_{\text{fp}} \theta) + \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} x_{c,m} \cos(2 \pi n_{\text{fp}} m \theta)\\ + \hat y(\theta) &= \sum_{m=1}^{\text{order}} y_{s,m} \sin(2 \pi n_{\text{fp}} m \theta)\\ + x(\theta) &= \hat x(\theta) \cos(2 \pi \theta) - \hat y(\theta) \sin(2 \pi \theta)\\ + y(\theta) &= \hat x(\theta) \sin(2 \pi \theta) + \hat y(\theta) \cos(2 \pi \theta)\\ + z(\theta) &= \sum_{m=1}^{\text{order}} z_{s,m} \sin(2 \pi n_{\text{fp}} m \theta) + if the coil is stellarator symmetric. When the coil is not stellarator symmetric, the formulas above become + .. math:: - \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} x_{c, m} cos(2pi m \theta) + x_{s, m} sin(2pi m \theta)\\ - \hat y(\theta) &= y_{c, 0} + \sum_{m=1}^{\text{order}} y_{c, m} cos(2pi m \theta) + y_{s, m} sin(2pi m \theta)\\ - x(\theta) &= \hat x(\theta) \cos(2pi \theta) - \hat y(\theta) \sin(2pi \theta)\\ - y(\theta) &= \hat x(\theta) \sin(2pi \theta) + \hat y(\theta) \cos(2pi \theta)\\ - z(\theta) &= z_{c, 0} + \sum_{m=1}^{\text{order}} z_{c, m} cos(2pi \theta) + z_{s, m} sin(2pi \theta) + \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} \left[ x_{c, m} \cos(2 \pi n_{\text{fp}} m \theta) + x_{s, m} \sin(2 \pi n_{\text{fp}} m \theta) \right] \\ + \hat y(\theta) &= y_{c, 0} + \sum_{m=1}^{\text{order}} \left[ y_{c, m} \cos(2 \pi n_{\text{fp}} m \theta) + y_{s, m} \sin(2 \pi n_{\text{fp}} m \theta) \right] \\ + x(\theta) &= \hat x(\theta) \cos(2 \pi \theta) - \hat y(\theta) \sin(2 \pi \theta)\\ + y(\theta) &= \hat x(\theta) \sin(2 \pi \theta) + \hat y(\theta) \cos(2 \pi \theta)\\ + z(\theta) &= z_{c, 0} + \sum_{m=1}^{\text{order}} \left[ z_{c, m} \cos(2 \pi n_{\text{fp}} m \theta) + z_{s, m} \sin(2 \pi n_{\text{fp}} m \theta) \right] Args: quadpoints: number of grid points/resolution along the curve, From 814d126cd0f38a15cc28e77adaafc359303b6121 Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Fri, 19 Apr 2024 09:18:45 -0400 Subject: [PATCH 042/131] CurveXYZHelical: reduce some redundant code, move imports to top of file --- src/simsopt/geo/curvexyzhelical.py | 12 ++++++------ tests/geo/test_curve.py | 4 +--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/simsopt/geo/curvexyzhelical.py b/src/simsopt/geo/curvexyzhelical.py index 77f68c6b6..f06b1340e 100644 --- a/src/simsopt/geo/curvexyzhelical.py +++ b/src/simsopt/geo/curvexyzhelical.py @@ -7,17 +7,16 @@ def jaxXYZHelicalFouriercurve_pure(dofs, quadpoints, order, nfp, stellsym): + theta, m = jnp.meshgrid(quadpoints, jnp.arange(order + 1), indexing='ij') + if stellsym: xc = dofs[:order+1] ys = dofs[order+1:2*order+1] zs = dofs[2*order+1:] - theta, m = jnp.meshgrid(quadpoints, jnp.arange(order+1), indexing='ij') xhat = np.sum(xc[None, :] * jnp.cos(2 * jnp.pi * nfp*m*theta), axis=1) yhat = np.sum(ys[None, :] * jnp.sin(2 * jnp.pi * nfp*m[:, 1:]*theta[:, 1:]), axis=1) - x = jnp.cos(2*jnp.pi*quadpoints) * xhat - jnp.sin(2*jnp.pi*quadpoints) * yhat - y = jnp.sin(2*jnp.pi*quadpoints) * xhat + jnp.cos(2*jnp.pi*quadpoints) * yhat z = jnp.sum(zs[None, :] * jnp.sin(2*jnp.pi*nfp * m[:, 1:]*theta[:, 1:]), axis=1) else: xc = dofs[0 : order+1] @@ -27,14 +26,15 @@ def jaxXYZHelicalFouriercurve_pure(dofs, quadpoints, order, nfp, stellsym): zc = dofs[4*order+2: 5*order+3] zs = dofs[5*order+3: ] - theta, m = jnp.meshgrid(quadpoints, jnp.arange(order+1), indexing='ij') xhat = np.sum(xc[None, :] * jnp.cos(2*jnp.pi*nfp*m*theta), axis=1) + np.sum(xs[None, :] * jnp.sin(2*jnp.pi*nfp*m[:, 1:]*theta[:, 1:]), axis=1) yhat = np.sum(yc[None, :] * jnp.cos(2*jnp.pi*nfp*m*theta), axis=1) + np.sum(ys[None, :] * jnp.sin(2*jnp.pi*nfp*m[:, 1:]*theta[:, 1:]), axis=1) - x = jnp.cos(2*jnp.pi*quadpoints) * xhat - jnp.sin(2*jnp.pi*quadpoints) * yhat - y = jnp.sin(2*jnp.pi*quadpoints) * xhat + jnp.cos(2*jnp.pi*quadpoints) * yhat z = np.sum(zc[None, :] * jnp.cos(2*jnp.pi*nfp*m*theta), axis=1) + np.sum(zs[None, :] * jnp.sin(2*jnp.pi*nfp*m[:, 1:]*theta[:, 1:]), axis=1) + angle = 2 * jnp.pi * quadpoints + x = jnp.cos(angle) * xhat - jnp.sin(angle) * yhat + y = jnp.sin(angle) * xhat + jnp.cos(angle) * yhat + gamma = jnp.zeros((len(quadpoints),3)) gamma = gamma.at[:, 0].add(x) gamma = gamma.at[:, 1].add(y) diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 72ca22fea..9861a352d 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -15,6 +15,7 @@ from simsopt.geo.curve import RotatedCurve, curves_to_vtk from simsopt.geo import parameters from simsopt.configs.zoo import get_ncsx_data, get_w7x_data +from simsopt.field import BiotSavart, Current, coils_via_symmetries, Coil from simsopt.field.coil import coils_to_makegrid from simsopt.geo import CurveLength, CurveCurveDistance @@ -59,7 +60,6 @@ def taylor_test(f, df, x, epsilons=None, direction=None): print("################################################################################") -#def get_curve(curvetype, rotated, x=np.linspace(0, 1, 100, endpoint=False)): def get_curve(curvetype, rotated, x=np.asarray([0.5])): np.random.seed(2) rand_scale = 0.01 @@ -170,7 +170,6 @@ def test_nonstellsym(self): # CurveXYZHelical curves. nfp = 3 curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp) - from simsopt.field import BiotSavart, Current, coils_via_symmetries, Coil current = Current(1e5) coils = coils_via_symmetries([curve], [current], 1, True) bs = BiotSavart(coils) @@ -223,7 +222,6 @@ def test_xyzhelical_symmetries(self): assert np.abs(pts[0, 2]+pts[1, 2]) <1e-15 # is the field from the stellarator symmetric curve actually stellarator symmetric? - from simsopt.field import BiotSavart, Current, Coil curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x=np.linspace(0, 1, 200, endpoint=False)) current = Current(1e5) coil = Coil(curve, current) From 2cfe3a132a4fad00087f062fb940cc084c710f7a Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 19 Apr 2024 11:08:30 -0400 Subject: [PATCH 043/131] fixed an aligned memory load causing a seg fault + the self-intersection unit test --- src/simsoptpp/boozerresidual_impl.h | 18 +++++++++--------- tests/geo/test_boozersurface.py | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/simsoptpp/boozerresidual_impl.h b/src/simsoptpp/boozerresidual_impl.h index c432e275d..dccaf9f29 100644 --- a/src/simsoptpp/boozerresidual_impl.h +++ b/src/simsoptpp/boozerresidual_impl.h @@ -202,19 +202,19 @@ template void boozer_residual_impl(double G, double iota, T& MYIF(deriv > 1) { // outer product d_rij0_dm (x) d_rij0_dm - for(int m = 0; m < ndofs + 2; m++){ - simd_t drtilij0_dm(drtilij0[m]); - simd_t drtilij1_dm(drtilij1[m]); - simd_t drtilij2_dm(drtilij2[m]); - for(int n = m; n < ndofs + 2; n+=simd_size){ - simd_t drtilij0_dn = xs::load_aligned(&drtilij0[n]); - simd_t drtilij1_dn = xs::load_aligned(&drtilij1[n]); - simd_t drtilij2_dn = xs::load_aligned(&drtilij2[n]); + for(int m = 0; m < ndofs + 2; m+=simd_size){ + simd_t drtilij0_dm = xs::load_aligned(&drtilij0[m]); + simd_t drtilij1_dm = xs::load_aligned(&drtilij1[m]); + simd_t drtilij2_dm = xs::load_aligned(&drtilij2[m]); + for(int n = m; n < ndofs + 2; n++){ + simd_t drtilij0_dn(drtilij0[n]); + simd_t drtilij1_dn(drtilij1[n]); + simd_t drtilij2_dn(drtilij2[n]); simd_t d2res_mn = drtilij0_dm * drtilij0_dn + drtilij1_dm * drtilij1_dn + drtilij2_dm * drtilij2_dn; int jjlimit = std::min(simd_size, ndofs+2-n); for(int jj = 0; jj < jjlimit; jj++){ - d2res(m, n+jj) += d2res_mn[jj]; + d2res(m+jj, n) += d2res_mn[jj]; } } } diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 2be3bfa95..6c5dd0f50 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -326,7 +326,7 @@ def subtest_boozer_surface_optimisation_convergence(self, surfacetype, print('Residual norm after second stage', np.linalg.norm(res['residual'])) assert res['success'] - assert boozer_surface.surface.is_self_intersecting(thetas=100) + assert not boozer_surface.surface.is_self_intersecting(thetas=100) # For the stellsym case we have z(0, 0) = y(0, 0) = 0. For the not # stellsym case, we enforce z(0, 0) = 0, but expect y(0, 0) \neq 0 From cda2234ab928ec89125662dac0036141d4c991d7 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 19 Apr 2024 11:55:49 -0400 Subject: [PATCH 044/131] adding missing packages for github actions --- .github/workflows/non_simd_tests.yml | 2 +- tests/geo/test_boozersurface.py | 36 +++++++--------------------- 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/.github/workflows/non_simd_tests.yml b/.github/workflows/non_simd_tests.yml index f3ae7c6c3..b59209470 100644 --- a/.github/workflows/non_simd_tests.yml +++ b/.github/workflows/non_simd_tests.yml @@ -84,7 +84,7 @@ jobs: - name: Install python dependencies run: | sudo apt-get install graphviz graphviz-dev - pip install wheel numpy scipy f90nml h5py scikit-build cmake qsc sympy pyevtk matplotlib ninja plotly networkx pygraphviz + pip install wheel numpy scipy f90nml h5py scikit-build cmake qsc sympy pyevtk matplotlib ninja plotly networkx pygraphviz ground bentley_ottmann - name: Install booz_xform run: pip install -v git+https://github.com/hiddenSymmetries/booz_xform diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 6c5dd0f50..ad771a714 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -60,8 +60,7 @@ def test_boozer_penalty_constraints_gradient(self): stellsym=stellsym, optimize_G=optimize_G, vectorize=vectorize): - self.subtest_boozer_penalty_constraints_gradient( - surfacetype, stellsym, optimize_G, vectorize) + self.subtest_boozer_penalty_constraints_gradient(surfacetype, stellsym, optimize_G, vectorize) def test_boozer_penalty_constraints_hessian(self): """ @@ -97,17 +96,13 @@ def subtest_boozer_penalty_constraints_gradient(self, surfacetype, stellsym, tf_target = 0.1 boozer_surface = BoozerSurface(bs, s, tf, tf_target) + fun = boozer_surface.boozer_penalty_constraints_vectorized if vectorize else boozer_surface.boozer_penalty_constraints iota = -0.3 x = np.concatenate((s.get_dofs(), [iota])) if optimize_G: x = np.concatenate((x, [2.*np.pi*current_sum*(4*np.pi*10**(-7)/(2 * np.pi))])) - if vectorize: - f0, J0 = boozer_surface.boozer_penalty_constraints_vectorized( - x, derivatives=1, constraint_weight=weight, optimize_G=optimize_G) - else: - f0, J0 = boozer_surface.boozer_penalty_constraints( - x, derivatives=1, constraint_weight=weight, optimize_G=optimize_G) + f0, J0 = fun(x, derivatives=1, constraint_weight=weight, optimize_G=optimize_G) h = np.random.uniform(size=x.shape)-0.5 Jex = J0@h @@ -115,14 +110,7 @@ def subtest_boozer_penalty_constraints_gradient(self, surfacetype, stellsym, epsilons = np.power(2., -np.asarray(range(7, 20))) print("###############################################################") for eps in epsilons: - if vectorize: - f1 = boozer_surface.boozer_penalty_constraints_vectorized( - x + eps*h, derivatives=0, constraint_weight=weight, - optimize_G=optimize_G) - else: - f1 = boozer_surface.boozer_penalty_constraints( - x + eps*h, derivatives=0, constraint_weight=weight, - optimize_G=optimize_G) + f1 = fun(x + eps*h, derivatives=0, constraint_weight=weight, optimize_G=optimize_G) Jfd = (f1-f0)/eps err = np.linalg.norm(Jfd-Jex)/np.linalg.norm(Jex) print(err/err_old, f0, f1) @@ -146,18 +134,15 @@ def subtest_boozer_penalty_constraints_hessian(self, surfacetype, stellsym, tf_target = 0.1 boozer_surface = BoozerSurface(bs, s, tf, tf_target) + fun = boozer_surface.boozer_penalty_constraints_vectorized if vectorize else boozer_surface.boozer_penalty_constraints iota = -0.3 x = np.concatenate((s.get_dofs(), [iota])) if optimize_G: x = np.concatenate( (x, [2.*np.pi*current_sum*(4*np.pi*10**(-7)/(2 * np.pi))])) - if vectorize: - f0, J0, H0 = boozer_surface.boozer_penalty_constraints_vectorized( - x, derivatives=2, optimize_G=optimize_G) - else: - f0, J0, H0 = boozer_surface.boozer_penalty_constraints( - x, derivatives=2, optimize_G=optimize_G) + + f0, J0, H0 = fun(x, derivatives=2, optimize_G=optimize_G) h1 = np.random.uniform(size=x.shape)-0.5 h2 = np.random.uniform(size=x.shape)-0.5 d2f = h1 @ H0 @ h2 @@ -166,12 +151,7 @@ def subtest_boozer_penalty_constraints_hessian(self, surfacetype, stellsym, epsilons = np.power(2., -np.asarray(range(10, 20))) print("###############################################################") for eps in epsilons: - if vectorize: - fp, Jp = boozer_surface.boozer_penalty_constraints_vectorized( - x + eps*h1, derivatives=1, optimize_G=optimize_G) - else: - fp, Jp = boozer_surface.boozer_penalty_constraints( - x + eps*h1, derivatives=1, optimize_G=optimize_G) + fp, Jp = fun(x + eps*h1, derivatives=1, optimize_G=optimize_G) d2f_fd = (Jp@h2-J0@h2)/eps err = np.abs(d2f_fd-d2f)/np.abs(d2f) print(err/err_old) From a694dca16c02306c933d53979202774ffb4d39fe Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 19 Apr 2024 12:43:54 -0400 Subject: [PATCH 045/131] tightening tolerances to unit test doesn't fail --- tests/geo/test_boozersurface.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index ad771a714..8a1ed1bbe 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -284,7 +284,7 @@ def subtest_boozer_surface_optimisation_convergence(self, surfacetype, # compute surface first using LBFGS exact and an area constraint res = boozer_surface.minimize_boozer_penalty_constraints_LBFGS( - tol=1e-9, maxiter=600, constraint_weight=100., iota=iota, G=G, + tol=1e-10, maxiter=600, constraint_weight=100., iota=iota, G=G, vectorize=vectorize) print('Residual norm after LBFGS', np.sqrt(2*res['fun'])) @@ -295,11 +295,11 @@ def subtest_boozer_surface_optimisation_convergence(self, surfacetype, iota=res['iota'], G=res['G']) elif second_stage == 'newton': res = boozer_surface.minimize_boozer_penalty_constraints_newton( - tol=1e-9, maxiter=15, constraint_weight=100., + tol=1e-10, maxiter=20, constraint_weight=100., iota=res['iota'], G=res['G'], stab=1e-4, vectorize=vectorize) elif second_stage == 'newton_exact': res = boozer_surface.minimize_boozer_exact_constraints_newton( - tol=1e-9, maxiter=15, iota=res['iota'], G=res['G']) + tol=1e-10, maxiter=15, iota=res['iota'], G=res['G']) elif second_stage == 'residual_exact': res = boozer_surface.solve_residual_equation_exactly_newton( tol=1e-12, maxiter=15, iota=res['iota'], G=res['G']) From 42f13c9a2481739d9908b7205c7fc1f18c5afa61 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 19 Apr 2024 19:39:44 -0400 Subject: [PATCH 046/131] fixing unit tests --- tests/geo/test_curve.py | 45 +++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 9861a352d..a6b822bee 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -163,7 +163,7 @@ def test_curvehelical_is_curvexyzhelical(self): curve1.set('xc(1)', r) curve1.set('zs(1)', -r) curve2 = CurveHelical(x, order, nfp, 1, R, r, x0=np.zeros((2*order,))) - assert np.mean(np.linalg.norm(curve1.gamma()-curve2.gamma(), axis=-1)) == 0 + np.testing.assert_allclose(curve1.gamma(), curve2.gamma(), atol=1e-14) def test_nonstellsym(self): # this test checks that you can obtain a stellarator symmetric magnetic field from two non-stellarator symmetric @@ -175,18 +175,9 @@ def test_nonstellsym(self): bs = BiotSavart(coils) bs.set_points([[1, 1, 1], [1, -1, -1]]) B=bs.B_cyl() - assert np.abs(B[0, 0]+B[1, 0]) <1e-15 - assert np.abs(B[0, 1]-B[1, 1]) <1e-15 - assert np.abs(B[0, 2]-B[1, 2]) <1e-15 - - # sanity check that a nonstellarator symmetric CurveXYZHelical produces a non-stellsym magnetic field - bs = BiotSavart([Coil(curve, Current(1e5))]) - bs.set_points([[1, 1, 1], [1, -1, -1]]) - B=bs.B_cyl() - assert not np.abs(B[0, 0]+B[1, 0]) <1e-15 - assert not np.abs(B[0, 1]-B[1, 1]) <1e-15 - assert not np.abs(B[0, 2]-B[1, 2]) <1e-15 - + np.testing.assert_allclose(B[0, 0], -B[1, 0], atol=1e-14) + np.testing.assert_allclose(B[0, 1], B[1, 1], atol=1e-14) + np.testing.assert_allclose(B[0, 2], B[1, 2], atol=1e-14) def test_xyzhelical_symmetries(self): @@ -197,29 +188,29 @@ def test_xyzhelical_symmetries(self): alpha = -2*np.pi/nfp R = np.array([[np.cos(alpha), np.sin(alpha), 0], [-np.sin(alpha), np.cos(alpha), 0], [0, 0, 1]]) print(R@out[0], out[1]) - assert np.linalg.norm(out[1]-R@out[0])<1e-15 + np.testing.assert_allclose(out[1], R@out[0], atol=1e-14) # does the stellarator symmetric curve indeed pass through (x0, 0, 0)? curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x = np.array([0])) out = curve.gamma() - assert out[0, 0] !=0 - assert out[0, 1] == 0 - assert out[0, 2] == 0 + assert np.abs(out[0, 0]) > 1e-3 + np.testing.assert_allclose(out[0, 1], 0, atol=1e-14) + np.testing.assert_allclose(out[0, 2], 0, atol=1e-14) # does the non-stellarator symmetric curve not pass through (x0, 0, 0)? curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp, x = np.array([0])) out = curve.gamma() - assert out[0, 0] !=0 - assert out[0, 1] != 0 - assert out[0, 2] != 0 + assert np.abs(out[0, 0]) > 1e-3 + assert np.abs(out[0, 1]) > 1e-3 + assert np.abs(out[0, 2]) > 1e-3 # is the stellarator symmetric curve actually stellarator symmetric? curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x = np.array([0.123, -0.123])) pts = curve.gamma() - assert np.abs(pts[0, 0]-pts[1, 0]) <1e-15 - assert np.abs(pts[0, 1]+pts[1, 1]) <1e-15 - assert np.abs(pts[0, 2]+pts[1, 2]) <1e-15 + np.testing.assert_allclose(pts[0, 0], pts[1, 0], atol=1e-14) + np.testing.assert_allclose(pts[0, 1], -pts[1, 1], atol= 1e-14) + np.testing.assert_allclose(pts[0, 2], -pts[1, 2], atol= 1e-14) # is the field from the stellarator symmetric curve actually stellarator symmetric? curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x=np.linspace(0, 1, 200, endpoint=False)) @@ -228,9 +219,9 @@ def test_xyzhelical_symmetries(self): bs = BiotSavart([coil]) bs.set_points([[1, 1, 1], [1, -1, -1]]) B=bs.B_cyl() - assert np.abs(B[0, 0]+B[1, 0]) <1e-15 - assert np.abs(B[0, 1]-B[1, 1]) <1e-15 - assert np.abs(B[0, 2]-B[1, 2]) <1e-15 + np.testing.assert_allclose(B[0, 0],-B[1, 0], atol=1e-14) + np.testing.assert_allclose(B[0, 1], B[1, 1], atol=1e-14) + np.testing.assert_allclose(B[0, 2], B[1, 2], atol=1e-14) # does the non-stellarator symmetric curve have rotational symmetry still? curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp, x = np.array([0.123, 0.123+1/nfp])) @@ -238,7 +229,7 @@ def test_xyzhelical_symmetries(self): alpha = -2*np.pi/nfp R = np.array([[np.cos(alpha), np.sin(alpha), 0], [-np.sin(alpha), np.cos(alpha), 0], [0, 0, 1]]) print(R@out[0], out[1]) - assert np.linalg.norm(out[1]-R@out[0])<1e-15 + np.testing.assert_allclose(out[1], R@out[0], atol=1e-14) def test_curve_helical_xyzfourier(self): x = np.asarray([0.6]) From b5123c01a78d33863221cbea4fe9d48e4e368023 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Sat, 20 Apr 2024 17:41:21 -0400 Subject: [PATCH 047/131] first attempt at allowing CurveXYZHelical to wrap multiple times toroidally before biting its tail --- src/simsopt/geo/curvexyzhelical.py | 31 +++++++++----- tests/geo/test_curve.py | 67 ++++++++++++++++++++++-------- 2 files changed, 70 insertions(+), 28 deletions(-) diff --git a/src/simsopt/geo/curvexyzhelical.py b/src/simsopt/geo/curvexyzhelical.py index f06b1340e..acffac2a9 100644 --- a/src/simsopt/geo/curvexyzhelical.py +++ b/src/simsopt/geo/curvexyzhelical.py @@ -1,11 +1,12 @@ import jax.numpy as jnp import numpy as np from .curve import JaxCurve +from math import gcd __all__ = ['CurveXYZHelical'] -def jaxXYZHelicalFouriercurve_pure(dofs, quadpoints, order, nfp, stellsym): +def jaxXYZHelicalFouriercurve_pure(dofs, quadpoints, order, nfp, stellsym, ntor): theta, m = jnp.meshgrid(quadpoints, jnp.arange(order + 1), indexing='ij') @@ -31,7 +32,7 @@ def jaxXYZHelicalFouriercurve_pure(dofs, quadpoints, order, nfp, stellsym): z = np.sum(zc[None, :] * jnp.cos(2*jnp.pi*nfp*m*theta), axis=1) + np.sum(zs[None, :] * jnp.sin(2*jnp.pi*nfp*m[:, 1:]*theta[:, 1:]), axis=1) - angle = 2 * jnp.pi * quadpoints + angle = 2 * jnp.pi * quadpoints * ntor x = jnp.cos(angle) * xhat - jnp.sin(angle) * yhat y = jnp.sin(angle) * xhat + jnp.cos(angle) * yhat @@ -49,8 +50,8 @@ class CurveXYZHelical(JaxCurve): .. math:: \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} x_{c,m} \cos(2 \pi n_{\text{fp}} m \theta)\\ \hat y(\theta) &= \sum_{m=1}^{\text{order}} y_{s,m} \sin(2 \pi n_{\text{fp}} m \theta)\\ - x(\theta) &= \hat x(\theta) \cos(2 \pi \theta) - \hat y(\theta) \sin(2 \pi \theta)\\ - y(\theta) &= \hat x(\theta) \sin(2 \pi \theta) + \hat y(\theta) \cos(2 \pi \theta)\\ + x(\theta) &= \hat x(\theta) \cos(2 \pi \theta n_{\text{tor}}) - \hat y(\theta) \sin(2 \pi \theta n_{\text{tor}})\\ + y(\theta) &= \hat x(\theta) \sin(2 \pi \theta n_{\text{tor}}) + \hat y(\theta) \cos(2 \pi \theta n_{\text{tor}})\\ z(\theta) &= \sum_{m=1}^{\text{order}} z_{s,m} \sin(2 \pi n_{\text{fp}} m \theta) if the coil is stellarator symmetric. When the coil is not stellarator symmetric, the formulas above @@ -59,26 +60,36 @@ class CurveXYZHelical(JaxCurve): .. math:: \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} \left[ x_{c, m} \cos(2 \pi n_{\text{fp}} m \theta) + x_{s, m} \sin(2 \pi n_{\text{fp}} m \theta) \right] \\ \hat y(\theta) &= y_{c, 0} + \sum_{m=1}^{\text{order}} \left[ y_{c, m} \cos(2 \pi n_{\text{fp}} m \theta) + y_{s, m} \sin(2 \pi n_{\text{fp}} m \theta) \right] \\ - x(\theta) &= \hat x(\theta) \cos(2 \pi \theta) - \hat y(\theta) \sin(2 \pi \theta)\\ - y(\theta) &= \hat x(\theta) \sin(2 \pi \theta) + \hat y(\theta) \cos(2 \pi \theta)\\ + x(\theta) &= \hat x(\theta) \cos(2 \pi \theta n_{\text{tor}}) - \hat y(\theta) \sin(2 \pi \theta n_{\text{tor}})\\ + y(\theta) &= \hat x(\theta) \sin(2 \pi \theta n_{\text{tor}}) + \hat y(\theta) \cos(2 \pi \theta n_{\text{tor}})\\ z(\theta) &= z_{c, 0} + \sum_{m=1}^{\text{order}} \left[ z_{c, m} \cos(2 \pi n_{\text{fp}} m \theta) + z_{s, m} \sin(2 \pi n_{\text{fp}} m \theta) \right] - + Args: quadpoints: number of grid points/resolution along the curve, order: how many Fourier harmonics to include in the Fourier representation, nfp: discrete rotational symmetry number, - stellsym: stellaratory symmetry if True, not stellarator symmetric otherwise. + stellsym: stellaratory symmetry if True, not stellarator symmetric otherwise, + ntor: the number of times the curve wraps toroidally before biting its tail. Note, + it is assumed that nfp and ntor are coprime. If they are not coprime, + then then the curve actually has nfp_new:=nfp // gcd(nfp, ntor), + and ntor_new:=ntor // gcd(nfp, ntor). To avoid confusion, + we assert that ntor and nfp are coprime at instatiation. ''' - def __init__(self, quadpoints, order, nfp, stellsym, **kwargs): + def __init__(self, quadpoints, order, nfp, stellsym, ntor=1, **kwargs): if isinstance(quadpoints, int): quadpoints = np.linspace(0, 1, quadpoints, endpoint=False) pure = lambda dofs, points: jaxXYZHelicalFouriercurve_pure( - dofs, points, order, nfp, stellsym) + dofs, points, order, nfp, stellsym, ntor) + nfp_true = nfp // gcd(nfp, ntor) + if nfp != nfp_true: + raise Exception('nfp and ntor must be coprime') + self.order = order self.nfp = nfp self.stellsym = stellsym + self.ntor = ntor self.coefficients = np.zeros(self.num_dofs()) if "dofs" not in kwargs: if "x0" not in kwargs: diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index a6b822bee..dc14c4113 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -18,7 +18,7 @@ from simsopt.field import BiotSavart, Current, coils_via_symmetries, Coil from simsopt.field.coil import coils_to_makegrid from simsopt.geo import CurveLength, CurveCurveDistance - +from math import gcd try: import pyevtk @@ -126,7 +126,7 @@ class Testing(unittest.TestCase): curvetypes = ["CurveXYZFourier", "JaxCurveXYZFourier", "CurveRZFourier", "CurvePlanarFourier", "CurveHelical", "CurveXYZHelical1","CurveXYZHelical2", "CurveHelicalInitx0"] - def get_curvexyzhelical(self, stellsym=True, x=None, nfp=None): + def get_curvexyzhelical(self, stellsym=True, x=None, nfp=None, ntor=1): # returns a CurveXYZHelical that is randomly perturbed np.random.seed(1) @@ -138,7 +138,7 @@ def get_curvexyzhelical(self, stellsym=True, x=None, nfp=None): x = np.linspace(0, 1, 200, endpoint=False) order = 2 - curve = CurveXYZHelical(x, order, nfp, stellsym) + curve = CurveXYZHelical(x, order, nfp, stellsym, ntor=ntor) R = 1 r = 0.25 curve.set('xc(0)', R) @@ -164,12 +164,21 @@ def test_curvehelical_is_curvexyzhelical(self): curve1.set('zs(1)', -r) curve2 = CurveHelical(x, order, nfp, 1, R, r, x0=np.zeros((2*order,))) np.testing.assert_allclose(curve1.gamma(), curve2.gamma(), atol=1e-14) - + def test_nonstellsym(self): + for nfp in [1, 2, 3, 4, 5, 6]: + for ntor in [1, 2, 3, 4, 5, 6]: + with self.subTest(nfp=nfp, ntor=ntor): + self.subtest_nonstellsym(nfp, ntor) + + def subtest_nonstellsym(self, nfp, ntor): + nfp_true = nfp // gcd(ntor, nfp) + if nfp_true != nfp: + return + # this test checks that you can obtain a stellarator symmetric magnetic field from two non-stellarator symmetric # CurveXYZHelical curves. - nfp = 3 - curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp) + curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp, ntor=ntor) current = Current(1e5) coils = coils_via_symmetries([curve], [current], 1, True) bs = BiotSavart(coils) @@ -178,20 +187,39 @@ def test_nonstellsym(self): np.testing.assert_allclose(B[0, 0], -B[1, 0], atol=1e-14) np.testing.assert_allclose(B[0, 1], B[1, 1], atol=1e-14) np.testing.assert_allclose(B[0, 2], B[1, 2], atol=1e-14) + + def test_ntor(self): + # this test checks that you can obtain a stellarator symmetric magnetic field from two non-stellarator symmetric + # CurveXYZHelical curves. + for nfp in [1, 2, 3, 4, 5, 6]: + for ntor in [1, 2, 3, 4, 5, 6]: + with self.subTest(nfp=nfp, ntor=ntor): + self.subtest_xyzhelical_symmetries(nfp, ntor) + + def subtest_xyzhelical_symmetries(self, nfp, ntor): + + nfp_true = nfp // gcd(ntor, nfp) + if nfp_true != nfp: + return - def test_xyzhelical_symmetries(self): - - nfp = 3 # does the stellarator symmetric curve have rotational symmetry? - curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x = np.array([0.123, 0.123+1/nfp])) + curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x=np.array([0.123, 0.123+ntor/nfp]), ntor=ntor) out = curve.gamma() alpha = -2*np.pi/nfp - R = np.array([[np.cos(alpha), np.sin(alpha), 0], [-np.sin(alpha), np.cos(alpha), 0], [0, 0, 1]]) + R = np.array([ + [np.cos(alpha), np.sin(alpha), 0], + [-np.sin(alpha), np.cos(alpha), 0], + [0, 0, 1] + ]) + print(R@out[0], out[1]) - np.testing.assert_allclose(out[1], R@out[0], atol=1e-14) + try: + np.testing.assert_allclose(out[1], R@out[0], atol=1e-14) + except: + np.testing.assert_allclose(out[1], np.linalg.inv(R)@out[0], atol=1e-14) # does the stellarator symmetric curve indeed pass through (x0, 0, 0)? - curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x = np.array([0])) + curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x = np.array([0]), ntor=ntor) out = curve.gamma() assert np.abs(out[0, 0]) > 1e-3 np.testing.assert_allclose(out[0, 1], 0, atol=1e-14) @@ -199,21 +227,21 @@ def test_xyzhelical_symmetries(self): # does the non-stellarator symmetric curve not pass through (x0, 0, 0)? - curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp, x = np.array([0])) + curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp, x = np.array([0]), ntor=ntor) out = curve.gamma() assert np.abs(out[0, 0]) > 1e-3 assert np.abs(out[0, 1]) > 1e-3 assert np.abs(out[0, 2]) > 1e-3 # is the stellarator symmetric curve actually stellarator symmetric? - curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x = np.array([0.123, -0.123])) + curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x = np.array([0.123, -0.123]), ntor=ntor) pts = curve.gamma() np.testing.assert_allclose(pts[0, 0], pts[1, 0], atol=1e-14) np.testing.assert_allclose(pts[0, 1], -pts[1, 1], atol= 1e-14) np.testing.assert_allclose(pts[0, 2], -pts[1, 2], atol= 1e-14) # is the field from the stellarator symmetric curve actually stellarator symmetric? - curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x=np.linspace(0, 1, 200, endpoint=False)) + curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x=np.linspace(0, 1, 200, endpoint=False), ntor=ntor) current = Current(1e5) coil = Coil(curve, current) bs = BiotSavart([coil]) @@ -224,12 +252,15 @@ def test_xyzhelical_symmetries(self): np.testing.assert_allclose(B[0, 2], B[1, 2], atol=1e-14) # does the non-stellarator symmetric curve have rotational symmetry still? - curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp, x = np.array([0.123, 0.123+1/nfp])) + curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp, x = np.array([0.123, 0.123+ntor/nfp]), ntor=ntor) out = curve.gamma() alpha = -2*np.pi/nfp R = np.array([[np.cos(alpha), np.sin(alpha), 0], [-np.sin(alpha), np.cos(alpha), 0], [0, 0, 1]]) print(R@out[0], out[1]) - np.testing.assert_allclose(out[1], R@out[0], atol=1e-14) + try: + np.testing.assert_allclose(out[1], R@out[0], atol=1e-14) + except: + np.testing.assert_allclose(out[1], np.linalg.inv(R)@out[0], atol=1e-14) def test_curve_helical_xyzfourier(self): x = np.asarray([0.6]) From 1a435df8e31f68c98f468d32434c04758aa44480 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Sat, 20 Apr 2024 18:12:00 -0400 Subject: [PATCH 048/131] fixing some docstrings in the tests --- tests/geo/test_curve.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index dc14c4113..daf613e94 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -166,6 +166,8 @@ def test_curvehelical_is_curvexyzhelical(self): np.testing.assert_allclose(curve1.gamma(), curve2.gamma(), atol=1e-14) def test_nonstellsym(self): + # this test checks that you can obtain a stellarator symmetric magnetic field from two non-stellarator symmetric + # CurveXYZHelical curves. for nfp in [1, 2, 3, 4, 5, 6]: for ntor in [1, 2, 3, 4, 5, 6]: with self.subTest(nfp=nfp, ntor=ntor): @@ -188,16 +190,14 @@ def subtest_nonstellsym(self, nfp, ntor): np.testing.assert_allclose(B[0, 1], B[1, 1], atol=1e-14) np.testing.assert_allclose(B[0, 2], B[1, 2], atol=1e-14) - def test_ntor(self): - # this test checks that you can obtain a stellarator symmetric magnetic field from two non-stellarator symmetric - # CurveXYZHelical curves. + def test_xyzhelical_symmetries(self): + # checking various symmetries of the CurveXYZHelical representation for nfp in [1, 2, 3, 4, 5, 6]: for ntor in [1, 2, 3, 4, 5, 6]: with self.subTest(nfp=nfp, ntor=ntor): self.subtest_xyzhelical_symmetries(nfp, ntor) def subtest_xyzhelical_symmetries(self, nfp, ntor): - nfp_true = nfp // gcd(ntor, nfp) if nfp_true != nfp: return From 4a608ef6b338feb5c8784e01255180f0a3e90fda Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Sat, 20 Apr 2024 18:29:50 -0400 Subject: [PATCH 049/131] changes to unit test --- src/simsopt/geo/boozersurface.py | 1 - src/simsoptpp/python.cpp | 2 -- tests/geo/test_boozersurface.py | 3 +-- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 58acc02e4..b4d8482aa 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -40,7 +40,6 @@ class BoozerSurface(Optimizable): where Newton is used to solve the first order necessary conditions for optimality. """ - def __init__(self, biotsavart, surface, label, targetlabel): super().__init__(depends_on=[biotsavart]) self.biotsavart = biotsavart diff --git a/src/simsoptpp/python.cpp b/src/simsoptpp/python.cpp index 2f153c5a3..3082265fe 100644 --- a/src/simsoptpp/python.cpp +++ b/src/simsoptpp/python.cpp @@ -12,8 +12,6 @@ typedef xt::pytensor PyTensor; #include - - #include "biot_savart_py.h" #include "biot_savart_vjp_py.h" #include "boozerradialinterpolant.h" diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 8a1ed1bbe..075438f13 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -360,8 +360,7 @@ def test_boozer_penalty_constraints_cpp_notcpp(self): for surfacetype in surfacetypes_list: for stellsym in stellsym_list: for weight_inv_modB in [False, True]: - for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1)]: - #for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 2, 2), (False, 2, 1), (True, 6, 9), (False, 7, 8),(True, 3, 3), (False, 3, 3)]: + for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 2, 2), (False, 2, 1), (True, 6, 9), (False, 7, 8),(True, 3, 3), (False, 3, 3)]: with self.subTest(surfacetype=surfacetype, stellsym=stellsym, optimize_G=optimize_G, From c6b445b933ba2b2aa33a2478f21042fcb4edc569 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Sat, 20 Apr 2024 18:34:46 -0400 Subject: [PATCH 050/131] was missing some vectorized calls --- src/simsopt/geo/boozersurface.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index b4d8482aa..09ba226a9 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -324,12 +324,9 @@ def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, cons else: x = np.concatenate((s.get_dofs(), [iota, G])) - if vectorize: - fun = lambda x: self.boozer_penalty_constraints_vectorized( - x, derivatives=1, constraint_weight=constraint_weight, optimize_G=G is not None) - else: - fun = lambda x: self.boozer_penalty_constraints( - x, derivatives=1, constraint_weight=constraint_weight, optimize_G=G is not None) + fun_name = self.boozer_penalty_constraints_vectorized else lambda x: self.boozer_penalty_constraints + fun = lambda x: fun_name(x, derivatives=1, constraint_weight=constraint_weight, optimize_G=G is not None) + res = minimize( fun, x, jac=True, method='L-BFGS-B', options={'maxiter': maxiter, 'ftol': tol, 'gtol': tol, 'maxcor': 200}) @@ -367,12 +364,9 @@ def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, cons x = np.concatenate((s.get_dofs(), [iota, G])) i = 0 - if vectorize: - val, dval, d2val = self.boozer_penalty_constraints_vectorized( - x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) - else: - val, dval, d2val = self.boozer_penalty_constraints( - x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) + fun_name = self.boozer_penalty_constraints_vectorized else lambda x: self.boozer_penalty_constraints + val, dval, d2val = fun_name(x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) + norm = np.linalg.norm(dval) while i < maxiter and norm > tol: d2val += stab*np.identity(d2val.shape[0]) @@ -380,13 +374,11 @@ def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, cons if norm < 1e-9: dx += np.linalg.solve(d2val, dval - d2val@dx) x = x - dx - val, dval, d2val = self.boozer_penalty_constraints( - x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) + val, dval, d2val = fun_name(x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) norm = np.linalg.norm(dval) i = i+1 - r = self.boozer_penalty_constraints( - x, derivatives=0, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) + r = fun_name(x, derivatives=0, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) res = { "residual": r, "jacobian": dval, "hessian": d2val, "iter": i, "success": norm <= tol, "G": None, } From 4feb0d6bf8f8bffcc7f618eedb0db1b46fb73224 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Sat, 20 Apr 2024 18:38:00 -0400 Subject: [PATCH 051/131] syntax error --- src/simsopt/geo/boozersurface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 09ba226a9..7d9a068a7 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -324,7 +324,7 @@ def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, cons else: x = np.concatenate((s.get_dofs(), [iota, G])) - fun_name = self.boozer_penalty_constraints_vectorized else lambda x: self.boozer_penalty_constraints + fun_name = self.boozer_penalty_constraints_vectorized if vectorize else self.boozer_penalty_constraints fun = lambda x: fun_name(x, derivatives=1, constraint_weight=constraint_weight, optimize_G=G is not None) res = minimize( @@ -364,7 +364,7 @@ def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, cons x = np.concatenate((s.get_dofs(), [iota, G])) i = 0 - fun_name = self.boozer_penalty_constraints_vectorized else lambda x: self.boozer_penalty_constraints + fun_name = self.boozer_penalty_constraints_vectorized if vectorize else self.boozer_penalty_constraints val, dval, d2val = fun_name(x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) norm = np.linalg.norm(dval) From eb2ed513e5224077b45a1edfd90090d193c15ce9 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 22 Apr 2024 12:18:26 -0400 Subject: [PATCH 052/131] renaming class, adding a trefoil unit test --- src/simsopt/geo/__init__.py | 4 +- ...elical.py => curvexyzfouriersymmetries.py} | 12 +-- tests/geo/test_curve.py | 82 +++++++++++++------ 3 files changed, 67 insertions(+), 31 deletions(-) rename src/simsopt/geo/{curvexyzhelical.py => curvexyzfouriersymmetries.py} (92%) diff --git a/src/simsopt/geo/__init__.py b/src/simsopt/geo/__init__.py index d0c7116bc..25cf7ea42 100644 --- a/src/simsopt/geo/__init__.py +++ b/src/simsopt/geo/__init__.py @@ -6,7 +6,7 @@ from .curvehelical import * from .curverzfourier import * from .curvexyzfourier import * -from .curvexyzhelical import * +from .curvexyzfouriersymmetries import * from .curveperturbed import * from .curveobjectives import * from .curveplanarfourier import * @@ -29,7 +29,7 @@ __all__ = (curve.__all__ + curvehelical.__all__ + curverzfourier.__all__ + curvexyzfourier.__all__ + - curvexyzhelical.__all__ + + curvexyzfouriersymmetries.__all__ + curveperturbed.__all__ + curveobjectives.__all__ + curveplanarfourier.__all__ + finitebuild.__all__ + plotting.__all__ + diff --git a/src/simsopt/geo/curvexyzhelical.py b/src/simsopt/geo/curvexyzfouriersymmetries.py similarity index 92% rename from src/simsopt/geo/curvexyzhelical.py rename to src/simsopt/geo/curvexyzfouriersymmetries.py index acffac2a9..c796d29ba 100644 --- a/src/simsopt/geo/curvexyzhelical.py +++ b/src/simsopt/geo/curvexyzfouriersymmetries.py @@ -3,10 +3,10 @@ from .curve import JaxCurve from math import gcd -__all__ = ['CurveXYZHelical'] +__all__ = ['CurveXYZFourierSymmetries'] -def jaxXYZHelicalFouriercurve_pure(dofs, quadpoints, order, nfp, stellsym, ntor): +def jaxXYZFourierSymmetriescurve_pure(dofs, quadpoints, order, nfp, stellsym, ntor): theta, m = jnp.meshgrid(quadpoints, jnp.arange(order + 1), indexing='ij') @@ -43,9 +43,9 @@ def jaxXYZHelicalFouriercurve_pure(dofs, quadpoints, order, nfp, stellsym, ntor) return gamma -class CurveXYZHelical(JaxCurve): - r'''A curve representation for a helical coil that does not lie on a torus. - The coordinates of the curve are given by: +class CurveXYZFourierSymmetries(JaxCurve): + r'''A curve representation that allows for stellarator and discrete rotational symmetries. This class can be used to + represent a helical coil that does not lie on a torus. The coordinates of the curve are given by: .. math:: \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} x_{c,m} \cos(2 \pi n_{\text{fp}} m \theta)\\ @@ -79,7 +79,7 @@ class CurveXYZHelical(JaxCurve): def __init__(self, quadpoints, order, nfp, stellsym, ntor=1, **kwargs): if isinstance(quadpoints, int): quadpoints = np.linspace(0, 1, quadpoints, endpoint=False) - pure = lambda dofs, points: jaxXYZHelicalFouriercurve_pure( + pure = lambda dofs, points: jaxXYZFourierSymmetriescurve_pure( dofs, points, order, nfp, stellsym, ntor) nfp_true = nfp // gcd(nfp, ntor) diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index daf613e94..664ce7aab 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -11,7 +11,7 @@ from simsopt.geo.curverzfourier import CurveRZFourier from simsopt.geo.curveplanarfourier import CurvePlanarFourier from simsopt.geo.curvehelical import CurveHelical -from simsopt.geo.curvexyzhelical import CurveXYZHelical +from simsopt.geo.curvexyzfouriersymmetries import CurveXYZFourierSymmetries from simsopt.geo.curve import RotatedCurve, curves_to_vtk from simsopt.geo import parameters from simsopt.configs.zoo import get_ncsx_data, get_w7x_data @@ -77,10 +77,10 @@ def get_curve(curvetype, rotated, x=np.asarray([0.5])): curve = CurveHelical(x, order, 5, 2, 1.0, 0.3, x0=np.ones((2*order,))) elif curvetype == "CurvePlanarFourier": curve = CurvePlanarFourier(x, order, 2, True) - elif curvetype == "CurveXYZHelical1": - curve = CurveXYZHelical(x, order, 2, True) - elif curvetype == "CurveXYZHelical2": - curve = CurveXYZHelical(x, order, 2, False) + elif curvetype == "CurveXYZFourierSymmetries1": + curve = CurveXYZFourierSymmetries(x, order, 2, True) + elif curvetype == "CurveXYZFourierSymmetries2": + curve = CurveXYZFourierSymmetries(x, order, 2, False) else: assert False @@ -95,14 +95,14 @@ def get_curve(curvetype, rotated, x=np.asarray([0.5])): dofs[order+1] = 0.1 elif curvetype in ["CurveHelical", "CurveHelicalInitx0"]: dofs[0] = np.pi/2 - elif curvetype == "CurveXYZHelical1": + elif curvetype == "CurveXYZFourierSymmetries1": R = 1 r = 0.5 curve.set('xc(0)', R) curve.set('xc(1)', -r) curve.set('zs(1)', -r) dofs = curve.get_dofs() - elif curvetype == "CurveXYZHelical2": + elif curvetype == "CurveXYZFourierSymmetries2": R = 1 r = 0.5 curve.set('xc(0)', R) @@ -124,10 +124,10 @@ def get_curve(curvetype, rotated, x=np.asarray([0.5])): class Testing(unittest.TestCase): - curvetypes = ["CurveXYZFourier", "JaxCurveXYZFourier", "CurveRZFourier", "CurvePlanarFourier", "CurveHelical", "CurveXYZHelical1","CurveXYZHelical2", "CurveHelicalInitx0"] + curvetypes = ["CurveXYZFourier", "JaxCurveXYZFourier", "CurveRZFourier", "CurvePlanarFourier", "CurveHelical", "CurveXYZFourierSymmetries1","CurveXYZFourierSymmetries2", "CurveHelicalInitx0"] - def get_curvexyzhelical(self, stellsym=True, x=None, nfp=None, ntor=1): - # returns a CurveXYZHelical that is randomly perturbed + def get_curvexyzfouriersymmetries(self, stellsym=True, x=None, nfp=None, ntor=1): + # returns a CurveXYZFourierSymmetries that is randomly perturbed np.random.seed(1) rand_scale = 1e-2 @@ -138,7 +138,7 @@ def get_curvexyzhelical(self, stellsym=True, x=None, nfp=None, ntor=1): x = np.linspace(0, 1, 200, endpoint=False) order = 2 - curve = CurveXYZHelical(x, order, nfp, stellsym, ntor=ntor) + curve = CurveXYZFourierSymmetries(x, order, nfp, stellsym, ntor=ntor) R = 1 r = 0.25 curve.set('xc(0)', R) @@ -151,12 +151,12 @@ def get_curvexyzhelical(self, stellsym=True, x=None, nfp=None, ntor=1): return curve - def test_curvehelical_is_curvexyzhelical(self): + def test_curvehelical_is_curvexyzfouriersymmetries(self): # this test checks that both helical coil representations can produce the same helical curve on a torus order = 1 nfp = 2 x = np.linspace(0, 1, 100, endpoint=False) - curve1 = CurveXYZHelical(x, order, nfp, True) + curve1 = CurveXYZFourierSymmetries(x, order, nfp, True) R = 1 r = 0.5 curve1.set('xc(0)', R) @@ -165,9 +165,45 @@ def test_curvehelical_is_curvexyzhelical(self): curve2 = CurveHelical(x, order, nfp, 1, R, r, x0=np.zeros((2*order,))) np.testing.assert_allclose(curve1.gamma(), curve2.gamma(), atol=1e-14) + def test_trefoil(self): + r''' This test checks that a CurveXYZFourierSymmetries can represent a trefoil knot. + A parametric representation of a trefoil knot is given by: + x(t) = sin(t) + 2sin(t) + y(t) = cos(t) - 2cos(t) + z(t) = -sin(3t) + + The above can be rewritten the CurveXYZFourierSymmetries representation, with + order = 1, nfp = 3, and ntor = 2: + + xhat(t) = sin(nfp*t) + yhat(t) = -2 + cos(nfp*t), + x(t) = xhat(t) * cos(ntor*t) - yhat(t) * sin(ntor*t), + y(t) = xhat(t) * sin(ntor*t) + yhat(t) * cos(ntor*t), + z(t) = -sin(nfp*t), + + i.e., xs(1)=1, yc(0)=-2, yc(1)=1, zs(1)=-1. + ''' + + order = 1 + nfp = 3 + ntor = 2 + x = np.linspace(0, 1, 500, endpoint=False) + curve = CurveXYZFourierSymmetries(x, order, nfp, False, ntor=ntor) + + X = np.sin(2*np.pi * x) + 2 * np.sin(2*2*np.pi * x) + Y = np.cos(2*np.pi * x) - 2 * np.cos(2*2*np.pi*x) + Z = -np.sin(3*2*np.pi*x) + XYZ = np.concatenate([X[:, None], Y[:, None], Z[:, None]], axis=1) + + curve.set('xs(1)', 1.) + curve.set('yc(0)', -2.) + curve.set('yc(1)', 1.) + curve.set('zs(1)', -1.) + np.testing.assert_allclose(curve.gamma(), XYZ, atol=1e-14) + def test_nonstellsym(self): # this test checks that you can obtain a stellarator symmetric magnetic field from two non-stellarator symmetric - # CurveXYZHelical curves. + # CurveXYZFourierSymmetries curves. for nfp in [1, 2, 3, 4, 5, 6]: for ntor in [1, 2, 3, 4, 5, 6]: with self.subTest(nfp=nfp, ntor=ntor): @@ -179,8 +215,8 @@ def subtest_nonstellsym(self, nfp, ntor): return # this test checks that you can obtain a stellarator symmetric magnetic field from two non-stellarator symmetric - # CurveXYZHelical curves. - curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp, ntor=ntor) + # CurveXYZFourierSymmetries curves. + curve = self.get_curvexyzfouriersymmetries(stellsym=False, nfp=nfp, ntor=ntor) current = Current(1e5) coils = coils_via_symmetries([curve], [current], 1, True) bs = BiotSavart(coils) @@ -191,7 +227,7 @@ def subtest_nonstellsym(self, nfp, ntor): np.testing.assert_allclose(B[0, 2], B[1, 2], atol=1e-14) def test_xyzhelical_symmetries(self): - # checking various symmetries of the CurveXYZHelical representation + # checking various symmetries of the CurveXYZFourierSymmetries representation for nfp in [1, 2, 3, 4, 5, 6]: for ntor in [1, 2, 3, 4, 5, 6]: with self.subTest(nfp=nfp, ntor=ntor): @@ -203,7 +239,7 @@ def subtest_xyzhelical_symmetries(self, nfp, ntor): return # does the stellarator symmetric curve have rotational symmetry? - curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x=np.array([0.123, 0.123+ntor/nfp]), ntor=ntor) + curve = self.get_curvexyzfouriersymmetries(stellsym=True, nfp=nfp, x=np.array([0.123, 0.123+ntor/nfp]), ntor=ntor) out = curve.gamma() alpha = -2*np.pi/nfp R = np.array([ @@ -219,7 +255,7 @@ def subtest_xyzhelical_symmetries(self, nfp, ntor): np.testing.assert_allclose(out[1], np.linalg.inv(R)@out[0], atol=1e-14) # does the stellarator symmetric curve indeed pass through (x0, 0, 0)? - curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x = np.array([0]), ntor=ntor) + curve = self.get_curvexyzfouriersymmetries(stellsym=True, nfp=nfp, x = np.array([0]), ntor=ntor) out = curve.gamma() assert np.abs(out[0, 0]) > 1e-3 np.testing.assert_allclose(out[0, 1], 0, atol=1e-14) @@ -227,21 +263,21 @@ def subtest_xyzhelical_symmetries(self, nfp, ntor): # does the non-stellarator symmetric curve not pass through (x0, 0, 0)? - curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp, x = np.array([0]), ntor=ntor) + curve = self.get_curvexyzfouriersymmetries(stellsym=False, nfp=nfp, x = np.array([0]), ntor=ntor) out = curve.gamma() assert np.abs(out[0, 0]) > 1e-3 assert np.abs(out[0, 1]) > 1e-3 assert np.abs(out[0, 2]) > 1e-3 # is the stellarator symmetric curve actually stellarator symmetric? - curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x = np.array([0.123, -0.123]), ntor=ntor) + curve = self.get_curvexyzfouriersymmetries(stellsym=True, nfp=nfp, x = np.array([0.123, -0.123]), ntor=ntor) pts = curve.gamma() np.testing.assert_allclose(pts[0, 0], pts[1, 0], atol=1e-14) np.testing.assert_allclose(pts[0, 1], -pts[1, 1], atol= 1e-14) np.testing.assert_allclose(pts[0, 2], -pts[1, 2], atol= 1e-14) # is the field from the stellarator symmetric curve actually stellarator symmetric? - curve = self.get_curvexyzhelical(stellsym=True, nfp=nfp, x=np.linspace(0, 1, 200, endpoint=False), ntor=ntor) + curve = self.get_curvexyzfouriersymmetries(stellsym=True, nfp=nfp, x=np.linspace(0, 1, 200, endpoint=False), ntor=ntor) current = Current(1e5) coil = Coil(curve, current) bs = BiotSavart([coil]) @@ -252,7 +288,7 @@ def subtest_xyzhelical_symmetries(self, nfp, ntor): np.testing.assert_allclose(B[0, 2], B[1, 2], atol=1e-14) # does the non-stellarator symmetric curve have rotational symmetry still? - curve = self.get_curvexyzhelical(stellsym=False, nfp=nfp, x = np.array([0.123, 0.123+ntor/nfp]), ntor=ntor) + curve = self.get_curvexyzfouriersymmetries(stellsym=False, nfp=nfp, x = np.array([0.123, 0.123+ntor/nfp]), ntor=ntor) out = curve.gamma() alpha = -2*np.pi/nfp R = np.array([[np.cos(alpha), np.sin(alpha), 0], [-np.sin(alpha), np.cos(alpha), 0], [0, 0, 1]]) From 4ae7c54cc530212dbbb9fe10e6ce965ac129a42a Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 22 Apr 2024 13:14:58 -0400 Subject: [PATCH 053/131] fixing unit tests --- tests/geo/test_curve.py | 49 +++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 664ce7aab..0eec5faef 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -168,18 +168,21 @@ def test_curvehelical_is_curvexyzfouriersymmetries(self): def test_trefoil(self): r''' This test checks that a CurveXYZFourierSymmetries can represent a trefoil knot. A parametric representation of a trefoil knot is given by: - x(t) = sin(t) + 2sin(t) - y(t) = cos(t) - 2cos(t) - z(t) = -sin(3t) + + .. math:: + x(t) &= sin(t) + 2sin(t) \\ + y(t) &= cos(t) - 2cos(t) \\ + z(t) &= -sin(3t) The above can be rewritten the CurveXYZFourierSymmetries representation, with order = 1, nfp = 3, and ntor = 2: - xhat(t) = sin(nfp*t) - yhat(t) = -2 + cos(nfp*t), - x(t) = xhat(t) * cos(ntor*t) - yhat(t) * sin(ntor*t), - y(t) = xhat(t) * sin(ntor*t) + yhat(t) * cos(ntor*t), - z(t) = -sin(nfp*t), + .. math:: + xhat(t) &= sin(nfp*t) \\ + yhat(t) &= -2 + cos(nfp*t), \\ + x(t) &= xhat(t) * cos(ntor*t) - yhat(t) * sin(ntor*t), \\ + y(t) &= xhat(t) * sin(ntor*t) + yhat(t) * cos(ntor*t), \\ + z(t) &= -sin(nfp*t), i.e., xs(1)=1, yc(0)=-2, yc(1)=1, zs(1)=-1. ''' @@ -191,7 +194,7 @@ def test_trefoil(self): curve = CurveXYZFourierSymmetries(x, order, nfp, False, ntor=ntor) X = np.sin(2*np.pi * x) + 2 * np.sin(2*2*np.pi * x) - Y = np.cos(2*np.pi * x) - 2 * np.cos(2*2*np.pi*x) + Y = np.cos(2*np.pi * x) - 2 * np.cos(2*2*np.pi * x) Z = -np.sin(3*2*np.pi*x) XYZ = np.concatenate([X[:, None], Y[:, None], Z[:, None]], axis=1) @@ -239,20 +242,17 @@ def subtest_xyzhelical_symmetries(self, nfp, ntor): return # does the stellarator symmetric curve have rotational symmetry? - curve = self.get_curvexyzfouriersymmetries(stellsym=True, nfp=nfp, x=np.array([0.123, 0.123+ntor/nfp]), ntor=ntor) + curve = self.get_curvexyzfouriersymmetries(stellsym=True, nfp=nfp, x=np.array([0.123, 0.123+1/nfp]), ntor=ntor) out = curve.gamma() - alpha = -2*np.pi/nfp + alpha = 2*np.pi*ntor/nfp R = np.array([ - [np.cos(alpha), np.sin(alpha), 0], - [-np.sin(alpha), np.cos(alpha), 0], + [np.cos(alpha), -np.sin(alpha), 0], + [np.sin(alpha), np.cos(alpha), 0], [0, 0, 1] ]) print(R@out[0], out[1]) - try: - np.testing.assert_allclose(out[1], R@out[0], atol=1e-14) - except: - np.testing.assert_allclose(out[1], np.linalg.inv(R)@out[0], atol=1e-14) + np.testing.assert_allclose(out[1], R@out[0], atol=1e-14) # does the stellarator symmetric curve indeed pass through (x0, 0, 0)? curve = self.get_curvexyzfouriersymmetries(stellsym=True, nfp=nfp, x = np.array([0]), ntor=ntor) @@ -288,15 +288,16 @@ def subtest_xyzhelical_symmetries(self, nfp, ntor): np.testing.assert_allclose(B[0, 2], B[1, 2], atol=1e-14) # does the non-stellarator symmetric curve have rotational symmetry still? - curve = self.get_curvexyzfouriersymmetries(stellsym=False, nfp=nfp, x = np.array([0.123, 0.123+ntor/nfp]), ntor=ntor) + curve = self.get_curvexyzfouriersymmetries(stellsym=False, nfp=nfp, x = np.array([0.123, 0.123+1./nfp]), ntor=ntor) out = curve.gamma() - alpha = -2*np.pi/nfp - R = np.array([[np.cos(alpha), np.sin(alpha), 0], [-np.sin(alpha), np.cos(alpha), 0], [0, 0, 1]]) + alpha = 2*np.pi*ntor/nfp + R = np.array([ + [np.cos(alpha), -np.sin(alpha), 0], + [np.sin(alpha), np.cos(alpha), 0], + [0, 0, 1] + ]) print(R@out[0], out[1]) - try: - np.testing.assert_allclose(out[1], R@out[0], atol=1e-14) - except: - np.testing.assert_allclose(out[1], np.linalg.inv(R)@out[0], atol=1e-14) + np.testing.assert_allclose(out[1], R@out[0], atol=1e-14) def test_curve_helical_xyzfourier(self): x = np.asarray([0.6]) From c91431fc2be9c2171e0fdd872214714b47a95925 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 22 Apr 2024 13:20:41 -0400 Subject: [PATCH 054/131] cleaning up the condition checking if ntor and nfp are coprime --- src/simsopt/geo/curvexyzfouriersymmetries.py | 3 +-- tests/geo/test_curve.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/simsopt/geo/curvexyzfouriersymmetries.py b/src/simsopt/geo/curvexyzfouriersymmetries.py index c796d29ba..d334086c3 100644 --- a/src/simsopt/geo/curvexyzfouriersymmetries.py +++ b/src/simsopt/geo/curvexyzfouriersymmetries.py @@ -82,8 +82,7 @@ def __init__(self, quadpoints, order, nfp, stellsym, ntor=1, **kwargs): pure = lambda dofs, points: jaxXYZFourierSymmetriescurve_pure( dofs, points, order, nfp, stellsym, ntor) - nfp_true = nfp // gcd(nfp, ntor) - if nfp != nfp_true: + if gcd(ntor, nfp) != 1: raise Exception('nfp and ntor must be coprime') self.order = order diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 0eec5faef..4209f9da8 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -213,8 +213,7 @@ def test_nonstellsym(self): self.subtest_nonstellsym(nfp, ntor) def subtest_nonstellsym(self, nfp, ntor): - nfp_true = nfp // gcd(ntor, nfp) - if nfp_true != nfp: + if gcd(ntor, nfp) != 1: return # this test checks that you can obtain a stellarator symmetric magnetic field from two non-stellarator symmetric From 5cec5ac6fd936285cccc0196552c2ac8f0640ebb Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 22 Apr 2024 13:40:18 -0400 Subject: [PATCH 055/131] testing on a stellsym and nonstellsym trefoil --- tests/geo/test_curve.py | 48 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 4209f9da8..22f9f4ecf 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -165,9 +165,9 @@ def test_curvehelical_is_curvexyzfouriersymmetries(self): curve2 = CurveHelical(x, order, nfp, 1, R, r, x0=np.zeros((2*order,))) np.testing.assert_allclose(curve1.gamma(), curve2.gamma(), atol=1e-14) - def test_trefoil(self): - r''' This test checks that a CurveXYZFourierSymmetries can represent a trefoil knot. - A parametric representation of a trefoil knot is given by: + def test_trefoil_nonstellsym(self): + r''' This test checks that a CurveXYZFourierSymmetries can represent a non-stellarator symmetric + trefoil knot. A parametric representation of a trefoil knot is given by: .. math:: x(t) &= sin(t) + 2sin(t) \\ @@ -184,7 +184,7 @@ def test_trefoil(self): y(t) &= xhat(t) * sin(ntor*t) + yhat(t) * cos(ntor*t), \\ z(t) &= -sin(nfp*t), - i.e., xs(1)=1, yc(0)=-2, yc(1)=1, zs(1)=-1. + i.e., The dofs are xs(1)=1, yc(0)=-2, yc(1)=1, zs(1)=-1, and zero otherwise. ''' order = 1 @@ -204,6 +204,46 @@ def test_trefoil(self): curve.set('zs(1)', -1.) np.testing.assert_allclose(curve.gamma(), XYZ, atol=1e-14) + def test_trefoil_stellsym(self): + r''' This test checks that a CurveXYZFourierSymmetries can represent a stellarator symmetric + trefoil knot. A parametric representation of a trefoil knot is given by: + + .. math:: + x(t) &= cos(t) - 2cos(t) \\ + y(t) &=-sin(t) - 2sin(t) \\ + z(t) &= -sin(3t) + + The above can be rewritten the CurveXYZFourierSymmetries representation, with + order = 1, nfp = 3, and ntor = 2: + + .. math:: + xhat(t) &= -2 + cos(t)\\ + yhat(t) &= -sin(t)\\ + x(t) &= xhat(t) * cos(ntor*t) - yhat(t) * sin(ntor*t), \\ + y(t) &= xhat(t) * sin(ntor*t) + yhat(t) * cos(ntor*t), \\ + z(t) &= -sin(nfp*t), + + i.e., xc(0)=-2, xc(1)=1, ys(1)=-1, zs(1)=-1. + ''' + + order = 1 + nfp = 3 + ntor = 2 + x = np.linspace(0, 1, 500, endpoint=False) + curve = CurveXYZFourierSymmetries(x, order, nfp, True, ntor=ntor) + + X = np.cos(2*np.pi * x) - 2 * np.cos(2*2*np.pi * x) + Y =-np.sin(2*np.pi * x) - 2 * np.sin(2*2*np.pi * x) + Z = -np.sin(3*2*np.pi*x) + XYZ = np.concatenate([X[:, None], Y[:, None], Z[:, None]], axis=1) + + curve.set('xc(0)', -2) + curve.set('xc(1)', 1) + curve.set('ys(1)', -1) + curve.set('zs(1)', -1) + np.testing.assert_allclose(curve.gamma(), XYZ, atol=1e-14) + + def test_nonstellsym(self): # this test checks that you can obtain a stellarator symmetric magnetic field from two non-stellarator symmetric # CurveXYZFourierSymmetries curves. From ee48c83b37fcbd15eda6f41dba4414f68860545d Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 22 Apr 2024 15:15:36 -0400 Subject: [PATCH 056/131] fixing docstrings --- src/simsopt/geo/curvexyzfouriersymmetries.py | 2 +- tests/geo/test_curve.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/simsopt/geo/curvexyzfouriersymmetries.py b/src/simsopt/geo/curvexyzfouriersymmetries.py index d334086c3..16f557330 100644 --- a/src/simsopt/geo/curvexyzfouriersymmetries.py +++ b/src/simsopt/geo/curvexyzfouriersymmetries.py @@ -73,7 +73,7 @@ class CurveXYZFourierSymmetries(JaxCurve): it is assumed that nfp and ntor are coprime. If they are not coprime, then then the curve actually has nfp_new:=nfp // gcd(nfp, ntor), and ntor_new:=ntor // gcd(nfp, ntor). To avoid confusion, - we assert that ntor and nfp are coprime at instatiation. + we assert that ntor and nfp are coprime at instantiation. ''' def __init__(self, quadpoints, order, nfp, stellsym, ntor=1, **kwargs): diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 22f9f4ecf..7202128e6 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -276,13 +276,14 @@ def test_xyzhelical_symmetries(self): self.subtest_xyzhelical_symmetries(nfp, ntor) def subtest_xyzhelical_symmetries(self, nfp, ntor): - nfp_true = nfp // gcd(ntor, nfp) - if nfp_true != nfp: + if gcd(nfp, ntor) != 1 : return # does the stellarator symmetric curve have rotational symmetry? curve = self.get_curvexyzfouriersymmetries(stellsym=True, nfp=nfp, x=np.array([0.123, 0.123+1/nfp]), ntor=ntor) out = curve.gamma() + + # NOTE: the point at angle t+1/nfp is the point at angle t, but rotated by 2pi *(ntor/nfp) radians. alpha = 2*np.pi*ntor/nfp R = np.array([ [np.cos(alpha), -np.sin(alpha), 0], @@ -327,6 +328,7 @@ def subtest_xyzhelical_symmetries(self, nfp, ntor): np.testing.assert_allclose(B[0, 2], B[1, 2], atol=1e-14) # does the non-stellarator symmetric curve have rotational symmetry still? + # NOTE: the point at angle t+1/nfp is the point at angle t, but rotated by 2pi *(ntor/nfp) radians. curve = self.get_curvexyzfouriersymmetries(stellsym=False, nfp=nfp, x = np.array([0.123, 0.123+1./nfp]), ntor=ntor) out = curve.gamma() alpha = 2*np.pi*ntor/nfp From ccea42129dd3962e3bb18a19ec603b128fa287b8 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 22 Apr 2024 16:19:43 -0400 Subject: [PATCH 057/131] fixing documentation so it compiles --- docs/source/simsopt.geo.rst | 6 +- src/simsopt/geo/curvexyzfouriersymmetries.py | 65 +++++++++++--------- tests/geo/test_curve.py | 55 ++++++++++------- 3 files changed, 74 insertions(+), 52 deletions(-) diff --git a/docs/source/simsopt.geo.rst b/docs/source/simsopt.geo.rst index d3da40ea2..92859f7c7 100644 --- a/docs/source/simsopt.geo.rst +++ b/docs/source/simsopt.geo.rst @@ -76,10 +76,10 @@ simsopt.geo.curvexyzfourier module :undoc-members: :show-inheritance: -simsopt.geo.curvexyzhelical module ----------------------------------- +simsopt.geo.curvexyzfouriersymmetries module +-------------------------------------------- -.. automodule:: simsopt.geo.curvexyzhelical +.. automodule:: simsopt.geo.curvexyzfouriersymmetries :members: :undoc-members: :show-inheritance: diff --git a/src/simsopt/geo/curvexyzfouriersymmetries.py b/src/simsopt/geo/curvexyzfouriersymmetries.py index 16f557330..b537e94f3 100644 --- a/src/simsopt/geo/curvexyzfouriersymmetries.py +++ b/src/simsopt/geo/curvexyzfouriersymmetries.py @@ -46,35 +46,44 @@ def jaxXYZFourierSymmetriescurve_pure(dofs, quadpoints, order, nfp, stellsym, nt class CurveXYZFourierSymmetries(JaxCurve): r'''A curve representation that allows for stellarator and discrete rotational symmetries. This class can be used to represent a helical coil that does not lie on a torus. The coordinates of the curve are given by: + + .. math:: + x(\theta) &= \hat x(\theta) \cos(2 \pi \theta n_{\text{tor}}) - \hat y(\theta) \sin(2 \pi \theta n_{\text{tor}})\\ + y(\theta) &= \hat x(\theta) \sin(2 \pi \theta n_{\text{tor}}) + \hat y(\theta) \cos(2 \pi \theta n_{\text{tor}})\\ + z(\theta) &= \sum_{m=1}^{\text{order}} z_{s,m} \sin(2 \pi n_{\text{fp}} m \theta) + + where + + .. math:: + \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} x_{c,m} \cos(2 \pi n_{\text{fp}} m \theta)\\ + \hat y(\theta) &= \sum_{m=1}^{\text{order}} y_{s,m} \sin(2 \pi n_{\text{fp}} m \theta)\\ + - .. math:: - \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} x_{c,m} \cos(2 \pi n_{\text{fp}} m \theta)\\ - \hat y(\theta) &= \sum_{m=1}^{\text{order}} y_{s,m} \sin(2 \pi n_{\text{fp}} m \theta)\\ - x(\theta) &= \hat x(\theta) \cos(2 \pi \theta n_{\text{tor}}) - \hat y(\theta) \sin(2 \pi \theta n_{\text{tor}})\\ - y(\theta) &= \hat x(\theta) \sin(2 \pi \theta n_{\text{tor}}) + \hat y(\theta) \cos(2 \pi \theta n_{\text{tor}})\\ - z(\theta) &= \sum_{m=1}^{\text{order}} z_{s,m} \sin(2 \pi n_{\text{fp}} m \theta) - - if the coil is stellarator symmetric. When the coil is not stellarator symmetric, the formulas above - become - - .. math:: - \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} \left[ x_{c, m} \cos(2 \pi n_{\text{fp}} m \theta) + x_{s, m} \sin(2 \pi n_{\text{fp}} m \theta) \right] \\ - \hat y(\theta) &= y_{c, 0} + \sum_{m=1}^{\text{order}} \left[ y_{c, m} \cos(2 \pi n_{\text{fp}} m \theta) + y_{s, m} \sin(2 \pi n_{\text{fp}} m \theta) \right] \\ - x(\theta) &= \hat x(\theta) \cos(2 \pi \theta n_{\text{tor}}) - \hat y(\theta) \sin(2 \pi \theta n_{\text{tor}})\\ - y(\theta) &= \hat x(\theta) \sin(2 \pi \theta n_{\text{tor}}) + \hat y(\theta) \cos(2 \pi \theta n_{\text{tor}})\\ - z(\theta) &= z_{c, 0} + \sum_{m=1}^{\text{order}} \left[ z_{c, m} \cos(2 \pi n_{\text{fp}} m \theta) + z_{s, m} \sin(2 \pi n_{\text{fp}} m \theta) \right] - - Args: - quadpoints: number of grid points/resolution along the curve, - order: how many Fourier harmonics to include in the Fourier representation, - nfp: discrete rotational symmetry number, - stellsym: stellaratory symmetry if True, not stellarator symmetric otherwise, - ntor: the number of times the curve wraps toroidally before biting its tail. Note, - it is assumed that nfp and ntor are coprime. If they are not coprime, - then then the curve actually has nfp_new:=nfp // gcd(nfp, ntor), - and ntor_new:=ntor // gcd(nfp, ntor). To avoid confusion, - we assert that ntor and nfp are coprime at instantiation. - ''' + if the coil is stellarator symmetric. When the coil is not stellarator symmetric, the formulas above + become + + .. math:: + x(\theta) &= \hat x(\theta) \cos(2 \pi \theta n_{\text{tor}}) - \hat y(\theta) \sin(2 \pi \theta n_{\text{tor}})\\ + y(\theta) &= \hat x(\theta) \sin(2 \pi \theta n_{\text{tor}}) + \hat y(\theta) \cos(2 \pi \theta n_{\text{tor}})\\ + z(\theta) &= z_{c, 0} + \sum_{m=1}^{\text{order}} \left[ z_{c, m} \cos(2 \pi n_{\text{fp}} m \theta) + z_{s, m} \sin(2 \pi n_{\text{fp}} m \theta) \right] + + where + + .. math:: + \hat x(\theta) &= x_{c, 0} + \sum_{m=1}^{\text{order}} \left[ x_{c, m} \cos(2 \pi n_{\text{fp}} m \theta) + x_{s, m} \sin(2 \pi n_{\text{fp}} m \theta) \right] \\ + \hat y(\theta) &= y_{c, 0} + \sum_{m=1}^{\text{order}} \left[ y_{c, m} \cos(2 \pi n_{\text{fp}} m \theta) + y_{s, m} \sin(2 \pi n_{\text{fp}} m \theta) \right] \\ + + Args: + quadpoints: number of grid points/resolution along the curve, + order: how many Fourier harmonics to include in the Fourier representation, + nfp: discrete rotational symmetry number, + stellsym: stellaratory symmetry if True, not stellarator symmetric otherwise, + ntor: the number of times the curve wraps toroidally before biting its tail. Note, + it is assumed that nfp and ntor are coprime. If they are not coprime, + then then the curve actually has nfp_new:=nfp // gcd(nfp, ntor), + and ntor_new:=ntor // gcd(nfp, ntor). The operator `//` is integer division. + To avoid confusion, we assert that ntor and nfp are coprime at instantiation. + ''' def __init__(self, quadpoints, order, nfp, stellsym, ntor=1, **kwargs): if isinstance(quadpoints, int): diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 7202128e6..48ed68305 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -81,6 +81,8 @@ def get_curve(curvetype, rotated, x=np.asarray([0.5])): curve = CurveXYZFourierSymmetries(x, order, 2, True) elif curvetype == "CurveXYZFourierSymmetries2": curve = CurveXYZFourierSymmetries(x, order, 2, False) + elif curvetype == "CurveXYZFourierSymmetries3": + curve = CurveXYZFourierSymmetries(x, order, 2, False, ntor=3) else: assert False @@ -112,6 +114,16 @@ def get_curve(curvetype, rotated, x=np.asarray([0.5])): curve.set('zc(0)', 1) curve.set('zs(1)', r) dofs = curve.get_dofs() + elif curvetype == "CurveXYZFourierSymmetries3": + R = 1 + r = 0.5 + curve.set('xc(0)', R) + curve.set('xs(1)', -0.1*r) + curve.set('xc(1)', -r) + curve.set('zs(1)', -r) + curve.set('zc(0)', 1) + curve.set('zs(1)', r) + dofs = curve.get_dofs() else: assert False @@ -124,7 +136,7 @@ def get_curve(curvetype, rotated, x=np.asarray([0.5])): class Testing(unittest.TestCase): - curvetypes = ["CurveXYZFourier", "JaxCurveXYZFourier", "CurveRZFourier", "CurvePlanarFourier", "CurveHelical", "CurveXYZFourierSymmetries1","CurveXYZFourierSymmetries2", "CurveHelicalInitx0"] + curvetypes = ["CurveXYZFourier", "JaxCurveXYZFourier", "CurveRZFourier", "CurvePlanarFourier", "CurveHelical", "CurveXYZFourierSymmetries1","CurveXYZFourierSymmetries2", "CurveXYZFourierSymmetries3", "CurveHelicalInitx0"] def get_curvexyzfouriersymmetries(self, stellsym=True, x=None, nfp=None, ntor=1): # returns a CurveXYZFourierSymmetries that is randomly perturbed @@ -169,21 +181,21 @@ def test_trefoil_nonstellsym(self): r''' This test checks that a CurveXYZFourierSymmetries can represent a non-stellarator symmetric trefoil knot. A parametric representation of a trefoil knot is given by: - .. math:: - x(t) &= sin(t) + 2sin(t) \\ - y(t) &= cos(t) - 2cos(t) \\ - z(t) &= -sin(3t) + x(t) = sin(t) + 2sin(t) + y(t) = cos(t) - 2cos(t) + z(t) = -sin(3t) The above can be rewritten the CurveXYZFourierSymmetries representation, with order = 1, nfp = 3, and ntor = 2: - .. math:: - xhat(t) &= sin(nfp*t) \\ - yhat(t) &= -2 + cos(nfp*t), \\ - x(t) &= xhat(t) * cos(ntor*t) - yhat(t) * sin(ntor*t), \\ - y(t) &= xhat(t) * sin(ntor*t) + yhat(t) * cos(ntor*t), \\ - z(t) &= -sin(nfp*t), + x(t) = xhat(t) * cos(ntor*t) - yhat(t) * sin(ntor*t), + y(t) = xhat(t) * sin(ntor*t) + yhat(t) * cos(ntor*t), + z(t) = -sin(nfp*t), + where + xhat(t) &= sin(nfp*t), + yhat(t) &= -2 + cos(nfp*t), + i.e., The dofs are xs(1)=1, yc(0)=-2, yc(1)=1, zs(1)=-1, and zero otherwise. ''' @@ -208,21 +220,22 @@ def test_trefoil_stellsym(self): r''' This test checks that a CurveXYZFourierSymmetries can represent a stellarator symmetric trefoil knot. A parametric representation of a trefoil knot is given by: - .. math:: - x(t) &= cos(t) - 2cos(t) \\ - y(t) &=-sin(t) - 2sin(t) \\ - z(t) &= -sin(3t) + x(t) = cos(t) - 2cos(t), + y(t) =-sin(t) - 2sin(t), + z(t) = -sin(3t). The above can be rewritten the CurveXYZFourierSymmetries representation, with order = 1, nfp = 3, and ntor = 2: - .. math:: - xhat(t) &= -2 + cos(t)\\ - yhat(t) &= -sin(t)\\ - x(t) &= xhat(t) * cos(ntor*t) - yhat(t) * sin(ntor*t), \\ - y(t) &= xhat(t) * sin(ntor*t) + yhat(t) * cos(ntor*t), \\ - z(t) &= -sin(nfp*t), + x(t) = xhat(t) * cos(ntor*t) - yhat(t) * sin(ntor*t), + y(t) = xhat(t) * sin(ntor*t) + yhat(t) * cos(ntor*t), + z(t) = -sin(nfp*t), + where + + xhat(t) = -2 + cos(nfp*t) + yhat(t) = -sin(nfp*t) + i.e., xc(0)=-2, xc(1)=1, ys(1)=-1, zs(1)=-1. ''' From 1c122674cf9694c421514ca1a1768b624f17b94b Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 22 Apr 2024 16:23:08 -0400 Subject: [PATCH 058/131] minor change to docstring --- tests/geo/test_curve.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 48ed68305..1f3e92d06 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -193,8 +193,8 @@ def test_trefoil_nonstellsym(self): z(t) = -sin(nfp*t), where - xhat(t) &= sin(nfp*t), - yhat(t) &= -2 + cos(nfp*t), + xhat(t) = sin(nfp*t), + yhat(t) = -2 + cos(nfp*t), i.e., The dofs are xs(1)=1, yc(0)=-2, yc(1)=1, zs(1)=-1, and zero otherwise. ''' From e10899de0aa00529163e19f2d32fcf02583e0b6f Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 22 Apr 2024 21:25:43 -0400 Subject: [PATCH 059/131] removed mayavi from VIS in optional-dependencies --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 14966b351..f34cda10d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,7 +71,7 @@ dynamic = ["version"] [project.optional-dependencies] SPEC = ["py_spec>=3.0.1", "pyoculus>=0.1.1", "h5py>=3.1.0"] MPI = ["mpi4py>=3.0.3"] -VIS = ["vtk >= 8.1.2", "PyQt5", "mayavi", "plotly", "networkx"] +VIS = ["vtk >= 8.1.2", "PyQt5", "plotly", "networkx"] DOCS = ["sphinx", "sphinx-rtd-theme"] [project.urls] From 4e75515fb8779fc074f17605d08eb72ad94f53c0 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 22 Apr 2024 22:01:28 -0400 Subject: [PATCH 060/131] adding one final unit test [skip ci] --- tests/geo/test_boozersurface.py | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 075438f13..6e30d2201 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -352,6 +352,52 @@ def subtest_boozer_serialization(self, label): # check that BoozerSurface.surface and label.surface are the same surfaces assert bs_regen.label.surface is bs_regen.surface + + def test_convergence_cpp_and_notcpp_same(self): + """ + This unit test verifies that that the cpp and not cpp implementations converge to + the same solutions + """ + x_vec = self.subtest_convergence_cpp_and_notcpp_same(True) + x_nonvec = self.subtest_convergence_cpp_and_notcpp_same(False) + np.testing.assert_allclose(x_vec, x_nonvec, atol=1e-14) + + def subtest_convergence_cpp_and_notcpp_same(self, vectorize): + """ + compute a surface using either the vectorized or non-vectorized subroutines + """ + curves, currents, ma = get_ncsx_data() + coils = coils_via_symmetries(curves, currents, ma.nfp, True) + current_sum = sum(abs(c.current.get_value()) for c in coils) + bs = BiotSavart(coils) + + s = get_surface('SurfaceXYZTensorFourier', True, nfp=ma.nfp) + s.fit_to_curve(ma, 0.1) + iota = -0.4 + + ar = Area(s) + ar_target = ar.J() + boozer_surface = BoozerSurface(bs, s, ar, ar_target) + + G = 2.*np.pi*current_sum*(4*np.pi*10**(-7)/(2 * np.pi)) + + # vectorized solution first + res = boozer_surface.minimize_boozer_penalty_constraints_LBFGS( + tol=1e-10, maxiter=600, constraint_weight=100., iota=iota, G=G, + vectorize=vectorize) + print('Residual norm after LBFGS', np.sqrt(2*res['fun'])) + + boozer_surface.recompute_bell() + res = boozer_surface.minimize_boozer_penalty_constraints_newton( + tol=1e-10, maxiter=20, constraint_weight=100., + iota=res['iota'], G=res['G'], stab=1e-4, vectorize=vectorize) + + assert res['success'] + x = boozer_surface.surface.x.copy() + iota = res['iota'] + G = res['G'] + return np.concatenate([x, [iota, G]]) + def test_boozer_penalty_constraints_cpp_notcpp(self): """ From 2c453bc62e60c5975766c1d6d4c26d564951d357 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 22 Apr 2024 22:04:04 -0400 Subject: [PATCH 061/131] undoing a change to what is output during minimize_boozer_penalty_constraints_newton [skip ci] --- src/simsopt/geo/boozersurface.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 7d9a068a7..a4c412452 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -377,8 +377,9 @@ def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, cons val, dval, d2val = fun_name(x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) norm = np.linalg.norm(dval) i = i+1 - - r = fun_name(x, derivatives=0, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) + + r = self.boozer_penalty_constraints( + x, derivatives=0, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) res = { "residual": r, "jacobian": dval, "hessian": d2val, "iter": i, "success": norm <= tol, "G": None, } From f595c3dabfee61fb3a9d7f46763418ea99f304e1 Mon Sep 17 00:00:00 2001 From: Bharat Medasani Date: Tue, 23 Apr 2024 10:22:19 -0400 Subject: [PATCH 062/131] Disable avx512 code in simsopt --- src/simsoptpp/simdhelpers.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/simsoptpp/simdhelpers.h b/src/simsoptpp/simdhelpers.h index b5485febc..994292d9d 100644 --- a/src/simsoptpp/simdhelpers.h +++ b/src/simsoptpp/simdhelpers.h @@ -129,6 +129,7 @@ using AlignedPaddedVec = std::vector>; #endif #if defined(USE_XSIMD) +/* #if __AVX512F__ // On skylake _mm512_sqrt_pd takes 24 CPI and _mm512_div_pd takes 16 CPI, so // 1/sqrt(vec) takes 40 CPI. Instead we can use the approximate inverse square @@ -147,6 +148,7 @@ inline simd_t rsqrt(simd_t r2){ return rinv; } #else +*/ inline simd_t rsqrt(const simd_t& r2){ //On my avx2 machine, computing the sqrt and then the inverse is actually a //bit faster. just keeping this line here to remind myself how to compute @@ -155,7 +157,7 @@ inline simd_t rsqrt(const simd_t& r2){ return 1./sqrt(r2); } -#endif +//#endif #endif inline double rsqrt(const double& r2){ From f7bdc53e481abb0604a96c370dcfffe8271da674 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 23 Apr 2024 15:22:19 -0400 Subject: [PATCH 063/131] modified unit tests for code coverage --- tests/geo/test_curve.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index 1f3e92d06..c7a31066b 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -163,18 +163,34 @@ def get_curvexyzfouriersymmetries(self, stellsym=True, x=None, nfp=None, ntor=1) return curve - def test_curvehelical_is_curvexyzfouriersymmetries(self): + def test_curvexyzsymmetries_raisesexception(self): + # test ensures that an exception is raised when you try and create a curvexyzfouriersymmetries + # where gcd(ntor, nfp) != 1. + + order = 1 + nfp = 1 + ntor = 2 + # nfp = 1 and ntor = 2 here, so it should work + curve = CurveXYZFourierSymmetries(100, order, nfp, True, ntor=ntor, x0=np.ones(3*order+1)) + + with self.assertRaises(Exception): + order = 1 + nfp = 2 + ntor = 2 + # nfp = 2 and ntor = 2 here, so an exception should be raised + curve = CurveXYZFourierSymmetries(100, order, nfp, True, ntor=ntor, x0=np.ones(3*order+1)) + + def test_curvexyzsymmetries_is_curvexyzfouriersymmetries(self): # this test checks that both helical coil representations can produce the same helical curve on a torus order = 1 nfp = 2 - x = np.linspace(0, 1, 100, endpoint=False) - curve1 = CurveXYZFourierSymmetries(x, order, nfp, True) + curve1 = CurveXYZFourierSymmetries(100, order, nfp, True) R = 1 r = 0.5 curve1.set('xc(0)', R) curve1.set('xc(1)', r) curve1.set('zs(1)', -r) - curve2 = CurveHelical(x, order, nfp, 1, R, r, x0=np.zeros((2*order,))) + curve2 = CurveHelical(np.linspace(0, 1, 100, endpoint=False), order, nfp, 1, R, r, x0=np.zeros((2*order,))) np.testing.assert_allclose(curve1.gamma(), curve2.gamma(), atol=1e-14) def test_trefoil_nonstellsym(self): From 6841058bb74eb5e89323045acf4696f788daf33e Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 23 Apr 2024 15:30:40 -0400 Subject: [PATCH 064/131] linting fix --- tests/geo/test_curve.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/geo/test_curve.py b/tests/geo/test_curve.py index c7a31066b..a997a6e84 100644 --- a/tests/geo/test_curve.py +++ b/tests/geo/test_curve.py @@ -172,15 +172,16 @@ def test_curvexyzsymmetries_raisesexception(self): ntor = 2 # nfp = 1 and ntor = 2 here, so it should work curve = CurveXYZFourierSymmetries(100, order, nfp, True, ntor=ntor, x0=np.ones(3*order+1)) - + print(curve.x) + with self.assertRaises(Exception): order = 1 nfp = 2 ntor = 2 # nfp = 2 and ntor = 2 here, so an exception should be raised - curve = CurveXYZFourierSymmetries(100, order, nfp, True, ntor=ntor, x0=np.ones(3*order+1)) - - def test_curvexyzsymmetries_is_curvexyzfouriersymmetries(self): + _ = CurveXYZFourierSymmetries(100, order, nfp, True, ntor=ntor, x0=np.ones(3*order+1)) + + def test_curvehelical_is_curvexyzfouriersymmetries(self): # this test checks that both helical coil representations can produce the same helical curve on a torus order = 1 nfp = 2 From e87861aaf5631dda75cc299caaa5607edca29593 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 23 Apr 2024 15:43:08 -0400 Subject: [PATCH 065/131] minor linting changes --- src/simsopt/geo/boozersurface.py | 15 ++++++--------- src/simsopt/geo/surfaceobjectives.py | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index a4c412452..863bb3079 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -40,6 +40,7 @@ class BoozerSurface(Optimizable): where Newton is used to solve the first order necessary conditions for optimality. """ + def __init__(self, biotsavart, surface, label, targetlabel): super().__init__(depends_on=[biotsavart]) self.biotsavart = biotsavart @@ -50,7 +51,7 @@ def __init__(self, biotsavart, surface, label, targetlabel): def recompute_bell(self, parent=None): self.need_to_run_code = True - + def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., scalarize=True, optimize_G=False, weight_inv_modB=False): r""" Define the residual @@ -135,7 +136,7 @@ def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., sca d2l = np.zeros((x.shape[0], x.shape[0])) d2l[:nsurfdofs, :nsurfdofs] = self.label.d2J_by_dsurfacecoefficientsdsurfacecoefficients() - + H = np.concatenate(( H, np.sqrt(constraint_weight) * d2l[None, :, :], @@ -235,7 +236,6 @@ def boozer_penalty_constraints_vectorized(self, dofs, derivatives=0, constraint_ return r, J, H - def boozer_exact_constraints(self, xl, derivatives=0, optimize_G=True): r""" This function returns the optimality conditions corresponding to the minimization problem @@ -377,7 +377,7 @@ def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, cons val, dval, d2val = fun_name(x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) norm = np.linalg.norm(dval) i = i+1 - + r = self.boozer_penalty_constraints( x, derivatives=0, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) res = { @@ -408,7 +408,7 @@ def minimize_boozer_penalty_constraints_ls(self, tol=1e-12, maxiter=10, constrai if not self.need_to_run_code: return self.res - + s = self.surface if G is None: x = np.concatenate((s.get_dofs(), [iota])) @@ -679,12 +679,9 @@ def solve_residual_equation_exactly_newton(self, tol=1e-10, maxiter=10, iota=0., P, L, U = lu(J) res = { - "residual": r, "jacobian": J, "iter": i, "success": norm <= tol, "G": G, "iota": iota, "PLU": (P, L, U), + "residual": r, "jacobian": J, "iter": i, "success": norm <= tol, "G": G, "s":s, "iota": iota, "PLU": (P, L, U), "mask": mask, 'type': 'exact' } - - self.res = res self.need_to_run_code = False return res - diff --git a/src/simsopt/geo/surfaceobjectives.py b/src/simsopt/geo/surfaceobjectives.py index bd3f73e76..db228ecc2 100644 --- a/src/simsopt/geo/surfaceobjectives.py +++ b/src/simsopt/geo/surfaceobjectives.py @@ -293,7 +293,7 @@ def boozer_surface_residual(surface, iota, G, biotsavart, derivatives=0, weight_ residual .. math:: - G\mathbf B_\text{BS}(\mathbf x) - ||\mathbf B_\text{BS}(\mathbf x)||^2 (\mathbf x_\varphi + \iota \mathbf x_\theta) + G\mathbf B_\text{BS}(\mathbf x) - \|\mathbf B_\text{BS}(\mathbf x)\|^2 (\mathbf x_\varphi + \iota \mathbf x_\theta) as well as the derivatives of this residual with respect to surface dofs, iota, and G. In the above, :math:`\mathbf x` are points on the surface, :math:`\iota` is the From a094ca550745d28e192566e3b8aadcd500fd07bc Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 23 Apr 2024 15:45:49 -0400 Subject: [PATCH 066/131] removing a comment --- src/simsopt/geo/boozersurface.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 863bb3079..24e37e18b 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -150,7 +150,6 @@ def boozer_penalty_constraints_vectorized(self, dofs, derivatives=0, constraint_ is much faster since it calls a vectorized implementation in cpp. """ - # this is essentially the scalarize option in previous implementation. This should be merged in that case... assert derivatives in [0, 1, 2] if optimize_G: sdofs = dofs[:-2] From 6e034d258b5950effc81c9bd0f0c24a1562c8ec5 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 23 Apr 2024 15:57:27 -0400 Subject: [PATCH 067/131] more linting changes --- src/simsopt/geo/boozersurface.py | 2 +- src/simsopt/geo/surfaceobjectives.py | 1 + tests/geo/test_boozersurface.py | 15 +++++---------- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 24e37e18b..f4edceea4 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -678,7 +678,7 @@ def solve_residual_equation_exactly_newton(self, tol=1e-10, maxiter=10, iota=0., P, L, U = lu(J) res = { - "residual": r, "jacobian": J, "iter": i, "success": norm <= tol, "G": G, "s":s, "iota": iota, "PLU": (P, L, U), + "residual": r, "jacobian": J, "iter": i, "success": norm <= tol, "G": G, "s": s, "iota": iota, "PLU": (P, L, U), "mask": mask, 'type': 'exact' } self.res = res diff --git a/src/simsopt/geo/surfaceobjectives.py b/src/simsopt/geo/surfaceobjectives.py index db228ecc2..6d5f0dfd3 100644 --- a/src/simsopt/geo/surfaceobjectives.py +++ b/src/simsopt/geo/surfaceobjectives.py @@ -463,6 +463,7 @@ def boozer_surface_residual(surface, iota, G, biotsavart, derivatives=0, weight_ return r, J, H + def parameter_derivatives(surface: Surface, shape_gradient: NDArray[Any, Float] ) -> NDArray[Any, Float]: diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 6e30d2201..e02824fea 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -398,7 +398,6 @@ def subtest_convergence_cpp_and_notcpp_same(self, vectorize): G = res['G'] return np.concatenate([x, [iota, G]]) - def test_boozer_penalty_constraints_cpp_notcpp(self): """ Test to verify cpp and python implementations of the BoozerLS objective return the same thing. @@ -406,7 +405,7 @@ def test_boozer_penalty_constraints_cpp_notcpp(self): for surfacetype in surfacetypes_list: for stellsym in stellsym_list: for weight_inv_modB in [False, True]: - for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 2, 2), (False, 2, 1), (True, 6, 9), (False, 7, 8),(True, 3, 3), (False, 3, 3)]: + for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 2, 2), (False, 2, 1), (True, 6, 9), (False, 7, 8), (True, 3, 3), (False, 3, 3)]: with self.subTest(surfacetype=surfacetype, stellsym=stellsym, optimize_G=optimize_G, @@ -434,7 +433,6 @@ def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, o elif ntheta == 2: thetas = [0.2432101234, 0.9832134] - s = get_surface(surfacetype, stellsym, nphi=nphi, ntheta=ntheta, thetas=thetas, phis=phis, mpol=3, ntor=3) s.fit_to_curve(ma, 0.1) s.x = s.x + np.random.rand(s.x.size)*1e-6 @@ -456,9 +454,8 @@ def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, o f1 = boozer_surface.boozer_penalty_constraints_vectorized( x, derivatives=0, constraint_weight=w, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) np.testing.assert_allclose(f0, f1, atol=1e-13, rtol=1e-13) - #print(np.abs(f0-f1)/np.abs(f0)) + print(np.abs(f0-f1)/np.abs(f0)) - # deriv = 1 f0, J0 = boozer_surface.boozer_penalty_constraints( x, derivatives=1, constraint_weight=w, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) @@ -470,8 +467,7 @@ def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, o # check directional derivative h1 = np.random.rand(J0.size)-0.5 np.testing.assert_allclose(J0@h1, J1@h1, atol=1e-13, rtol=1e-13) - #print(np.abs(f0-f1)/np.abs(f0), np.abs(J0@h1-J1@h1)/np.abs(J0@h1)) - + print(np.abs(f0-f1)/np.abs(f0), np.abs(J0@h1-J1@h1)/np.abs(J0@h1)) # deriv = 2 f0, J0, H0 = boozer_surface.boozer_penalty_constraints( @@ -487,8 +483,7 @@ def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, o np.testing.assert_allclose(f0, f1, atol=1e-13, rtol=1e-13) np.testing.assert_allclose(J0@h1, J1@h1, atol=1e-13, rtol=1e-13) np.testing.assert_allclose((H0@h1)@h2, (H1@h1)@h2, atol=1e-13, rtol=1e-13) - #print(np.abs(f0-f1)/np.abs(f0), np.abs(J0@h1-J1@h1)/np.abs(J0@h1), np.abs((H0@h1)@h2-(H1@h1)@h2)/np.abs((H0@h1)@h2)) - + print(np.abs(f0-f1)/np.abs(f0), np.abs(J0@h1-J1@h1)/np.abs(J0@h1), np.abs((H0@h1)@h2-(H1@h1)@h2)/np.abs((H0@h1)@h2)) def compute_differences(Ha, Hb): diff = np.abs(Ha.flatten() - Hb.flatten()) @@ -497,12 +492,12 @@ def compute_differences(Ha, Hb): i1 = ij1[0][0] j1 = ij1[1][0] - ij2 = np.where(rel_diff.reshape(Ha.shape) == np.max(rel_diff)) i2 = ij2[0][0] j2 = ij2[1][0] print(f'max err ({i1:03}, {j1:03}): {np.max(diff):.6e}, {Ha[i1, j1]:.6e}\nmax rel err ({i2:03}, {j2:03}): {np.max(rel_diff):.6e}, {Ha[i2,j2]:.6e}\n') compute_differences(H0, H1) + if __name__ == "__main__": unittest.main() From 0cf68fe61130210d300a815f6ae571254f457ef9 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 23 Apr 2024 16:04:40 -0400 Subject: [PATCH 068/131] more linting --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 046f45db4..6a41b4654 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,6 +159,8 @@ set_target_properties(profiling target_include_directories(profiling PRIVATE "thirdparty/xtensor/include" "thirdparty/xsimd/include" "thirdparty/xtl/include" "thirdparty/eigen" "src/simsoptpp/") target_link_libraries(profiling PRIVATE fmt::fmt-header-only) + + #get_cmake_property(_variableNames VARIABLES) #list (SORT _variableNames) #foreach (_variableName ${_variableNames}) From 30e2420eea1277f7e2f45f9e8cc08a56a71d53d2 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 23 Apr 2024 16:43:19 -0400 Subject: [PATCH 069/131] more docstring and linting changes --- src/simsopt/geo/boozersurface.py | 7 +++++-- src/simsopt/geo/surface.py | 2 +- src/simsopt/geo/surfaceobjectives.py | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index f4edceea4..1bef2e825 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -73,7 +73,9 @@ def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., sca i.e. the least squares residual and optionally the gradient and the Hessian of :math:`J(x)`. - For ``weight_inv_modB=False``, the residuals are unweighted, and they are multiplied by 1/ + If ``weight_inv_modB=True``, the Boozer residuals are weighted by the inverse of the field strength + (i.e. multiplied by :math:`1/\|\mathbf B \|`), otherwise, they are unweighted (multiplied by 1). Setting + this to True is useful to prevent the least squares residual from scaling with the coil currents. """ assert derivatives in [0, 1, 2] @@ -147,7 +149,8 @@ def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., sca def boozer_penalty_constraints_vectorized(self, dofs, derivatives=0, constraint_weight=1., optimize_G=False, weight_inv_modB=False): """ This function returns the same thing as `boozer_penalty_constraints` when `scalarized=True`. It - is much faster since it calls a vectorized implementation in cpp. + is much faster and uses less memory since it calls a vectorized implementation in cpp. This is + especially true when `derivatives=2`, i.e., when the Hessian is requested. """ assert derivatives in [0, 1, 2] diff --git a/src/simsopt/geo/surface.py b/src/simsopt/geo/surface.py index ef12cb80d..9da6fba97 100644 --- a/src/simsopt/geo/surface.py +++ b/src/simsopt/geo/surface.py @@ -518,7 +518,7 @@ def minor_radius(self): Return the minor radius of the surface using the formula .. math:: - R_{\text{minor}} &= \sqrt{ \overline{A} / \pi } + R_{\text{minor}} = \sqrt{ \overline{A} / \pi } where :math:`\overline{A}` is the average cross sectional area. diff --git a/src/simsopt/geo/surfaceobjectives.py b/src/simsopt/geo/surfaceobjectives.py index 6d5f0dfd3..83e831dc5 100644 --- a/src/simsopt/geo/surfaceobjectives.py +++ b/src/simsopt/geo/surfaceobjectives.py @@ -309,7 +309,7 @@ def boozer_surface_residual(surface, iota, G, biotsavart, derivatives=0, weight_ G: a constant that is a function of the coil currents in vacuum field biotsavart: the Biot-Savart magnetic field derivatives: how many spatial derivatives of the residual to compute - weight_inv_modB: whether or not to weight the residual by :math:`\|\mathbf B\|`. This + weight_inv_modB: whether or not to weight the residual by :math:`1/\|\mathbf B\|`. This is useful to activate so that the residual does not scale with the coil currents. From 939a8594e3c20acaafb71f00c1cde6aca77a75b2 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 23 Apr 2024 19:20:05 -0400 Subject: [PATCH 070/131] missed a bug introduced when I was fixing the aligned memory access --- src/simsoptpp/boozerresidual_impl.h | 2 +- tests/geo/test_boozersurface.py | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/simsoptpp/boozerresidual_impl.h b/src/simsoptpp/boozerresidual_impl.h index dccaf9f29..cb9ab3832 100644 --- a/src/simsoptpp/boozerresidual_impl.h +++ b/src/simsoptpp/boozerresidual_impl.h @@ -212,7 +212,7 @@ template void boozer_residual_impl(double G, double iota, T& simd_t drtilij2_dn(drtilij2[n]); simd_t d2res_mn = drtilij0_dm * drtilij0_dn + drtilij1_dm * drtilij1_dn + drtilij2_dm * drtilij2_dn; - int jjlimit = std::min(simd_size, ndofs+2-n); + int jjlimit = std::min(simd_size, ndofs+2-m); for(int jj = 0; jj < jjlimit; jj++){ d2res(m+jj, n) += d2res_mn[jj]; } diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index e02824fea..903ac27a9 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -405,14 +405,16 @@ def test_boozer_penalty_constraints_cpp_notcpp(self): for surfacetype in surfacetypes_list: for stellsym in stellsym_list: for weight_inv_modB in [False, True]: - for (optimize_G, nphi, ntheta) in [(True, 1, 1), (False, 1, 1), (True, 2, 2), (False, 2, 1), (True, 6, 9), (False, 7, 8), (True, 3, 3), (False, 3, 3)]: + for (optimize_G, nphi, ntheta, mpol, ntor) in [(True, 1, 1, 3, 3), (False, 1, 1, 13, 2), (True, 2, 2, 10, 3), (False, 2, 1, 3, 4), (True, 6, 9, 3, 3), (False, 7, 8, 3, 4), (True, 3, 3, 3, 3), (False, 3, 3, 3, 5)]: with self.subTest(surfacetype=surfacetype, stellsym=stellsym, optimize_G=optimize_G, - weight_inv_modB=weight_inv_modB): - self.subtest_boozer_penalty_constraints_cpp_notcpp(surfacetype, stellsym, optimize_G, nphi, ntheta, weight_inv_modB) + weight_inv_modB=weight_inv_modB, + mpol=mpol, + ntor=ntor): + self.subtest_boozer_penalty_constraints_cpp_notcpp(surfacetype, stellsym, optimize_G, nphi, ntheta, weight_inv_modB, mpol, ntor) - def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, optimize_G, nphi, ntheta, weight_inv_modB): + def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, optimize_G, nphi, ntheta, weight_inv_modB, mpol, ntor): np.random.seed(1) curves, currents, ma = get_ncsx_data() @@ -433,7 +435,7 @@ def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, o elif ntheta == 2: thetas = [0.2432101234, 0.9832134] - s = get_surface(surfacetype, stellsym, nphi=nphi, ntheta=ntheta, thetas=thetas, phis=phis, mpol=3, ntor=3) + s = get_surface(surfacetype, stellsym, nphi=nphi, ntheta=ntheta, thetas=thetas, phis=phis, mpol=mpol, ntor=ntor) s.fit_to_curve(ma, 0.1) s.x = s.x + np.random.rand(s.x.size)*1e-6 From 773b9ec6cc55aaf1c80404943f5ed125627adeed Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 23 Apr 2024 20:28:17 -0400 Subject: [PATCH 071/131] adding packages missing, but needed for unit tests --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 637981a4c..269c9588d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -93,7 +93,7 @@ jobs: - name: Install python dependencies run: | sudo apt-get install graphviz graphviz-dev - pip install numpy cmake scikit-build f90nml ninja wheel setuptools sympy qsc pyevtk matplotlib plotly networkx pygraphviz mpi4py py_spec pyoculus h5py + pip install numpy cmake scikit-build f90nml ninja wheel setuptools sympy qsc pyevtk matplotlib plotly networkx pygraphviz mpi4py py_spec pyoculus h5py ground bentley_ottmann - name: Install booz_xform run: pip install -v git+https://github.com/hiddenSymmetries/booz_xform From 736d6ebf72e3f92aa2d2721447407e90fe4d1f42 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 23 Apr 2024 21:39:41 -0400 Subject: [PATCH 072/131] tightening tolerances again for unit test --- tests/geo/test_boozersurface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 903ac27a9..98956473a 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -284,9 +284,9 @@ def subtest_boozer_surface_optimisation_convergence(self, surfacetype, # compute surface first using LBFGS exact and an area constraint res = boozer_surface.minimize_boozer_penalty_constraints_LBFGS( - tol=1e-10, maxiter=600, constraint_weight=100., iota=iota, G=G, + tol=1e-11, maxiter=700, constraint_weight=100., iota=iota, G=G, vectorize=vectorize) - print('Residual norm after LBFGS', np.sqrt(2*res['fun'])) + print('Residual norm after LBFGS', res['iter'], np.sqrt(2*res['fun'])) boozer_surface.recompute_bell() if second_stage == 'ls': From b0bb9266c8dab047f0a59b43a2a73a7633d2afd9 Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Thu, 25 Apr 2024 11:29:06 -0400 Subject: [PATCH 073/131] Implemented make_rotating_ellipse --- src/simsopt/geo/surfacerzfourier.py | 37 +++++++++++ tests/geo/test_surface_rzfourier.py | 99 +++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/src/simsopt/geo/surfacerzfourier.py b/src/simsopt/geo/surfacerzfourier.py index 4ea4ec57a..391da4f47 100644 --- a/src/simsopt/geo/surfacerzfourier.py +++ b/src/simsopt/geo/surfacerzfourier.py @@ -637,6 +637,43 @@ def write_nml(self, filename: str): with open(filename, 'w') as f: f.write(self.get_nml()) + def make_rotating_ellipse(self, major_radius, minor_radius, elongation, torsion=0): + """ + Set the surface shape to be a rotating ellipse with the given + parameters. + + Values of ``elongation`` larger than 1 will result in the elliptical + cross-section at :math:`\phi=0` being taller than it is wide. + Values of ``elongation`` less than 1 will result in the elliptical + cross-section at :math:`\phi=0` being wider than it is tall. + + The sign convention is such that both the rotating elongation and + positive ``torsion`` will contribute positively to iota according to + VMEC's sign convention. + + Args: + major_radius: Average major radius of the surface. + minor_radius: Average minor radius of the surface. + elongation: Elongation of the elliptical cross-section. + torsion: Value to use for the (m,n)=(0,1) mode of RC and -ZS, which + controls the torsion of the magnetic axis. + """ + + self.local_full_x = np.zeros_like(self.local_full_x) + self.set_rc(0, 0, major_radius) + self.set_rc(0, 1, torsion) + self.set_zs(0, 1, -torsion) + + sqrt_elong = np.sqrt(elongation) + amplitude = 0.5 * minor_radius * (1 / sqrt_elong - sqrt_elong) + self.set_rc(1, 1, amplitude) + self.set_zs(1, 1, -amplitude) + + amplitude = 0.5 * minor_radius * (1 / sqrt_elong + sqrt_elong) + self.set_rc(1, 0, amplitude) + self.set_zs(1, 0, amplitude) + + return_fn_map = {'area': sopp.SurfaceRZFourier.area, 'volume': sopp.SurfaceRZFourier.volume, 'aspect-ratio': Surface.aspect_ratio} diff --git a/tests/geo/test_surface_rzfourier.py b/tests/geo/test_surface_rzfourier.py index 976f4cfaf..0afddbb23 100755 --- a/tests/geo/test_surface_rzfourier.py +++ b/tests/geo/test_surface_rzfourier.py @@ -10,6 +10,13 @@ from simsopt.geo.surface import Surface from simsopt._core.optimizable import Optimizable +try: + import vmec +except ImportError: + vmec = None + +from simsopt.mhd import Vmec + TEST_DIR = Path(__file__).parent / ".." / "test_files" stellsym_list = [True, False] @@ -631,6 +638,98 @@ def test_shared_dof_serialization(self): self.assertAlmostEqual(s2.area(), surf_objs[1].area()) self.assertIs(surf_objs[0].dofs, surf_objs[1].dofs) + def test_make_rotating_ellipse(self): + major_radius = 8.4 + minor_radius = 2.3 + elongation = 2.7 + torsion = 0.6 + nfp = 3 + sqrt_elong = np.sqrt(elongation) + surf = SurfaceRZFourier.from_nphi_ntheta(ntor=2, mpol=3, nphi=2, ntheta=4, range="field period", nfp=nfp) + surf.make_rotating_ellipse(major_radius, minor_radius, elongation, torsion) + + xyz = surf.gamma() + R = np.sqrt(xyz[:, :, 0]**2 + xyz[:, :, 1]**2) + Z = xyz[:, :, 2] + + # Check phi=0 plane: + np.testing.assert_allclose( + R[0, :], + [major_radius + torsion + minor_radius / sqrt_elong, + major_radius + torsion, + major_radius + torsion - minor_radius / sqrt_elong, + major_radius + torsion] + ) + np.testing.assert_allclose( + Z[0, :], + [0, + minor_radius * sqrt_elong, + 0, + -minor_radius * sqrt_elong], + atol=1e-14, + ) + + # Check phi=pi/nfp plane: + np.testing.assert_allclose( + R[1, :], + [major_radius - torsion + minor_radius * sqrt_elong, + major_radius - torsion, + major_radius - torsion - minor_radius * sqrt_elong, + major_radius - torsion] + ) + np.testing.assert_allclose( + Z[1, :], + [0, + minor_radius / sqrt_elong, + 0, + -minor_radius / sqrt_elong], + atol=1e-14, + ) + + # Now make the same surface shape with more quadpoints: + surf = SurfaceRZFourier.from_nphi_ntheta(ntor=1, mpol=1, nphi=64, ntheta=65, range="field period", nfp=nfp) + surf.make_rotating_ellipse(major_radius, minor_radius, elongation, torsion) + np.testing.assert_allclose(surf.major_radius(), major_radius) + np.testing.assert_allclose(surf.minor_radius(), minor_radius) + np.testing.assert_allclose(surf.aspect_ratio(), major_radius / minor_radius) + + # Check that the cross-sectional area is correct at every phi: + gamma = surf.gamma() + R = np.sqrt(gamma[:, :, 0]**2 + gamma[:, :, 1]**2) + gammadash2 = surf.gammadash2() + dZdtheta = gammadash2[:, :, 2] + dtheta = surf.quadpoints_theta[1] - surf.quadpoints_theta[0] + area_vs_phi = np.abs(np.sum(R * dZdtheta, axis=1) * dtheta) + np.testing.assert_allclose(area_vs_phi, np.pi * minor_radius**2) + + @unittest.skipIf(vmec is None, "vmec python extension is not installed") + def test_make_rotating_ellipse_iota(self): + """make_rotating_ellipse() should give positive iota.""" + filename = str(TEST_DIR / 'input.LandremanPaul2021_QH_reactorScale_lowres') + with ScratchDir("."): + eq = Vmec(filename) + eq.indata.mpol = 4 # Lower resolution to expedite test + eq.indata.ntor = 4 + eq.indata.ftol_array[:2] = [1e-8, 1e-10] + + # Try the case of elongation=1 with positive torsion: + major_radius = 8.4 + minor_radius = 1.3 + elongation = 1.0 + torsion = 0.9 + eq.boundary.make_rotating_ellipse(major_radius, minor_radius, elongation, torsion) + eq.run() + np.testing.assert_array_less(0, eq.wout.iotaf) + + # Try the case of zero torsion with rotating elongation: + major_radius = 8.4 + minor_radius = 1.3 + elongation = 2.1 + torsion = 0.0 + eq.boundary.make_rotating_ellipse(major_radius, minor_radius, elongation, torsion) + eq.run() + np.testing.assert_array_less(0, eq.wout.iotaf) + class SurfaceRZPseudospectralTests(unittest.TestCase): def test_names(self): From 9a29c6330c80b75a0dda1966ce56dc1aa484f490 Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Thu, 25 Apr 2024 14:29:45 -0400 Subject: [PATCH 074/131] Add test coverage for CircularCoil.to_vtk() --- tests/field/test_magneticfields.py | 8 +++-- .../field/test_magneticfields_optimization.py | 36 ++++++++++++------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/tests/field/test_magneticfields.py b/tests/field/test_magneticfields.py index 5b67aba1b..028cd8d91 100644 --- a/tests/field/test_magneticfields.py +++ b/tests/field/test_magneticfields.py @@ -372,10 +372,14 @@ def test_circularcoil_Bfield(self): field = CircularCoil(r0=radius, center=center, I=current, normal=[np.pi/2, -angle]) field.set_points(points) - assert np.allclose(field.B(), [[0.01016974, 0.00629875, -0.00220838]]) + np.testing.assert_allclose(field.B(), [[0.01016974, 0.00629875, -0.00220838]], rtol=1e-6) # test coil location - assert np.allclose(field.gamma(points=4), [[1.3575,1.456,2.789],[0.123,center[1]+radius*np.cos(-angle),center[2]-radius*np.sin(-angle)], + np.testing.assert_allclose(field.gamma(points=4), [[1.3575,1.456,2.789],[0.123,center[1]+radius*np.cos(-angle),center[2]-radius*np.sin(-angle)], [-1.1115,1.456,2.789],[0.123,center[1]-radius*np.cos(-angle),center[2]+radius*np.sin(-angle)]]) + with ScratchDir("."): + for close in [True, False]: + field.to_vtk('test', close=close) + def test_circularcoil_Bfield_toroidal_arrangement(self): # This makes N_coils with centered at major radius R_m diff --git a/tests/field/test_magneticfields_optimization.py b/tests/field/test_magneticfields_optimization.py index 8545549b4..da8249641 100644 --- a/tests/field/test_magneticfields_optimization.py +++ b/tests/field/test_magneticfields_optimization.py @@ -15,7 +15,7 @@ class Testing(unittest.TestCase): def test_circularcoil_current_optimization(self): - # test I,r0 optimization + # test optimization of I and r0 coil = CircularCoil() x0 = np.random.rand(coil.dof_size) x0[1] = 0 @@ -24,7 +24,7 @@ def test_circularcoil_current_optimization(self): x0[5] = 0 x0[6] = 0 coil.x = x0 - coil.fix([1,2,3,5,6]) + coil.fix([1, 2, 3, 5, 6]) print('Initial coil radius: ', coil.x[0]) print('Initial coil current: ', coil.x[1]) @@ -34,14 +34,15 @@ def test_circularcoil_current_optimization(self): def get_I(c): return c.I + def get_B(c): return c.B()[0][2] I_coil = make_optimizable(get_I, coil) B_coil = make_optimizable(get_B, coil) - Bmag = 1.2*2*np.pi/1.12345 - prob = LeastSquaresProblem.from_tuples([(I_coil.J, 1.2e7, 2e6),(B_coil.J, Bmag, 1.0)]) + Bmag = 1.2 * 2 * np.pi / 1.12345 + prob = LeastSquaresProblem.from_tuples([(I_coil.J, 1.2e7, 2e6), (B_coil.J, Bmag, 1.0)]) with ScratchDir("."): least_squares_serial_solve(prob) @@ -60,14 +61,16 @@ def test_circularcoil_position_optimization(self): x0[5] = 0 x0[6] = 0 coil.x = x0 - coil.fix([0,4,5,6]) + coil.fix([0, 4, 5, 6]) print('Initial coil position: ', coil.x) def Bx(c): return c.B()[0][0] + def By(c): return c.B()[0][1] + def Bz(c): return c.B()[0][2] @@ -75,8 +78,12 @@ def Bz(c): By_coil = make_optimizable(By, coil) Bz_coil = make_optimizable(Bz, coil) - Bmag = 1.2*2*np.pi/1.12345 - prob = LeastSquaresProblem.from_tuples([(Bx_coil.J, 0, 1.0),(By_coil.J, 0, 1.0),(Bz_coil.J, Bmag, 1.0)]) + Bmag = 1.2 * 2 * np.pi / 1.12345 + prob = LeastSquaresProblem.from_tuples( + [(Bx_coil.J, 0, 1.0), + (By_coil.J, 0, 1.0), + (Bz_coil.J, Bmag, 1.0)] + ) points = np.array([[1, 1, 1]]) coil.set_points(points) @@ -101,7 +108,7 @@ def test_circularcoil_orientation_optimization(self): x0[3] = 0 x0[4] = 4.8 coil.x = x0 - coil.fix([0,1,2,3,4]) + coil.fix([0, 1, 2, 3, 4]) print('Initial coil normal: ', coil.x) @@ -110,8 +117,10 @@ def test_circularcoil_orientation_optimization(self): def Bx(c): return c.B()[0][0] + def By(c): return c.B()[0][1] + def Bz(c): return c.B()[0][2] @@ -119,12 +128,15 @@ def Bz(c): By_coil = make_optimizable(By, coil) Bz_coil = make_optimizable(Bz, coil) - Bmag = np.sqrt(2)/2*1.2*2*np.pi/1.12345 - prob = LeastSquaresProblem.from_tuples([(Bx_coil.J, Bmag, 1.0),(By_coil.J, 0, 1.0),(Bz_coil.J, Bmag, 1.0)]) + Bmag = np.sqrt(2) / 2 * 1.2 * 2 * np.pi / 1.12345 + prob = LeastSquaresProblem.from_tuples( + [(Bx_coil.J, Bmag, 1.0), + (By_coil.J, 0, 1.0), + (Bz_coil.J, Bmag, 1.0)] + ) with ScratchDir("."): least_squares_serial_solve(prob) print(' Final coil normal: ', coil.x) - assert np.allclose(coil.x, [0, np.pi/4], atol=1e-6) - + assert np.allclose(coil.x, [0, np.pi / 4], atol=1e-6) From d82cb17746e87d8cb3bd8459db705620af26bac0 Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Thu, 25 Apr 2024 14:58:18 -0400 Subject: [PATCH 075/131] Added test that CircularCoil.gamma() matches CurveXYZFourier.gamma() --- tests/field/test_magneticfields.py | 44 ++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/tests/field/test_magneticfields.py b/tests/field/test_magneticfields.py index 028cd8d91..df46b91ca 100644 --- a/tests/field/test_magneticfields.py +++ b/tests/field/test_magneticfields.py @@ -221,6 +221,20 @@ def test_circularcoil_Bfield(self): Bfield_regen = json.loads(field_json_str, cls=GSONDecoder) self.assertTrue(np.allclose(Bfield.B(), Bfield_regen.B())) + def compare_gammas(circular_coil, general_coil): + # Verify that the gamma values are the same, up to a shift in the + # array index. + gamma1 = general_coil.curve.gamma() + gamma2 = circular_coil.gamma(len(curve.quadpoints)) + if general_coil.current.get_value() * circular_coil.I < 0: + # Currents are opposite sign, so the direction of the points + # will be reversed. + gamma1 = np.flipud(gamma1) + + index = np.argmin(np.linalg.norm(gamma1[0, None] - gamma2, axis=1)) + gamma3 = np.roll(gamma2, -index, axis=0) + np.testing.assert_allclose(gamma1, gamma3, atol=1e-14) + # Verify that divergence is zero dB1_by_dX = Bfield.dB_by_dX() assert np.allclose(dB1_by_dX[:, 0, 0]+dB1_by_dX[:, 1, 1]+dB1_by_dX[:, 2, 2], np.zeros((npoints))) @@ -232,11 +246,13 @@ def test_circularcoil_Bfield(self): points = np.asarray(npoints * [[-1.41513202e-03, 8.99999382e-01, -3.14473221e-04]]) np.random.seed(0) points += pointVar * (np.random.rand(*points.shape)-0.5) + ## verify with a x^2+z^2=radius^2 circular coil normal = [np.pi/2, np.pi/2] curve = CurveXYZFourier(300, 1) curve.set_dofs([center[0], radius, 0., center[1], 0., 0., center[2], 0., radius]) - Bcircular = BiotSavart([Coil(curve, Current(current))]) + general_coil = Coil(curve, Current(current)) + Bcircular = BiotSavart([general_coil]) Bfield = CircularCoil(I=current, r0=radius, normal=normal, center=center) Bfield.set_points(points) Bcircular.set_points(points) @@ -246,11 +262,14 @@ def test_circularcoil_Bfield(self): assert np.allclose(Bfield.dB_by_dX(), Bcircular.dB_by_dX()) assert np.allclose(dB1_by_dX[:, 0, 0]+dB1_by_dX[:, 1, 1]+dB1_by_dX[:, 2, 2], np.zeros((npoints))) assert np.allclose(dB1_by_dX, transpGradB1) + compare_gammas(Bfield, general_coil) + # use normal = [0, 1, 0] normal = [0, 1, 0] curve = CurveXYZFourier(300, 1) curve.set_dofs([center[0], radius, 0., center[1], 0., 0., center[2], 0., radius]) - Bcircular = BiotSavart([Coil(curve, Current(current))]) + general_coil = Coil(curve, Current(current)) + Bcircular = BiotSavart([general_coil]) Bfield = CircularCoil(I=current, r0=radius, normal=normal, center=center) Bfield.set_points(points) Bcircular.set_points(points) @@ -260,11 +279,14 @@ def test_circularcoil_Bfield(self): assert np.allclose(Bfield.dB_by_dX(), Bcircular.dB_by_dX()) assert np.allclose(dB1_by_dX[:, 0, 0]+dB1_by_dX[:, 1, 1]+dB1_by_dX[:, 2, 2], np.zeros((npoints))) assert np.allclose(dB1_by_dX, transpGradB1) + compare_gammas(Bfield, general_coil) + ## verify with a y^2+z^2=radius^2 circular coil normal = [0, np.pi/2] curve = CurveXYZFourier(300, 1) curve.set_dofs([center[0], 0, 0., center[1], radius, 0., center[2], 0., radius]) - Bcircular = BiotSavart([Coil(curve, Current(-current))]) + general_coil = Coil(curve, Current(-current)) + Bcircular = BiotSavart([general_coil]) Bfield = CircularCoil(I=current, r0=radius, normal=normal, center=center) Bfield.set_points(points) Bcircular.set_points(points) @@ -274,6 +296,7 @@ def test_circularcoil_Bfield(self): assert np.allclose(Bfield.dB_by_dX(), Bcircular.dB_by_dX()) assert np.allclose(dB1_by_dX[:, 0, 0]+dB1_by_dX[:, 1, 1]+dB1_by_dX[:, 2, 2], np.zeros((npoints))) # divergence assert np.allclose(dB1_by_dX, transpGradB1) # symmetry of the gradient + compare_gammas(Bfield, general_coil) # one points Bfield.set_points(np.asarray([[0.1, 0.2, 0.3]])) @@ -294,7 +317,8 @@ def test_circularcoil_Bfield(self): normal = [1, 0, 0] curve = CurveXYZFourier(300, 1) curve.set_dofs([center[0], 0, 0., center[1], radius, 0., center[2], 0., radius]) - Bcircular = BiotSavart([Coil(curve, Current(-current))]) + general_coil = Coil(curve, Current(-current)) + Bcircular = BiotSavart([general_coil]) Bfield = CircularCoil(I=current, r0=radius, normal=normal, center=center) Bfield.set_points(points) Bcircular.set_points(points) @@ -304,12 +328,15 @@ def test_circularcoil_Bfield(self): assert np.allclose(Bfield.dB_by_dX(), Bcircular.dB_by_dX()) assert np.allclose(dB1_by_dX[:, 0, 0]+dB1_by_dX[:, 1, 1]+dB1_by_dX[:, 2, 2], np.zeros((npoints))) # divergence assert np.allclose(dB1_by_dX, transpGradB1) # symmetry of the gradient + compare_gammas(Bfield, general_coil) + ## verify with a x^2+y^2=radius^2 circular coil center = [0, 0, 0] normal = [0, 0] curve = CurveXYZFourier(300, 1) curve.set_dofs([center[0], 0, radius, center[1], radius, 0., center[2], 0., 0.]) - Bcircular = BiotSavart([Coil(curve, Current(current))]) + general_coil = Coil(curve, Current(current)) + Bcircular = BiotSavart([general_coil]) curve2 = CurveRZFourier(300, 1, 1, True) curve2.set_dofs([radius, 0, 0]) Bcircular2 = BiotSavart([Coil(curve2, Current(current))]) @@ -325,12 +352,15 @@ def test_circularcoil_Bfield(self): assert np.allclose(Bfield.dB_by_dX(), Bcircular2.dB_by_dX()) assert np.allclose(dB1_by_dX[:, 0, 0]+dB1_by_dX[:, 1, 1]+dB1_by_dX[:, 2, 2], np.zeros((npoints))) # divergence assert np.allclose(dB1_by_dX, transpGradB1) # symmetry of the gradient + compare_gammas(Bfield, general_coil) + # use normal = [0, 0, 1] center = [0, 0, 0] normal = [0, 0, 1] curve = CurveXYZFourier(300, 1) curve.set_dofs([center[0], 0, radius, center[1], radius, 0., center[2], 0., 0.]) - Bcircular = BiotSavart([Coil(curve, Current(current))]) + general_coil = Coil(curve, Current(current)) + Bcircular = BiotSavart([general_coil]) curve2 = CurveRZFourier(300, 1, 1, True) curve2.set_dofs([radius, 0, 0]) Bcircular2 = BiotSavart([Coil(curve, Current(current))]) @@ -346,6 +376,8 @@ def test_circularcoil_Bfield(self): assert np.allclose(Bfield.dB_by_dX(), Bcircular2.dB_by_dX()) assert np.allclose(dB1_by_dX[:, 0, 0]+dB1_by_dX[:, 1, 1]+dB1_by_dX[:, 2, 2], np.zeros((npoints))) # divergence assert np.allclose(dB1_by_dX, transpGradB1) # symmetry of the gradient + compare_gammas(Bfield, general_coil) + ## Test with results from coilpy radius = 1.2345 center = np.array([0.123, 1.456, 2.789]) From bc79d97dea2a4bad03c22b425e42cfd3aaf4b82f Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Fri, 26 Apr 2024 06:21:53 -0400 Subject: [PATCH 076/131] Add regression test requested by Rogerio --- tests/geo/test_surface_rzfourier.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/geo/test_surface_rzfourier.py b/tests/geo/test_surface_rzfourier.py index 0afddbb23..538cf17d2 100755 --- a/tests/geo/test_surface_rzfourier.py +++ b/tests/geo/test_surface_rzfourier.py @@ -712,7 +712,7 @@ def test_make_rotating_ellipse_iota(self): eq.indata.ntor = 4 eq.indata.ftol_array[:2] = [1e-8, 1e-10] - # Try the case of elongation=1 with positive torsion: + # Try the case of elongation=1 with positive axis torsion: major_radius = 8.4 minor_radius = 1.3 elongation = 1.0 @@ -720,8 +720,9 @@ def test_make_rotating_ellipse_iota(self): eq.boundary.make_rotating_ellipse(major_radius, minor_radius, elongation, torsion) eq.run() np.testing.assert_array_less(0, eq.wout.iotaf) + np.testing.assert_allclose(eq.mean_iota(), 0.26990720954583547, rtol=1e-6) - # Try the case of zero torsion with rotating elongation: + # Try the case of zero axis torsion with rotating elongation: major_radius = 8.4 minor_radius = 1.3 elongation = 2.1 @@ -729,6 +730,7 @@ def test_make_rotating_ellipse_iota(self): eq.boundary.make_rotating_ellipse(major_radius, minor_radius, elongation, torsion) eq.run() np.testing.assert_array_less(0, eq.wout.iotaf) + np.testing.assert_allclose(eq.mean_iota(), 0.4291137962772453, rtol=1e-6) class SurfaceRZPseudospectralTests(unittest.TestCase): From dbd99ba51fe7420c0fcb7b853e8b3d9c51dd0a79 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 1 May 2024 12:04:56 -0400 Subject: [PATCH 077/131] making weight_inv_modB default to True --- examples/2_Intermediate/boozer.py | 2 ++ src/simsopt/geo/boozersurface.py | 4 ++-- src/simsopt/geo/surfaceobjectives.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/2_Intermediate/boozer.py b/examples/2_Intermediate/boozer.py index 222a763d7..3b847d2fc 100755 --- a/examples/2_Intermediate/boozer.py +++ b/examples/2_Intermediate/boozer.py @@ -50,6 +50,8 @@ print(f"After LBFGS: iota={res['iota']:.3f}, tf={tf.J():.3f}, area={s.area():.3f}, ||residual||={np.linalg.norm(boozer_surface_residual(s, res['iota'], res['G'], bs, derivatives=0)):.3e}") if "DISPLAY" in os.environ: s.plot() + +boozer_surface.need_to_run_code = True # now drive the residual down using a specialised least squares algorithm res = boozer_surface.minimize_boozer_penalty_constraints_ls(tol=1e-10, maxiter=100, constraint_weight=100., iota=res['iota'], G=res['G'], method='manual') print(f"After Lev-Mar: iota={res['iota']:.3f}, tf={tf.J():.3f}, area={s.area():.3f}, ||residual||={np.linalg.norm(boozer_surface_residual(s, res['iota'], res['G'], bs, derivatives=0)):.3e}") diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 1bef2e825..0f4606623 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -52,7 +52,7 @@ def __init__(self, biotsavart, surface, label, targetlabel): def recompute_bell(self, parent=None): self.need_to_run_code = True - def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., scalarize=True, optimize_G=False, weight_inv_modB=False): + def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., scalarize=True, optimize_G=False, weight_inv_modB=True): r""" Define the residual @@ -146,7 +146,7 @@ def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., sca d2val = J.T @ J + np.sum(r[:, None, None] * H, axis=0) return val, dval, d2val - def boozer_penalty_constraints_vectorized(self, dofs, derivatives=0, constraint_weight=1., optimize_G=False, weight_inv_modB=False): + def boozer_penalty_constraints_vectorized(self, dofs, derivatives=0, constraint_weight=1., optimize_G=False, weight_inv_modB=True): """ This function returns the same thing as `boozer_penalty_constraints` when `scalarized=True`. It is much faster and uses less memory since it calls a vectorized implementation in cpp. This is diff --git a/src/simsopt/geo/surfaceobjectives.py b/src/simsopt/geo/surfaceobjectives.py index 83e831dc5..03c2373ce 100644 --- a/src/simsopt/geo/surfaceobjectives.py +++ b/src/simsopt/geo/surfaceobjectives.py @@ -287,7 +287,7 @@ def dJ(self): return Derivative({self.surface: deriv}) -def boozer_surface_residual(surface, iota, G, biotsavart, derivatives=0, weight_inv_modB=False): +def boozer_surface_residual(surface, iota, G, biotsavart, derivatives=0, weight_inv_modB=True): r""" For a given surface, this function computes the residual From f4c993179c4d880b71ef297dfa219112b7a471f0 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 1 May 2024 13:45:47 -0400 Subject: [PATCH 078/131] making weight_inv_modB default to False on one function --- src/simsopt/geo/surfaceobjectives.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simsopt/geo/surfaceobjectives.py b/src/simsopt/geo/surfaceobjectives.py index 03c2373ce..83e831dc5 100644 --- a/src/simsopt/geo/surfaceobjectives.py +++ b/src/simsopt/geo/surfaceobjectives.py @@ -287,7 +287,7 @@ def dJ(self): return Derivative({self.surface: deriv}) -def boozer_surface_residual(surface, iota, G, biotsavart, derivatives=0, weight_inv_modB=True): +def boozer_surface_residual(surface, iota, G, biotsavart, derivatives=0, weight_inv_modB=False): r""" For a given surface, this function computes the residual From e8c5433757f9d65b87f76afef7da67c6dc34f98b Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Thu, 2 May 2024 07:31:24 -0400 Subject: [PATCH 079/131] Saving residuals file for least-squares solves is now optional --- src/simsopt/solve/mpi.py | 45 ++++++++++++++++++------------- src/simsopt/solve/serial.py | 45 ++++++++++++++++++------------- tests/mhd/test_integrated_mpi.py | 2 +- tests/solve/test_least_squares.py | 11 ++++---- 4 files changed, 59 insertions(+), 44 deletions(-) diff --git a/src/simsopt/solve/mpi.py b/src/simsopt/solve/mpi.py index 6876cecaf..0f6a6988b 100644 --- a/src/simsopt/solve/mpi.py +++ b/src/simsopt/solve/mpi.py @@ -79,6 +79,7 @@ def least_squares_mpi_solve(prob: LeastSquaresProblem, abs_step: float = 1.0e-7, rel_step: float = 0.0, diff_method: str = "forward", + save_residuals: bool = False, **kwargs): """ Solve a nonlinear-least-squares minimization problem using @@ -101,6 +102,8 @@ def least_squares_mpi_solve(prob: LeastSquaresProblem, "forward". If ``centered``, centered finite differences will be used. If ``forward``, one-sided finite differences will be used. Else, error is raised. + save_residuals: Whether to save the residuals at each iteration. + This may be useful for debugging, although the file can become large. kwargs: Any arguments to pass to `scipy.optimize.least_squares `_. For instance, you can supply ``max_nfev=100`` to set @@ -159,20 +162,21 @@ def _f_proc0(x): objective_file.write(f"Problem type:\nleast_squares\nnparams:\n{prob.dof_size}\n") objective_file.write("function_evaluation,seconds") - residuals_file = open(f"residuals_{datestr}.dat", 'w') - residuals_file.write(f"Problem type:\nleast_squares\nnparams:\n{prob.dof_size}\n") - residuals_file.write("function_evaluation,seconds") - for j in range(prob.dof_size): objective_file.write(f",x({j})") objective_file.write(",objective_function\n") - for j in range(prob.dof_size): - residuals_file.write(f",x({j})") - residuals_file.write(",objective_function") - for j in range(len(residuals)): - residuals_file.write(f",F({j})") - residuals_file.write("\n") + if save_residuals: + residuals_file = open(f"residuals_{datestr}.dat", 'w') + residuals_file.write(f"Problem type:\nleast_squares\nnparams:\n{prob.dof_size}\n") + residuals_file.write("function_evaluation,seconds") + + for j in range(prob.dof_size): + residuals_file.write(f",x({j})") + residuals_file.write(",objective_function") + for j in range(len(residuals)): + residuals_file.write(f",F({j})") + residuals_file.write("\n") del_t = time() - start_time objective_file.write(f"{nevals:6d},{del_t:12.4e}") @@ -181,14 +185,16 @@ def _f_proc0(x): objective_file.write(f",{objective_val:24.16e}\n") objective_file.flush() - residuals_file.write(f"{nevals:6d},{del_t:12.4e}") - for xj in x: - residuals_file.write(f",{xj:24.16e}") - residuals_file.write(f",{objective_val:24.16e}") - for fj in unweighted_residuals: - residuals_file.write(f",{fj:24.16e}") - residuals_file.write("\n") - residuals_file.flush() + if save_residuals: + residuals_file.write(f"{nevals:6d},{del_t:12.4e}") + for xj in x: + residuals_file.write(f",{xj:24.16e}") + residuals_file.write(f",{objective_val:24.16e}") + for fj in unweighted_residuals: + residuals_file.write(f",{fj:24.16e}") + residuals_file.write("\n") + residuals_file.flush() + nevals += 1 logger.debug(f"residuals are {residuals}") return residuals @@ -225,7 +231,8 @@ def _f_proc0(x): x = result.x objective_file.close() - residuals_file.close() + if save_residuals: + residuals_file.close() datalog_started = False logger.info("Completed solve.") diff --git a/src/simsopt/solve/serial.py b/src/simsopt/solve/serial.py index 5096d828c..14865da7b 100644 --- a/src/simsopt/solve/serial.py +++ b/src/simsopt/solve/serial.py @@ -33,6 +33,7 @@ def least_squares_serial_solve(prob: LeastSquaresProblem, abs_step: float = 1.0e-7, rel_step: float = 0.0, diff_method: str = "forward", + save_residuals: bool = False, **kwargs): """ Solve a nonlinear-least-squares minimization problem using @@ -52,6 +53,8 @@ def least_squares_serial_solve(prob: LeastSquaresProblem, ``"forward"``. If ``"centered"``, centered finite differences will be used. If ``"forward"``, one-sided finite differences will be used. Else, error is raised. + save_residuals: Whether to save the residuals at each iteration. + This can be useful for debugging, although the file can become large. kwargs: Any arguments to pass to `scipy.optimize.least_squares `_. For instance, you can supply ``max_nfev=100`` to set @@ -62,7 +65,8 @@ def least_squares_serial_solve(prob: LeastSquaresProblem, datestr = datetime.now().strftime("%Y-%m-%d-%H-%M-%S") objective_file = open(f"simsopt_{datestr}.dat", 'w') - residuals_file = open(f"residuals_{datestr}.dat", 'w') + if save_residuals: + residuals_file = open(f"residuals_{datestr}.dat", 'w') nevals = 0 start_time = time() @@ -105,15 +109,16 @@ def objective(x): objective_file.write(f",x({j})") objective_file.write(",objective_function\n") - residuals_file.write( - f"Problem type:\nleast_squares\nnparams:\n{ndofs}\n") - residuals_file.write("function_evaluation,seconds") - for j in range(ndofs): - residuals_file.write(f",x({j})") - residuals_file.write(",objective_function") - for j in range(len(residuals)): - residuals_file.write(f",F({j})") - residuals_file.write("\n") + if save_residuals: + residuals_file.write( + f"Problem type:\nleast_squares\nnparams:\n{ndofs}\n") + residuals_file.write("function_evaluation,seconds") + for j in range(ndofs): + residuals_file.write(f",x({j})") + residuals_file.write(",objective_function") + for j in range(len(residuals)): + residuals_file.write(f",F({j})") + residuals_file.write("\n") elapsed_t = time() - start_time objective_file.write(f"{nevals:6d},{elapsed_t:12.4e}") @@ -123,14 +128,15 @@ def objective(x): objective_file.write("\n") objective_file.flush() - residuals_file.write(f"{nevals:6d},{elapsed_t:12.4e}") - for xj in x: - residuals_file.write(f",{xj:24.16e}") - residuals_file.write(f",{objective_val:24.16e}") - for fj in residuals: - residuals_file.write(f",{fj:24.16e}") - residuals_file.write("\n") - residuals_file.flush() + if save_residuals: + residuals_file.write(f"{nevals:6d},{elapsed_t:12.4e}") + for xj in x: + residuals_file.write(f",{xj:24.16e}") + residuals_file.write(f",{objective_val:24.16e}") + for fj in residuals: + residuals_file.write(f",{fj:24.16e}") + residuals_file.write("\n") + residuals_file.flush() nevals += 1 return residuals @@ -154,7 +160,8 @@ def objective(x): datalogging_started = False objective_file.close() - residuals_file.close() + if save_residuals: + residuals_file.close() logger.info("Completed solve.") prob.x = result.x diff --git a/tests/mhd/test_integrated_mpi.py b/tests/mhd/test_integrated_mpi.py index d00448154..40dc773c4 100644 --- a/tests/mhd/test_integrated_mpi.py +++ b/tests/mhd/test_integrated_mpi.py @@ -190,7 +190,7 @@ def test_Residue_parallelization(self): (residue2.J, 0, 1)]) # Solve for two nfevs to test if runs - least_squares_mpi_solve(prob, mpi=mpi, grad=grad, max_nfev=2) + least_squares_mpi_solve(prob, mpi=mpi, grad=grad, save_residuals=True, max_nfev=2) # No assertions, run is too short to complete, just testing if it does run diff --git a/tests/solve/test_least_squares.py b/tests/solve/test_least_squares.py index a2a04d77f..4896e1903 100755 --- a/tests/solve/test_least_squares.py +++ b/tests/solve/test_least_squares.py @@ -72,11 +72,12 @@ def test_solve_rosenbrock(self): """ with ScratchDir("."): for solver in solvers: - #for grad in [True, False]: - r = Rosenbrock() - prob = LeastSquaresProblem(0, 1, depends_on=r) - solver(prob) # , grad=grad) - self.assertAlmostEqual(prob.objective(), 0) + for save_residuals in [True, False]: + #for grad in [True, False]: + r = Rosenbrock() + prob = LeastSquaresProblem(0, 1, depends_on=r) + solver(prob, save_residuals=save_residuals) # , grad=grad) + self.assertAlmostEqual(prob.objective(), 0) if __name__ == "__main__": From 58b9bf71320482fafd473a7306a584cad9881741 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 3 May 2024 10:45:41 -0400 Subject: [PATCH 080/131] merge with master [skip ci] --- examples/2_Intermediate/boozerQA_ls_mpi.py | 7 +- .../inputs/input_ncsx/ncsx_init.json | 32 +- src/simsopt/geo/boozersurface.py | 43 +- src/simsoptpp/boozerresidual.cpp | 703 ------------------ src/simsoptpp/boozerresidual.h | 14 - tests/geo/test_boozersurface.py | 83 +-- 6 files changed, 50 insertions(+), 832 deletions(-) delete mode 100644 src/simsoptpp/boozerresidual.cpp delete mode 100644 src/simsoptpp/boozerresidual.h diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index 104f09764..ec5c62d5c 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -24,6 +24,7 @@ def pprint(*args, **kwargs): comm = None size = 1 pprint = print + rank = 0 """ This example optimizes the NCSX coils and currents for QA on potentially multiple surfaces using the BoozerLS approach. @@ -59,7 +60,6 @@ def pprint(*args, **kwargs): surfaces = surfaces[:nsurfaces] boozer_surfaces = boozer_surfaces[:nsurfaces] ress = ress[:nsurfaces] - for boozer_surface, res in zip(boozer_surfaces, ress): boozer_surface.run_code('ls', res['iota'], res['G'], verbose=False) @@ -115,7 +115,6 @@ def pprint(*args, **kwargs): prevs = {'sdofs': [surface.x.copy() for surface in mpi_surfaces], 'iota': [boozer_surface.res['iota'] for boozer_surface in mpi_boozer_surfaces], 'G': [boozer_surface.res['G'] for boozer_surface in mpi_boozer_surfaces], 'J': JF.J(), 'dJ': JF.dJ().copy(), 'it': 0} - def fun(dofs): # initialize to last accepted surface values for idx, surface in enumerate(mpi_surfaces): @@ -124,8 +123,8 @@ def fun(dofs): boozer_surface.res['iota'] = prevs['iota'][idx] boozer_surface.res['G'] = prevs['G'][idx] - alldofs = MPI.COMM_WORLD.allgather(dofs) - assert np.all(np.norm(alldofs[0]-d) == 0 for d in alldofs) + #alldofs = MPI.COMM_WORLD.allgather(dofs) + #assert np.all(np.norm(alldofs[0]-d) == 0 for d in alldofs) JF.x = dofs J = JF.J() diff --git a/examples/2_Intermediate/inputs/input_ncsx/ncsx_init.json b/examples/2_Intermediate/inputs/input_ncsx/ncsx_init.json index 40adef205..557585731 100644 --- a/examples/2_Intermediate/inputs/input_ncsx/ncsx_init.json +++ b/examples/2_Intermediate/inputs/input_ncsx/ncsx_init.json @@ -19639,8 +19639,7 @@ "value": "Volume2" }, "targetlabel": -0.2960004452246598, - "constraint_weight": 100.0, - "reg": null + "constraint_weight": 100.0 }, "BiotSavart2": { "@module": "simsopt.field.biotsavart", @@ -21380,8 +21379,7 @@ "value": "Volume3" }, "targetlabel": -0.6985426179774754, - "constraint_weight": 100.0, - "reg": null + "constraint_weight": 100.0 }, "BiotSavart3": { "@module": "simsopt.field.biotsavart", @@ -23121,8 +23119,7 @@ "value": "Volume4" }, "targetlabel": -1.101084790730291, - "constraint_weight": 100.0, - "reg": null + "constraint_weight": 100.0 }, "BiotSavart4": { "@module": "simsopt.field.biotsavart", @@ -24862,8 +24859,7 @@ "value": "Volume5" }, "targetlabel": -1.5036269634831068, - "constraint_weight": 100.0, - "reg": null + "constraint_weight": 100.0 }, "BiotSavart5": { "@module": "simsopt.field.biotsavart", @@ -26603,8 +26599,7 @@ "value": "Volume6" }, "targetlabel": -1.9061691362359223, - "constraint_weight": 100.0, - "reg": null + "constraint_weight": 100.0 }, "BiotSavart6": { "@module": "simsopt.field.biotsavart", @@ -28344,8 +28339,7 @@ "value": "Volume7" }, "targetlabel": -2.308711308988738, - "constraint_weight": 100.0, - "reg": null + "constraint_weight": 100.0 }, "BiotSavart7": { "@module": "simsopt.field.biotsavart", @@ -30085,8 +30079,7 @@ "value": "Volume8" }, "targetlabel": -2.7112534817415535, - "constraint_weight": 100.0, - "reg": null + "constraint_weight": 100.0 }, "BiotSavart8": { "@module": "simsopt.field.biotsavart", @@ -31826,8 +31819,7 @@ "value": "Volume9" }, "targetlabel": -3.113795654494369, - "constraint_weight": 100.0, - "reg": null + "constraint_weight": 100.0 }, "BiotSavart9": { "@module": "simsopt.field.biotsavart", @@ -33567,8 +33559,7 @@ "value": "Volume10" }, "targetlabel": -3.5163378272471846, - "constraint_weight": 100.0, - "reg": null + "constraint_weight": 100.0 }, "BiotSavart10": { "@module": "simsopt.field.biotsavart", @@ -35308,8 +35299,7 @@ "value": "Volume11" }, "targetlabel": -3.91888, - "constraint_weight": 100.0, - "reg": null + "constraint_weight": 100.0 } } -} \ No newline at end of file +} diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 79496aef7..d9f1e22e7 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -1,6 +1,7 @@ import numpy as np from scipy.linalg import lu from scipy.optimize import minimize, least_squares +import simsoptpp as sopp from .surfaceobjectives import boozer_surface_residual, boozer_surface_dexactresidual_dcoils_dcurrents_vjp, boozer_surface_dlsqgrad_dcoils_vjp from .._core.optimizable import Optimizable @@ -65,13 +66,12 @@ def run_code(self, boozer_type, iota, G=None, verbose=True): elif boozer_type == 'ls': # first try BFGS - #res = self.minimize_boozer_penalty_constraints_ls(tol=1e-10, maxiter=100, constraint_weight=self.constraint_weight, iota=iota, G=G, method='manual') - res = self.compute_boozerls_BFGS(tol=1e-10, maxiter=1500, constraint_weight=self.constraint_weight, iota=iota, G=G, verbose=verbose) + res = self.minimize_boozer_penalty_constraints_LBFGS(tol=1e-10, maxiter=1500, constraint_weight=self.constraint_weight, iota=iota, G=G, verbose=verbose, limited_memory=False) iota, G = res['iota'], res['G'] ## polish off using Newton's method self.need_to_run_code = True - res = self.compute_boozerls_newton(tol=1e-11, maxiter=40, constraint_weight=self.constraint_weight, iota=iota, G=G, verbose=verbose) + res = self.minimize_boozer_penalty_constraints_newton(tol=1e-11, maxiter=40, constraint_weight=self.constraint_weight, iota=iota, G=G, verbose=verbose) return res else: raise Exception(f"boozer_type not supported: {boozer_type}") @@ -111,17 +111,17 @@ def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., sca sdofs = x[:-1] iota = x[-1] G = None - nsurfdofs = sdofs.size s = self.surface + num_res = 3 * s.quadpoints_phi.size * s.quadpoints_theta.size biotsavart = self.biotsavart s.set_dofs(sdofs) boozer = boozer_surface_residual(s, iota, G, biotsavart, derivatives=derivatives, weight_inv_modB=weight_inv_modB) + boozer = tuple([b/np.sqrt(num_res) for b in boozer]) r = boozer[0] - l = self.label.J() rl = (l-self.targetlabel) rz = (s.gamma()[0, 0, 2] - 0.) @@ -216,6 +216,7 @@ def boozer_penalty_constraints_vectorized(self, dofs, derivatives=0, constraint_ if derivatives == 2: d2B_by_dXdX = biotsavart.d2B_by_dXdX().reshape((nphi, ntheta, 3, 3, 3)) + num_res = 3 * s.quadpoints_phi.size * s.quadpoints_theta.size if derivatives == 0: val = sopp.boozer_residual(G, iota, xphi, xtheta, B, weight_inv_modB) boozer = val, @@ -225,6 +226,8 @@ def boozer_penalty_constraints_vectorized(self, dofs, derivatives=0, constraint_ elif derivatives == 2: val, dval, d2val = sopp.boozer_residual_ds2(G, iota, B, dB_dx, d2B_by_dXdX, xphi, xtheta, dx_dc, dxphi_dc, dxtheta_dc, weight_inv_modB) boozer = val, dval, d2val + + boozer = tuple([b/num_res for b in boozer]) lab = self.label.J() @@ -328,7 +331,7 @@ def boozer_exact_constraints(self, xl, derivatives=0, optimize_G=True): dres[-1, :-2] = drz return res, dres - def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, constraint_weight=1., iota=0., G=None, vectorize=False): + def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, constraint_weight=1., iota=0., G=None, vectorize=True, limited_memory=True, verbose=False): r""" This function tries to find the surface that approximately solves @@ -353,9 +356,15 @@ def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, cons fun_name = self.boozer_penalty_constraints_vectorized if vectorize else self.boozer_penalty_constraints fun = lambda x: fun_name(x, derivatives=1, constraint_weight=constraint_weight, optimize_G=G is not None) + method = 'L-BFGS-B' if limited_memory else 'BFGS' + options = {'maxiter': maxiter, 'gtol': tol} + if limited_memory: + options['maxcor'] = 200 + options['ftol'] = tol + res = minimize( - fun, x, jac=True, method='L-BFGS-B', - options={'maxiter': maxiter, 'ftol': tol, 'gtol': tol, 'maxcor': 200}) + fun, x, jac=True, method=method, + options=options) resdict = { "fun": res.fun, "gradient": res.jac, "iter": res.nit, "info": res, "success": res.success, "G": None, @@ -373,9 +382,13 @@ def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, cons self.res = resdict self.need_to_run_code = False + + if verbose: + print(f"{method} solve - {resdict['success']} iter={resdict['iter']}, iota={resdict['iota']:.16f}, ||grad||_inf = {np.linalg.norm(resdict['gradient'], ord=np.inf):.3e}", flush=True) + return resdict - def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, stab=0., vectorize=False): + def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, stab=0., vectorize=True, verbose=False): """ This function does the same as :mod:`minimize_boozer_penalty_constraints_LBFGS`, but instead of LBFGS it uses Newton's method. @@ -403,11 +416,14 @@ def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, cons val, dval, d2val = fun_name(x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) norm = np.linalg.norm(dval) i = i+1 - + r = self.boozer_penalty_constraints( x, derivatives=0, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) + + P, L, U = lu(d2val) res = { - "residual": r, "jacobian": dval, "hessian": d2val, "iter": i, "success": norm <= tol, "G": None, + "residual": r, "jacobian": dval, "hessian": d2val, "iter": i, "success": norm <= tol, "G": None, + "PLU" : (P, L, U), "vjp": boozer_surface_dlsqgrad_dcoils_vjp, "type": "ls" } if G is None: s.set_dofs(x[:-1]) @@ -417,11 +433,14 @@ def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, cons iota = x[-2] G = x[-1] res['G'] = G - res['s'] = s res['iota'] = iota self.res = res self.need_to_run_code = False + + if verbose: + print(f"NEWTON solve - {res['success']} iter={res['iter']}, iota={res['iota']:.16f}, ||grad||_inf = {np.linalg.norm(res['jacobian'], ord=np.inf):.3e}", flush=True) + return res def minimize_boozer_penalty_constraints_ls(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, method='lm'): diff --git a/src/simsoptpp/boozerresidual.cpp b/src/simsoptpp/boozerresidual.cpp deleted file mode 100644 index 821e02e96..000000000 --- a/src/simsoptpp/boozerresidual.cpp +++ /dev/null @@ -1,703 +0,0 @@ -#include "boozerresidual.h" - -#include "xsimd/xsimd.hpp" -#include "simdhelpers.h" -#include "vec3dsimd.h" -#include "xtensor/xarray.hpp" -#include "xtensor/xview.hpp" -#include "xtensor/xstrided_view.hpp" -#include -#include "xtensor/xadapt.hpp" - -double boozer_residual(double G, double iota, Array& xphi, Array& xtheta, Array& B){ - int nphi = B.shape(0); - int ntheta = B.shape(1); - Array res = xt::zeros({nphi, ntheta, 3}); - int num_points = 3 * nphi * ntheta; - for(int i=0; i -void boozer_residual_ds_impl(double G, double iota, T& B, T& dB_dx, T& xphi, T& xtheta, T& dx_ds, T& dxphi_ds, T& dxtheta_ds, double& res, T& dres){ - int nphi = xphi.shape(0); - int ntheta = xtheta.shape(1); - size_t ndofs = dx_ds.shape(3); - int num_points = 3 * nphi * ntheta; - - constexpr size_t simd_size = xsimd::simd_type::size; - auto dx_ds_ij0 = AlignedPaddedVec(ndofs, 0); - auto dx_ds_ij1 = AlignedPaddedVec(ndofs, 0); - auto dx_ds_ij2 = AlignedPaddedVec(ndofs, 0); - auto dxphi_ds_ij0 = AlignedPaddedVec(ndofs, 0); - auto dxphi_ds_ij1 = AlignedPaddedVec(ndofs, 0); - auto dxphi_ds_ij2 = AlignedPaddedVec(ndofs, 0); - auto dxtheta_ds_ij0 = AlignedPaddedVec(ndofs, 0); - auto dxtheta_ds_ij1 = AlignedPaddedVec(ndofs, 0); - auto dxtheta_ds_ij2 = AlignedPaddedVec(ndofs, 0); - - simd_t it(iota); - simd_t GG(G); - for(int i=0; i boozer_residual_ds(double G, double iota, Array& B, Array& dB_dx, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds){ - // flatten the quadrature points - int nphi = xphi.shape(0); - int ntheta = xtheta.shape(1); - size_t ndofs = dx_ds.shape(3); - int num_points = nphi * ntheta; - - int num_threads= 0; - #pragma omp parallel reduction(+:num_threads) - num_threads += 1; - - int batch_size = num_points / num_threads; - if(num_points % num_threads != 0) - batch_size++; - - vector res_list(num_threads, 0.); - vector> dres_list; - - for(int idx = 0; idx < num_threads; idx++){ - dres_list.push_back(xt::zeros({ndofs+2})); - } - - double res =0.; - xt::xarray dres =xt::zeros({ndofs+2}); - - - #pragma omp parallel for - for (int idx = 0; idx < num_threads; ++idx) { - int idx_start = batch_size * idx; - int idx_end = batch_size * (idx+1) > num_points ? num_points : batch_size*(idx+1); - size_t diff = idx_end-idx_start; - - size_t size_B = 3; - size_t size_dB_dx = 3 * 3; - size_t size_d2B_dx2 = 3 * 3 * 3; - size_t size_xphi = 3; - size_t size_xtheta = 3; - size_t size_dx_ds = 3 * ndofs; - size_t size_dxphi_ds = 3 * ndofs; - size_t size_dxtheta_ds = 3 * ndofs; - - vector shape_B = {diff, 1, 3}; - vector shape_dB_dx = {diff, 1, 3, 3}; - vector shape_d2B_dx2 = {diff, 1, 3, 3, 3}; - vector shape_xphi = {diff, 1, 3}; - vector shape_xtheta = {diff, 1, 3}; - vector shape_dx_ds = {diff, 1, 3, ndofs}; - vector shape_dxphi_ds = {diff, 1, 3, ndofs}; - vector shape_dxtheta_ds = {diff, 1, 3, ndofs}; - - xt::xarray bB = xt::adapt(B.data() + idx_start*size_B , diff*size_B , xt::no_ownership(), shape_B ); - xt::xarray bdB_dx = xt::adapt(dB_dx.data() + idx_start*size_dB_dx , diff*size_dB_dx , xt::no_ownership(), shape_dB_dx ); - xt::xarray bxphi = xt::adapt(xphi.data() + idx_start*size_xphi , diff*size_xphi , xt::no_ownership(), shape_xphi ); - xt::xarray bxtheta = xt::adapt(xtheta.data() + idx_start*size_xtheta , diff*size_xtheta , xt::no_ownership(), shape_xtheta ); - xt::xarray bdx_ds = xt::adapt(dx_ds.data() + idx_start*size_dx_ds , diff*size_dx_ds , xt::no_ownership(), shape_dx_ds ); - xt::xarray bdxphi_ds = xt::adapt(dxphi_ds.data() + idx_start*size_dxphi_ds , diff*size_dxphi_ds , xt::no_ownership(), shape_dxphi_ds ); - xt::xarray bdxtheta_ds = xt::adapt(dxtheta_ds.data()+ idx_start*size_dxtheta_ds, diff*size_dxtheta_ds, xt::no_ownership(), shape_dxtheta_ds); - - boozer_residual_ds_impl>(G, iota, bB, bdB_dx, bxphi, bxtheta, bdx_ds, bdxphi_ds, bdxtheta_ds, res_list[idx], dres_list[idx]); - res_list[idx] *= (idx_end-idx_start)*3; - dres_list[idx] *= (idx_end-idx_start)*3; - } - - for(int i=0; i < num_threads; i++){ - res+=res_list[i]/num_points/3.; - dres+=dres_list[i]/num_points/3.; - } - - auto tup = std::make_tuple(res, dres); - return tup; -} - - - - -template -void boozer_residual_ds2_impl(double G, double iota, T& B, T& dB_dx, T& d2B_dx2, T& xphi, T& xtheta, T& dx_ds, T& dxphi_ds, T& dxtheta_ds, double& res, T& dres, T& d2res){ - int nphi = xphi.shape(0); - int ntheta = xtheta.shape(1); - size_t ndofs = dx_ds.shape(3); - int num_points = 3 * nphi * ntheta; - - constexpr size_t simd_size = xsimd::simd_type::size; - auto dx_ds_ij0 = AlignedPaddedVec(ndofs, 0); - auto dx_ds_ij1 = AlignedPaddedVec(ndofs, 0); - auto dx_ds_ij2 = AlignedPaddedVec(ndofs, 0); - auto dxphi_ds_ij0 = AlignedPaddedVec(ndofs, 0); - auto dxphi_ds_ij1 = AlignedPaddedVec(ndofs, 0); - auto dxphi_ds_ij2 = AlignedPaddedVec(ndofs, 0); - auto dxtheta_ds_ij0 = AlignedPaddedVec(ndofs, 0); - auto dxtheta_ds_ij1 = AlignedPaddedVec(ndofs, 0); - auto dxtheta_ds_ij2 = AlignedPaddedVec(ndofs, 0); - - auto drtilij0 = AlignedPaddedVec(ndofs+2, 0); - auto drtilij1 = AlignedPaddedVec(ndofs+2, 0); - auto drtilij2 = AlignedPaddedVec(ndofs+2, 0); - - auto dresij0 = AlignedPaddedVec(ndofs+2, 0); - auto dresij1 = AlignedPaddedVec(ndofs+2, 0); - auto dresij2 = AlignedPaddedVec(ndofs+2, 0); - - auto dw_ij = AlignedPaddedVec(ndofs+2, 0); - - auto dtang_ij0 = AlignedPaddedVec(ndofs+2, 0); - auto dtang_ij1 = AlignedPaddedVec(ndofs+2, 0); - auto dtang_ij2 = AlignedPaddedVec(ndofs+2, 0); - - auto dB2_ij = AlignedPaddedVec(ndofs+2, 0); - auto dBij0 = AlignedPaddedVec(ndofs+2, 0); - auto dBij1 = AlignedPaddedVec(ndofs+2, 0); - auto dBij2 = AlignedPaddedVec(ndofs+2, 0); - auto dmodB_ij = AlignedPaddedVec(ndofs+2, 0); - - simd_t it(iota); - simd_t GG(G); - - for(int i=0; i boozer_residual_ds2(double G, double iota, Array& B, Array& dB_dx, Array& d2B_dx2, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds){ - // flatten the quadrature points - int nphi = xphi.shape(0); - int ntheta = xtheta.shape(1); - size_t ndofs = dx_ds.shape(3); - int num_points = nphi * ntheta; - - int num_threads= 0; - #pragma omp parallel reduction(+:num_threads) - num_threads += 1; - - int batch_size = num_points / num_threads; - if(num_points % num_threads != 0) - batch_size++; - - vector res_list(num_threads, 0.); - vector> dres_list; - vector> d2res_list; - - for(int idx = 0; idx < num_threads; idx++){ - dres_list.push_back(xt::zeros({ndofs+2})); - d2res_list.push_back(xt::zeros({ndofs+2, ndofs+2})); - } - - double res =0.; - xt::xarray dres =xt::zeros({ndofs+2}); - xt::xarray d2res=xt::zeros({ndofs+2, ndofs+2}); - - - #pragma omp parallel for - for (int idx = 0; idx < num_threads; ++idx) { - int idx_start = batch_size * idx; - int idx_end = batch_size * (idx+1) > num_points ? num_points : batch_size*(idx+1); - size_t diff = idx_end-idx_start; - - size_t size_B = 3; - size_t size_dB_dx = 3 * 3; - size_t size_d2B_dx2 = 3 * 3 * 3; - size_t size_xphi = 3; - size_t size_xtheta = 3; - size_t size_dx_ds = 3 * ndofs; - size_t size_dxphi_ds = 3 * ndofs; - size_t size_dxtheta_ds = 3 * ndofs; - - vector shape_B = {diff, 1, 3}; - vector shape_dB_dx = {diff, 1, 3, 3}; - vector shape_d2B_dx2 = {diff, 1, 3, 3, 3}; - vector shape_xphi = {diff, 1, 3}; - vector shape_xtheta = {diff, 1, 3}; - vector shape_dx_ds = {diff, 1, 3, ndofs}; - vector shape_dxphi_ds = {diff, 1, 3, ndofs}; - vector shape_dxtheta_ds = {diff, 1, 3, ndofs}; - - xt::xarray bB = xt::adapt(B.data() + idx_start*size_B , diff*size_B , xt::no_ownership(), shape_B ); - xt::xarray bdB_dx = xt::adapt(dB_dx.data() + idx_start*size_dB_dx , diff*size_dB_dx , xt::no_ownership(), shape_dB_dx ); - xt::xarray bdB2_dx2 = xt::adapt(d2B_dx2.data() + idx_start*size_d2B_dx2 , diff*size_d2B_dx2 , xt::no_ownership(), shape_d2B_dx2 ); - xt::xarray bxphi = xt::adapt(xphi.data() + idx_start*size_xphi , diff*size_xphi , xt::no_ownership(), shape_xphi ); - xt::xarray bxtheta = xt::adapt(xtheta.data() + idx_start*size_xtheta , diff*size_xtheta , xt::no_ownership(), shape_xtheta ); - xt::xarray bdx_ds = xt::adapt(dx_ds.data() + idx_start*size_dx_ds , diff*size_dx_ds , xt::no_ownership(), shape_dx_ds ); - xt::xarray bdxphi_ds = xt::adapt(dxphi_ds.data() + idx_start*size_dxphi_ds , diff*size_dxphi_ds , xt::no_ownership(), shape_dxphi_ds ); - xt::xarray bdxtheta_ds = xt::adapt(dxtheta_ds.data()+ idx_start*size_dxtheta_ds, diff*size_dxtheta_ds, xt::no_ownership(), shape_dxtheta_ds); - - boozer_residual_ds2_impl>(G, iota, bB, bdB_dx, bdB2_dx2, bxphi, bxtheta, bdx_ds, bdxphi_ds, bdxtheta_ds, res_list[idx], dres_list[idx], d2res_list[idx]); - res_list[idx] *= (idx_end-idx_start)*3; - dres_list[idx] *= (idx_end-idx_start)*3; - d2res_list[idx] *= (idx_end-idx_start)*3; - } - - for(int i=0; i < num_threads; i++){ - res+=res_list[i]/num_points/3.; - dres+=dres_list[i]/num_points/3.; - d2res+=d2res_list[i]/num_points/3.; - } - - auto tup = std::make_tuple(res, dres, d2res); - return tup; -} - -Array boozer_residual_dc(double G, Array& dB_dc, Array& B, Array& tang, Array& B2, Array& dxphi_dc, double iota, Array& dxtheta_dc){ - int nphi = dB_dc.shape(0); - int ntheta = dB_dc.shape(1); - int ndofs = dB_dc.shape(3); - Array res = xt::zeros({nphi, ntheta, 3, ndofs}); - double* B_dB_dc = new double[ndofs]; - for(int i=0; i Array; -using std::vector; - -double boozer_residual(double G, double iota, Array& xphi, Array& xtheta, Array& B); -std::tuple boozer_residual_ds(double G, double iota, Array& B, Array& dB_dx, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds); -std::tuple boozer_residual_ds2(double G, double iota, Array& B, Array& dB_dx, Array& d2B_dx2, Array& xphi, Array& xtheta, Array& dx_ds, Array& dxphi_ds, Array& dxtheta_ds); - - -Array boozer_residual_dc(double G, Array& dB_dc, Array& B, Array& tang, Array& B2, Array& dxphi_dc, double iota, Array& dxtheta_dc); diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 3c40f6d69..8851f6a29 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -281,21 +281,22 @@ def subtest_boozer_surface_optimisation_convergence(self, surfacetype, G = 2.*np.pi*current_sum*(4*np.pi*10**(-7)/(2 * np.pi)) else: G = None - + + cw = (s.quadpoints_phi.size * s.quadpoints_theta.size * 3) # compute surface first using LBFGS exact and an area constraint res = boozer_surface.minimize_boozer_penalty_constraints_LBFGS( - tol=1e-11, maxiter=700, constraint_weight=100., iota=iota, G=G, + tol=1e-11, maxiter=700, constraint_weight=100/cw, iota=iota, G=G, vectorize=vectorize) print('Residual norm after LBFGS', res['iter'], np.sqrt(2*res['fun'])) boozer_surface.recompute_bell() if second_stage == 'ls': res = boozer_surface.minimize_boozer_penalty_constraints_ls( - tol=1e-11, maxiter=100, constraint_weight=1000., + tol=1e-11, maxiter=100, constraint_weight=1000./cw, iota=res['iota'], G=res['G']) elif second_stage == 'newton': res = boozer_surface.minimize_boozer_penalty_constraints_newton( - tol=1e-10, maxiter=20, constraint_weight=100., + tol=1e-10, maxiter=20, constraint_weight=100./cw, iota=res['iota'], G=res['G'], stab=1e-4, vectorize=vectorize) elif second_stage == 'newton_exact': res = boozer_surface.minimize_boozer_exact_constraints_newton( @@ -500,80 +501,6 @@ def compute_differences(Ha, Hb): print(f'max err ({i1:03}, {j1:03}): {np.max(diff):.6e}, {Ha[i1, j1]:.6e}\nmax rel err ({i2:03}, {j2:03}): {np.max(rel_diff):.6e}, {Ha[i2,j2]:.6e}\n') compute_differences(H0, H1) - def test_boozer_penalty_constraints_cpp_notcpp(self): - """ - Test to verify cpp and python implementations of the BoozerLS objective return the same thing. - """ - for surfacetype in surfacetypes_list: - for stellsym in stellsym_list: - for (optimize_G, nphi, ntheta) in [(True, 10, 17), (False, 13, 21)]: - with self.subTest(surfacetype=surfacetype, - stellsym=stellsym, - optimize_G=optimize_G): - self.subtest_boozer_penalty_constraints_cpp_notcpp(surfacetype, stellsym, optimize_G, nphi, ntheta) - - def subtest_boozer_penalty_constraints_cpp_notcpp(self, surfacetype, stellsym, optimize_G, nphi, ntheta): - - np.random.seed(1) - curves, currents, ma = get_ncsx_data() - coils = coils_via_symmetries(curves, currents, 3, stellsym) - bs = BiotSavart(coils) - bs_tf = BiotSavart(coils) - current_sum = sum(abs(c.current.get_value()) for c in coils) - - s = get_surface(surfacetype, stellsym, nphi=nphi, ntheta=ntheta) - s.fit_to_curve(ma, 0.1) - s.x = s.x + np.random.rand(s.x.size)*1e-6 - - tf = ToroidalFlux(s, bs_tf, nphi=51, ntheta=51) - - tf_target = 0.1 - boozer_surface = BoozerSurface(bs, s, tf, tf_target) - - iota = -0.3 - x = np.concatenate((s.get_dofs(), [iota])) - if optimize_G: - x = np.concatenate( - (x, [2.*np.pi*current_sum*(4*np.pi*10**(-7)/(2 * np.pi))])) - - w = 1e2 - f0, J0, H0 = boozer_surface.boozer_penalty_constraints( - x, derivatives=2, constraint_weight=w, optimize_G=optimize_G, weight_inv_modB=True) - f1, J1, H1 = boozer_surface.boozerls_penalty( - x, derivatives=2, constraint_weight=w, optimize_G=optimize_G) - - # f1, and J1 scale the quadratic residual terms by 1/(number of residuals), while f0 and J0 do not. - # rescale below so that both quantities are comparable. - diff1 = (boozer_surface.label.J() - boozer_surface.targetlabel) - diff2 = s.gamma()[0, 0, 2] - f1 -= 0.5 * w * (diff1**2 + diff2**2) - f1 *= (3 * len(s.quadpoints_phi)*len(s.quadpoints_theta)) - f1 += 0.5 * w * (diff1**2 + diff2**2) - - to_add = [0] - if optimize_G: - to_add = [0, 0] - - dl = np.append(boozer_surface.label.dJ(partials=True)(s), to_add) - drz = np.append(s.dgamma_by_dcoeff()[0, 0, 2, :], to_add) - J1 -= w * (diff1 * dl + diff2 * drz) - J1 *= (3*len(s.quadpoints_phi)*len(s.quadpoints_theta)) - J1 += w * (diff1 * dl + diff2 * drz) - - nsurfdofs = s.x.size - d2l = np.zeros((x.size, x.size)) - d2l[:nsurfdofs, :nsurfdofs] = boozer_surface.label.d2J_by_dsurfacecoefficientsdsurfacecoefficients() - H1 -= w * dl[:, None] * dl[None, :] + w * diff1 * d2l - H1 -= w * drz[:, None] * drz[None, :] - H1 *= (3*len(s.quadpoints_phi)*len(s.quadpoints_theta)) - H1 += w * dl[:, None] * dl[None, :] + w * diff1 * d2l - H1 += w * drz[:, None] * drz[None, :] - - self.assertAlmostEqual(f0, f1) - np.testing.assert_allclose(J0, J1) - norm = np.max(np.abs(H0)) - assert np.all(np.abs((H0-H1)/norm) < 1e-13) - if __name__ == "__main__": unittest.main() From 1df2242745b59c5e1c7565674315e6d79bde0e21 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 3 May 2024 13:07:36 -0400 Subject: [PATCH 081/131] added unit test for BoozerResidual objective --- src/simsopt/geo/boozersurface.py | 2 ++ src/simsopt/geo/surfaceobjectives.py | 14 +------------ tests/geo/surface_test_helpers.py | 31 +++++++++++++++++++--------- tests/geo/test_surface_objectives.py | 30 +++++++++++++++++++++++++-- 4 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index d9f1e22e7..ecfcd3581 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -119,6 +119,7 @@ def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., sca s.set_dofs(sdofs) boozer = boozer_surface_residual(s, iota, G, biotsavart, derivatives=derivatives, weight_inv_modB=weight_inv_modB) + # normalizing the residuals here boozer = tuple([b/np.sqrt(num_res) for b in boozer]) r = boozer[0] @@ -227,6 +228,7 @@ def boozer_penalty_constraints_vectorized(self, dofs, derivatives=0, constraint_ val, dval, d2val = sopp.boozer_residual_ds2(G, iota, B, dB_dx, d2B_by_dXdX, xphi, xtheta, dx_dc, dxphi_dc, dxtheta_dc, weight_inv_modB) boozer = val, dval, d2val + # normalizing the residuals here boozer = tuple([b/num_res for b in boozer]) lab = self.label.J() diff --git a/src/simsopt/geo/surfaceobjectives.py b/src/simsopt/geo/surfaceobjectives.py index aa7cb1afc..f3e3b162b 100644 --- a/src/simsopt/geo/surfaceobjectives.py +++ b/src/simsopt/geo/surfaceobjectives.py @@ -1016,12 +1016,6 @@ def compute(self): Jtil = np.concatenate((J/np.sqrt(num_points), np.sqrt(self.constraint_weight) * dl[None, :]), axis=0) dJ_ds = Jtil.T@rtil - if booz_surf.res['type'] == 'lscons': - if booz_surf.surface.stellsym: - dJ_ds = np.concatenate((dJ_ds, [0.])) - else: - dJ_ds = np.concatenate((dJ_ds, [0., 0.])) - adj = forward_backward(P, L, U, dJ_ds) adj_times_dg_dcoil = dconstraint_dcoils_vjp(adj, booz_surf, iota, G) @@ -1096,13 +1090,7 @@ def boozer_surface_dlsqgrad_dcoils_vjp(lm, booz_surf, iota, G): G is known for exact boozer surfaces, so if G=None is passed, then that value is used instead. """ - - if booz_surf.res['type'] == 'lscons': - if booz_surf.surface.stellsym: - lm = lm[:-1] - else: - lm = lm[:-2] - + surface = booz_surf.surface biotsavart = booz_surf.biotsavart nphi = surface.quadpoints_phi.size diff --git a/tests/geo/surface_test_helpers.py b/tests/geo/surface_test_helpers.py index 6effa0e37..1aa40586d 100644 --- a/tests/geo/surface_test_helpers.py +++ b/tests/geo/surface_test_helpers.py @@ -3,7 +3,7 @@ import numpy as np from simsopt.configs import get_ncsx_data from simsopt.field import coils_via_symmetries, BiotSavart -from simsopt.geo import Volume, Area, ToroidalFlux, SurfaceXYZFourier, SurfaceRZFourier, SurfaceXYZTensorFourier, BoozerSurface +from simsopt.geo import Volume, Area, ToroidalFlux, SurfaceXYZFourier, SurfaceRZFourier, SurfaceXYZTensorFourier, BoozerSurface, AspectRatio TEST_DIR = Path(__file__).parent / ".." / "test_files" @@ -74,12 +74,12 @@ def get_exact_surface(surface_type='SurfaceXYZFourier'): return s -def get_boozer_surface(label="Volume", nphi=None, ntheta=None): +def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exact'): """ Returns a boozer surface that will be used in unit tests. """ - assert label == "Volume" or label == "ToroidalFlux" or label == "Area" + assert label == "Volume" or label == "ToroidalFlux" or label == "Area" or label == "AspectRatio" base_curves, base_currents, ma = get_ncsx_data() coils = coils_via_symmetries(base_curves, base_currents, 3, True) @@ -88,13 +88,18 @@ def get_boozer_surface(label="Volume", nphi=None, ntheta=None): G0 = 2. * np.pi * current_sum * (4 * np.pi * 10**(-7) / (2 * np.pi)) ## RESOLUTION DETAILS OF SURFACE ON WHICH WE OPTIMIZE FOR QA - mpol = 6 - ntor = 6 + mpol = 6 if boozer_type == 'exact' else 3 + ntor = 6 if boozer_type == 'exact' else 3 stellsym = True nfp = 3 + + if boozer_type == 'exact': + phis = np.linspace(0, 1/nfp, 2*ntor+1, endpoint=False) + thetas = np.linspace(0, 1, 2*mpol+1, endpoint=False) + elif boozer_type == 'ls': + phis = np.linspace(0, 1/nfp, 20, endpoint=False) + thetas = np.linspace(0, 1, 20, endpoint=False) - phis = np.linspace(0, 1/nfp, 2*ntor+1, endpoint=False) - thetas = np.linspace(0, 1, 2*mpol+1, endpoint=False) s = SurfaceXYZTensorFourier( mpol=mpol, ntor=ntor, stellsym=stellsym, nfp=nfp, quadpoints_phi=phis, quadpoints_theta=thetas) s.fit_to_curve(ma, 0.1, flip_theta=True) @@ -110,10 +115,16 @@ def get_boozer_surface(label="Volume", nphi=None, ntheta=None): elif label == "Area": lab = Area(s, nphi=nphi, ntheta=ntheta) lab_target = lab.J() + elif label == "AspectRatio": + lab = AspectRatio(s, nphi=nphi, ntheta=ntheta) + lab_target = lab.J()*0.9 ## COMPUTE THE SURFACE - boozer_surface = BoozerSurface(bs, s, lab, lab_target) - res = boozer_surface.solve_residual_equation_exactly_newton(tol=1e-13, maxiter=20, iota=iota, G=G0) - print(f"NEWTON {res['success']}: iter={res['iter']}, iota={res['iota']:.3f}, vol={s.volume():.3f}") + cw = None if boozer_type == 'exact' else 100. + boozer_surface = BoozerSurface(bs, s, lab, lab_target, constraint_weight=cw) + boozer_surface.run_code(boozer_type, iota, G=G0, verbose=True) + + #res = boozer_surface.solve_residual_equation_exactly_newton(tol=1e-13, maxiter=20, iota=iota, G=G0) + #print(f"NEWTON {res['success']}: iter={res['iter']}, iota={res['iota']:.3f}, vol={s.volume():.3f}") return bs, boozer_surface diff --git a/tests/geo/test_surface_objectives.py b/tests/geo/test_surface_objectives.py index 759d3ccaf..895df1bf6 100644 --- a/tests/geo/test_surface_objectives.py +++ b/tests/geo/test_surface_objectives.py @@ -2,7 +2,7 @@ import numpy as np from simsopt.field.biotsavart import BiotSavart from simsopt.field.coil import coils_via_symmetries -from simsopt.geo.surfaceobjectives import ToroidalFlux, QfmResidual, parameter_derivatives, Volume, PrincipalCurvature, MajorRadius, Iotas, NonQuasiSymmetricRatio +from simsopt.geo.surfaceobjectives import ToroidalFlux, QfmResidual, parameter_derivatives, Volume, PrincipalCurvature, MajorRadius, Iotas, NonQuasiSymmetricRatio, AspectRatio, BoozerResidual from simsopt.configs.zoo import get_ncsx_data from .surface_test_helpers import get_surface, get_exact_surface, get_boozer_surface @@ -338,9 +338,35 @@ def df(dofs): epsilons=np.power(2., -np.asarray(range(13, 19)))) +class BoozerResidualTests(unittest.TestCase): + def test_boozerresidual_derivative(self): + """ + Taylor test for derivative of surface non QS ratio wrt coil parameters + """ + for label in ["Volume"]: + with self.subTest(label=label): + self.subtest_boozerresidual_derivative(label) + + def subtest_boozerresidual_derivative(self, label): + bs, boozer_surface = get_boozer_surface(label=label, boozer_type='ls') + coeffs = bs.x + br = BoozerResidual(boozer_surface, bs) + + def f(dofs): + bs.x = dofs + return br.J() + + def df(dofs): + bs.x = dofs + return br.dJ() + + taylor_test1(f, df, coeffs, + epsilons=np.power(2., -np.asarray(range(13, 19)))) + + class LabelTests(unittest.TestCase): def test_label_surface_derivative1(self): - for label in ["Volume", "ToroidalFlux", "Area"]: + for label in ["Volume", "ToroidalFlux", "Area", "AspectRatio"]: with self.subTest(label=label): self.subtest_label_derivative1(label) From b6e0b66abcc61a81b7b1e0f4c92049fdd78b1790 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 3 May 2024 13:16:40 -0400 Subject: [PATCH 082/131] added more unit tests --- examples/2_Intermediate/boozerQA_ls_mpi.py | 7 ++-- tests/geo/test_surface_objectives.py | 46 +++++++++++++--------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index ec5c62d5c..fa0fdb7f9 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -1,10 +1,9 @@ #!/usr/bin/env python3 -from simsopt.geo import SurfaceXYZTensorFourier, SurfaceRZFourier, BoozerSurface, curves_to_vtk, boozer_surface_residual, \ - ToroidalFlux, Volume, MajorRadius, CurveLength, CurveCurveDistance, NonQuasiSymmetricRatio, Iotas, BoozerResidual, \ - LpCurveCurvature, MeanSquaredCurvature, ArclengthVariation +from simsopt.geo import curves_to_vtk, MajorRadius, CurveLength, CurveCurveDistance, NonQuasiSymmetricRatio, Iotas,\ + BoozerResidual, LpCurveCurvature, MeanSquaredCurvature, ArclengthVariation from simsopt._core import load from simsopt.objectives import MPIObjective, MPIOptimizable -from simsopt.field import BiotSavart, coils_via_symmetries +from simsopt.field import BiotSavart from simsopt.configs import get_ncsx_data from simsopt.objectives import QuadraticPenalty from scipy.optimize import minimize diff --git a/tests/geo/test_surface_objectives.py b/tests/geo/test_surface_objectives.py index 895df1bf6..146dd20a2 100644 --- a/tests/geo/test_surface_objectives.py +++ b/tests/geo/test_surface_objectives.py @@ -259,13 +259,15 @@ def test_major_radius_derivative(self): """ Taylor test for derivative of surface major radius wrt coil parameters """ - - for label in ["Volume", "ToroidalFlux"]: - with self.subTest(label=label): - self.subtest_major_radius_surface_derivative(label) - - def subtest_major_radius_surface_derivative(self, label): - bs, boozer_surface = get_boozer_surface(label=label, nphi=51, ntheta=51) + for boozer_type in ['exact', 'ls']: + for label in ["Volume", "ToroidalFlux"]: + with self.subTest(label=label, boozer_type=boozer_type): + if boozer_type == 'ls' and label == 'ToroidalFlux': + continue + self.subtest_major_radius_surface_derivative(label, boozer_type) + + def subtest_major_radius_surface_derivative(self, label, boozer_type): + bs, boozer_surface = get_boozer_surface(label=label, nphi=51, ntheta=51, boozer_type=boozer_type) coeffs = bs.x mr = MajorRadius(boozer_surface) @@ -286,16 +288,19 @@ def test_iotas_derivative(self): Taylor test for derivative of surface rotational transform wrt coil parameters """ - for label in ["Volume", "ToroidalFlux"]: - with self.subTest(label=label): - self.subtest_iotas_derivative(label) + for boozer_type in ['exact', 'ls']: + for label in ["Volume", "ToroidalFlux"]: + if boozer_type == 'ls' and label == 'ToroidalFlux': + continue + with self.subTest(label=label, boozer_type=boozer_type): + self.subtest_iotas_derivative(label, boozer_type) - def subtest_iotas_derivative(self, label): + def subtest_iotas_derivative(self, label, boozer_type): """ Taylor test for derivative of surface rotational transform wrt coil parameters """ - bs, boozer_surface = get_boozer_surface(label=label) + bs, boozer_surface = get_boozer_surface(label=label, boozer_type=boozer_type) coeffs = bs.x io = Iotas(boozer_surface) @@ -316,13 +321,16 @@ def test_nonQSratio_derivative(self): """ Taylor test for derivative of surface non QS ratio wrt coil parameters """ - for label in ["Volume", "ToroidalFlux"]: - for axis in [False, True]: - with self.subTest(label=label, axis=axis): - self.subtest_nonQSratio_derivative(label, axis) - - def subtest_nonQSratio_derivative(self, label, axis): - bs, boozer_surface = get_boozer_surface(label=label) + for boozer_type in ['exact', 'ls']: + for label in ["Volume", "ToroidalFlux"]: + if boozer_type == 'ls' and label == 'ToroidalFlux': + continue + for axis in [False, True]: + with self.subTest(label=label, axis=axis, boozer_type=boozer_type): + self.subtest_nonQSratio_derivative(label, axis, boozer_type) + + def subtest_nonQSratio_derivative(self, label, axis, boozer_type): + bs, boozer_surface = get_boozer_surface(label=label, boozer_type=boozer_type) coeffs = bs.x io = NonQuasiSymmetricRatio(boozer_surface, bs, quasi_poloidal=axis) From 251fadef7ad0d30c282a23182feb23909171bfca Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 3 May 2024 13:25:20 -0400 Subject: [PATCH 083/131] changed to pprint to proc0_print --- examples/2_Intermediate/boozerQA_ls_mpi.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index fa0fdb7f9..66334000c 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -7,6 +7,7 @@ from simsopt.configs import get_ncsx_data from simsopt.objectives import QuadraticPenalty from scipy.optimize import minimize +from simsopt.util import proc0_print import numpy as np import os try: @@ -15,14 +16,9 @@ rank = comm.rank size = comm.size - def pprint(*args, **kwargs): - if comm.rank == 0: # only print on rank 0 - print(*args, **kwargs) - except ImportError: comm = None size = 1 - pprint = print rank = 0 """ @@ -51,8 +47,8 @@ def pprint(*args, **kwargs): OUT_DIR = "./output/" os.makedirs(OUT_DIR, exist_ok=True) -pprint("Running 2_Intermediate/boozerQA_ls_mpi.py") -pprint("================================") +proc0_print("Running 2_Intermediate/boozerQA_ls_mpi.py") +proc0_print("================================") base_curves, base_currents, coils, curves, surfaces, boozer_surfaces, ress = load(IN_DIR + f"ncsx_init.json") nsurfaces = 2 @@ -171,14 +167,14 @@ def callback(x): outstr += f"{'∫ κ^2 dl / ∫ dl':{width}}" + ', '.join([f'{Jmsc.J():.6f}' for Jmsc in msc_list]) + "\n" outstr += "\n\n" - pprint(outstr) + proc0_print(outstr) prevs['it'] += 1 dofs = JF.x callback(dofs) -pprint(""" +proc0_print(""" ################################################################################ ### Run the optimization ####################################################### ################################################################################ @@ -191,5 +187,5 @@ def callback(x): curves_to_vtk(curves, OUT_DIR + f"curves_opt") boozer_surface.surface.to_vtk(OUT_DIR + "surf_opt") -pprint("End of 2_Intermediate/boozerQA_ls.py") -pprint("================================") +proc0_print("End of 2_Intermediate/boozerQA_ls.py") +proc0_print("================================") From 205cc7d77718512e4fb9551f18e5caaabe235c37 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 3 May 2024 14:01:55 -0400 Subject: [PATCH 084/131] added unit test for MPIOptimizable class [skip ci] --- tests/objectives/test_utilities.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/tests/objectives/test_utilities.py b/tests/objectives/test_utilities.py index 5357cd6cd..59b09c8a3 100644 --- a/tests/objectives/test_utilities.py +++ b/tests/objectives/test_utilities.py @@ -3,9 +3,10 @@ import numpy as np +from simsopt.geo import SurfaceXYZTensorFourier from simsopt.geo.curvexyzfourier import CurveXYZFourier from simsopt.geo.curveobjectives import CurveLength, LpCurveTorsion -from simsopt.objectives.utilities import MPIObjective, QuadraticPenalty +from simsopt.objectives.utilities import MPIObjective, QuadraticPenalty, MPIOptimizable from simsopt.geo import parameters from simsopt._core.json import GSONDecoder, GSONEncoder, SIMSON parameters['jit'] = False @@ -84,3 +85,26 @@ def test_mpi_objective(self): Jmpi1 = MPIObjective(Js1subset, comm, needs_splitting=False) assert abs(Jmpi1.J() - sum(J.J() for J in Js)/n) < 1e-14 assert np.sum(np.abs(Jmpi1.dJ() - sum(J.dJ() for J in Js)/n)) < 1e-14 + + def test_mpi_optimizable(self): + """ + This test checks that the `x` attribute of the surfaces is correctly communicated across the ranks. + """ + if MPI is None: + print("skip test_mpi_optimizable") + return + + comm = MPI.COMM_WORLD + surfaces = [SurfaceXYZTensorFourier(mpol=1, ntor=1, stellsym=True) for i in range(comm.size)] + + equal_to = [] + for i in range(comm.size): + x = np.zeros(surfaces[i].x.size) + x[:] = i + equal_to.append(x) + if comm.rank == i: + surfaces[i].x = x.copy() + + mpi_surfaces = MPIOptimizable(surfaces, ["x"], comm) + for s, sx in zip(mpi_surfaces, equal_to): + np.testing.assert_allclose(s.x, sx, atol=1e-14) From e9522cd700a85b8c6b5e79da89c2054d1ecae7e5 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 3 May 2024 14:19:34 -0400 Subject: [PATCH 085/131] edit to test_mpi_optimizable --- tests/objectives/test_utilities.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tests/objectives/test_utilities.py b/tests/objectives/test_utilities.py index 59b09c8a3..8060d0cba 100644 --- a/tests/objectives/test_utilities.py +++ b/tests/objectives/test_utilities.py @@ -9,6 +9,7 @@ from simsopt.objectives.utilities import MPIObjective, QuadraticPenalty, MPIOptimizable from simsopt.geo import parameters from simsopt._core.json import GSONDecoder, GSONEncoder, SIMSON +from simsopt._core.util import parallel_loop_bounds parameters['jit'] = False try: from mpi4py import MPI @@ -95,16 +96,19 @@ def test_mpi_optimizable(self): return comm = MPI.COMM_WORLD - surfaces = [SurfaceXYZTensorFourier(mpol=1, ntor=1, stellsym=True) for i in range(comm.size)] + for size in [1, 2, 3, 4, 5]: + surfaces = [SurfaceXYZTensorFourier(mpol=1, ntor=1, stellsym=True) for i in range(size)] - equal_to = [] - for i in range(comm.size): - x = np.zeros(surfaces[i].x.size) - x[:] = i - equal_to.append(x) - if comm.rank == i: - surfaces[i].x = x.copy() + equal_to = [] + for i in range(size): + x = np.zeros(surfaces[i].x.size) + x[:] = i + equal_to.append(x) + + startidx, endidx = parallel_loop_bounds(comm, len(surfaces)) + for idx in range(startidx, endidx): + surfaces[idx].x = equal_to[idx] - mpi_surfaces = MPIOptimizable(surfaces, ["x"], comm) - for s, sx in zip(mpi_surfaces, equal_to): - np.testing.assert_allclose(s.x, sx, atol=1e-14) + mpi_surfaces = MPIOptimizable(surfaces, ["x"], comm) + for s, sx in zip(mpi_surfaces, equal_to): + np.testing.assert_allclose(s.x, sx, atol=1e-14) From a65680e20be866ce3db8534d97ea342c4264dd38 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 3 May 2024 14:28:53 -0400 Subject: [PATCH 086/131] fixing a unit test --- examples/2_Intermediate/boozerQA_ls_mpi.py | 4 ++-- tests/geo/test_boozersurface.py | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index 66334000c..ba38b3f15 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -118,8 +118,8 @@ def fun(dofs): boozer_surface.res['iota'] = prevs['iota'][idx] boozer_surface.res['G'] = prevs['G'][idx] - #alldofs = MPI.COMM_WORLD.allgather(dofs) - #assert np.all(np.norm(alldofs[0]-d) == 0 for d in alldofs) + alldofs = MPI.COMM_WORLD.allgather(dofs) + assert np.all(np.norm(alldofs[0]-d) == 0 for d in alldofs) JF.x = dofs J = JF.J() diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 8851f6a29..c23995a09 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -382,16 +382,17 @@ def subtest_convergence_cpp_and_notcpp_same(self, vectorize): G = 2.*np.pi*current_sum*(4*np.pi*10**(-7)/(2 * np.pi)) + cw = 3*s.quadpoints_phi.size * s.quadpoints_theta.size # vectorized solution first res = boozer_surface.minimize_boozer_penalty_constraints_LBFGS( - tol=1e-10, maxiter=600, constraint_weight=100., iota=iota, G=G, + tol=1e-10, maxiter=600, constraint_weight=100./cw, iota=iota, G=G, vectorize=vectorize) print('Residual norm after LBFGS', np.sqrt(2*res['fun'])) boozer_surface.recompute_bell() res = boozer_surface.minimize_boozer_penalty_constraints_newton( - tol=1e-10, maxiter=20, constraint_weight=100., - iota=res['iota'], G=res['G'], stab=1e-4, vectorize=vectorize) + tol=1e-10, maxiter=20, constraint_weight=100./cw, + iota=res['iota'], G=res['G'], stab=0., vectorize=vectorize) assert res['success'] x = boozer_surface.surface.x.copy() From 7b0e7724054fc3591a95e9b1b52461d7fe05c053 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 3 May 2024 15:58:40 -0400 Subject: [PATCH 087/131] linting fix [skip ci] --- examples/2_Intermediate/boozerQA_ls_mpi.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index ba38b3f15..73e6ed019 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -4,7 +4,6 @@ from simsopt._core import load from simsopt.objectives import MPIObjective, MPIOptimizable from simsopt.field import BiotSavart -from simsopt.configs import get_ncsx_data from simsopt.objectives import QuadraticPenalty from scipy.optimize import minimize from simsopt.util import proc0_print @@ -50,7 +49,7 @@ proc0_print("Running 2_Intermediate/boozerQA_ls_mpi.py") proc0_print("================================") -base_curves, base_currents, coils, curves, surfaces, boozer_surfaces, ress = load(IN_DIR + f"ncsx_init.json") +base_curves, base_currents, coils, curves, surfaces, boozer_surfaces, ress = load(IN_DIR + "ncsx_init.json") nsurfaces = 2 surfaces = surfaces[:nsurfaces] boozer_surfaces = boozer_surfaces[:nsurfaces] @@ -104,7 +103,7 @@ boozer_surface.surface.to_vtk(OUT_DIR + f"surf_init_{rank}") if comm is None or comm.rank == 0: - curves_to_vtk(curves, OUT_DIR + f"curves_init") + curves_to_vtk(curves, OUT_DIR + "curves_init") # dictionary used to save the last accepted surface dofs in the line search, in case Newton's method fails prevs = {'sdofs': [surface.x.copy() for surface in mpi_surfaces], 'iota': [boozer_surface.res['iota'] for boozer_surface in mpi_boozer_surfaces], From 3ca3fc1571e13a1ae98d7e070390c2772ad89971 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 6 May 2024 14:14:10 -0400 Subject: [PATCH 088/131] edits to example --- examples/2_Intermediate/boozerQA_ls_mpi.py | 24 ++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index 73e6ed019..8dc921b22 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -38,6 +38,11 @@ Surface solves using the BoozerLS approach can be costly, so this script supports distributing the solves across multiple MPI ranks. +You can change the value of nsurfaces below to optimize for nested surfaces and QS on up to 7 surfaces. The BoozerSurface +solves can be distributed to Nranks ranks using: + mpirun -n Nranks ./boozerQA_ls_mpi.py +where nsurfaces is the number of surfaces your optimizing on. + More details on this work can be found at or doi:10.1063/5.0129716 arxiv:2210.03248. """ @@ -50,7 +55,11 @@ proc0_print("================================") base_curves, base_currents, coils, curves, surfaces, boozer_surfaces, ress = load(IN_DIR + "ncsx_init.json") -nsurfaces = 2 + +# you can optimize for QA on up to 10 surfaces, by changing nsurfaces below. +nsurfaces = 3 +assert nsurfaces <=10 + surfaces = surfaces[:nsurfaces] boozer_surfaces = boozer_surfaces[:nsurfaces] ress = ress[:nsurfaces] @@ -117,15 +126,18 @@ def fun(dofs): boozer_surface.res['iota'] = prevs['iota'][idx] boozer_surface.res['G'] = prevs['G'][idx] - alldofs = MPI.COMM_WORLD.allgather(dofs) - assert np.all(np.norm(alldofs[0]-d) == 0 for d in alldofs) - + #alldofs = MPI.COMM_WORLD.allgather(dofs) + #assert np.all(np.norm(alldofs[0]-d) == 0 for d in alldofs) + JF.x = dofs J = JF.J() grad = JF.dJ() - success = np.all([boozer_surface.res['success'] for boozer_surface in mpi_boozer_surfaces]) - if not success: + # check to make sure that all the surface solves succeeded + success1 = np.all([boozer_surface.res['success'] for boozer_surface in mpi_boozer_surfaces]) + # check to make sure that the surfaces are not self-intersecting + success2 = np.all([not surface.is_self_intersecting() for surface in mpi_surfaces]) + if not (success1 and success2): J = prevs['J'] grad = -prevs['dJ'] for idx, boozer_surface in enumerate(mpi_boozer_surfaces): From f8ae885d2799d8ab697d273799a45fb39574185a Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 6 May 2024 14:22:52 -0400 Subject: [PATCH 089/131] linting fix --- examples/2_Intermediate/boozerQA_ls_mpi.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index 8dc921b22..878661f3a 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -38,7 +38,7 @@ Surface solves using the BoozerLS approach can be costly, so this script supports distributing the solves across multiple MPI ranks. -You can change the value of nsurfaces below to optimize for nested surfaces and QS on up to 7 surfaces. The BoozerSurface +You can change the value of nsurfaces below to optimize for nested surfaces and QS on up to 10 surfaces. The BoozerSurface solves can be distributed to Nranks ranks using: mpirun -n Nranks ./boozerQA_ls_mpi.py where nsurfaces is the number of surfaces your optimizing on. @@ -195,7 +195,7 @@ def callback(x): MAXITER = 50 if ci else 1e3 res = minimize(fun, dofs, jac=True, method='BFGS', options={'maxiter': MAXITER}, tol=1e-15, callback=callback) -curves_to_vtk(curves, OUT_DIR + f"curves_opt") +curves_to_vtk(curves, OUT_DIR + "curves_opt") boozer_surface.surface.to_vtk(OUT_DIR + "surf_opt") proc0_print("End of 2_Intermediate/boozerQA_ls.py") From d8884a74c9ffb8e536b5728bad1013d477650d19 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 6 May 2024 14:33:03 -0400 Subject: [PATCH 090/131] linting fix --- tests/geo/test_surface_objectives.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/geo/test_surface_objectives.py b/tests/geo/test_surface_objectives.py index 146dd20a2..3b0e63b2b 100644 --- a/tests/geo/test_surface_objectives.py +++ b/tests/geo/test_surface_objectives.py @@ -2,7 +2,7 @@ import numpy as np from simsopt.field.biotsavart import BiotSavart from simsopt.field.coil import coils_via_symmetries -from simsopt.geo.surfaceobjectives import ToroidalFlux, QfmResidual, parameter_derivatives, Volume, PrincipalCurvature, MajorRadius, Iotas, NonQuasiSymmetricRatio, AspectRatio, BoozerResidual +from simsopt.geo.surfaceobjectives import ToroidalFlux, QfmResidual, parameter_derivatives, Volume, PrincipalCurvature, MajorRadius, Iotas, NonQuasiSymmetricRatio, BoozerResidual from simsopt.configs.zoo import get_ncsx_data from .surface_test_helpers import get_surface, get_exact_surface, get_boozer_surface From 069c5f780b7fbd69802a3c21bea475904c030471 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 6 May 2024 15:55:25 -0400 Subject: [PATCH 091/131] tightening tolerances for unit tests --- tests/geo/test_boozersurface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index c23995a09..7c40997b3 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -285,7 +285,7 @@ def subtest_boozer_surface_optimisation_convergence(self, surfacetype, cw = (s.quadpoints_phi.size * s.quadpoints_theta.size * 3) # compute surface first using LBFGS exact and an area constraint res = boozer_surface.minimize_boozer_penalty_constraints_LBFGS( - tol=1e-11, maxiter=700, constraint_weight=100/cw, iota=iota, G=G, + tol=1e-12, maxiter=700, constraint_weight=100/cw, iota=iota, G=G, vectorize=vectorize) print('Residual norm after LBFGS', res['iter'], np.sqrt(2*res['fun'])) From c9d729b17df41908759998675ac80053114a3531 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 6 May 2024 17:28:11 -0400 Subject: [PATCH 092/131] more unit tests for code coverage --- tests/geo/test_boozersurface.py | 21 +++++++++++++++++++++ tests/objectives/test_utilities.py | 5 +++++ 2 files changed, 26 insertions(+) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 7c40997b3..6c6ea421b 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -354,6 +354,27 @@ def subtest_boozer_serialization(self, label): # check that BoozerSurface.surface and label.surface are the same surfaces assert bs_regen.label.surface is bs_regen.surface + def test_run_code(self): + """ + This unit test verifies that the run_code portion of the BoozerSurface class is working as expected + """ + bs, boozer_surface = get_boozer_surface(boozer_type='ls') + boozer_surface.run_code('ls', boozer_surface.res['iota'], boozer_surface.res['G'], verbose=False) + + # this second time should not actually run + boozer_surface.run_code('ls', boozer_surface.res['iota'], boozer_surface.res['G'], verbose=False) + + bs, boozer_surface = get_boozer_surface(boozer_type='exact') + boozer_surface.run_code('exact', boozer_surface.res['iota'], boozer_surface.res['G'], verbose=False) + + # this second time should not actually run + boozer_surface.run_code('exact', boozer_surface.res['iota'], boozer_surface.res['G'], verbose=False) + + boozer_surface.need_to_run_code=True + # this should raise an exception + with self.assertRaises(Exception): + boozer_surface.run_code('', boozer_surface.res['iota'], boozer_surface.res['G'], verbose=False) + def test_convergence_cpp_and_notcpp_same(self): """ This unit test verifies that that the cpp and not cpp implementations converge to diff --git a/tests/objectives/test_utilities.py b/tests/objectives/test_utilities.py index 8060d0cba..2989523f9 100644 --- a/tests/objectives/test_utilities.py +++ b/tests/objectives/test_utilities.py @@ -112,3 +112,8 @@ def test_mpi_optimizable(self): mpi_surfaces = MPIOptimizable(surfaces, ["x"], comm) for s, sx in zip(mpi_surfaces, equal_to): np.testing.assert_allclose(s.x, sx, atol=1e-14) + + # this should raise an exception + mpi_surfaces = [SurfaceXYZTensorFourier(mpol=1, ntor=1, stellsym=True) for i in range(size)] + with self.assertRaises(Exception): + _ = MPIOptimizable(surfaces, ["y"], comm) From 29be21abc817223e9fb0db781daa517da3cb609c Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Mon, 6 May 2024 14:31:36 -0700 Subject: [PATCH 093/131] minor changes to the example --- examples/2_Intermediate/boozerQA_ls_mpi.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index 878661f3a..4366ae65c 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -57,7 +57,7 @@ base_curves, base_currents, coils, curves, surfaces, boozer_surfaces, ress = load(IN_DIR + "ncsx_init.json") # you can optimize for QA on up to 10 surfaces, by changing nsurfaces below. -nsurfaces = 3 +nsurfaces = 10 assert nsurfaces <=10 surfaces = surfaces[:nsurfaces] @@ -110,9 +110,10 @@ # let's fix the coil current base_currents[0].fix_all() -boozer_surface.surface.to_vtk(OUT_DIR + f"surf_init_{rank}") if comm is None or comm.rank == 0: curves_to_vtk(curves, OUT_DIR + "curves_init") + for idx, surface in enumerate(mpi_surfaces): + surface.to_vtk(OUT_DIR + f"surf_init_{idx}") # dictionary used to save the last accepted surface dofs in the line search, in case Newton's method fails prevs = {'sdofs': [surface.x.copy() for surface in mpi_surfaces], 'iota': [boozer_surface.res['iota'] for boozer_surface in mpi_boozer_surfaces], @@ -195,8 +196,10 @@ def callback(x): MAXITER = 50 if ci else 1e3 res = minimize(fun, dofs, jac=True, method='BFGS', options={'maxiter': MAXITER}, tol=1e-15, callback=callback) -curves_to_vtk(curves, OUT_DIR + "curves_opt") -boozer_surface.surface.to_vtk(OUT_DIR + "surf_opt") +if comm is None or comm.rank == 0: + curves_to_vtk(curves, OUT_DIR + "curves_opt") + for idx, surface in enumerate(mpi_surfaces): + surface.to_vtk(OUT_DIR + f"surf_opt_{idx}") proc0_print("End of 2_Intermediate/boozerQA_ls.py") proc0_print("================================") From ca116816396fa298ef18338b1795c6e4c268d240 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 7 May 2024 11:23:12 -0400 Subject: [PATCH 094/131] small change to unit tests for code coverage --- tests/geo/test_surface_objectives.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/geo/test_surface_objectives.py b/tests/geo/test_surface_objectives.py index 3b0e63b2b..7fea67dec 100644 --- a/tests/geo/test_surface_objectives.py +++ b/tests/geo/test_surface_objectives.py @@ -379,7 +379,7 @@ def test_label_surface_derivative1(self): self.subtest_label_derivative1(label) def subtest_label_derivative1(self, label): - bs, boozer_surface = get_boozer_surface(label=label) + bs, boozer_surface = get_boozer_surface(label=label, nphi=13, ntheta=14) surface = boozer_surface.surface label = boozer_surface.label coeffs = surface.x From d872fcf1c96ad35bb4a575c87ca7d14122c48afd Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 7 May 2024 11:49:39 -0400 Subject: [PATCH 095/131] more edits to the text in the example --- examples/2_Intermediate/boozerQA_ls_mpi.py | 46 +++++++++++++--------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index 4366ae65c..b7239c69c 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -25,23 +25,32 @@ For a single surface, the objective is: J = ( \int_S B_nonQA**2 dS )/(\int_S B_QA dS) + + \int \int BoozerResidual(varphi, theta)^2 d\varphi d\theta + 0.5*(iota - iota_0)**2 + 0.5*(major_radius - target_major_radius)**2 + 0.5*max(\sum_{coils} CurveLength - CurveLengthTarget, 0)**2 - -We first load a surface close to the magnetic axis, then optimize for QA on that surface. -The objective also includes penalty terms on the rotational transform, major radius, -and total coil length. The rotational transform and major radius penalty ensures that the surface's -rotational transform and aspect ratio do not stray too far from the value in the initial configuration. -There is also a penalty on the total coil length as a regularizer to prevent the coils from becoming -too complex. The BFGS optimizer is used, and quasisymmetry is improved substantially on the surface. -Surface solves using the BoozerLS approach can be costly, so this script supports distributing the solves -across multiple MPI ranks. - -You can change the value of nsurfaces below to optimize for nested surfaces and QS on up to 10 surfaces. The BoozerSurface -solves can be distributed to Nranks ranks using: - mpirun -n Nranks ./boozerQA_ls_mpi.py -where nsurfaces is the number of surfaces your optimizing on. + + other coil regularization penalties on curvature, mean squared curvature, + coil-to-coil distance, and coil arclength. + +We first load surfaces in the NCSX equilibrium, then optimize for QA on them. +The first term the objective minimizes the deviation from quasi-axisymmetry on the loaded surfaces. +The second term minimizes the Boozer residual on the surfaces, which pushes the optimizer to heal +islands and generalized chaos. It is typically a good idea to weight this penalty term to be ~ the +same order of magnitude of the first term in the objective. + +The objective also includes penalty terms on the rotational transform, major radius, total coil length, curvature, +mean squared curvature, and coil arclength. The rotational transform and major radius penalty ensures +that the surfaces' rotational transform and aspect ratio do not stray too far from the value in the initial configuration. +There are also a few coil regularization penalties to prevent the coils from becoming too complex. The BFGS +optimizer is used, and quasisymmetry is improved substantially on the surface. Surface solves using the BoozerLS +approach can be costly, so this script supports distributing the solves across multiple MPI ranks. + +You can change the value of the variable `nsurfaces` below to optimize for nested surfaces and QS on up to 10 surfaces. +The BoozerSurface solves can be distributed to Nranks ranks using: + mpirun -np Nranks ./boozerQA_ls_mpi.py +where `nsurfaces` is the number of surfaces your optimizing on. For example, if you want one surface solve per rank, +and nsurfaces=Nranks=2, then the proper call is: + mpirun -np 2 ./boozerQA_ls_mpi.py More details on this work can be found at or doi:10.1063/5.0129716 arxiv:2210.03248. """ @@ -57,7 +66,7 @@ base_curves, base_currents, coils, curves, surfaces, boozer_surfaces, ress = load(IN_DIR + "ncsx_init.json") # you can optimize for QA on up to 10 surfaces, by changing nsurfaces below. -nsurfaces = 10 +nsurfaces = 2 assert nsurfaces <=10 surfaces = surfaces[:nsurfaces] @@ -70,6 +79,7 @@ mpi_boozer_surfaces = MPIOptimizable(boozer_surfaces, ["res", "need_to_run_code"], comm) mrs = [MajorRadius(boozer_surface) for boozer_surface in boozer_surfaces] +mrs_equality = [len(mrs)*QuadraticPenalty(mr, mr.J(), 'identity') if idx == len(mrs)-1 else 0*QuadraticPenalty(mr, mr.J(), 'identity') for idx, mr in enumerate(mrs)] iotas = [Iotas(boozer_surface) for boozer_surface in boozer_surfaces] nonQSs = [NonQuasiSymmetricRatio(boozer_surface, BiotSavart(coils)) for boozer_surface in boozer_surfaces] brs = [BoozerResidual(boozer_surface, BiotSavart(coils)) for boozer_surface in boozer_surfaces] @@ -92,7 +102,7 @@ Jiotas = QuadraticPenalty(mean_iota, IOTAS_TARGET, 'identity') JnonQSRatio = MPIObjective(nonQSs, comm, needs_splitting=True) JBoozerResidual = MPIObjective(brs, comm, needs_splitting=True) -Jmajor_radius = MPIObjective([len(mrs)*QuadraticPenalty(mr, mr.J(), 'identity') if idx == 0 else 0*QuadraticPenalty(mr, mr.J(), 'identity') for idx, mr in enumerate(mrs)], comm, needs_splitting=True) +Jmajor_radius = MPIObjective(mrs_equality, comm, needs_splitting=True) ls = [CurveLength(c) for c in base_curves] Jls = QuadraticPenalty(sum(ls), float(sum(ls).J()), 'max') @@ -110,7 +120,7 @@ # let's fix the coil current base_currents[0].fix_all() -if comm is None or comm.rank == 0: +if comm is None or rank == 0: curves_to_vtk(curves, OUT_DIR + "curves_init") for idx, surface in enumerate(mpi_surfaces): surface.to_vtk(OUT_DIR + f"surf_init_{idx}") @@ -196,7 +206,7 @@ def callback(x): MAXITER = 50 if ci else 1e3 res = minimize(fun, dofs, jac=True, method='BFGS', options={'maxiter': MAXITER}, tol=1e-15, callback=callback) -if comm is None or comm.rank == 0: +if comm is None or rank == 0: curves_to_vtk(curves, OUT_DIR + "curves_opt") for idx, surface in enumerate(mpi_surfaces): surface.to_vtk(OUT_DIR + f"surf_opt_{idx}") From 4e6fca10343a89441319af50e7a7e1444249f9ce Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 7 May 2024 12:52:53 -0400 Subject: [PATCH 096/131] changes for code coverage --- src/simsopt/geo/boozersurface.py | 17 +++++--- src/simsopt/geo/surfaceobjectives.py | 28 ++++++++----- tests/geo/surface_test_helpers.py | 4 +- tests/geo/test_boozersurface.py | 14 ++++--- tests/geo/test_surface_objectives.py | 60 ++++++++++++++++------------ 5 files changed, 75 insertions(+), 48 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index ecfcd3581..6bebde08f 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -55,17 +55,24 @@ def recompute_bell(self, parent=None): def run_code(self, boozer_type, iota, G=None, verbose=True): """ - Run the default solvers. + Run the default solvers, i.e., run Newton's method directly if you are computing a BoozerExact surface, + and run BFGS followed by Newton if you are computing a BoozerLS surface. """ if not self.need_to_run_code: return - + + # BoozerExact default solver if boozer_type == 'exact': res = self.solve_residual_equation_exactly_newton(tol=1e-13, maxiter=40, iota=iota, G=G, verbose=verbose) return res - + + # BoozerLS default solver elif boozer_type == 'ls': - # first try BFGS + # you need a label constraint for a BoozerLS surface + assert self.constraint_weight is not None + + # first try BFGS. You could also try L-BFGS by setting limited_memory=True, which might be faster. However, BFGS appears + # to generally result in solutions closer to optimality. res = self.minimize_boozer_penalty_constraints_LBFGS(tol=1e-10, maxiter=1500, constraint_weight=self.constraint_weight, iota=iota, G=G, verbose=verbose, limited_memory=False) iota, G = res['iota'], res['G'] @@ -679,7 +686,7 @@ def solve_residual_equation_exactly_newton(self, tol=1e-10, maxiter=10, iota=0., label = self.label if G is None: - G = 2. * np.pi * np.sum(np.abs(self.biotsavart.coil_currents)) * (4 * np.pi * 10**(-7) / (2 * np.pi)) + G = 2. * np.pi * np.sum(np.abs([c.current.get_value() for c in self.biotsavart.coils])) * (4 * np.pi * 10**(-7) / (2 * np.pi)) x = np.concatenate((s.get_dofs(), [iota, G])) i = 0 r, J = boozer_surface_residual(s, iota, G, self.biotsavart, derivatives=1) diff --git a/src/simsopt/geo/surfaceobjectives.py b/src/simsopt/geo/surfaceobjectives.py index f3e3b162b..d62ec574a 100644 --- a/src/simsopt/geo/surfaceobjectives.py +++ b/src/simsopt/geo/surfaceobjectives.py @@ -782,9 +782,11 @@ def compute(self): dJ_by_dB = self.dJ_by_dB().reshape((-1, 3)) dJ_by_dcoils = self.biotsavart.B_vjp(dJ_by_dB) - + # tack on dJ_diota = dJ_dG = 0 to the end of dJ_ds - dJ_ds = np.concatenate((self.dJ_by_dsurfacecoefficients(), [0., 0.])) + dJ_ds = np.zeros(L.shape[0]) + dj_ds = self.dJ_by_dsurfacecoefficients() + dJ_ds[:dj_ds.size] = dj_ds adj = forward_backward(P, L, U, dJ_ds) adj_times_dg_dcoil = dconstraint_dcoils_vjp(adj, booz_surf, iota, G) @@ -919,9 +921,14 @@ def compute(self): P, L, U = booz_surf.res['PLU'] dconstraint_dcoils_vjp = self.boozer_surface.res['vjp'] - # tack on dJ_diota = dJ_dG = 0 to the end of dJ_ds dJ_ds = np.zeros(L.shape[0]) - dJ_ds[-2] = 1. + if G is not None: + # tack on dJ_diota = 1, and dJ_dG = 0 to the end of dJ_ds + dJ_ds[-2] = 1. + else: + # tack on dJ_diota = 1 to the end of dJ_ds + dJ_ds[-1] = 1. + adj = forward_backward(P, L, U, dJ_ds) adj_times_dg_dcoil = dconstraint_dcoils_vjp(adj, booz_surf, iota, G) @@ -1012,7 +1019,8 @@ def compute(self): # dJ_diota, dJ_dG to the end of dJ_ds are on the end dl = np.zeros((J.shape[1],)) - dl[:-2] = self.boozer_surface.label.dJ_by_dsurfacecoefficients() + dlabel_dsurface = self.boozer_surface.label.dJ_by_dsurfacecoefficients() + dl[:dlabel_dsurface.size] = dlabel_dsurface Jtil = np.concatenate((J/np.sqrt(num_points), np.sqrt(self.constraint_weight) * dl[None, :]), axis=0) dJ_ds = Jtil.T@rtil @@ -1050,8 +1058,6 @@ def boozer_surface_dexactresidual_dcoils_dcurrents_vjp(lm, booz_surf, iota, G): \lambda^T \frac{d\mathbf{r}}{d\text{currents}} &= [G\lambda - 2\lambda\|\mathbf B(\mathbf x)\| (\mathbf{x}_\varphi + \iota \mathbf{x}_\theta) ]^T \frac{d\mathbf B}{d\text{currents}} where :math:`\mathbf{r}` is the Boozer residual. - G is known for exact boozer surfaces, so if G=None is passed, then that - value is used instead. Args: lm: adjoint variable, @@ -1061,9 +1067,9 @@ def boozer_surface_dexactresidual_dcoils_dcurrents_vjp(lm, booz_surf, iota, G): """ surface = booz_surf.surface biotsavart = booz_surf.biotsavart - user_provided_G = G is not None - if not user_provided_G: - G = 2. * np.pi * np.sum(np.abs(biotsavart.coil_currents)) * (4 * np.pi * 10**(-7) / (2 * np.pi)) + + # G must be provided here + assert G is not None res, dres_dB = boozer_surface_residual_dB(surface, iota, G, biotsavart) dres_dB = dres_dB.reshape((-1, 3, 3)) @@ -1124,7 +1130,7 @@ def boozer_surface_residual_dB(surface, iota, G, biotsavart, derivatives=0, weig user_provided_G = G is not None if not user_provided_G: - G = 2. * np.pi * np.sum(np.abs(biotsavart.coil_currents)) * (4 * np.pi * 10**(-7) / (2 * np.pi)) + G = 2. * np.pi * np.sum(np.abs([c.current.get_value() for c in biotsavart.coils])) * (4 * np.pi * 10**(-7) / (2 * np.pi)) x = surface.gamma() xphi = surface.gammadash1() diff --git a/tests/geo/surface_test_helpers.py b/tests/geo/surface_test_helpers.py index 1aa40586d..fe9c12933 100644 --- a/tests/geo/surface_test_helpers.py +++ b/tests/geo/surface_test_helpers.py @@ -74,7 +74,7 @@ def get_exact_surface(surface_type='SurfaceXYZFourier'): return s -def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exact'): +def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exact', optimize_G=True): """ Returns a boozer surface that will be used in unit tests. """ @@ -85,7 +85,7 @@ def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exac coils = coils_via_symmetries(base_curves, base_currents, 3, True) bs = BiotSavart(coils) current_sum = sum(abs(c.current.get_value()) for c in coils) - G0 = 2. * np.pi * current_sum * (4 * np.pi * 10**(-7) / (2 * np.pi)) + G0 = 2. * np.pi * current_sum * (4 * np.pi * 10**(-7) / (2 * np.pi)) if optimize_G else None ## RESOLUTION DETAILS OF SURFACE ON WHICH WE OPTIMIZE FOR QA mpol = 6 if boozer_type == 'exact' else 3 diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 6c6ea421b..3e599451c 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -359,21 +359,25 @@ def test_run_code(self): This unit test verifies that the run_code portion of the BoozerSurface class is working as expected """ bs, boozer_surface = get_boozer_surface(boozer_type='ls') - boozer_surface.run_code('ls', boozer_surface.res['iota'], boozer_surface.res['G'], verbose=False) + boozer_surface.run_code('ls', boozer_surface.res['iota'], G=boozer_surface.res['G'], verbose=False) # this second time should not actually run - boozer_surface.run_code('ls', boozer_surface.res['iota'], boozer_surface.res['G'], verbose=False) + boozer_surface.run_code('ls', boozer_surface.res['iota'], G=boozer_surface.res['G'], verbose=False) bs, boozer_surface = get_boozer_surface(boozer_type='exact') - boozer_surface.run_code('exact', boozer_surface.res['iota'], boozer_surface.res['G'], verbose=False) + boozer_surface.run_code('exact', boozer_surface.res['iota'], G=boozer_surface.res['G'], verbose=False) # this second time should not actually run - boozer_surface.run_code('exact', boozer_surface.res['iota'], boozer_surface.res['G'], verbose=False) + boozer_surface.run_code('exact', boozer_surface.res['iota'], G=boozer_surface.res['G'], verbose=False) + boozer_surface.need_to_run_code=True + # run without providing value of G + boozer_surface.run_code('exact', boozer_surface.res['iota'], verbose=True) + boozer_surface.need_to_run_code=True # this should raise an exception with self.assertRaises(Exception): - boozer_surface.run_code('', boozer_surface.res['iota'], boozer_surface.res['G'], verbose=False) + boozer_surface.run_code('', boozer_surface.res['iota'], G=boozer_surface.res['G'], verbose=False) def test_convergence_cpp_and_notcpp_same(self): """ diff --git a/tests/geo/test_surface_objectives.py b/tests/geo/test_surface_objectives.py index 7fea67dec..5e3d184b7 100644 --- a/tests/geo/test_surface_objectives.py +++ b/tests/geo/test_surface_objectives.py @@ -261,13 +261,16 @@ def test_major_radius_derivative(self): """ for boozer_type in ['exact', 'ls']: for label in ["Volume", "ToroidalFlux"]: - with self.subTest(label=label, boozer_type=boozer_type): - if boozer_type == 'ls' and label == 'ToroidalFlux': - continue - self.subtest_major_radius_surface_derivative(label, boozer_type) - - def subtest_major_radius_surface_derivative(self, label, boozer_type): - bs, boozer_surface = get_boozer_surface(label=label, nphi=51, ntheta=51, boozer_type=boozer_type) + for optimize_G in [True, False]: + with self.subTest(label=label, boozer_type=boozer_type, optimize_G=optimize_G): + if boozer_type == 'ls' and label == 'ToroidalFlux': + continue + if boozer_type == 'exact' and optimize_G is False: + continue + self.subtest_major_radius_surface_derivative(label, boozer_type, optimize_G) + + def subtest_major_radius_surface_derivative(self, label, boozer_type, optimize_G): + bs, boozer_surface = get_boozer_surface(label=label, nphi=51, ntheta=51, boozer_type=boozer_type, optimize_G=optimize_G) coeffs = bs.x mr = MajorRadius(boozer_surface) @@ -290,17 +293,20 @@ def test_iotas_derivative(self): for boozer_type in ['exact', 'ls']: for label in ["Volume", "ToroidalFlux"]: - if boozer_type == 'ls' and label == 'ToroidalFlux': - continue - with self.subTest(label=label, boozer_type=boozer_type): - self.subtest_iotas_derivative(label, boozer_type) + for optimize_G in [True, False]: + if boozer_type == 'ls' and label == 'ToroidalFlux': + continue + if boozer_type == 'exact' and optimize_G is False: + continue + with self.subTest(label=label, boozer_type=boozer_type, optimize_G=optimize_G): + self.subtest_iotas_derivative(label, boozer_type, optimize_G) - def subtest_iotas_derivative(self, label, boozer_type): + def subtest_iotas_derivative(self, label, boozer_type, optimize_G): """ Taylor test for derivative of surface rotational transform wrt coil parameters """ - bs, boozer_surface = get_boozer_surface(label=label, boozer_type=boozer_type) + bs, boozer_surface = get_boozer_surface(label=label, boozer_type=boozer_type, optimize_G=optimize_G) coeffs = bs.x io = Iotas(boozer_surface) @@ -323,14 +329,17 @@ def test_nonQSratio_derivative(self): """ for boozer_type in ['exact', 'ls']: for label in ["Volume", "ToroidalFlux"]: - if boozer_type == 'ls' and label == 'ToroidalFlux': - continue - for axis in [False, True]: - with self.subTest(label=label, axis=axis, boozer_type=boozer_type): - self.subtest_nonQSratio_derivative(label, axis, boozer_type) - - def subtest_nonQSratio_derivative(self, label, axis, boozer_type): - bs, boozer_surface = get_boozer_surface(label=label, boozer_type=boozer_type) + for optimize_G in [True, False]: + if boozer_type == 'ls' and label == 'ToroidalFlux': + continue + if boozer_type == 'exact' and optimize_G is False: + continue + for axis in [False, True]: + with self.subTest(label=label, axis=axis, boozer_type=boozer_type, optimize_G=optimize_G): + self.subtest_nonQSratio_derivative(label, axis, boozer_type, optimize_G) + + def subtest_nonQSratio_derivative(self, label, axis, boozer_type, optimize_G): + bs, boozer_surface = get_boozer_surface(label=label, boozer_type=boozer_type, optimize_G=optimize_G) coeffs = bs.x io = NonQuasiSymmetricRatio(boozer_surface, bs, quasi_poloidal=axis) @@ -352,11 +361,12 @@ def test_boozerresidual_derivative(self): Taylor test for derivative of surface non QS ratio wrt coil parameters """ for label in ["Volume"]: - with self.subTest(label=label): - self.subtest_boozerresidual_derivative(label) + for optimize_G in [True, False]: + with self.subTest(label=label, optimize_G=optimize_G): + self.subtest_boozerresidual_derivative(label, optimize_G) - def subtest_boozerresidual_derivative(self, label): - bs, boozer_surface = get_boozer_surface(label=label, boozer_type='ls') + def subtest_boozerresidual_derivative(self, label, optimize_G): + bs, boozer_surface = get_boozer_surface(label=label, boozer_type='ls', optimize_G=optimize_G) coeffs = bs.x br = BoozerResidual(boozer_surface, bs) From 31cdd2251b5da594ce935341ef5ffbd4a3800a37 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Tue, 7 May 2024 15:46:10 -0400 Subject: [PATCH 097/131] fix to example --- examples/2_Intermediate/boozerQA_ls_mpi.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index b7239c69c..1299283ca 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -122,7 +122,8 @@ if comm is None or rank == 0: curves_to_vtk(curves, OUT_DIR + "curves_init") - for idx, surface in enumerate(mpi_surfaces): +for idx, surface in enumerate(mpi_surfaces): + if comm is None or rank == 0: surface.to_vtk(OUT_DIR + f"surf_init_{idx}") # dictionary used to save the last accepted surface dofs in the line search, in case Newton's method fails @@ -137,8 +138,10 @@ def fun(dofs): boozer_surface.res['iota'] = prevs['iota'][idx] boozer_surface.res['G'] = prevs['G'][idx] - #alldofs = MPI.COMM_WORLD.allgather(dofs) - #assert np.all(np.norm(alldofs[0]-d) == 0 for d in alldofs) + # this check makes sure that all ranks have exactly the same dofs + if comm is not None: + alldofs = comm.allgather(dofs) + assert np.all(np.all(alldofs[0]-d == 0) for d in alldofs) JF.x = dofs J = JF.J() @@ -208,7 +211,8 @@ def callback(x): res = minimize(fun, dofs, jac=True, method='BFGS', options={'maxiter': MAXITER}, tol=1e-15, callback=callback) if comm is None or rank == 0: curves_to_vtk(curves, OUT_DIR + "curves_opt") - for idx, surface in enumerate(mpi_surfaces): +for idx, surface in enumerate(mpi_surfaces): + if comm is None or rank == 0: surface.to_vtk(OUT_DIR + f"surf_opt_{idx}") proc0_print("End of 2_Intermediate/boozerQA_ls.py") From d68dec92bfd757afe449e2dcdf82e7ba81d330b4 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 8 May 2024 12:21:40 -0400 Subject: [PATCH 098/131] changes for code coverage --- tests/geo/surface_test_helpers.py | 9 +++------ tests/geo/test_surface_objectives.py | 16 ++++++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tests/geo/surface_test_helpers.py b/tests/geo/surface_test_helpers.py index fe9c12933..6b0d6205b 100644 --- a/tests/geo/surface_test_helpers.py +++ b/tests/geo/surface_test_helpers.py @@ -74,7 +74,7 @@ def get_exact_surface(surface_type='SurfaceXYZFourier'): return s -def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exact', optimize_G=True): +def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exact', optimize_G=True, converge=True, stellsym=True): """ Returns a boozer surface that will be used in unit tests. """ @@ -90,7 +90,6 @@ def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exac ## RESOLUTION DETAILS OF SURFACE ON WHICH WE OPTIMIZE FOR QA mpol = 6 if boozer_type == 'exact' else 3 ntor = 6 if boozer_type == 'exact' else 3 - stellsym = True nfp = 3 if boozer_type == 'exact': @@ -122,9 +121,7 @@ def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exac ## COMPUTE THE SURFACE cw = None if boozer_type == 'exact' else 100. boozer_surface = BoozerSurface(bs, s, lab, lab_target, constraint_weight=cw) - boozer_surface.run_code(boozer_type, iota, G=G0, verbose=True) - - #res = boozer_surface.solve_residual_equation_exactly_newton(tol=1e-13, maxiter=20, iota=iota, G=G0) - #print(f"NEWTON {res['success']}: iter={res['iter']}, iota={res['iota']:.3f}, vol={s.volume():.3f}") + if converge: + boozer_surface.run_code(boozer_type, iota, G=G0, verbose=True) return bs, boozer_surface diff --git a/tests/geo/test_surface_objectives.py b/tests/geo/test_surface_objectives.py index 5e3d184b7..42d8545d0 100644 --- a/tests/geo/test_surface_objectives.py +++ b/tests/geo/test_surface_objectives.py @@ -385,11 +385,15 @@ def df(dofs): class LabelTests(unittest.TestCase): def test_label_surface_derivative1(self): for label in ["Volume", "ToroidalFlux", "Area", "AspectRatio"]: - with self.subTest(label=label): - self.subtest_label_derivative1(label) - - def subtest_label_derivative1(self, label): - bs, boozer_surface = get_boozer_surface(label=label, nphi=13, ntheta=14) + for stellsym in stellsym_list: + for nphi, ntheta in [(13, 14), (None, None), (13, None), (None, 14)]: + with self.subTest(label=label, stellsym=stellsym, converge=stellsym): + # don't converge the BoozerSurface when stellsym=False because it takes a long time + # for a unit test + self.subtest_label_derivative1(label, stellsym=stellsym, converge=stellsym, nphi=nphi, ntheta=ntheta) + + def subtest_label_derivative1(self, label, stellsym, converge, nphi, ntheta): + bs, boozer_surface = get_boozer_surface(label=label, nphi=nphi, ntheta=ntheta, converge=converge, stellsym=stellsym) surface = boozer_surface.surface label = boozer_surface.label coeffs = surface.x @@ -406,7 +410,7 @@ def df(dofs): epsilons=np.power(2., -np.asarray(range(13, 19)))) def test_label_surface_derivative2(self): - for label in ["Volume", "ToroidalFlux", "Area"]: + for label in ["Volume", "ToroidalFlux", "Area", "AspectRatio"]: with self.subTest(label=label): self.subtest_label_derivative2(label) From a9953c7da4b1e917aa921d0f12884a1a0a5cb66d Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 8 May 2024 13:33:55 -0400 Subject: [PATCH 099/131] small change in finite difference test --- tests/geo/test_surface_objectives.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/geo/test_surface_objectives.py b/tests/geo/test_surface_objectives.py index 42d8545d0..e146a7849 100644 --- a/tests/geo/test_surface_objectives.py +++ b/tests/geo/test_surface_objectives.py @@ -407,7 +407,7 @@ def df(dofs): return label.dJ(partials=True)(surface) taylor_test1(f, df, coeffs, - epsilons=np.power(2., -np.asarray(range(13, 19)))) + epsilons=np.power(2., -np.asarray(range(12, 18)))) def test_label_surface_derivative2(self): for label in ["Volume", "ToroidalFlux", "Area", "AspectRatio"]: From df64329ef5c81d750c82b4978bce964b51dc781a Mon Sep 17 00:00:00 2001 From: Stefan Buller Date: Tue, 14 May 2024 13:32:10 -0400 Subject: [PATCH 100/131] Added support for stellarator non-symmetric configurations in vmec_splines. --- src/simsopt/mhd/vmec_diagnostics.py | 85 ++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 7 deletions(-) diff --git a/src/simsopt/mhd/vmec_diagnostics.py b/src/simsopt/mhd/vmec_diagnostics.py index 716524595..357c945fa 100644 --- a/src/simsopt/mhd/vmec_diagnostics.py +++ b/src/simsopt/mhd/vmec_diagnostics.py @@ -720,15 +720,22 @@ def vmec_splines(vmec): """ vmec.run() results = Struct() - if vmec.wout.lasym: - raise ValueError("vmec_splines is not yet set up for non-stellarator-symmetric cases.") - rmnc = [] zmns = [] lmns = [] d_rmnc_d_s = [] d_zmns_d_s = [] d_lmns_d_s = [] + + # for stellarator non-symmetric configs + rmns = [] + zmnc = [] + lmnc = [] + d_rmns_d_s = [] + d_zmnc_d_s = [] + d_lmnc_d_s = [] + + for jmn in range(vmec.wout.mnmax): rmnc.append(InterpolatedUnivariateSpline(vmec.s_full_grid, vmec.wout.rmnc[jmn, :])) zmns.append(InterpolatedUnivariateSpline(vmec.s_full_grid, vmec.wout.zmns[jmn, :])) @@ -736,7 +743,24 @@ def vmec_splines(vmec): d_rmnc_d_s.append(rmnc[-1].derivative()) d_zmns_d_s.append(zmns[-1].derivative()) d_lmns_d_s.append(lmns[-1].derivative()) - + if vmec.wout.lasym: + # stellarator non-symmetric + rmns.append(InterpolatedUnivariateSpline(vmec.s_full_grid, vmec.wout.rmns[jmn, :])) + zmnc.append(InterpolatedUnivariateSpline(vmec.s_full_grid, vmec.wout.zmnc[jmn, :])) + lmnc.append(InterpolatedUnivariateSpline(vmec.s_half_grid, vmec.wout.lmnc[jmn, 1:])) + d_rmns_d_s.append(rmns[-1].derivative()) + d_zmnc_d_s.append(zmnc[-1].derivative()) + d_lmnc_d_s.append(lmnc[-1].derivative()) + else: + # if stellarator symmetric, set modes to zero + rmns.append(InterpolatedUnivariateSpline([0,1], [0, 0], k=1)) + zmnc.append(InterpolatedUnivariateSpline([0,1], [0, 0], k=1)) + lmnc.append(InterpolatedUnivariateSpline([0,1], [0, 0], k=1)) + d_rmns_d_s.append(rmns[-1].derivative()) + d_zmnc_d_s.append(zmnc[-1].derivative()) + d_lmnc_d_s.append(lmnc[-1].derivative()) + + # nyquist quantities gmnc = [] bmnc = [] bsupumnc = [] @@ -747,6 +771,20 @@ def vmec_splines(vmec): d_bmnc_d_s = [] d_bsupumnc_d_s = [] d_bsupvmnc_d_s = [] + + # for stellarator non-symmetric configs + gmns = [] + bmns = [] + bsupumns = [] + bsupvmns = [] + bsubsmnc = [] + bsubumns = [] + bsubvmns = [] + d_bmns_d_s = [] + d_bsupumns_d_s = [] + d_bsupvmns_d_s = [] + + for jmn in range(vmec.wout.mnmax_nyq): gmnc.append(InterpolatedUnivariateSpline(vmec.s_half_grid, vmec.wout.gmnc[jmn, 1:])) bmnc.append(InterpolatedUnivariateSpline(vmec.s_half_grid, vmec.wout.bmnc[jmn, 1:])) @@ -759,7 +797,34 @@ def vmec_splines(vmec): d_bmnc_d_s.append(bmnc[-1].derivative()) d_bsupumnc_d_s.append(bsupumnc[-1].derivative()) d_bsupvmnc_d_s.append(bsupvmnc[-1].derivative()) - + if vmec.wout.lasym: + # stellarator non-symmetric + gmns.append(InterpolatedUnivariateSpline(vmec.s_half_grid, vmec.wout.gmns[jmn, 1:])) + bmns.append(InterpolatedUnivariateSpline(vmec.s_half_grid, vmec.wout.bmns[jmn, 1:])) + bsupumns.append(InterpolatedUnivariateSpline(vmec.s_half_grid, vmec.wout.bsupumns[jmn, 1:])) + bsupvmns.append(InterpolatedUnivariateSpline(vmec.s_half_grid, vmec.wout.bsupvmns[jmn, 1:])) + # Note that bsubsmns is on the full mesh, unlike the other components: + bsubsmnc.append(InterpolatedUnivariateSpline(vmec.s_full_grid, vmec.wout.bsubsmnc[jmn, :])) + bsubumns.append(InterpolatedUnivariateSpline(vmec.s_half_grid, vmec.wout.bsubumns[jmn, 1:])) + bsubvmns.append(InterpolatedUnivariateSpline(vmec.s_half_grid, vmec.wout.bsubvmns[jmn, 1:])) + d_bmns_d_s.append(bmns[-1].derivative()) + d_bsupumns_d_s.append(bsupumns[-1].derivative()) + d_bsupvmns_d_s.append(bsupvmns[-1].derivative()) + else: + # if stellarator symmetric, set modes to zero + gmns.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) + bmns.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) + bsupumns.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) + bsupvmns.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) + # Note that bsubsmns is on the full mesh, unlike the other components: + bsubsmnc.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) + bsubumns.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) + bsubvmns.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) + d_bmns_d_s.append(bmns[-1].derivative()) + d_bsupumns_d_s.append(bsupumns[-1].derivative()) + d_bsupvmns_d_s.append(bsupvmns[-1].derivative()) + + # Handle 1d profiles: results.pressure = InterpolatedUnivariateSpline(vmec.s_half_grid, vmec.wout.pres[1:]) results.d_pressure_d_s = results.pressure.derivative() @@ -775,6 +840,11 @@ def vmec_splines(vmec): variables = ['rmnc', 'zmns', 'lmns', 'd_rmnc_d_s', 'd_zmns_d_s', 'd_lmns_d_s', 'gmnc', 'bmnc', 'd_bmnc_d_s', 'bsupumnc', 'bsupvmnc', 'd_bsupumnc_d_s', 'd_bsupvmnc_d_s', 'bsubsmns', 'bsubumnc', 'bsubvmnc'] + # stellarator non-symmetric + variables = variables + \ + ['rmns', 'zmnc', 'lmnc', 'd_rmns_d_s', 'd_zmnc_d_s', 'd_lmnc_d_s', + 'gmns', 'bmns', 'd_bmns_d_s', 'bsupumns', 'bsupvmns', 'd_bsupumns_d_s', 'd_bsupvmns_d_s', + 'bsubsmnc', 'bsubumns', 'bsubvmns'] for v in variables: results.__setattr__(v, eval(v)) @@ -983,7 +1053,8 @@ def vmec_compute_geometry(vs, s, theta, phi, phi_center=0): d_R_d_s = np.einsum('ij,jikl->ikl', d_rmnc_d_s, cosangle) d_R_d_theta_vmec = -np.einsum('ij,jikl->ikl', rmnc, msinangle) d_R_d_phi = np.einsum('ij,jikl->ikl', rmnc, nsinangle) - + + Z = np.einsum('ij,jikl->ikl', zmns, sinangle) d_Z_d_s = np.einsum('ij,jikl->ikl', d_zmns_d_s, sinangle) d_Z_d_theta_vmec = np.einsum('ij,jikl->ikl', zmns, mcosangle) @@ -1332,7 +1403,7 @@ def residual(theta_v, phi0, theta_p_target, jradius): variables = ['modB', 'B_sup_theta_pest', 'B_sup_phi', 'B_cross_grad_B_dot_grad_alpha', 'B_cross_grad_B_dot_grad_psi', 'B_cross_kappa_dot_grad_alpha', 'B_cross_kappa_dot_grad_psi', 'grad_alpha_dot_grad_alpha', 'grad_alpha_dot_grad_psi', 'grad_psi_dot_grad_psi', - 'bmag', 'gradpar_theta_pest', 'gradpar_phi', 'gbdrift', 'gbdrift0', 'cvdrift', 'cvdrift0', 'gds2', 'gds21', 'gds22'] + 'bmag', 'gradpar_theta_pest', 'gradpar_phi', 'gbdrift', 'gbdrift0', 'cvdrift', 'cvdrift0', 'gds2', 'gds21', 'gds22', 'X', 'Y', 'Z', 'grad_s_X', 'grad_s_Y', 'grad_s_Z'] for j, variable in enumerate(variables): plt.subplot(nrows, ncols, j + 1) plt.plot(phi[0, 0, :], eval("results." + variable + '[0, 0, :]')) From fb235f05437238d872da4eeb47c695bc45f81029 Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Wed, 15 May 2024 08:53:20 -0400 Subject: [PATCH 101/131] Eliminated duplicated code in vmec_splines; fixed broken test for vmec_fieldlines --- src/simsopt/mhd/vmec_diagnostics.py | 48 ++++++++++++++--------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/simsopt/mhd/vmec_diagnostics.py b/src/simsopt/mhd/vmec_diagnostics.py index 357c945fa..5632d2dcf 100644 --- a/src/simsopt/mhd/vmec_diagnostics.py +++ b/src/simsopt/mhd/vmec_diagnostics.py @@ -720,6 +720,7 @@ def vmec_splines(vmec): """ vmec.run() results = Struct() + stellsym = not vmec.wout.lasym rmnc = [] zmns = [] lmns = [] @@ -748,17 +749,15 @@ def vmec_splines(vmec): rmns.append(InterpolatedUnivariateSpline(vmec.s_full_grid, vmec.wout.rmns[jmn, :])) zmnc.append(InterpolatedUnivariateSpline(vmec.s_full_grid, vmec.wout.zmnc[jmn, :])) lmnc.append(InterpolatedUnivariateSpline(vmec.s_half_grid, vmec.wout.lmnc[jmn, 1:])) - d_rmns_d_s.append(rmns[-1].derivative()) - d_zmnc_d_s.append(zmnc[-1].derivative()) - d_lmnc_d_s.append(lmnc[-1].derivative()) else: # if stellarator symmetric, set modes to zero - rmns.append(InterpolatedUnivariateSpline([0,1], [0, 0], k=1)) - zmnc.append(InterpolatedUnivariateSpline([0,1], [0, 0], k=1)) - lmnc.append(InterpolatedUnivariateSpline([0,1], [0, 0], k=1)) - d_rmns_d_s.append(rmns[-1].derivative()) - d_zmnc_d_s.append(zmnc[-1].derivative()) - d_lmnc_d_s.append(lmnc[-1].derivative()) + rmns.append(InterpolatedUnivariateSpline([0, 1], [0, 0], k=1)) + zmnc.append(InterpolatedUnivariateSpline([0, 1], [0, 0], k=1)) + lmnc.append(InterpolatedUnivariateSpline([0, 1], [0, 0], k=1)) + + d_rmns_d_s.append(rmns[-1].derivative()) + d_zmnc_d_s.append(zmnc[-1].derivative()) + d_lmnc_d_s.append(lmnc[-1].derivative()) # nyquist quantities gmnc = [] @@ -807,22 +806,19 @@ def vmec_splines(vmec): bsubsmnc.append(InterpolatedUnivariateSpline(vmec.s_full_grid, vmec.wout.bsubsmnc[jmn, :])) bsubumns.append(InterpolatedUnivariateSpline(vmec.s_half_grid, vmec.wout.bsubumns[jmn, 1:])) bsubvmns.append(InterpolatedUnivariateSpline(vmec.s_half_grid, vmec.wout.bsubvmns[jmn, 1:])) - d_bmns_d_s.append(bmns[-1].derivative()) - d_bsupumns_d_s.append(bsupumns[-1].derivative()) - d_bsupvmns_d_s.append(bsupvmns[-1].derivative()) else: # if stellarator symmetric, set modes to zero - gmns.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) - bmns.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) - bsupumns.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) - bsupvmns.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) - # Note that bsubsmns is on the full mesh, unlike the other components: - bsubsmnc.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) - bsubumns.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) - bsubvmns.append(InterpolatedUnivariateSpline([0,1],[0, 0], k=1)) - d_bmns_d_s.append(bmns[-1].derivative()) - d_bsupumns_d_s.append(bsupumns[-1].derivative()) - d_bsupvmns_d_s.append(bsupvmns[-1].derivative()) + gmns.append(InterpolatedUnivariateSpline([0, 1], [0, 0], k=1)) + bmns.append(InterpolatedUnivariateSpline([0, 1], [0, 0], k=1)) + bsupumns.append(InterpolatedUnivariateSpline([0, 1], [0, 0], k=1)) + bsupvmns.append(InterpolatedUnivariateSpline([0, 1], [0, 0], k=1)) + bsubsmnc.append(InterpolatedUnivariateSpline([0, 1], [0, 0], k=1)) + bsubumns.append(InterpolatedUnivariateSpline([0, 1], [0, 0], k=1)) + bsubvmns.append(InterpolatedUnivariateSpline([0, 1], [0, 0], k=1)) + + d_bmns_d_s.append(bmns[-1].derivative()) + d_bsupumns_d_s.append(bsupumns[-1].derivative()) + d_bsupvmns_d_s.append(bsupvmns[-1].derivative()) # Handle 1d profiles: @@ -839,7 +835,7 @@ def vmec_splines(vmec): variables = ['rmnc', 'zmns', 'lmns', 'd_rmnc_d_s', 'd_zmns_d_s', 'd_lmns_d_s', 'gmnc', 'bmnc', 'd_bmnc_d_s', 'bsupumnc', 'bsupvmnc', 'd_bsupumnc_d_s', 'd_bsupvmnc_d_s', - 'bsubsmns', 'bsubumnc', 'bsubvmnc'] + 'bsubsmns', 'bsubumnc', 'bsubvmnc', 'stellsym'] # stellarator non-symmetric variables = variables + \ ['rmns', 'zmnc', 'lmnc', 'd_rmns_d_s', 'd_zmnc_d_s', 'd_lmnc_d_s', @@ -950,6 +946,8 @@ def vmec_compute_geometry(vs, s, theta, phi, phi_center=0): # If given a Vmec object, convert it to vmec_splines: if isinstance(vs, Vmec): vs = vmec_splines(vs) + if not vs.stellsym: + raise NotImplementedError("vmec_compute_geometry() does not yet support non-stellarator-symmetric configurations.") # Make sure s is an array: try: @@ -1403,7 +1401,7 @@ def residual(theta_v, phi0, theta_p_target, jradius): variables = ['modB', 'B_sup_theta_pest', 'B_sup_phi', 'B_cross_grad_B_dot_grad_alpha', 'B_cross_grad_B_dot_grad_psi', 'B_cross_kappa_dot_grad_alpha', 'B_cross_kappa_dot_grad_psi', 'grad_alpha_dot_grad_alpha', 'grad_alpha_dot_grad_psi', 'grad_psi_dot_grad_psi', - 'bmag', 'gradpar_theta_pest', 'gradpar_phi', 'gbdrift', 'gbdrift0', 'cvdrift', 'cvdrift0', 'gds2', 'gds21', 'gds22', 'X', 'Y', 'Z', 'grad_s_X', 'grad_s_Y', 'grad_s_Z'] + 'bmag', 'gradpar_theta_pest', 'gradpar_phi', 'gbdrift', 'gbdrift0', 'cvdrift', 'cvdrift0', 'gds2', 'gds21', 'gds22'] for j, variable in enumerate(variables): plt.subplot(nrows, ncols, j + 1) plt.plot(phi[0, 0, :], eval("results." + variable + '[0, 0, :]')) From 2ee3b39d86ada165965b34fb0262a8ff5bccd5c5 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 15 May 2024 17:40:58 -0400 Subject: [PATCH 102/131] adding support for solver options, more changes for code coverage --- examples/2_Intermediate/boozerQA_ls_mpi.py | 2 +- src/simsopt/geo/boozersurface.py | 120 +++++++++++++++++---- src/simsopt/geo/surfaceobjectives.py | 20 ++-- src/simsopt/geo/surfacexyztensorfourier.py | 6 +- tests/geo/surface_test_helpers.py | 9 +- tests/geo/test_boozersurface.py | 15 +-- tests/geo/test_surface_objectives.py | 76 +++++++------ 7 files changed, 168 insertions(+), 80 deletions(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index 1299283ca..63f01b52e 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -73,7 +73,7 @@ boozer_surfaces = boozer_surfaces[:nsurfaces] ress = ress[:nsurfaces] for boozer_surface, res in zip(boozer_surfaces, ress): - boozer_surface.run_code('ls', res['iota'], res['G'], verbose=False) + boozer_surface.run_code(res['iota'], res['G']) mpi_surfaces = MPIOptimizable(surfaces, ["x"], comm) mpi_boozer_surfaces = MPIOptimizable(boozer_surfaces, ["res", "need_to_run_code"], comm) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 6bebde08f..32a447023 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -5,6 +5,7 @@ from .surfaceobjectives import boozer_surface_residual, boozer_surface_dexactresidual_dcoils_dcurrents_vjp, boozer_surface_dlsqgrad_dcoils_vjp from .._core.optimizable import Optimizable +from functools import partial __all__ = ['BoozerSurface'] @@ -23,10 +24,13 @@ class BoozerSurface(Optimizable): to a magnetic surface of the field and :math:`(\phi,\theta)` that parametrize the surface correspond to Boozer angles, and the constraints are satisfied. - The surface label can be area, volume, or toroidal flux. The label on the computed surface will be equal or close - to the user-provided ``targetlabel``, depending on how the label constraint is imposed. This - constrained least squares problem can be solved by scalarizing and adding the constraint as - an additional penalty term to the objective. This is done in + There are two approaches for computing these surfaces, called BoozerLS or BoozerExact surfaces. + + For BoozerLS surfaces, the objective mentioned above is minimized :math:`J(x)`, subject to + the surface label constraint. The surface label can be area, volume, or toroidal flux. The label + on the computed surface will be equal or close to the user-provided ``targetlabel``, depending on + how the label constraint is imposed. This constrained least squares problem can be solved by + scalarizing and adding the constraint as an additional penalty term to the objective. This is done in #. :mod:`minimize_boozer_penalty_constraints_LBFGS` #. :mod:`minimize_boozer_penalty_constraints_newton` @@ -39,49 +43,120 @@ class BoozerSurface(Optimizable): #. :mod:`minimize_boozer_exact_constraints_newton` where Newton is used to solve the first order necessary conditions for optimality. + + For BoozerExact surfaces, we try to find surfaces such that the residual :math:`\mathbf r(x)` + is exactly equal to zero at a specific set of colocation points on the surface. The colocation + points are chosen such that the number of colocation points is equal to the number of unknowns + in on the surface, so that the resulting nonlinear system of equations can be solved using + Newton's method. This is done in: + + #. :mod:`solve_residual_equation_exactly_newton` + + Note that there are specific requirements on the set of colocation points, i.e. + :mod:`surface.quadpoints_phi` and :mod:`surface.quadpoints_theta`, for stellarator + symmetric BoozerExact surfaces, see `solve_residual_equation_exactly_newton` + and `SurfaceXYZTensorFourier.get_stellsym_mask()` for more information. + + Alternatively, the user can use the default solvers in + + #. :mod:`run_code(iota_guess, G=G_guess)` + + for BoozerExact or BoozerLS surfaces. """ - def __init__(self, biotsavart, surface, label, targetlabel, constraint_weight=None): + def __init__(self, biotsavart, surface, label, targetlabel, constraint_weight=None, options=None): super().__init__(depends_on=[biotsavart]) + + from simsopt.geo import SurfaceXYZFourier, SurfaceXYZTensorFourier + if not isinstance(surface, SurfaceXYZTensorFourier) and not isinstance(surface, SurfaceXYZFourier): + raise Exception("The input surface must be a SurfaceXYZTensorFourier or SurfaceXYZFourier.") + self.biotsavart = biotsavart self.surface = surface self.label = label self.targetlabel = targetlabel self.constraint_weight = constraint_weight + self.boozer_type = 'ls' if constraint_weight else 'exact' self.need_to_run_code = True + + if options is None: + options={} + + # set the default options now + if 'verbose' not in options: + options['verbose'] = True + if 'G' not in options: + options['G'] = None + + # default solver options for the BoozerExact and BoozerLS solvers + if self.boozer_type == 'exact': + if 'newton_tol' not in options: + options['newton_tol'] = 1e-13 + if 'newton_maxiter' not in options: + options['newton_maxiter'] = 40 + elif self.boozer_type == 'ls': + if 'bfgs_tol' not in options: + options['bfgs_tol'] = 1e-10 + if 'newton_tol' not in options: + options['newton_tol'] = 1e-11 + if 'newton_maxiter' not in options: + options['newton_maxiter'] = 40 + if 'bfgs_maxiter' not in options: + options['bfgs_maxiter'] = 1500 + if 'limited_memory' not in options: + options['limited_memory'] = False + if 'weight_inv_modB' not in options: + options['weight_inv_modB'] = True + self.options = options def recompute_bell(self, parent=None): self.need_to_run_code = True - def run_code(self, boozer_type, iota, G=None, verbose=True): + def run_code(self, iota, G=None): """ Run the default solvers, i.e., run Newton's method directly if you are computing a BoozerExact surface, and run BFGS followed by Newton if you are computing a BoozerLS surface. + + Args: + boozer_type: either 'exact' or 'ls', to indicate whether a BoozerExact or a BoozerLS surface is to be computed. + iota: guess for value of rotational transform on the surface, + G: guess for value of G on surface, defaults to None. + options: dictionary of solver options. If keyword is not specified, then a default + value is used. Possible keywords are: + `verbose`: display convergence information + `newton_tol`: tolerance for newton solver + `bfgs_tol`: tolerance for bfgs solver + `newton_maxiter`: maximum number of iterations for Newton solver + `bfgs_maxiter`: maximum number of iterations for BFGS solver + `limited_memory`: True if L-BFGS solver is desired, False if the BFGS solver otherwise. + `weight_inv_modB`: for BoozerLS surfaces, weight the residual by modB so that it does not scale with coil currents. Defaults to True. """ if not self.need_to_run_code: return # BoozerExact default solver - if boozer_type == 'exact': - res = self.solve_residual_equation_exactly_newton(tol=1e-13, maxiter=40, iota=iota, G=G, verbose=verbose) + if self.boozer_type == 'exact': + res = self.solve_residual_equation_exactly_newton(iota=iota, G=G, tol=self.options['newton_tol'], maxiter=self.options['newton_maxiter'], verbose=self.options['verbose']) return res # BoozerLS default solver - elif boozer_type == 'ls': + elif self.boozer_type == 'ls': # you need a label constraint for a BoozerLS surface assert self.constraint_weight is not None - # first try BFGS. You could also try L-BFGS by setting limited_memory=True, which might be faster. However, BFGS appears + # first try BFGS. You could also try L-BFGS by setting limited_memory=True in the options dictionary, which might be faster. However, BFGS appears # to generally result in solutions closer to optimality. - res = self.minimize_boozer_penalty_constraints_LBFGS(tol=1e-10, maxiter=1500, constraint_weight=self.constraint_weight, iota=iota, G=G, verbose=verbose, limited_memory=False) + res = self.minimize_boozer_penalty_constraints_LBFGS(constraint_weight=self.constraint_weight, iota=iota, G=G, \ + tol=self.options['bfgs_tol'], maxiter=self.options['bfgs_maxiter'], verbose=self.options['verbose'], limited_memory=self.options['limited_memory'],\ + weight_inv_modB=self.options['weight_inv_modB']) iota, G = res['iota'], res['G'] ## polish off using Newton's method self.need_to_run_code = True - res = self.minimize_boozer_penalty_constraints_newton(tol=1e-11, maxiter=40, constraint_weight=self.constraint_weight, iota=iota, G=G, verbose=verbose) + res = self.minimize_boozer_penalty_constraints_newton(constraint_weight=self.constraint_weight, iota=iota, G=G, \ + verbose=self.options['verbose'], tol=self.options['newton_tol'], maxiter=self.options['newton_maxiter'],\ + weight_inv_modB=self.options['weight_inv_modB']) return res - else: - raise Exception(f"boozer_type not supported: {boozer_type}") def boozer_penalty_constraints(self, x, derivatives=0, constraint_weight=1., scalarize=True, optimize_G=False, weight_inv_modB=True): r""" @@ -340,7 +415,7 @@ def boozer_exact_constraints(self, xl, derivatives=0, optimize_G=True): dres[-1, :-2] = drz return res, dres - def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, constraint_weight=1., iota=0., G=None, vectorize=True, limited_memory=True, verbose=False): + def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, constraint_weight=1., iota=0., G=None, vectorize=True, limited_memory=True, weight_inv_modB=True, verbose=False): r""" This function tries to find the surface that approximately solves @@ -363,7 +438,7 @@ def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, cons x = np.concatenate((s.get_dofs(), [iota, G])) fun_name = self.boozer_penalty_constraints_vectorized if vectorize else self.boozer_penalty_constraints - fun = lambda x: fun_name(x, derivatives=1, constraint_weight=constraint_weight, optimize_G=G is not None) + fun = lambda x: fun_name(x, derivatives=1, constraint_weight=constraint_weight, optimize_G=G is not None, weight_inv_modB=weight_inv_modB) method = 'L-BFGS-B' if limited_memory else 'BFGS' options = {'maxiter': maxiter, 'gtol': tol} @@ -376,7 +451,7 @@ def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, cons options=options) resdict = { - "fun": res.fun, "gradient": res.jac, "iter": res.nit, "info": res, "success": res.success, "G": None, + "fun": res.fun, "gradient": res.jac, "iter": res.nit, "info": res, "success": res.success, "G": None, 'weight_inv_modB':weight_inv_modB, 'type':'ls' } if G is None: s.set_dofs(res.x[:-1]) @@ -397,7 +472,7 @@ def minimize_boozer_penalty_constraints_LBFGS(self, tol=1e-3, maxiter=1000, cons return resdict - def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, stab=0., vectorize=True, verbose=False): + def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, constraint_weight=1., iota=0., G=None, stab=0., vectorize=True, weight_inv_modB=True, verbose=False): """ This function does the same as :mod:`minimize_boozer_penalty_constraints_LBFGS`, but instead of LBFGS it uses Newton's method. @@ -413,7 +488,7 @@ def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, cons i = 0 fun_name = self.boozer_penalty_constraints_vectorized if vectorize else self.boozer_penalty_constraints - val, dval, d2val = fun_name(x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) + val, dval, d2val = fun_name(x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None, weight_inv_modB=weight_inv_modB) norm = np.linalg.norm(dval) while i < maxiter and norm > tol: @@ -422,17 +497,18 @@ def minimize_boozer_penalty_constraints_newton(self, tol=1e-12, maxiter=10, cons if norm < 1e-9: dx += np.linalg.solve(d2val, dval - d2val@dx) x = x - dx - val, dval, d2val = fun_name(x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None) + val, dval, d2val = fun_name(x, derivatives=2, constraint_weight=constraint_weight, optimize_G=G is not None, weight_inv_modB=weight_inv_modB) norm = np.linalg.norm(dval) i = i+1 r = self.boozer_penalty_constraints( - x, derivatives=0, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None) + x, derivatives=0, constraint_weight=constraint_weight, scalarize=False, optimize_G=G is not None, weight_inv_modB=weight_inv_modB) P, L, U = lu(d2val) res = { "residual": r, "jacobian": dval, "hessian": d2val, "iter": i, "success": norm <= tol, "G": None, - "PLU" : (P, L, U), "vjp": boozer_surface_dlsqgrad_dcoils_vjp, "type": "ls" + "PLU" : (P, L, U), "vjp": partial(boozer_surface_dlsqgrad_dcoils_vjp, weight_inv_modB=weight_inv_modB),\ + "type": "ls", "weight_inv_modB": weight_inv_modB } if G is None: s.set_dofs(x[:-1]) diff --git a/src/simsopt/geo/surfaceobjectives.py b/src/simsopt/geo/surfaceobjectives.py index d62ec574a..63a676675 100644 --- a/src/simsopt/geo/surfaceobjectives.py +++ b/src/simsopt/geo/surfaceobjectives.py @@ -659,7 +659,7 @@ def recompute_bell(self, parent=None): def compute(self): if self.boozer_surface.need_to_run_code: res = self.boozer_surface.res - res = self.boozer_surface.run_code(res['type'], res['iota'], G=res['G']) + res = self.boozer_surface.run_code(res['iota'], G=res['G']) surface = self.surface self._J = surface.major_radius() @@ -747,7 +747,7 @@ def dJ(self): def compute(self): if self.boozer_surface.need_to_run_code: res = self.boozer_surface.res - res = self.boozer_surface.run_code(res['type'], res['iota'], G=res['G']) + res = self.boozer_surface.run_code(res['iota'], G=res['G']) self.biotsavart.set_points(self.surface.gamma().reshape((-1, 3))) axis = self.axis @@ -905,13 +905,14 @@ def dJ(self): def recompute_bell(self, parent=None): self._J = None + self._dJ = None self._dJ_by_dcoefficients = None self._dJ_by_dcoilcurrents = None def compute(self): if self.boozer_surface.need_to_run_code: res = self.boozer_surface.res - res = self.boozer_surface.run_code(res['type'], res['iota'], G=res['G']) + res = self.boozer_surface.run_code(res['iota'], G=res['G']) self._J = self.boozer_surface.res['iota'] @@ -993,7 +994,7 @@ def recompute_bell(self, parent=None): def compute(self): if self.boozer_surface.need_to_run_code: res = self.boozer_surface.res - res = self.boozer_surface.run_code(res['type'], res['iota'], G=res['G']) + res = self.boozer_surface.run_code(res['iota'], G=res['G']) self.surface.set_dofs(self.in_surface.get_dofs()) self.biotsavart.set_points(self.surface.gamma().reshape((-1, 3))) @@ -1006,7 +1007,7 @@ def compute(self): surface = self.surface iota = self.boozer_surface.res['iota'] G = self.boozer_surface.res['G'] - r, J = boozer_surface_residual(surface, iota, G, self.biotsavart, derivatives=1, weight_inv_modB=True) + r, J = boozer_surface_residual(surface, iota, G, self.biotsavart, derivatives=1, weight_inv_modB=res['weight_inv_modB']) rtil = np.concatenate((r/np.sqrt(num_points), [np.sqrt(self.constraint_weight)*(self.boozer_surface.label.J()-self.boozer_surface.targetlabel)])) self._J = 0.5*np.sum(rtil**2) @@ -1035,10 +1036,11 @@ def dJ_by_dB(self): """ surface = self.surface + res = self.boozer_surface.res nphi = self.surface.quadpoints_phi.size ntheta = self.surface.quadpoints_theta.size num_points = 3 * nphi * ntheta - r, r_dB = boozer_surface_residual_dB(surface, self.boozer_surface.res['iota'], self.boozer_surface.res['G'], self.biotsavart, derivatives=0, weight_inv_modB=True) + r, r_dB = boozer_surface_residual_dB(surface, self.boozer_surface.res['iota'], self.boozer_surface.res['G'], self.biotsavart, derivatives=0, weight_inv_modB=res['weight_inv_modB']) r /= np.sqrt(num_points) r_dB /= np.sqrt(num_points) @@ -1086,7 +1088,7 @@ def boozer_surface_dexactresidual_dcoils_dcurrents_vjp(lm, booz_surf, iota, G): return lm_times_dres_dcoils+lm_times_dlabel_dcoils -def boozer_surface_dlsqgrad_dcoils_vjp(lm, booz_surf, iota, G): +def boozer_surface_dlsqgrad_dcoils_vjp(lm, booz_surf, iota, G, weight_inv_modB=True): """ For a given surface with points x on it, this function computes the vector-Jacobian product of \lm^T * dlsqgrad_dcoils, \lm^T * dlsqgrad_dcurrents: @@ -1096,14 +1098,14 @@ def boozer_surface_dlsqgrad_dcoils_vjp(lm, booz_surf, iota, G): G is known for exact boozer surfaces, so if G=None is passed, then that value is used instead. """ - + surface = booz_surf.surface biotsavart = booz_surf.biotsavart nphi = surface.quadpoints_phi.size ntheta = surface.quadpoints_theta.size num_points = 3 * nphi * ntheta # r, dr_dB, J, d2residual_dsurfacedB, d2residual_dsurfacedgradB - boozer = boozer_surface_residual_dB(surface, iota, G, biotsavart, derivatives=1, weight_inv_modB=True) + boozer = boozer_surface_residual_dB(surface, iota, G, biotsavart, derivatives=1, weight_inv_modB=weight_inv_modB) r = boozer[0]/np.sqrt(num_points) dr_dB = boozer[1].reshape((-1, 3, 3))/np.sqrt(num_points) dr_ds = boozer[2]/np.sqrt(num_points) diff --git a/src/simsopt/geo/surfacexyztensorfourier.py b/src/simsopt/geo/surfacexyztensorfourier.py index a6e2197aa..8244d2f04 100644 --- a/src/simsopt/geo/surfacexyztensorfourier.py +++ b/src/simsopt/geo/surfacexyztensorfourier.py @@ -159,10 +159,12 @@ def npsame(a, b): npsame(thetas, np.linspace(0, 1, 2*mpol+1, endpoint=False)): mask[:, mpol+1:] = False mask[ntor+1:, 0] = False - if npsame(phis, np.linspace(0, 1/self.nfp, 2*ntor+1, endpoint=False)) and \ + elif npsame(phis, np.linspace(0, 1/self.nfp, 2*ntor+1, endpoint=False)) and \ npsame(thetas, np.linspace(0, 0.5, mpol+1, endpoint=False)): mask[ntor+1:, 0] = False - if npsame(phis, np.linspace(0, 1/(2*self.nfp), ntor+1, endpoint=False)) and \ + elif npsame(phis, np.linspace(0, 1/(2*self.nfp), ntor+1, endpoint=False)) and \ npsame(thetas, np.linspace(0, 1, 2*mpol+1, endpoint=False)): mask[0, mpol+1:] = False + else: + raise Exception('Stellarator symmetric BoozerExact surfaces require a specific set of quadrature points on the surface. See the SurfaceXYZTensorFourier.get_stellsym_mask() docstring for more information.') return mask diff --git a/tests/geo/surface_test_helpers.py b/tests/geo/surface_test_helpers.py index 6b0d6205b..1a1a6b559 100644 --- a/tests/geo/surface_test_helpers.py +++ b/tests/geo/surface_test_helpers.py @@ -74,12 +74,15 @@ def get_exact_surface(surface_type='SurfaceXYZFourier'): return s -def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exact', optimize_G=True, converge=True, stellsym=True): +def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exact', optimize_G=True, converge=True, stellsym=True, weight_inv_modB=False): """ Returns a boozer surface that will be used in unit tests. """ assert label == "Volume" or label == "ToroidalFlux" or label == "Area" or label == "AspectRatio" + + if boozer_type == 'exact': + assert weight_inv_modB == False base_curves, base_currents, ma = get_ncsx_data() coils = coils_via_symmetries(base_curves, base_currents, 3, True) @@ -120,8 +123,8 @@ def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exac ## COMPUTE THE SURFACE cw = None if boozer_type == 'exact' else 100. - boozer_surface = BoozerSurface(bs, s, lab, lab_target, constraint_weight=cw) + boozer_surface = BoozerSurface(bs, s, lab, lab_target, constraint_weight=cw, options={'weight_inv_modB':weight_inv_modB}) if converge: - boozer_surface.run_code(boozer_type, iota, G=G0, verbose=True) + boozer_surface.run_code(iota, G=G0) return bs, boozer_surface diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 3e599451c..c90118345 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -359,26 +359,21 @@ def test_run_code(self): This unit test verifies that the run_code portion of the BoozerSurface class is working as expected """ bs, boozer_surface = get_boozer_surface(boozer_type='ls') - boozer_surface.run_code('ls', boozer_surface.res['iota'], G=boozer_surface.res['G'], verbose=False) + boozer_surface.run_code(boozer_surface.res['iota'], G=boozer_surface.res['G']) # this second time should not actually run - boozer_surface.run_code('ls', boozer_surface.res['iota'], G=boozer_surface.res['G'], verbose=False) + boozer_surface.run_code(boozer_surface.res['iota'], G=boozer_surface.res['G']) bs, boozer_surface = get_boozer_surface(boozer_type='exact') - boozer_surface.run_code('exact', boozer_surface.res['iota'], G=boozer_surface.res['G'], verbose=False) + boozer_surface.run_code(boozer_surface.res['iota'], G=boozer_surface.res['G']) # this second time should not actually run - boozer_surface.run_code('exact', boozer_surface.res['iota'], G=boozer_surface.res['G'], verbose=False) + boozer_surface.run_code(boozer_surface.res['iota'], G=boozer_surface.res['G']) boozer_surface.need_to_run_code=True # run without providing value of G - boozer_surface.run_code('exact', boozer_surface.res['iota'], verbose=True) + boozer_surface.run_code(boozer_surface.res['iota']) - boozer_surface.need_to_run_code=True - # this should raise an exception - with self.assertRaises(Exception): - boozer_surface.run_code('', boozer_surface.res['iota'], G=boozer_surface.res['G'], verbose=False) - def test_convergence_cpp_and_notcpp_same(self): """ This unit test verifies that that the cpp and not cpp implementations converge to diff --git a/tests/geo/test_surface_objectives.py b/tests/geo/test_surface_objectives.py index e146a7849..29dcf0511 100644 --- a/tests/geo/test_surface_objectives.py +++ b/tests/geo/test_surface_objectives.py @@ -262,15 +262,18 @@ def test_major_radius_derivative(self): for boozer_type in ['exact', 'ls']: for label in ["Volume", "ToroidalFlux"]: for optimize_G in [True, False]: - with self.subTest(label=label, boozer_type=boozer_type, optimize_G=optimize_G): - if boozer_type == 'ls' and label == 'ToroidalFlux': - continue - if boozer_type == 'exact' and optimize_G is False: - continue - self.subtest_major_radius_surface_derivative(label, boozer_type, optimize_G) - - def subtest_major_radius_surface_derivative(self, label, boozer_type, optimize_G): - bs, boozer_surface = get_boozer_surface(label=label, nphi=51, ntheta=51, boozer_type=boozer_type, optimize_G=optimize_G) + for weight_inv_modB in [True, False]: + with self.subTest(label=label, boozer_type=boozer_type, optimize_G=optimize_G): + if boozer_type == 'ls' and label == 'ToroidalFlux': + continue + if boozer_type == 'exact' and optimize_G is False: + continue + if boozer_type == 'exact' and weight_inv_modB: + continue + self.subtest_major_radius_surface_derivative(label, boozer_type, optimize_G, weight_inv_modB) + + def subtest_major_radius_surface_derivative(self, label, boozer_type, optimize_G, weight_inv_modB): + bs, boozer_surface = get_boozer_surface(label=label, nphi=51, ntheta=51, boozer_type=boozer_type, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) coeffs = bs.x mr = MajorRadius(boozer_surface) @@ -294,19 +297,22 @@ def test_iotas_derivative(self): for boozer_type in ['exact', 'ls']: for label in ["Volume", "ToroidalFlux"]: for optimize_G in [True, False]: - if boozer_type == 'ls' and label == 'ToroidalFlux': - continue - if boozer_type == 'exact' and optimize_G is False: - continue - with self.subTest(label=label, boozer_type=boozer_type, optimize_G=optimize_G): - self.subtest_iotas_derivative(label, boozer_type, optimize_G) - - def subtest_iotas_derivative(self, label, boozer_type, optimize_G): + for weight_inv_modB in [True, False]: + if boozer_type == 'ls' and label == 'ToroidalFlux': + continue + if boozer_type == 'exact' and optimize_G is False: + continue + if boozer_type == 'exact' and weight_inv_modB: + continue + with self.subTest(label=label, boozer_type=boozer_type, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB): + self.subtest_iotas_derivative(label, boozer_type, optimize_G, weight_inv_modB) + + def subtest_iotas_derivative(self, label, boozer_type, optimize_G, weight_inv_modB): """ Taylor test for derivative of surface rotational transform wrt coil parameters """ - bs, boozer_surface = get_boozer_surface(label=label, boozer_type=boozer_type, optimize_G=optimize_G) + bs, boozer_surface = get_boozer_surface(label=label, boozer_type=boozer_type, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) coeffs = bs.x io = Iotas(boozer_surface) @@ -329,17 +335,20 @@ def test_nonQSratio_derivative(self): """ for boozer_type in ['exact', 'ls']: for label in ["Volume", "ToroidalFlux"]: - for optimize_G in [True, False]: - if boozer_type == 'ls' and label == 'ToroidalFlux': - continue - if boozer_type == 'exact' and optimize_G is False: - continue - for axis in [False, True]: - with self.subTest(label=label, axis=axis, boozer_type=boozer_type, optimize_G=optimize_G): - self.subtest_nonQSratio_derivative(label, axis, boozer_type, optimize_G) - - def subtest_nonQSratio_derivative(self, label, axis, boozer_type, optimize_G): - bs, boozer_surface = get_boozer_surface(label=label, boozer_type=boozer_type, optimize_G=optimize_G) + for weight_inv_modB in [True, False]: + for optimize_G in [True, False]: + if boozer_type == 'ls' and label == 'ToroidalFlux': + continue + if boozer_type == 'exact' and optimize_G is False: + continue + if boozer_type == 'exact' and weight_inv_modB: + continue + for axis in [False, True]: + with self.subTest(label=label, axis=axis, boozer_type=boozer_type, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB): + self.subtest_nonQSratio_derivative(label, axis, boozer_type, optimize_G, weight_inv_modB) + + def subtest_nonQSratio_derivative(self, label, axis, boozer_type, optimize_G, weight_inv_modB): + bs, boozer_surface = get_boozer_surface(label=label, boozer_type=boozer_type, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) coeffs = bs.x io = NonQuasiSymmetricRatio(boozer_surface, bs, quasi_poloidal=axis) @@ -362,11 +371,12 @@ def test_boozerresidual_derivative(self): """ for label in ["Volume"]: for optimize_G in [True, False]: - with self.subTest(label=label, optimize_G=optimize_G): - self.subtest_boozerresidual_derivative(label, optimize_G) + for weight_inv_modB in [True, False]: + with self.subTest(label=label, optimize_G=optimize_G, weight_inv_modB=weight_inv_modB): + self.subtest_boozerresidual_derivative(label, optimize_G, weight_inv_modB) - def subtest_boozerresidual_derivative(self, label, optimize_G): - bs, boozer_surface = get_boozer_surface(label=label, boozer_type='ls', optimize_G=optimize_G) + def subtest_boozerresidual_derivative(self, label, optimize_G, weight_inv_modB): + bs, boozer_surface = get_boozer_surface(label=label, boozer_type='ls', optimize_G=optimize_G, weight_inv_modB=weight_inv_modB) coeffs = bs.x br = BoozerResidual(boozer_surface, bs) From 0401b8baf3c32a1b9226c24e2aad132b40dfe915 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Thu, 16 May 2024 11:06:51 -0400 Subject: [PATCH 103/131] changes for code coverage --- tests/geo/surface_test_helpers.py | 6 ++- tests/geo/test_boozersurface.py | 64 +++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/tests/geo/surface_test_helpers.py b/tests/geo/surface_test_helpers.py index 1a1a6b559..dfd981568 100644 --- a/tests/geo/surface_test_helpers.py +++ b/tests/geo/surface_test_helpers.py @@ -123,7 +123,11 @@ def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exac ## COMPUTE THE SURFACE cw = None if boozer_type == 'exact' else 100. - boozer_surface = BoozerSurface(bs, s, lab, lab_target, constraint_weight=cw, options={'weight_inv_modB':weight_inv_modB}) + if weight_inv_modB: + boozer_surface = BoozerSurface(bs, s, lab, lab_target, constraint_weight=cw) + else: + boozer_surface = BoozerSurface(bs, s, lab, lab_target, constraint_weight=cw, options={'weight_inv_modB':False}) + if converge: boozer_surface.run_code(iota, G=G0) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index c90118345..b307bd4af 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -4,6 +4,7 @@ from simsopt.field.coil import coils_via_symmetries from simsopt.geo.boozersurface import BoozerSurface from simsopt.field.biotsavart import BiotSavart +from simsopt.geo import SurfaceXYZTensorFourier, SurfaceRZFourier from simsopt.geo.surfaceobjectives import ToroidalFlux, Area from simsopt.configs.zoo import get_ncsx_data, get_hsx_data, get_giuliani_data from .surface_test_helpers import get_surface, get_exact_surface, get_boozer_surface @@ -522,6 +523,69 @@ def compute_differences(Ha, Hb): print(f'max err ({i1:03}, {j1:03}): {np.max(diff):.6e}, {Ha[i1, j1]:.6e}\nmax rel err ({i2:03}, {j2:03}): {np.max(rel_diff):.6e}, {Ha[i2,j2]:.6e}\n') compute_differences(H0, H1) + def test_boozer_surface_quadpoints(self): + """ + this unit test checks that the quadpoints mask for stellarator symmetric Boozer Surfaces are correctly initialized + """ + for idx in range(4): + with self.subTest(idx=idx): + self.subtest_boozer_surface_quadpoints(idx) + + def subtest_boozer_surface_quadpoints(self, idx): + mpol = 6 + ntor = 6 + nfp = 3 + + if idx == 0: + phis = np.linspace(0, 1/nfp, 2*ntor+1, endpoint=False) + thetas = np.linspace(0, 1, 2*mpol+1, endpoint=False) + mask_true = np.ones((phis.size, thetas.size), dtype=bool) + mask_true[:, mpol+1:] = False + mask_true[ntor+1:, 0] = False + elif idx == 1: + phis = np.linspace(0, 1/nfp, 2*ntor+1, endpoint=False) + thetas = np.linspace(0, 0.5, mpol+1, endpoint=False) + mask_true = np.ones((phis.size, thetas.size), dtype=bool) + mask_true[ntor+1:, 0] = False + elif idx == 2: + phis = np.linspace(0, 1/(2*nfp), ntor+1, endpoint=False) + thetas = np.linspace(0, 1, 2*mpol+1, endpoint=False) + mask_true = np.ones((phis.size, thetas.size), dtype=bool) + mask_true[0, mpol+1:] = False + elif idx == 3: + phis = np.linspace(0, 1., 2*ntor+1, endpoint=False) + thetas = np.linspace(0, 1., 2*mpol+1, endpoint=False) + + s = SurfaceXYZTensorFourier(mpol=mpol, ntor=ntor, stellsym=True, nfp=nfp, quadpoints_phi=phis, quadpoints_theta=thetas) + + if idx < 3: # the first three quadrature point sets should pass without issue. + mask = s.get_stellsym_mask() + assert np.all(mask == mask_true) + else: + with self.assertRaises(Exception): + mask = s.get_stellsym_mask() + + def test_boozer_surface_type_assert(self): + """ + this unit test checks that an exception is raised if a SurfaceRZFourier is passed to a BoozerSurface + """ + mpol = 6 + ntor = 6 + nfp = 3 + phis = np.linspace(0, 1/nfp, 2*ntor+1, endpoint=False) + thetas = np.linspace(0, 1, 2*mpol+1, endpoint=False) + s = SurfaceRZFourier(mpol=mpol, ntor=ntor, stellsym=True, nfp=nfp, quadpoints_phi=phis, quadpoints_theta=thetas) + + base_curves, base_currents, ma = get_ncsx_data() + coils = coils_via_symmetries(base_curves, base_currents, 3, True) + bs = BiotSavart(coils) + + lab = Area(s) + lab_target = 0.1 + + with self.assertRaises(Exception): + boozer_surface = BoozerSurface(bs, s, lab, lab_target) + if __name__ == "__main__": unittest.main() From 47666b52716a33fce2b132ee14fc402d9d1a3689 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Thu, 16 May 2024 11:09:41 -0400 Subject: [PATCH 104/131] linting fix --- tests/geo/test_boozersurface.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index b307bd4af..1cb199073 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -584,7 +584,7 @@ def test_boozer_surface_type_assert(self): lab_target = 0.1 with self.assertRaises(Exception): - boozer_surface = BoozerSurface(bs, s, lab, lab_target) + _ = BoozerSurface(bs, s, lab, lab_target) if __name__ == "__main__": From 8a5101e0443a577fdc0f31aee9629e622cd6362b Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Thu, 16 May 2024 11:21:34 -0400 Subject: [PATCH 105/131] fix to example --- examples/2_Intermediate/boozerQA_ls_mpi.py | 4 ++-- src/simsopt/geo/surfaceobjectives.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index 63f01b52e..6c0bf5ea0 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -61,7 +61,7 @@ os.makedirs(OUT_DIR, exist_ok=True) proc0_print("Running 2_Intermediate/boozerQA_ls_mpi.py") -proc0_print("================================") +proc0_print("=========================================") base_curves, base_currents, coils, curves, surfaces, boozer_surfaces, ress = load(IN_DIR + "ncsx_init.json") @@ -216,4 +216,4 @@ def callback(x): surface.to_vtk(OUT_DIR + f"surf_opt_{idx}") proc0_print("End of 2_Intermediate/boozerQA_ls.py") -proc0_print("================================") +proc0_print("====================================") diff --git a/src/simsopt/geo/surfaceobjectives.py b/src/simsopt/geo/surfaceobjectives.py index 63a676675..188b49d24 100644 --- a/src/simsopt/geo/surfaceobjectives.py +++ b/src/simsopt/geo/surfaceobjectives.py @@ -1007,7 +1007,7 @@ def compute(self): surface = self.surface iota = self.boozer_surface.res['iota'] G = self.boozer_surface.res['G'] - r, J = boozer_surface_residual(surface, iota, G, self.biotsavart, derivatives=1, weight_inv_modB=res['weight_inv_modB']) + r, J = boozer_surface_residual(surface, iota, G, self.biotsavart, derivatives=1, weight_inv_modB=self.boozer_surface.res['weight_inv_modB']) rtil = np.concatenate((r/np.sqrt(num_points), [np.sqrt(self.constraint_weight)*(self.boozer_surface.label.J()-self.boozer_surface.targetlabel)])) self._J = 0.5*np.sum(rtil**2) From 44e56c4ac4af5436a42582c569497068c345df00 Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Fri, 17 May 2024 09:25:20 -0400 Subject: [PATCH 106/131] Fix area -> aspect ratio in AspectRatio, tidy up boozerQA_ls_mpi.py and test_mpi_optimizable --- examples/2_Intermediate/boozerQA_ls_mpi.py | 59 ++++++++++++---------- src/simsopt/geo/surfaceobjectives.py | 4 +- tests/geo/surface_test_helpers.py | 2 +- tests/objectives/test_utilities.py | 8 +-- 4 files changed, 36 insertions(+), 37 deletions(-) diff --git a/examples/2_Intermediate/boozerQA_ls_mpi.py b/examples/2_Intermediate/boozerQA_ls_mpi.py index 6c0bf5ea0..f754fb170 100755 --- a/examples/2_Intermediate/boozerQA_ls_mpi.py +++ b/examples/2_Intermediate/boozerQA_ls_mpi.py @@ -1,26 +1,6 @@ -#!/usr/bin/env python3 -from simsopt.geo import curves_to_vtk, MajorRadius, CurveLength, CurveCurveDistance, NonQuasiSymmetricRatio, Iotas,\ - BoozerResidual, LpCurveCurvature, MeanSquaredCurvature, ArclengthVariation -from simsopt._core import load -from simsopt.objectives import MPIObjective, MPIOptimizable -from simsopt.field import BiotSavart -from simsopt.objectives import QuadraticPenalty -from scipy.optimize import minimize -from simsopt.util import proc0_print -import numpy as np -import os -try: - from mpi4py import MPI - comm = MPI.COMM_WORLD - rank = comm.rank - size = comm.size - -except ImportError: - comm = None - size = 1 - rank = 0 +#!/usr/bin/env python -""" +r""" This example optimizes the NCSX coils and currents for QA on potentially multiple surfaces using the BoozerLS approach. For a single surface, the objective is: @@ -52,9 +32,33 @@ and nsurfaces=Nranks=2, then the proper call is: mpirun -np 2 ./boozerQA_ls_mpi.py -More details on this work can be found at or doi:10.1063/5.0129716 arxiv:2210.03248. +More details on this work can be found at +A Giuliani et al, "Direct stellarator coil optimization for nested magnetic surfaces with precise +quasi-symmetry", Physics of Plasmas 30, 042511 (2023) doi:10.1063/5.0129716 +or arxiv:2210.03248. """ +import os +import numpy as np +from scipy.optimize import minimize +from simsopt.geo import curves_to_vtk, MajorRadius, CurveLength, CurveCurveDistance, NonQuasiSymmetricRatio, Iotas,\ + BoozerResidual, LpCurveCurvature, MeanSquaredCurvature, ArclengthVariation +from simsopt._core import load +from simsopt.objectives import MPIObjective, MPIOptimizable +from simsopt.field import BiotSavart +from simsopt.objectives import QuadraticPenalty +from simsopt.util import proc0_print, in_github_actions +try: + from mpi4py import MPI + comm = MPI.COMM_WORLD + rank = comm.rank + size = comm.size + +except ImportError: + comm = None + size = 1 + rank = 0 + # Directory for output IN_DIR = "./inputs/input_ncsx/" OUT_DIR = "./output/" @@ -67,7 +71,7 @@ # you can optimize for QA on up to 10 surfaces, by changing nsurfaces below. nsurfaces = 2 -assert nsurfaces <=10 +assert nsurfaces <= 10 surfaces = surfaces[:nsurfaces] boozer_surfaces = boozer_surfaces[:nsurfaces] @@ -205,8 +209,7 @@ def callback(x): ################################################################################ """) # Number of iterations to perform: -ci = "CI" in os.environ and os.environ['CI'].lower() in ['1', 'true'] -MAXITER = 50 if ci else 1e3 +MAXITER = 50 if in_github_actions else 1e3 res = minimize(fun, dofs, jac=True, method='BFGS', options={'maxiter': MAXITER}, tol=1e-15, callback=callback) if comm is None or rank == 0: @@ -215,5 +218,5 @@ def callback(x): if comm is None or rank == 0: surface.to_vtk(OUT_DIR + f"surf_opt_{idx}") -proc0_print("End of 2_Intermediate/boozerQA_ls.py") -proc0_print("====================================") +proc0_print("End of 2_Intermediate/boozerQA_ls_mpi.py") +proc0_print("========================================") diff --git a/src/simsopt/geo/surfaceobjectives.py b/src/simsopt/geo/surfaceobjectives.py index 188b49d24..e743af500 100644 --- a/src/simsopt/geo/surfaceobjectives.py +++ b/src/simsopt/geo/surfaceobjectives.py @@ -18,7 +18,7 @@ class AspectRatio(Optimizable): """ - Wrapper class for surface area label. + Wrapper class for surface aspect ratio. """ def __init__(self, surface, range=None, nphi=None, ntheta=None): @@ -46,7 +46,7 @@ def __init__(self, surface, range=None, nphi=None, ntheta=None): def J(self): """ - Compute the area of a surface. + Compute the aspect ratio of a surface. """ return self.surface.aspect_ratio() diff --git a/tests/geo/surface_test_helpers.py b/tests/geo/surface_test_helpers.py index dfd981568..3e9490ba6 100644 --- a/tests/geo/surface_test_helpers.py +++ b/tests/geo/surface_test_helpers.py @@ -79,7 +79,7 @@ def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exac Returns a boozer surface that will be used in unit tests. """ - assert label == "Volume" or label == "ToroidalFlux" or label == "Area" or label == "AspectRatio" + assert label in ["Volume", "ToroidalFlux", "Area", "AspectRatio"] if boozer_type == 'exact': assert weight_inv_modB == False diff --git a/tests/objectives/test_utilities.py b/tests/objectives/test_utilities.py index 2989523f9..1c6414dd2 100644 --- a/tests/objectives/test_utilities.py +++ b/tests/objectives/test_utilities.py @@ -63,10 +63,8 @@ def test_quadratic_penalty(self): with self.assertRaises(Exception): self.subtest_quadratic_penalty(curve, J.J()+0.1, 'NotInList') + @unittest.skipIf(MPI is None, "mpi4py not found") def test_mpi_objective(self): - if MPI is None: - print("skip test_mpi_objective") - return comm = MPI.COMM_WORLD c = self.create_curve() @@ -87,13 +85,11 @@ def test_mpi_objective(self): assert abs(Jmpi1.J() - sum(J.J() for J in Js)/n) < 1e-14 assert np.sum(np.abs(Jmpi1.dJ() - sum(J.dJ() for J in Js)/n)) < 1e-14 + @unittest.skipIf(MPI is None, "mpi4py not found") def test_mpi_optimizable(self): """ This test checks that the `x` attribute of the surfaces is correctly communicated across the ranks. """ - if MPI is None: - print("skip test_mpi_optimizable") - return comm = MPI.COMM_WORLD for size in [1, 2, 3, 4, 5]: From 6890be81b4341d0a997ba84194638e228fd50698 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 17 May 2024 16:17:58 -0400 Subject: [PATCH 107/131] clarifying documentation and fixing unit test --- src/simsopt/geo/boozersurface.py | 8 +++++--- tests/geo/surface_test_helpers.py | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/simsopt/geo/boozersurface.py b/src/simsopt/geo/boozersurface.py index 32a447023..ba0fc3a87 100644 --- a/src/simsopt/geo/boozersurface.py +++ b/src/simsopt/geo/boozersurface.py @@ -85,8 +85,6 @@ def __init__(self, biotsavart, surface, label, targetlabel, constraint_weight=No # set the default options now if 'verbose' not in options: options['verbose'] = True - if 'G' not in options: - options['G'] = None # default solver options for the BoozerExact and BoozerLS solvers if self.boozer_type == 'exact': @@ -120,7 +118,7 @@ def run_code(self, iota, G=None): Args: boozer_type: either 'exact' or 'ls', to indicate whether a BoozerExact or a BoozerLS surface is to be computed. iota: guess for value of rotational transform on the surface, - G: guess for value of G on surface, defaults to None. + G: guess for value of G on surface, defaults to None. Note that if None is used, then the coil currents must be fixed. options: dictionary of solver options. If keyword is not specified, then a default value is used. Possible keywords are: `verbose`: display convergence information @@ -134,6 +132,10 @@ def run_code(self, iota, G=None): if not self.need_to_run_code: return + # for coil optimizations, the gradient calculations of the objective assume that the coil currents are fixed when G is None. + if G is None: + assert np.all([c.current.dofs.all_fixed() for c in self.biotsavart.coils]) + # BoozerExact default solver if self.boozer_type == 'exact': res = self.solve_residual_equation_exactly_newton(iota=iota, G=G, tol=self.options['newton_tol'], maxiter=self.options['newton_maxiter'], verbose=self.options['verbose']) diff --git a/tests/geo/surface_test_helpers.py b/tests/geo/surface_test_helpers.py index 3e9490ba6..12d9fcfdd 100644 --- a/tests/geo/surface_test_helpers.py +++ b/tests/geo/surface_test_helpers.py @@ -90,6 +90,11 @@ def get_boozer_surface(label="Volume", nphi=None, ntheta=None, boozer_type='exac current_sum = sum(abs(c.current.get_value()) for c in coils) G0 = 2. * np.pi * current_sum * (4 * np.pi * 10**(-7) / (2 * np.pi)) if optimize_G else None + # currents need to be fixed if optimize_G is None + if optimize_G is False: + for c in bs.coils: + c.current.fix_all() + ## RESOLUTION DETAILS OF SURFACE ON WHICH WE OPTIMIZE FOR QA mpol = 6 if boozer_type == 'exact' else 3 ntor = 6 if boozer_type == 'exact' else 3 From 8be1c500dbf466eecaea36794521a1baba4e02f0 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 17 May 2024 17:36:26 -0400 Subject: [PATCH 108/131] edit to unit test --- tests/geo/test_boozersurface.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 1cb199073..461437cc1 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -365,15 +365,18 @@ def test_run_code(self): # this second time should not actually run boozer_surface.run_code(boozer_surface.res['iota'], G=boozer_surface.res['G']) + for c in bs.coils: + c.current.fix_all() + + boozer_surface.need_to_run_code=True + # run without providing value of G + boozer_surface.run_code(boozer_surface.res['iota']) + bs, boozer_surface = get_boozer_surface(boozer_type='exact') boozer_surface.run_code(boozer_surface.res['iota'], G=boozer_surface.res['G']) # this second time should not actually run boozer_surface.run_code(boozer_surface.res['iota'], G=boozer_surface.res['G']) - - boozer_surface.need_to_run_code=True - # run without providing value of G - boozer_surface.run_code(boozer_surface.res['iota']) def test_convergence_cpp_and_notcpp_same(self): """ From 11f176b7125cf4b097be899441ea6aea573c05c7 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Fri, 17 May 2024 17:59:28 -0400 Subject: [PATCH 109/131] another edit to unit test --- tests/geo/test_boozersurface.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/geo/test_boozersurface.py b/tests/geo/test_boozersurface.py index 461437cc1..badd5b34e 100644 --- a/tests/geo/test_boozersurface.py +++ b/tests/geo/test_boozersurface.py @@ -378,6 +378,10 @@ def test_run_code(self): # this second time should not actually run boozer_surface.run_code(boozer_surface.res['iota'], G=boozer_surface.res['G']) + # run the BoozerExact algorithm without a guess for G + boozer_surface.need_to_run_code = True + boozer_surface.solve_residual_equation_exactly_newton(iota=boozer_surface.res['iota']) + def test_convergence_cpp_and_notcpp_same(self): """ This unit test verifies that that the cpp and not cpp implementations converge to From da35cd0c0e80338ec36cf9f3219f002628db44b7 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 29 May 2024 15:45:42 -0400 Subject: [PATCH 110/131] cleaning up unit test --- tests/core/test_optimizable.py | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/tests/core/test_optimizable.py b/tests/core/test_optimizable.py index a035d7154..caa63a293 100755 --- a/tests/core/test_optimizable.py +++ b/tests/core/test_optimizable.py @@ -1365,18 +1365,6 @@ def dJ(self): return Derivative({self: self.local_full_x}) -class OptClassSharedDOFsQuadratic(Optimizable): - def __init__(self, **kwargs): - super().__init__(**kwargs) - - def J(self): - return sum(self.x) - - @derivative_dec - def dJ(self): - return Derivative({self: self.local_full_x}) - - class TestOptimizableSharedDOFs(unittest.TestCase): """ Test the DOFs sharing for the Optimizable classes @@ -1435,11 +1423,11 @@ def test_derivative(self): self.assertTrue((sum_obj.dJ(partials=True)(adder_shared_dofs) == sum_obj.dJ()).all()) def test_shared_dofs_as_derivative(self): - quadA = OptClassSharedDOFsQuadratic(x0=[1, 2, 3], names=["x", "y", "z"], + quadA = OptClassSharedDOFs(x0=[1, 2, 3], names=["x", "y", "z"], fixed=[False, False, True]) - quadA_shared_dofs = OptClassSharedDOFsQuadratic(dofs=quadA.dofs) + quadA_shared_dofs = OptClassSharedDOFs(dofs=quadA.dofs) - quadB = OptClassSharedDOFsQuadratic(x0=[np.pi, 1, 1.21], names=["xx", "yy", "zz"], + quadB = OptClassSharedDOFs(x0=[np.pi, 1, 1.21], names=["xx", "yy", "zz"], fixed=[False, False, True]) sum_quad = quadA + quadA_shared_dofs + quadB deriv = sum_quad.dJ(partials=True)(sum_quad, as_derivative=True) From b1350c2ebf7fc34f280268dc486e54cfda915956 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Wed, 29 May 2024 16:01:33 -0400 Subject: [PATCH 111/131] adding another unit test --- tests/core/test_optimizable.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/tests/core/test_optimizable.py b/tests/core/test_optimizable.py index caa63a293..222c94ec1 100755 --- a/tests/core/test_optimizable.py +++ b/tests/core/test_optimizable.py @@ -1422,19 +1422,34 @@ def test_derivative(self): self.assertTrue((sum_obj.dJ(partials=True)(adder_orig) == sum_obj.dJ()).all()) self.assertTrue((sum_obj.dJ(partials=True)(adder_shared_dofs) == sum_obj.dJ()).all()) - def test_shared_dofs_as_derivative(self): - quadA = OptClassSharedDOFs(x0=[1, 2, 3], names=["x", "y", "z"], + def test_as_derivative1(self): + # this test checks that you can restrict the Derivative dictionary + # to the proper subset of Optimizables when as_derivative=True + + optA = OptClassSharedDOFs(x0=[1, 2, 3], names=["x", "y", "z"], fixed=[False, False, True]) - quadA_shared_dofs = OptClassSharedDOFs(dofs=quadA.dofs) + optA_shared_dofs = OptClassSharedDOFs(dofs=optA.dofs) - quadB = OptClassSharedDOFs(x0=[np.pi, 1, 1.21], names=["xx", "yy", "zz"], + optB = OptClassSharedDOFs(x0=[np.pi, 1, 1.21], names=["xx", "yy", "zz"], fixed=[False, False, True]) - sum_quad = quadA + quadA_shared_dofs + quadB - deriv = sum_quad.dJ(partials=True)(sum_quad, as_derivative=True) + sum_opt = optA + optA_shared_dofs + optB + deriv = sum_opt.dJ(partials=True)(sum_opt, as_derivative=True) - np.testing.assert_allclose(deriv(quadA), quadA.dJ()*2, atol=1e-14) - np.testing.assert_allclose(deriv(quadA_shared_dofs), quadA.dJ()*2, atol=1e-14) - np.testing.assert_allclose(deriv(sum_quad), np.concatenate((quadA.dJ()*2, quadB.dJ())), atol=1e-14) + # restrict to optA + np.testing.assert_allclose(deriv(optA), optA.dJ()*2, atol=1e-14) + # restrict to optA_shared_dofs + np.testing.assert_allclose(deriv(optA_shared_dofs), optA.dJ()*2, atol=1e-14) + # restrict to sum_opt + np.testing.assert_allclose(deriv(sum_opt), np.concatenate((optA.dJ()*2, optB.dJ())), atol=1e-14) + + def test_as_derivative2(self): + # this test checks that when you sum a Derivative dictionary generated using as_derivative=True, + # to another that things work as expected when some DOFs are fixed. + + opt = OptClassSharedDOFs(x0=[1, 2, 3], names=["x", "y", "z"], + fixed=[False, False, True]) + deriv = opt.dJ(partials=True)(opt, as_derivative=True) + opt.dJ(partials=True) + np.testing.assert_allclose(deriv(opt), opt.dJ()*2, atol=1e-14) def test_load_save(self): import tempfile From 0b2ef408f09e27a24ff0cbecd2cc71276c74f53d Mon Sep 17 00:00:00 2001 From: daringli Date: Wed, 29 May 2024 22:06:52 +0200 Subject: [PATCH 112/131] Added a file not found exception handling. --- src/simsopt/mhd/vmec.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/simsopt/mhd/vmec.py b/src/simsopt/mhd/vmec.py index beef7c96e..822815fdb 100644 --- a/src/simsopt/mhd/vmec.py +++ b/src/simsopt/mhd/vmec.py @@ -755,7 +755,11 @@ def run(self): # Delete the previous output file, if desired: for filename in self.files_to_delete: - os.remove(filename) + try: + os.remove(filename) + except FileNotFoundError: + logger.debug('Tried to delete the file {filename} but it was not found') + self.files_to_delete = [] # Record the latest output file to delete if we run again: From a715c0f41579efc982aaf8b4a94fb352ebc199cc Mon Sep 17 00:00:00 2001 From: daringli <731405+daringli@users.noreply.github.com> Date: Wed, 29 May 2024 21:38:33 -0400 Subject: [PATCH 113/131] Fixed missing f in the f-string Thanks to VascoSch92! --- src/simsopt/mhd/vmec.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simsopt/mhd/vmec.py b/src/simsopt/mhd/vmec.py index a2e0ce4f9..507c8c9a7 100644 --- a/src/simsopt/mhd/vmec.py +++ b/src/simsopt/mhd/vmec.py @@ -755,7 +755,7 @@ def run(self): try: os.remove(filename) except FileNotFoundError: - logger.debug('Tried to delete the file {filename} but it was not found') + logger.debug(f"Tried to delete the file {filename} but it was not found") self.files_to_delete = [] From 903914142de065c70aa7a86c976d8c29aaa2ea25 Mon Sep 17 00:00:00 2001 From: Andrew Giuliani Date: Thu, 30 May 2024 11:30:53 -0400 Subject: [PATCH 114/131] cleaning up docstring --- src/simsopt/_core/derivative.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/simsopt/_core/derivative.py b/src/simsopt/_core/derivative.py index 01b3baca7..6b62d848a 100644 --- a/src/simsopt/_core/derivative.py +++ b/src/simsopt/_core/derivative.py @@ -173,9 +173,12 @@ def __call__(self, optim, as_derivative=False): Args: optim: An Optimizable object - as_derivative: if True return as a Derivative object, else return as an numpy array. The keys + as_derivative: if True return as a Derivative object. The keys of the returned Derivative dictionary can include `optim`, the ancestors of `optim` - or Optimizables that share DOFs with ancestors of `optim`. + or Optimizables that share DOFs with ancestors of `optim`. The values are numpy arrays + corresponding to the derivatives with respect to all degrees of freedom, both free and fixed. + If False, return as a numpy array. The entries of the array correspond only to free + DOFs, and fixed ones are removed out. """ from .optimizable import Optimizable # Import here to avoid circular import assert isinstance(optim, Optimizable) @@ -186,11 +189,9 @@ def __call__(self, optim, as_derivative=False): for k in optim.unique_dof_lineage: for opt in k.dofs.dep_opts(): - # the next if-statament is there to avoid the dictionary from accumulating # empty values e.g. if there are no local DOFs to opt, then self.data[opt] # returns np.array([]). - if opt.local_full_dof_size > 0: derivs.append(self.data[opt]) keys.append(opt) From 389389c9f8c6ac53360785c8286f8361d20a992b Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Sun, 2 Jun 2024 06:47:11 -0400 Subject: [PATCH 115/131] Implemented L_{grad B} and tests for it --- src/simsopt/mhd/vmec_diagnostics.py | 158 +++++++++++++++++- tests/mhd/test_vmec_diagnostics.py | 136 +++++++++++++++ tests/test_files/input.purely_toroidal_field | 37 ++++ .../wout_purely_toroidal_field_reference.nc | Bin 0 -> 124068 bytes 4 files changed, 325 insertions(+), 6 deletions(-) create mode 100644 tests/test_files/input.purely_toroidal_field create mode 100644 tests/test_files/wout_purely_toroidal_field_reference.nc diff --git a/src/simsopt/mhd/vmec_diagnostics.py b/src/simsopt/mhd/vmec_diagnostics.py index 5632d2dcf..4f4e640b1 100644 --- a/src/simsopt/mhd/vmec_diagnostics.py +++ b/src/simsopt/mhd/vmec_diagnostics.py @@ -899,6 +899,7 @@ def vmec_compute_geometry(vs, s, theta, phi, phi_center=0): - ``grad_alpha_dot_grad_alpha``: :math:`|\nabla\alpha|^2 = \nabla\alpha\cdot\nabla\alpha`. - ``grad_alpha_dot_grad_psi``: :math:`\nabla\alpha\cdot\nabla\psi`. - ``grad_psi_dot_grad_psi``: :math:`|\nabla\psi|^2 = \nabla\psi\cdot\nabla\psi`. + - ``L_grad_B``: The scale length of the magnetic field, from Kappel et al, PPCF 66 025018 (2024). - ``iota``: The rotational transform :math:`\iota`. This array has shape ``(ns,)``. - ``shat``: The magnetic shear :math:`\hat s= (x/q) (d q / d x)` where :math:`x = \mathrm{Aminor_p} \, \sqrt{s}` and :math:`q=1/\iota`. This array has shape ``(ns,)``. @@ -1027,6 +1028,8 @@ def vmec_compute_geometry(vs, s, theta, phi, phi_center=0): bsubsmns = np.zeros((ns, mnmax_nyq)) bsubumnc = np.zeros((ns, mnmax_nyq)) bsubvmnc = np.zeros((ns, mnmax_nyq)) + d_bsupumnc_d_s = np.zeros((ns, mnmax_nyq)) + d_bsupvmnc_d_s = np.zeros((ns, mnmax_nyq)) for jmn in range(mnmax_nyq): gmnc[:, jmn] = vs.gmnc[jmn](s) bmnc[:, jmn] = vs.bmnc[jmn](s) @@ -1036,6 +1039,8 @@ def vmec_compute_geometry(vs, s, theta, phi, phi_center=0): bsubsmns[:, jmn] = vs.bsubsmns[jmn](s) bsubumnc[:, jmn] = vs.bsubumnc[jmn](s) bsubvmnc[:, jmn] = vs.bsubvmnc[jmn](s) + d_bsupumnc_d_s[:, jmn] = vs.d_bsupumnc_d_s[jmn](s) + d_bsupvmnc_d_s[:, jmn] = vs.d_bsupvmnc_d_s[jmn](s) # Now that we know theta_vmec, compute all the geometric quantities angle = xm[:, None, None, None] * theta_vmec[None, :, :, :] - xn[:, None, None, None] * phi[None, :, :, :] @@ -1043,25 +1048,40 @@ def vmec_compute_geometry(vs, s, theta, phi, phi_center=0): sinangle = np.sin(angle) mcosangle = xm[:, None, None, None] * cosangle ncosangle = xn[:, None, None, None] * cosangle + mncosangle = xm[:, None, None, None] * xn[:, None, None, None] * cosangle + m2cosangle = xm[:, None, None, None]**2 * cosangle + n2cosangle = xn[:, None, None, None]**2 * cosangle msinangle = xm[:, None, None, None] * sinangle nsinangle = xn[:, None, None, None] * sinangle + mnsinangle = xm[:, None, None, None] * xn[:, None, None, None] * sinangle + m2sinangle = xm[:, None, None, None]**2 * sinangle + n2sinangle = xn[:, None, None, None]**2 * sinangle # Order of indices in cosangle and sinangle: mn, s, theta, phi # Order of indices in rmnc, bmnc, etc: s, mn R = np.einsum('ij,jikl->ikl', rmnc, cosangle) d_R_d_s = np.einsum('ij,jikl->ikl', d_rmnc_d_s, cosangle) - d_R_d_theta_vmec = -np.einsum('ij,jikl->ikl', rmnc, msinangle) + d_R_d_theta_vmec = np.einsum('ij,jikl->ikl', -rmnc, msinangle) d_R_d_phi = np.einsum('ij,jikl->ikl', rmnc, nsinangle) - + d2_R_d_phi2 = np.einsum('ij,jikl->ikl', -rmnc, n2cosangle) + d2_R_d_theta_vmec2 = np.einsum('ij,jikl->ikl', -rmnc, m2cosangle) + d2_R_d_theta_vmec_d_phi = np.einsum('ij,jikl->ikl', rmnc, mncosangle) + d2_R_d_s_d_theta_vmec = np.einsum('ij,jikl->ikl', -d_rmnc_d_s, msinangle) + d2_R_d_s_d_phi = np.einsum('ij,jikl->ikl', d_rmnc_d_s, nsinangle) Z = np.einsum('ij,jikl->ikl', zmns, sinangle) d_Z_d_s = np.einsum('ij,jikl->ikl', d_zmns_d_s, sinangle) d_Z_d_theta_vmec = np.einsum('ij,jikl->ikl', zmns, mcosangle) - d_Z_d_phi = -np.einsum('ij,jikl->ikl', zmns, ncosangle) + d_Z_d_phi = np.einsum('ij,jikl->ikl', -zmns, ncosangle) + d2_Z_d_theta_vmec2 = np.einsum('ij,jikl->ikl', -zmns, m2sinangle) + d2_Z_d_phi2 = np.einsum('ij,jikl->ikl', -zmns, n2sinangle) + d2_Z_d_theta_vmec_d_phi = np.einsum('ij,jikl->ikl', zmns, mnsinangle) + d2_Z_d_s_d_theta_vmec = np.einsum('ij,jikl->ikl', d_zmns_d_s, mcosangle) + d2_Z_d_s_d_phi = np.einsum('ij,jikl->ikl', -d_zmns_d_s, ncosangle) lambd = np.einsum('ij,jikl->ikl', lmns, sinangle) d_lambda_d_s = np.einsum('ij,jikl->ikl', d_lmns_d_s, sinangle) d_lambda_d_theta_vmec = np.einsum('ij,jikl->ikl', lmns, mcosangle) - d_lambda_d_phi = -np.einsum('ij,jikl->ikl', lmns, ncosangle) + d_lambda_d_phi = np.einsum('ij,jikl->ikl', -lmns, ncosangle) theta_pest = theta_vmec + lambd # Now handle the Nyquist quantities: @@ -1076,7 +1096,7 @@ def vmec_compute_geometry(vs, s, theta, phi, phi_center=0): sqrt_g_vmec = np.einsum('ij,jikl->ikl', gmnc, cosangle) modB = np.einsum('ij,jikl->ikl', bmnc, cosangle) d_B_d_s = np.einsum('ij,jikl->ikl', d_bmnc_d_s, cosangle) - d_B_d_theta_vmec = -np.einsum('ij,jikl->ikl', bmnc, msinangle) + d_B_d_theta_vmec = np.einsum('ij,jikl->ikl', -bmnc, msinangle) d_B_d_phi = np.einsum('ij,jikl->ikl', bmnc, nsinangle) B_sup_theta_vmec = np.einsum('ij,jikl->ikl', bsupumnc, cosangle) @@ -1085,6 +1105,12 @@ def vmec_compute_geometry(vs, s, theta, phi, phi_center=0): B_sub_theta_vmec = np.einsum('ij,jikl->ikl', bsubumnc, cosangle) B_sub_phi = np.einsum('ij,jikl->ikl', bsubvmnc, cosangle) B_sup_theta_pest = iota[:, None, None] * B_sup_phi + d_B_sup_phi_d_theta_vmec = np.einsum('ij,jikl->ikl', -bsupvmnc, msinangle) + d_B_sup_phi_d_phi = np.einsum('ij,jikl->ikl', bsupvmnc, nsinangle) + d_B_sup_theta_vmec_d_theta_vmec = np.einsum('ij,jikl->ikl', -bsupumnc, msinangle) + d_B_sup_theta_vmec_d_phi = np.einsum('ij,jikl->ikl', bsupumnc, nsinangle) + d_B_sup_theta_vmec_d_s = np.einsum('ij,jikl->ikl', d_bsupumnc_d_s, cosangle) + d_B_sup_phi_d_s = np.einsum('ij,jikl->ikl', d_bsupvmnc_d_s, cosangle) sqrt_g_vmec_alt = R * (d_Z_d_s * d_R_d_theta_vmec - d_R_d_s * d_Z_d_theta_vmec) @@ -1223,6 +1249,119 @@ def vmec_compute_geometry(vs, s, theta, phi, phi_center=0): cvdrift0 = gbdrift0 + # Quantities related to the grad \vec{B} tensor. + # See Appendix C of Kappel et al, "The Magnetic Gradient Scale Length + # Explains Why Certain Plasmas Require Close External Magnetic Coils" + # Plasma Phys. Control. Fusion 66 (2024) 025018 + # https://doi.org/10.1088/1361-6587/ad1a3e + + d_B_X_d_s = ( + d_B_sup_theta_vmec_d_s * d_R_d_theta_vmec * cosphi + + B_sup_theta_vmec * d2_R_d_s_d_theta_vmec * cosphi + + d_B_sup_phi_d_s * d_R_d_phi * cosphi + + B_sup_phi * d2_R_d_s_d_phi * cosphi + - d_B_sup_phi_d_s * R * sinphi + - B_sup_phi * d_R_d_s * sinphi + ) + + d_B_X_d_theta = ( + d_B_sup_theta_vmec_d_theta_vmec * d_R_d_theta_vmec * cosphi + + B_sup_theta_vmec * d2_R_d_theta_vmec2 * cosphi + + d_B_sup_phi_d_theta_vmec * d_R_d_phi * cosphi + + B_sup_phi * d2_R_d_theta_vmec_d_phi * cosphi + - d_B_sup_phi_d_theta_vmec * R * sinphi + - B_sup_phi * d_R_d_theta_vmec * sinphi + ) + + d_B_X_d_phi = ( + d_B_sup_theta_vmec_d_phi * d_R_d_theta_vmec * cosphi + + B_sup_theta_vmec * d2_R_d_theta_vmec_d_phi * cosphi + - B_sup_theta_vmec * d_R_d_theta_vmec * sinphi + + d_B_sup_phi_d_phi * d_R_d_phi * cosphi + + B_sup_phi * d2_R_d_phi2 * cosphi + - B_sup_phi * d_R_d_phi * sinphi + - d_B_sup_phi_d_phi * R * sinphi + - B_sup_phi * d_R_d_phi * sinphi + - B_sup_phi * R * cosphi + ) + + d_B_Y_d_s = ( + d_B_sup_theta_vmec_d_s * d_R_d_theta_vmec * sinphi + + B_sup_theta_vmec * d2_R_d_s_d_theta_vmec * sinphi + + d_B_sup_phi_d_s * d_R_d_phi * sinphi + + B_sup_phi * d2_R_d_s_d_phi * sinphi + + d_B_sup_phi_d_s * R * cosphi + + B_sup_phi * d_R_d_s * cosphi + ) + + d_B_Y_d_theta = ( + d_B_sup_theta_vmec_d_theta_vmec * d_R_d_theta_vmec * sinphi + + B_sup_theta_vmec * d2_R_d_theta_vmec2 * sinphi + + d_B_sup_phi_d_theta_vmec * d_R_d_phi * sinphi + + B_sup_phi * d2_R_d_theta_vmec_d_phi * sinphi + + d_B_sup_phi_d_theta_vmec * R * cosphi + + B_sup_phi * d_R_d_theta_vmec * cosphi + ) + + d_B_Y_d_phi = ( + d_B_sup_theta_vmec_d_phi * d_R_d_theta_vmec * sinphi + + B_sup_theta_vmec * d2_R_d_theta_vmec_d_phi * sinphi + + B_sup_theta_vmec * d_R_d_theta_vmec * cosphi + + d_B_sup_phi_d_phi * d_R_d_phi * sinphi + + B_sup_phi * d2_R_d_phi2 * sinphi + + B_sup_phi * d_R_d_phi * cosphi + + d_B_sup_phi_d_phi * R * cosphi + + B_sup_phi * d_R_d_phi * cosphi + - B_sup_phi * R * sinphi + ) + + d_B_Z_d_s = ( + d_B_sup_theta_vmec_d_s * d_Z_d_theta_vmec + + B_sup_theta_vmec * d2_Z_d_s_d_theta_vmec + + d_B_sup_phi_d_s * d_Z_d_phi + + B_sup_phi * d2_Z_d_s_d_phi + ) + + d_B_Z_d_theta = ( + d_B_sup_theta_vmec_d_theta_vmec * d_Z_d_theta_vmec + + B_sup_theta_vmec * d2_Z_d_theta_vmec2 + + d_B_sup_phi_d_theta_vmec * d_Z_d_phi + + B_sup_phi * d2_Z_d_theta_vmec_d_phi + ) + + d_B_Z_d_phi = ( + d_B_sup_theta_vmec_d_phi * d_Z_d_theta_vmec + + B_sup_theta_vmec * d2_Z_d_theta_vmec_d_phi + + d_B_sup_phi_d_phi * d_Z_d_phi + + B_sup_phi * d2_Z_d_phi2 + ) + + grad_B__XX = d_B_X_d_s * grad_s_X + d_B_X_d_theta * grad_theta_vmec_X + d_B_X_d_phi * grad_phi_X + grad_B__XY = d_B_X_d_s * grad_s_Y + d_B_X_d_theta * grad_theta_vmec_Y + d_B_X_d_phi * grad_phi_Y + grad_B__XZ = d_B_X_d_s * grad_s_Z + d_B_X_d_theta * grad_theta_vmec_Z + d_B_X_d_phi * grad_phi_Z + + grad_B__YX = d_B_Y_d_s * grad_s_X + d_B_Y_d_theta * grad_theta_vmec_X + d_B_Y_d_phi * grad_phi_X + grad_B__YY = d_B_Y_d_s * grad_s_Y + d_B_Y_d_theta * grad_theta_vmec_Y + d_B_Y_d_phi * grad_phi_Y + grad_B__YZ = d_B_Y_d_s * grad_s_Z + d_B_Y_d_theta * grad_theta_vmec_Z + d_B_Y_d_phi * grad_phi_Z + + grad_B__ZX = d_B_Z_d_s * grad_s_X + d_B_Z_d_theta * grad_theta_vmec_X + d_B_Z_d_phi * grad_phi_X + grad_B__ZY = d_B_Z_d_s * grad_s_Y + d_B_Z_d_theta * grad_theta_vmec_Y + d_B_Z_d_phi * grad_phi_Y + grad_B__ZZ = d_B_Z_d_s * grad_s_Z + d_B_Z_d_theta * grad_theta_vmec_Z + d_B_Z_d_phi * grad_phi_Z + + grad_B_double_dot_grad_B = ( + grad_B__XX * grad_B__XX + + grad_B__XY * grad_B__XY + + grad_B__XZ * grad_B__XZ + + grad_B__YX * grad_B__YX + + grad_B__YY * grad_B__YY + + grad_B__YZ * grad_B__YZ + + grad_B__ZX * grad_B__ZX + + grad_B__ZY * grad_B__ZY + + grad_B__ZZ * grad_B__ZZ + ) + norm_grad_B = np.sqrt(grad_B_double_dot_grad_B) + L_grad_B = modB * np.sqrt(2 / grad_B_double_dot_grad_B) + # Package results into a structure to return: results = Struct() variables = ['ns', 'ntheta', 'nphi', 's', 'iota', 'd_iota_d_s', 'd_pressure_d_s', 'shat', @@ -1230,6 +1369,10 @@ def vmec_compute_geometry(vs, s, theta, phi, phi_center=0): 'd_lambda_d_s', 'd_lambda_d_theta_vmec', 'd_lambda_d_phi', 'sqrt_g_vmec', 'sqrt_g_vmec_alt', 'modB', 'd_B_d_s', 'd_B_d_theta_vmec', 'd_B_d_phi', 'B_sup_theta_vmec', 'B_sup_theta_pest', 'B_sup_phi', 'B_sub_s', 'B_sub_theta_vmec', 'B_sub_phi', 'edge_toroidal_flux_over_2pi', 'sinphi', 'cosphi', + 'd2_R_d_phi2', 'd2_R_d_theta_vmec2', 'd2_R_d_theta_vmec_d_phi', 'd2_R_d_s_d_theta_vmec', 'd2_R_d_s_d_phi', + 'd2_Z_d_theta_vmec2', 'd2_Z_d_phi2', 'd2_Z_d_theta_vmec_d_phi', 'd2_Z_d_s_d_theta_vmec', 'd2_Z_d_s_d_phi', + 'd_B_sup_phi_d_theta_vmec', 'd_B_sup_phi_d_phi', 'd_B_sup_theta_vmec_d_theta_vmec', + 'd_B_sup_theta_vmec_d_phi', 'd_B_sup_theta_vmec_d_s', 'd_B_sup_phi_d_s', 'R', 'd_R_d_s', 'd_R_d_theta_vmec', 'd_R_d_phi', 'X', 'Y', 'Z', 'd_Z_d_s', 'd_Z_d_theta_vmec', 'd_Z_d_phi', 'd_X_d_theta_vmec', 'd_X_d_phi', 'd_X_d_s', 'd_Y_d_theta_vmec', 'd_Y_d_phi', 'd_Y_d_s', 'grad_s_X', 'grad_s_Y', 'grad_s_Z', 'grad_theta_vmec_X', 'grad_theta_vmec_Y', 'grad_theta_vmec_Z', @@ -1241,7 +1384,10 @@ def vmec_compute_geometry(vs, s, theta, phi, phi_center=0): 'B_cross_grad_B_dot_grad_psi', 'B_cross_kappa_dot_grad_psi', 'B_cross_kappa_dot_grad_alpha', 'grad_alpha_dot_grad_alpha', 'grad_alpha_dot_grad_psi', 'grad_psi_dot_grad_psi', 'L_reference', 'B_reference', 'toroidal_flux_sign', - 'bmag', 'gradpar_theta_pest', 'gradpar_phi', 'gds2', 'gds21', 'gds22', 'gbdrift', 'gbdrift0', 'cvdrift', 'cvdrift0'] + 'bmag', 'gradpar_theta_pest', 'gradpar_phi', 'gds2', 'gds21', 'gds22', 'gbdrift', 'gbdrift0', 'cvdrift', 'cvdrift0', + 'grad_B__XX', 'grad_B__XY', 'grad_B__XZ', 'grad_B__YX', 'grad_B__YY', 'grad_B__YZ', 'grad_B__ZX', 'grad_B__ZY', 'grad_B__ZZ', + 'grad_B_double_dot_grad_B', 'norm_grad_B', 'L_grad_B', + ] for v in variables: results.__setattr__(v, eval(v)) diff --git a/tests/mhd/test_vmec_diagnostics.py b/tests/mhd/test_vmec_diagnostics.py index 82a5c545e..a65400e0b 100755 --- a/tests/mhd/test_vmec_diagnostics.py +++ b/tests/mhd/test_vmec_diagnostics.py @@ -490,6 +490,142 @@ def test_compare_to_desc(self): np.testing.assert_allclose(simsopt_data.grad_psi_dot_grad_psi, desc_data, rtol=0.005, atol=0.0005) + def test_derivatives(self): + """ + Compare some of the derivatives to finite differences. + """ + vmec = Vmec(os.path.join(TEST_DIR, "wout_LandremanPaul2021_QA_lowres.nc")) + + ds = 0.01 + s = [1.0 - ds, 1.0] + ntheta = 100 + nphi = 102 + theta = np.linspace(0, 2 * np.pi, ntheta, endpoint=False) + phi = np.linspace(0, 2 * np.pi / vmec.wout.nfp, nphi, endpoint=False) + dtheta = theta[1] - theta[0] + dphi = phi[1] - phi[0] + + def d_d_theta(f): + return (np.roll(f, -1, axis=1) - np.roll(f, 1, axis=1)) / (2 * dtheta) + + def d_d_phi(f): + return (np.roll(f, -1, axis=2) - np.roll(f, 1, axis=2)) / (2 * dphi) + + def d2_d_theta2(f): + return (np.roll(f, -1, axis=1) - 2 * f + np.roll(f, 1, axis=1)) / (dtheta**2) + + def d2_d_phi2(f): + return (np.roll(f, -1, axis=2) - 2 * f + np.roll(f, 1, axis=2)) / (dphi**2) + + def d_d_s(f): + return (f[1, :, :] - f[0, :, :]) / ds + + def s_mean(f): + # Average over the two surfaces + return 0.5 * (f[0, :, :] + f[1, :, :]) + + data = vmec_compute_geometry(vmec, s, theta, phi) + + np.testing.assert_allclose(data.d_R_d_theta_vmec, d_d_theta(data.R), atol=3e-3) + np.testing.assert_allclose(data.d2_R_d_theta_vmec_d_phi, d_d_theta(d_d_phi(data.R)), atol=2e-3) + np.testing.assert_allclose(data.d2_Z_d_theta_vmec_d_phi, d_d_theta(d_d_phi(data.Z)), atol=2e-3) + np.testing.assert_allclose(data.d2_R_d_theta_vmec2, d2_d_theta2(data.R), atol=4e-4) + np.testing.assert_allclose(data.d2_Z_d_theta_vmec2, d2_d_theta2(data.Z), atol=3e-4) + np.testing.assert_allclose(data.d2_R_d_phi2, d2_d_phi2(data.R), atol=2e-3) + np.testing.assert_allclose(data.d2_Z_d_phi2, d2_d_phi2(data.Z), atol=2e-3) + np.testing.assert_allclose(s_mean(data.d2_R_d_s_d_phi), d_d_s(data.d_R_d_phi), atol=3e-6) + np.testing.assert_allclose(s_mean(data.d2_Z_d_s_d_phi), d_d_s(data.d_Z_d_phi), atol=2e-6) + np.testing.assert_allclose(s_mean(data.d2_R_d_s_d_theta_vmec), d_d_s(data.d_R_d_theta_vmec), atol=2e-6) + np.testing.assert_allclose(s_mean(data.d2_Z_d_s_d_theta_vmec), d_d_s(data.d_Z_d_theta_vmec), atol=2e-6) + + np.testing.assert_allclose(data.d_B_sup_theta_vmec_d_theta_vmec, d_d_theta(data.B_sup_theta_vmec), atol=2e-2) + np.testing.assert_allclose(data.d_B_sup_theta_vmec_d_phi, d_d_phi(data.B_sup_theta_vmec), atol=4e-3) + np.testing.assert_allclose(data.d_B_sup_phi_d_theta_vmec, d_d_theta(data.B_sup_phi), atol=8e-3) + np.testing.assert_allclose(data.d_B_sup_phi_d_phi, d_d_phi(data.B_sup_phi), atol=8e-4) + np.testing.assert_allclose(s_mean(data.d_B_sup_phi_d_s), d_d_s(data.B_sup_phi), atol=6e-6) + np.testing.assert_allclose(s_mean(data.d_B_sup_theta_vmec_d_s), d_d_s(data.B_sup_theta_vmec), atol=4e-5) + + if False: + # f_an = np.squeeze(data.d2_R_d_phi2)[1, :, :] + # f_fd = np.squeeze(d2_d_phi2(data.R))[1, :, :] + f_an = s_mean(data.d2_R_d_s_d_theta_vmec) + f_fd = d_d_s(data.d_R_d_theta_vmec) + import matplotlib.pyplot as plt + plt.figure(figsize=(14, 7)) + nrows = 1 + ncols = 3 + ncontours = 25 + + plt.subplot(nrows, ncols, 1) + plt.contour(phi, theta, f_an, ncontours) + plt.colorbar() + plt.title("analytic") + + plt.subplot(nrows, ncols, 2) + plt.contour(phi, theta, f_fd, ncontours) + plt.colorbar() + plt.title("finite diff") + + plt.subplot(nrows, ncols, 3) + plt.contour(phi, theta, f_an - f_fd, ncontours) + plt.colorbar() + plt.title("diff") + + plt.tight_layout() + plt.show() + + def test_L_grad_B_regression(self): + """ + Compare L_{grad B} to an indepedent calculation in Matt Landreman's + Matlab code m20240601_01_gradBTensorComplexityMetricForVMEC.m + """ + vmec = Vmec(os.path.join(TEST_DIR, "wout_LandremanPaul2021_QA_lowres.nc")) + + s = 1.0 + ntheta = 9 + nphi = 7 + theta = np.linspace(0, 2 * np.pi, ntheta, endpoint=True) + phi = np.linspace(0, 2 * np.pi / vmec.wout.nfp, nphi, endpoint=True) + + data = vmec_compute_geometry(vmec, s, theta, phi) + + matlab_data = np.array([ + [0.777048118791033, 0.850059335051267, 1.058251880937882, 1.238755906102585, 1.058251880937882, 0.850059335051267, 0.777048118791033], + [0.732357468770512, 0.887635027604753, 1.100038034467113, 1.149372447382607, 0.914652536061020, 0.732423846297739, 0.732357468770512], + [0.642772279126891, 0.810075234122540, 1.009506601358511, 1.036192879128092, 0.822941521630497, 0.638233465781766, 0.642772279126891], + [0.561114055795734, 0.718502389029629, 0.920071594222606, 0.997769685332234, 0.817986738735225, 0.595098001722719, 0.561114055795734], + [0.520891960189527, 0.633214068787356, 0.866980355399107, 0.967856711826989, 0.866980355399108, 0.633214068787355, 0.520891960189527], + [0.561114055795734, 0.595098001722719, 0.817986738735225, 0.997769685332234, 0.920071594222606, 0.718502389029630, 0.561114055795734], + [0.642772279126891, 0.638233465781766, 0.822941521630497, 1.036192879128092, 1.009506601358511, 0.810075234122540, 0.642772279126891], + [0.732357468770512, 0.732423846297739, 0.914652536061019, 1.149372447382608, 1.100038034467113, 0.887635027604753, 0.732357468770512], + [0.777048118791033, 0.850059335051268, 1.058251880937882, 1.238755906102585, 1.058251880937882, 0.850059335051267, 0.777048118791033], + ]) + + np.testing.assert_allclose(np.squeeze(data.L_grad_B), matlab_data, rtol=7e-3) + + # Trace of the grad \vec{B} tensor is div(B), which should be 0. + div_B = data.grad_B__XX + data.grad_B__YY + data.grad_B__ZZ + np.testing.assert_allclose(div_B, 0, atol=4e-4) + + def test_L_grad_B_axisymmetry(self): + """ + For a purely toroidal magnetic field, L_{grad B} should equal the major radius. + """ + vmec = Vmec(os.path.join(TEST_DIR, "wout_purely_toroidal_field_reference.nc")) + + s = 1.0 + ntheta = 50 + nphi = 4 + theta = np.linspace(0, 2 * np.pi, ntheta, endpoint=True) + phi = np.linspace(0, 2 * np.pi / vmec.wout.nfp, nphi, endpoint=True) + + data = vmec_compute_geometry(vmec, s, theta, phi) + np.testing.assert_allclose(data.L_grad_B, data.R, rtol=1e-5) + + # Trace of the grad \vec{B} tensor is div(B), which should be 0. + div_B = data.grad_B__XX + data.grad_B__YY + data.grad_B__ZZ + np.testing.assert_allclose(div_B, 0, atol=3e-11) + class VmecFieldlinesTests(unittest.TestCase): def test_fieldline_grids(self): diff --git a/tests/test_files/input.purely_toroidal_field b/tests/test_files/input.purely_toroidal_field new file mode 100644 index 000000000..343d885d3 --- /dev/null +++ b/tests/test_files/input.purely_toroidal_field @@ -0,0 +1,37 @@ +! DSHAPE tokamak boundary shape from Hirshman and Whitson 1983, but with no pressure and iota ~ 0. +&INDATA + MGRID_FILE = 'NONE ' + LOPTIM = F + LSPECTRUM_DUMP = F + DELT = 0.9 + TCON0 = 2. + NFP = 1 + MPOL = 6 + NTOR = 0 + +! NS_ARRAY = 13 25 51 +! FTOL_ARRAY = 1e-20 1e-20 1e-11 +! NITER_ARRAY = 1000 1500 2000 + + NS_ARRAY = 13 25 51 101 + FTOL_ARRAY = 1e-20 1e-20 1e-20 1e-15 + NITER_ARRAY = 1000 1500 2000 30000 + +! NS_ARRAY = 13 25 51 101 150 201 +! FTOL_ARRAY = 1e-20 1e-20 1e-20 1e-20 1e-20 1e-14 +! NITER_ARRAY = 1000 1500 2000 2500 3000 30000 + + NSTEP = 200 + NVACSKIP = 3 + GAMMA = 0.00000000E+00 + PHIEDGE = 5.0 + CURTOR = 1.0 + SPRES_PED = 1.0000E+00 + NCURR = 0 + AM = 0.0 + AI = 1.0e-6 ! Add a tiny iota so the problem is not completely degenerate + AC = 0.0 + RBC(0, 0) = 3.510 ZBS(0, 0) = 0.000 + RBC(0, 1) = 1.000 ZBS(0, 1) = 1.470 + RBC(0, 2) = 0.106 ZBS(0, 2) = -0.160 + / diff --git a/tests/test_files/wout_purely_toroidal_field_reference.nc b/tests/test_files/wout_purely_toroidal_field_reference.nc new file mode 100644 index 0000000000000000000000000000000000000000..5beb6f8590d9b006b54381e89c9f59ffb9fbc2b7 GIT binary patch literal 124068 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΁ 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®$90xr_Du9`nmk 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 Date: Sat, 8 Jun 2024 17:59:56 -0400 Subject: [PATCH 116/131] Fix link to nersc page on wiki --- docs/source/containers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/containers.rst b/docs/source/containers.rst index a9f28effd..9bc0043f0 100644 --- a/docs/source/containers.rst +++ b/docs/source/containers.rst @@ -130,7 +130,7 @@ issues associated with Docker containers. Shifter allows to you use the simsopt Docker image files hosted on Docker Hub. Detailed instructions for using Shifter can be found at the `NERSC page on the simsopt wiki -`_. +`_. .. _singularity_doc: From f8d8e5dcc5b6426448772a079ea8c40df3a966d8 Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Sun, 16 Jun 2024 07:35:55 -0400 Subject: [PATCH 117/131] Add libxrender1 to containers for mayavi --- .github/workflows/singularity.yml | 1 + ci/Dockerfile.ubuntu | 2 +- ci/singularity.def | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/singularity.yml b/.github/workflows/singularity.yml index 55f686e49..809197d44 100644 --- a/.github/workflows/singularity.yml +++ b/.github/workflows/singularity.yml @@ -12,6 +12,7 @@ on: # Do the builds on all pull requests (to test them) pull_request: [] + workflow_dispatch: jobs: build-containers: diff --git a/ci/Dockerfile.ubuntu b/ci/Dockerfile.ubuntu index ee7fbfbfa..4c8c7d06c 100644 --- a/ci/Dockerfile.ubuntu +++ b/ci/Dockerfile.ubuntu @@ -5,7 +5,7 @@ FROM --platform=linux/amd64 ubuntu:22.04 as intermediate RUN apt update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential gfortran git m4 wget cmake ninja-build \ libopenblas-dev libfftw3-dev libhdf5-dev libhdf5-serial-dev libnetcdf-dev libnetcdff-dev libgl1-mesa-dev \ - python3-dev python3-pip python3-venv + python3-dev python3-pip python3-venv libxrender1 # Install mpich manually WORKDIR /src diff --git a/ci/singularity.def b/ci/singularity.def index 03ddd49f5..c070fddb1 100644 --- a/ci/singularity.def +++ b/ci/singularity.def @@ -8,7 +8,7 @@ Stage: devel libfabric-dev libfabric-bin \ libhwloc-dev libpmix-dev libevent-dev \ libopenblas-dev libfftw3-dev libhdf5-dev libhdf5-serial-dev libnetcdf-dev libnetcdff-dev libgl1-mesa-dev \ - python3-dev python3-pip python3-venv + python3-dev python3-pip python3-venv libxrender1 %post From 4bd94feae9064f695022c4a98dc8f0108f0866a4 Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Tue, 18 Jun 2024 09:13:29 -0400 Subject: [PATCH 118/131] Try to get CIs working again following numpy 2.0 release --- .github/workflows/extensive_test.yml | 2 +- .github/workflows/tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/extensive_test.yml b/.github/workflows/extensive_test.yml index f60d2e15f..dc28d372e 100644 --- a/.github/workflows/extensive_test.yml +++ b/.github/workflows/extensive_test.yml @@ -98,7 +98,7 @@ jobs: - name: Install python dependencies run: | sudo apt-get install graphviz graphviz-dev - pip install wheel numpy scipy f90nml h5py scikit-build cmake qsc sympy pyevtk matplotlib ninja plotly networkx pygraphviz ground bentley_ottmann + pip install wheel numpy<2.0.0 scipy f90nml h5py scikit-build cmake qsc sympy pyevtk matplotlib ninja plotly networkx pygraphviz ground bentley_ottmann - name: Install booz_xform if: contains(matrix.packages, 'vmec') || contains(matrix.packages, 'all') diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 269c9588d..54c6b70c5 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -93,7 +93,7 @@ jobs: - name: Install python dependencies run: | sudo apt-get install graphviz graphviz-dev - pip install numpy cmake scikit-build f90nml ninja wheel setuptools sympy qsc pyevtk matplotlib plotly networkx pygraphviz mpi4py py_spec pyoculus h5py ground bentley_ottmann + pip install numpy<2.0.0 cmake scikit-build f90nml ninja wheel setuptools sympy qsc pyevtk matplotlib plotly networkx pygraphviz mpi4py py_spec pyoculus h5py ground bentley_ottmann - name: Install booz_xform run: pip install -v git+https://github.com/hiddenSymmetries/booz_xform From 674db321d71c34e65e0310f0a03dc6f14da7f80e Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Tue, 18 Jun 2024 09:17:42 -0400 Subject: [PATCH 119/131] Quotes around version inequality --- .github/workflows/extensive_test.yml | 2 +- .github/workflows/tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/extensive_test.yml b/.github/workflows/extensive_test.yml index dc28d372e..b7e07749e 100644 --- a/.github/workflows/extensive_test.yml +++ b/.github/workflows/extensive_test.yml @@ -98,7 +98,7 @@ jobs: - name: Install python dependencies run: | sudo apt-get install graphviz graphviz-dev - pip install wheel numpy<2.0.0 scipy f90nml h5py scikit-build cmake qsc sympy pyevtk matplotlib ninja plotly networkx pygraphviz ground bentley_ottmann + pip install wheel "numpy<2.0.0" scipy f90nml h5py scikit-build cmake qsc sympy pyevtk matplotlib ninja plotly networkx pygraphviz ground bentley_ottmann - name: Install booz_xform if: contains(matrix.packages, 'vmec') || contains(matrix.packages, 'all') diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 54c6b70c5..f91910245 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -93,7 +93,7 @@ jobs: - name: Install python dependencies run: | sudo apt-get install graphviz graphviz-dev - pip install numpy<2.0.0 cmake scikit-build f90nml ninja wheel setuptools sympy qsc pyevtk matplotlib plotly networkx pygraphviz mpi4py py_spec pyoculus h5py ground bentley_ottmann + pip install "numpy<2.0.0" cmake scikit-build f90nml ninja wheel setuptools sympy qsc pyevtk matplotlib plotly networkx pygraphviz mpi4py py_spec pyoculus h5py ground bentley_ottmann - name: Install booz_xform run: pip install -v git+https://github.com/hiddenSymmetries/booz_xform From 98d9f20636ab1e28256aba858e81fc445f10eed4 Mon Sep 17 00:00:00 2001 From: Bharat Medasani Date: Mon, 24 Jun 2024 10:02:13 -0400 Subject: [PATCH 120/131] replace nptyping with numpy.typing --- pyproject.toml | 2 +- src/simsopt/_core/types.py | 11 +++++++---- src/simsopt/geo/surfaceobjectives.py | 7 ++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f34cda10d..870f48767 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,7 +57,7 @@ dependencies = [ "jaxlib>=0.1.56", "scipy>=1.5.4", "Deprecated>=1.2.10", - "nptyping>=1.3.0", + # "nptyping>=1.3.0", "monty>=2021.6.10", "ruamel.yaml", "sympy", diff --git a/src/simsopt/_core/types.py b/src/simsopt/_core/types.py index ac473e5b3..21dc29010 100644 --- a/src/simsopt/_core/types.py +++ b/src/simsopt/_core/types.py @@ -9,11 +9,14 @@ from typing import Union, Sequence, Any from numbers import Integral, Real -from nptyping import NDArray, Float, Int, Bool +# from nptyping import NDArray, Float, Int, Bool +import numpy as np +from numpy.typing import NDArray -RealArray = Union[Sequence[Real], NDArray[Any, Float]] -IntArray = Union[Sequence[Integral], NDArray[Any, Int]] +# RealArray is a type alias for numpy double array or RealArray +RealArray = Union[Sequence[Real], NDArray[np.double]] +IntArray = Union[Sequence[Integral], NDArray[np.int_]] StrArray = Sequence[str] -BoolArray = Union[Sequence[bool], NDArray[Any, Bool]] +BoolArray = Union[Sequence[bool], NDArray[np.bool]] Key = Union[Integral, str] diff --git a/src/simsopt/geo/surfaceobjectives.py b/src/simsopt/geo/surfaceobjectives.py index e743af500..5a92408e9 100644 --- a/src/simsopt/geo/surfaceobjectives.py +++ b/src/simsopt/geo/surfaceobjectives.py @@ -1,11 +1,12 @@ from typing import Any import numpy as np -from nptyping import NDArray, Float +# from nptyping import NDArray, Float import simsoptpp as sopp from .._core.optimizable import Optimizable from .._core.derivative import Derivative, derivative_dec +from .._core.types import RealArray from .surface import Surface from .surfacexyztensorfourier import SurfaceXYZTensorFourier from ..objectives.utilities import forward_backward @@ -517,8 +518,8 @@ def boozer_surface_residual(surface, iota, G, biotsavart, derivatives=0, weight_ def parameter_derivatives(surface: Surface, - shape_gradient: NDArray[Any, Float] - ) -> NDArray[Any, Float]: + shape_gradient: RealArray + ) -> RealArray: r""" Converts the shape gradient of a given figure of merit, :math:`f`, to derivatives with respect to parameters defining a surface. For From a8dafae66c2af34b5fbed0dce61473b984b4c71c Mon Sep 17 00:00:00 2001 From: Bharat Medasani Date: Mon, 24 Jun 2024 11:07:13 -0400 Subject: [PATCH 121/131] Replacing np.bool with bool --- src/simsopt/_core/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simsopt/_core/types.py b/src/simsopt/_core/types.py index 21dc29010..6ba9ff184 100644 --- a/src/simsopt/_core/types.py +++ b/src/simsopt/_core/types.py @@ -17,6 +17,6 @@ RealArray = Union[Sequence[Real], NDArray[np.double]] IntArray = Union[Sequence[Integral], NDArray[np.int_]] StrArray = Sequence[str] -BoolArray = Union[Sequence[bool], NDArray[np.bool]] +BoolArray = Union[Sequence[bool], NDArray[bool]] Key = Union[Integral, str] From 63fa27a2a19bb8062432fb89a4935ce1f9d09d69 Mon Sep 17 00:00:00 2001 From: Bharat Medasani Date: Mon, 24 Jun 2024 11:19:36 -0400 Subject: [PATCH 122/131] limit numpy to below 2.0 in non-simd-tests --- .github/workflows/non_simd_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/non_simd_tests.yml b/.github/workflows/non_simd_tests.yml index b59209470..121cc36ee 100644 --- a/.github/workflows/non_simd_tests.yml +++ b/.github/workflows/non_simd_tests.yml @@ -84,7 +84,7 @@ jobs: - name: Install python dependencies run: | sudo apt-get install graphviz graphviz-dev - pip install wheel numpy scipy f90nml h5py scikit-build cmake qsc sympy pyevtk matplotlib ninja plotly networkx pygraphviz ground bentley_ottmann + pip install wheel "numpy<2.0.0" scipy f90nml h5py scikit-build cmake qsc sympy pyevtk matplotlib ninja plotly networkx pygraphviz ground bentley_ottmann - name: Install booz_xform run: pip install -v git+https://github.com/hiddenSymmetries/booz_xform From 66b09f30fddd764458b4031393be1f54d59c1e21 Mon Sep 17 00:00:00 2001 From: Bharat Medasani Date: Mon, 24 Jun 2024 11:27:21 -0400 Subject: [PATCH 123/131] Cleanup code --- src/simsopt/_core/types.py | 4 +--- src/simsopt/geo/surfaceobjectives.py | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/simsopt/_core/types.py b/src/simsopt/_core/types.py index 6ba9ff184..ad634f2a4 100644 --- a/src/simsopt/_core/types.py +++ b/src/simsopt/_core/types.py @@ -6,14 +6,12 @@ This module contains small utility functions and classes. """ -from typing import Union, Sequence, Any +from typing import Union, Sequence # , Any from numbers import Integral, Real -# from nptyping import NDArray, Float, Int, Bool import numpy as np from numpy.typing import NDArray -# RealArray is a type alias for numpy double array or RealArray RealArray = Union[Sequence[Real], NDArray[np.double]] IntArray = Union[Sequence[Integral], NDArray[np.int_]] StrArray = Sequence[str] diff --git a/src/simsopt/geo/surfaceobjectives.py b/src/simsopt/geo/surfaceobjectives.py index 5a92408e9..d5db86f4b 100644 --- a/src/simsopt/geo/surfaceobjectives.py +++ b/src/simsopt/geo/surfaceobjectives.py @@ -1,7 +1,4 @@ -from typing import Any - import numpy as np -# from nptyping import NDArray, Float import simsoptpp as sopp from .._core.optimizable import Optimizable From a97db7b31df2cea494e628c8992db262b630aca6 Mon Sep 17 00:00:00 2001 From: Bharat Medasani Date: Mon, 24 Jun 2024 11:31:01 -0400 Subject: [PATCH 124/131] limit numpy version to less than 2.0.0 --- pyproject.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 870f48767..236e4c4cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,12 +52,11 @@ keywords = [ "magnetostatics" ] dependencies = [ - "numpy>=1.21", + "numpy>=1.21,<2.0.0", "jax>=0.2.5", "jaxlib>=0.1.56", "scipy>=1.5.4", "Deprecated>=1.2.10", - # "nptyping>=1.3.0", "monty>=2021.6.10", "ruamel.yaml", "sympy", From 9dd34c5b0f7eab40f1fed3532983affb96061341 Mon Sep 17 00:00:00 2001 From: Bharat Medasani Date: Mon, 24 Jun 2024 13:37:35 -0400 Subject: [PATCH 125/131] update github runner for macos from 11 to 12 --- .github/workflows/conda.yml | 2 +- .github/workflows/wheel.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conda.yml b/.github/workflows/conda.yml index 48926a07f..b53322842 100644 --- a/.github/workflows/conda.yml +++ b/.github/workflows/conda.yml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: false matrix: - platform: [ubuntu-latest, macos-11] + platform: [ubuntu-latest, macos-12] python-version: ["3.9"] runs-on: ${{ matrix.platform }} diff --git a/.github/workflows/wheel.yml b/.github/workflows/wheel.yml index 8044ebfe4..159b78e8f 100644 --- a/.github/workflows/wheel.yml +++ b/.github/workflows/wheel.yml @@ -8,7 +8,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [macos-11, ubuntu-20.04] + os: [macos-12, ubuntu-20.04] steps: - uses: actions/checkout@v4 From 8fba42ceb768f5623539794af81ea169190e3c77 Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 27 Jun 2024 10:20:42 +0200 Subject: [PATCH 126/131] clear spec cache to avoid sporadic mismatch --- src/simsopt/mhd/spec.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/simsopt/mhd/spec.py b/src/simsopt/mhd/spec.py index 05e304a52..00501af93 100644 --- a/src/simsopt/mhd/spec.py +++ b/src/simsopt/mhd/spec.py @@ -141,6 +141,10 @@ def __init__(self, filename = f"{filename}.sp" logger.info(f"Initializing a SPEC object from file: {filename}") + #If spec has run before, clear the f90wrap array caches. + if spec.allglobal._arrays: + self._clear_f90wrap_array_caches() + if tolerance <= 0: raise ValueError( 'tolerance should be greater than zero' @@ -716,6 +720,13 @@ def set_dofs(self, x): if p is not None: p.phiedge = x[0] + def _clear_f90wrap_array_caches(self): + """ + Clear the f90wrap array caches. This is necessary when a new file is read after SPEC has run before. + """ + spec.allglobal._arrays = {} + spec.inputlist._arrays = {} logger.debug("Done with init") + def init(self, filename: str): """ Initialize SPEC fortran state from an input file. @@ -737,7 +748,6 @@ def init(self, filename: str): spec.allglobal.broadcast_inputs() logger.debug('About to call preset') spec.preset() - logger.debug("Done with init") def run(self, update_guess: bool = True): """ From d11685beac1d2e6096be9a2b74b008e352d6d0bc Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 27 Jun 2024 10:25:29 +0200 Subject: [PATCH 127/131] fix paste error --- src/simsopt/mhd/spec.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/simsopt/mhd/spec.py b/src/simsopt/mhd/spec.py index 00501af93..27cfcd408 100644 --- a/src/simsopt/mhd/spec.py +++ b/src/simsopt/mhd/spec.py @@ -725,7 +725,7 @@ def _clear_f90wrap_array_caches(self): Clear the f90wrap array caches. This is necessary when a new file is read after SPEC has run before. """ spec.allglobal._arrays = {} - spec.inputlist._arrays = {} logger.debug("Done with init") + spec.inputlist._arrays = {} def init(self, filename: str): """ @@ -748,6 +748,7 @@ def init(self, filename: str): spec.allglobal.broadcast_inputs() logger.debug('About to call preset') spec.preset() + logger.debug("Done with init") def run(self, update_guess: bool = True): """ From 6ac3fa8485940519e0ce7eb118a4b07397c8fe7d Mon Sep 17 00:00:00 2001 From: Bharat Medasani Date: Thu, 27 Jun 2024 11:12:10 -0400 Subject: [PATCH 128/131] Fix for python 3.8 and numpy dependency --- pyproject.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 236e4c4cd..b89247f2c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,9 @@ [build-system] requires = [ - "scikit-build-core>=0.3.3", + "scikit-build-core", "pybind11", - "oldest-supported-numpy", + "numpy >= 2.0.0; python_version > '3.8'", + "oldest-supported-numpy; python_version <= '3.8'", "setuptools_scm>=8.0", 'tomli; python_version < "3.11"',] build-backend = "scikit_build_core.build" From bd5d9e9cdcb051fc287306ce66c200f6d5624c0b Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 28 Jun 2024 12:41:09 +0200 Subject: [PATCH 129/131] update containers --- ci/Dockerfile.ubuntu | 10 ++++++---- ci/singularity.def | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ci/Dockerfile.ubuntu b/ci/Dockerfile.ubuntu index 4c8c7d06c..39b11e23d 100644 --- a/ci/Dockerfile.ubuntu +++ b/ci/Dockerfile.ubuntu @@ -40,20 +40,22 @@ RUN python3 -m pip install wheel RUN python3 -m venv /venv/ RUN /venv/bin/pip install -U pip -RUN /venv/bin/python -m pip install numpy scipy jax jaxlib f90nml mpi4py jupyter notebook ipython qsc sympy scikit-build ninja "pybind11[global]" cmake -RUN /venv/bin/pip install git+https://github.com/zhucaoxiang/f90wrap +RUN /venv/bin/python -m pip install numpy scipy jax jaxlib f90nml mpi4py jupyter notebook ipython qsc sympy scikit-build ninja "pybind11[global]" cmake f90wrap h5py ENV PATH="/venv/bin:${PATH}" RUN git clone --depth 1 https://github.com/PrincetonUniversity/SPEC.git /src/SPEC && \ cd /src/SPEC && \ - /venv/bin/pip install -v . 2>&1 | tee spec_build.log + /venv/bin/pip install -v . 2>&1 | tee spec_build.log && \ + cd Utilities/pythontools && \ + /venv/bin/pip install -r requirements.txt + /venv/bin/pip install -v . RUN git clone --depth 1 https://github.com/hiddenSymmetries/VMEC2000.git /src/VMEC && \ cd /src/VMEC && \ cp cmake/machines/ubuntu.json cmake_config_file.json && \ /venv/bin/pip install -v . 2>&1 | tee vmec_build.log -RUN /venv/bin/pip install h5py pyoculus py_spec +RUN /venv/bin/pip install pyoculus RUN /venv/bin/pip install vtk==9.2.6 pyqt5 matplotlib pyevtk plotly RUN /venv/bin/pip install mayavi RUN /venv/bin/pip install git+https://github.com/hiddenSymmetries/booz_xform diff --git a/ci/singularity.def b/ci/singularity.def index c070fddb1..11a70ac81 100644 --- a/ci/singularity.def +++ b/ci/singularity.def @@ -44,8 +44,7 @@ Stage: devel python3 -m venv /venv/ . /venv/bin/activate /venv/bin/pip install -U pip - /venv/bin/pip install numpy scipy jax jaxlib f90nml jupyter notebook ipython qsc sympy scikit-build ninja "pybind11[global]" cmake - /venv/bin/pip install git+https://github.com/zhucaoxiang/f90wrap + /venv/bin/pip install numpy scipy jax jaxlib f90nml jupyter notebook ipython qsc sympy scikit-build ninja "pybind11[global]" cmake f90wrap h5py PATH="/usr/local/bin:/venv/bin:${PATH}" LD_LIBRARY_PATH="/usr/local/lib:${LD_LIBRARY_PATH}" @@ -60,7 +59,10 @@ Stage: devel cd SPEC && \ /venv/bin/python setup.py bdist_wheel && \ /venv/bin/pip install -v dist/*.whl && \ - cd .. && \ + cd Utilities/pythontools && \ + /venv/bin/pip install -r requirements.txt && \ + /venv/bin/pip install . && \ + cd ../../.. && \ rm -rf SPEC git clone --depth 1 https://github.com/hiddenSymmetries/VMEC2000.git && \ @@ -70,7 +72,7 @@ Stage: devel cd .. && \ rm -rf VMEC2000 - /venv/bin/pip install h5py pyoculus py_spec + /venv/bin/pip install pyoculus /venv/bin/pip install vtk==9.2.6 pyqt5 matplotlib pyevtk plotly /venv/bin/pip install mayavi /venv/bin/pip install git+https://github.com/hiddenSymmetries/booz_xform From ca972ce6c34a42ea3c416af039c233e014af6c5a Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 28 Jun 2024 12:58:02 +0200 Subject: [PATCH 130/131] fix line continuation --- ci/Dockerfile.ubuntu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/Dockerfile.ubuntu b/ci/Dockerfile.ubuntu index 39b11e23d..afac3239d 100644 --- a/ci/Dockerfile.ubuntu +++ b/ci/Dockerfile.ubuntu @@ -47,7 +47,7 @@ RUN git clone --depth 1 https://github.com/PrincetonUniversity/SPEC.git /src/SPE cd /src/SPEC && \ /venv/bin/pip install -v . 2>&1 | tee spec_build.log && \ cd Utilities/pythontools && \ - /venv/bin/pip install -r requirements.txt + /venv/bin/pip install -r requirements.txt && \ /venv/bin/pip install -v . RUN git clone --depth 1 https://github.com/hiddenSymmetries/VMEC2000.git /src/VMEC && \ From 7bc1e4c175052713e1bfb09589f384c3273beb69 Mon Sep 17 00:00:00 2001 From: Matt Landreman Date: Wed, 3 Jul 2024 11:56:44 -0400 Subject: [PATCH 131/131] Mention github issue and PR in comments related to spec CI failures --- src/simsopt/mhd/spec.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/simsopt/mhd/spec.py b/src/simsopt/mhd/spec.py index 27cfcd408..ec7444417 100644 --- a/src/simsopt/mhd/spec.py +++ b/src/simsopt/mhd/spec.py @@ -141,7 +141,9 @@ def __init__(self, filename = f"{filename}.sp" logger.info(f"Initializing a SPEC object from file: {filename}") - #If spec has run before, clear the f90wrap array caches. + # If spec has run before, clear the f90wrap array caches. + # See https://github.com/hiddenSymmetries/simsopt/pull/431 + # This addresses the issue https://github.com/hiddenSymmetries/simsopt/issues/357 if spec.allglobal._arrays: self._clear_f90wrap_array_caches() @@ -722,7 +724,12 @@ def set_dofs(self, x): def _clear_f90wrap_array_caches(self): """ - Clear the f90wrap array caches. This is necessary when a new file is read after SPEC has run before. + Clear the f90wrap array caches. This is necessary when a new file is + read after SPEC has run before. + + See https://github.com/hiddenSymmetries/simsopt/pull/431 + + This function is for addressing the issue https://github.com/hiddenSymmetries/simsopt/issues/357 """ spec.allglobal._arrays = {} spec.inputlist._arrays = {}