def test_interpolated_field_convergence_rate(self): R0test = 1.5 B0test = 0.8 B0 = ToroidalField(R0test, B0test) coils, currents, _ = get_ncsx_data(Nt_coils=5, Nt_ma=10, ppp=5) stellarator = CoilCollection(coils, currents, 3, True) bs = BiotSavart(stellarator.coils, stellarator.currents) old_err_1 = 1e6 old_err_2 = 1e6 btotal = bs + B0 for n in [4, 8, 16]: rmin = 1.3 rmax = 1.7 rsteps = n phimin = 0 phimax = 2 * np.pi phisteps = n * 32 zmin = -0.1 zmax = 0.1 zsteps = n bsh = InterpolatedField(btotal, 2, [rmin, rmax, rsteps], [phimin, phimax, phisteps], [zmin, zmax, zsteps], True) err_1 = np.mean(bsh.estimate_error_B(1000)) err_2 = np.mean(bsh.estimate_error_GradAbsB(1000)) print(err_1, err_2) assert err_1 < 0.6**3 * old_err_1 assert err_2 < 0.6**3 * old_err_2 old_err_1 = err_1 old_err_2 = err_2
def test_residual(self): """ This test loads a SurfaceXYZFourier that interpolates the xyz coordinates of a surface in the NCSX configuration that was computed on a previous branch of pyplasmaopt. Here, we verify that the Boozer residual at these interpolation points is small. """ s = get_exact_surface() coils, currents, ma = get_ncsx_data() stellarator = CoilCollection(coils, currents, 3, True) bs = BiotSavart(stellarator.coils, stellarator.currents) bs_tf = BiotSavart(stellarator.coils, stellarator.currents) weight = 1. tf = ToroidalFlux(s, bs_tf) # these data are obtained from `boozer` branch of pyplamsaopt tf_target = 0.41431152 iota = -0.44856192 boozer_surface = BoozerSurface(bs, s, tf, tf_target) x = np.concatenate((s.get_dofs(), [iota])) r0 = boozer_surface.boozer_penalty_constraints( x, derivatives=0, constraint_weight=weight, optimize_G=False, scalarize=False) # the residual should be close to zero for all entries apart from the y # and z coordinate at phi=0 and theta=0 (and the corresponding rotations) ignores_idxs = np.zeros_like(r0) ignores_idxs[[1, 2, 693, 694, 695, 1386, 1387, 1388, -2, -1]] = 1 assert np.max(np.abs(r0[ignores_idxs < 0.5])) < 1e-8 assert np.max(np.abs(r0[-2:])) < 1e-6
def __init__(self, *args, **kwargs): super(ParticleTracingTesting, self).__init__(*args, **kwargs) logger = logging.getLogger('simsopt.field.tracing') logger.setLevel(1) coils, currents, ma = get_ncsx_data(Nt_coils=8) currents = [3 * c for c in currents] stellarator = CoilCollection(coils, currents, 3, True) bs = BiotSavart(stellarator.coils, stellarator.currents) n = 16 rrange = (1.1, 1.8, n) phirange = (0, 2 * np.pi / 3, n * 2) zrange = (0, 0.3, n // 2) bsh = InterpolatedField(bs, UniformInterpolationRule(5), rrange, phirange, zrange, True, nfp=3, stellsym=True) print(bsh.estimate_error_B(1000)) print(bsh.estimate_error_GradAbsB(1000)) # trick to clear the cache in the biot savart class to reduce memory usage bs.set_points(np.asarray([[0., 0., 0.]])).GradAbsB() self.bsh = bsh self.ma = ma if with_evtk: bsh.to_vtk('/tmp/bfield')
def test_residual(self): """ This test loads a SurfaceXYZFourier that interpolates the xyz coordinates of a surface in the NCSX configuration that was computed on a previous branch of pyplasmaopt. Here, we verify that the QFM residual at these interpolation points is small. This test has been copied from test_boozersurface.py since Boozer coordinates are well defined when a magnetic surface exists, and thus the QFM residual should be small. """ s = get_exact_surface() coils, currents, ma = get_ncsx_data() stellarator = CoilCollection(coils, currents, 3, True) bs = BiotSavart(stellarator.coils, stellarator.currents) bs_tf = BiotSavart(stellarator.coils, stellarator.currents) weight = 1. tf = ToroidalFlux(s, bs_tf) # these data are obtained from `boozer` branch of pyplamsaopt tf_target = 0.41431152 qfm_surface = QfmSurface(bs, s, tf, tf_target) x = s.get_dofs() r0 = qfm_surface.qfm_penalty_constraints(x, derivatives=0, constraint_weight=weight) assert (r0 < 1e-10)
def test_poincare_plot(self): coils, currents, ma = get_ncsx_data(Nt_coils=15) nfp = 3 stellarator = CoilCollection(coils, currents, nfp, True) bs = BiotSavart(stellarator.coils, stellarator.currents) n = 10 rrange = (1.0, 1.9, n) phirange = (0, 2*np.pi/nfp, n*2) zrange = (0, 0.4, n) bsh = InterpolatedField( bs, UniformInterpolationRule(2), rrange, phirange, zrange, True, nfp=3, stellsym=True ) nlines = 4 r0 = np.linalg.norm(ma.gamma()[0, :2]) z0 = ma.gamma()[0, 2] R0 = [r0 + i*0.01 for i in range(nlines)] Z0 = [z0 for i in range(nlines)] nphis = 4 phis = np.linspace(0, 2*np.pi/nfp, nphis, endpoint=False) res_tys, res_phi_hits = compute_fieldlines( bsh, R0, Z0, tmax=1000, phis=phis, stopping_criteria=[]) try: import matplotlib # noqa plot_poincare_data(res_phi_hits, phis, '/tmp/fieldlines.png') except ImportError: pass
def subtest_boozer_penalty_constraints_gradient(self, surfacetype, stellsym, optimize_G=False): np.random.seed(1) coils, currents, ma = get_ncsx_data() stellarator = CoilCollection(coils, currents, 3, True) bs = BiotSavart(stellarator.coils, stellarator.currents) bs_tf = BiotSavart(stellarator.coils, stellarator.currents) s = get_surface(surfacetype, stellsym) s.fit_to_curve(ma, 0.1) weight = 11.1232 tf = ToroidalFlux(s, bs_tf) 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 * np.sum(np.abs(bs.coil_currents)) * (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) h = np.random.uniform(size=x.shape) - 0.5 Jex = J0 @ h err_old = 1e9 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) Jfd = (f1 - f0) / eps err = np.linalg.norm(Jfd - Jex) / np.linalg.norm(Jex) print(err / err_old, f0, f1) assert err < err_old * 0.55 err_old = err print( "################################################################################" )
def test_poincare_ncsx_known(self): coils, currents, ma = get_ncsx_data(Nt_coils=25) nfp = 3 stellarator = CoilCollection(coils, currents, nfp, True) currents = [-c for c in currents] bs = BiotSavart(stellarator.coils, stellarator.currents) R0 = [np.linalg.norm(ma.gamma()[0, :2])] Z0 = [ma.gamma()[0, 2]] phis = np.arctan2(ma.gamma()[:, 1], ma.gamma()[:, 0]) res_tys, res_phi_hits = compute_fieldlines( bs, R0, Z0, tmax=10, phis=phis, stopping_criteria=[]) for i in range(len(phis)-1): assert np.linalg.norm(ma.gamma()[i+1, :] - res_phi_hits[0][i, 2:5]) < 1e-4
def subtest_boozer_constrained_jacobian(self, surfacetype, stellsym, optimize_G=False): np.random.seed(1) coils, currents, ma = get_ncsx_data() stellarator = CoilCollection(coils, currents, 3, True) bs = BiotSavart(stellarator.coils, stellarator.currents) bs_tf = BiotSavart(stellarator.coils, stellarator.currents) s = get_surface(surfacetype, stellsym) s.fit_to_curve(ma, 0.1) tf = ToroidalFlux(s, bs_tf) tf_target = 0.1 boozer_surface = BoozerSurface(bs, s, tf, tf_target) iota = -0.3 lm = [0., 0.] x = np.concatenate((s.get_dofs(), [iota])) if optimize_G: x = np.concatenate((x, [ 2. * np.pi * np.sum(np.abs(bs.coil_currents)) * (4 * np.pi * 10**(-7) / (2 * np.pi)) ])) xl = np.concatenate((x, lm)) res0, dres0 = boozer_surface.boozer_exact_constraints( xl, derivatives=1, optimize_G=optimize_G) h = np.random.uniform(size=xl.shape) - 0.5 dres_exact = dres0 @ h err_old = 1e9 epsilons = np.power(2., -np.asarray(range(7, 20))) print( "################################################################################" ) for eps in epsilons: res1 = boozer_surface.boozer_exact_constraints( xl + eps * h, derivatives=0, optimize_G=optimize_G) dres_fd = (res1 - res0) / eps err = np.linalg.norm(dres_fd - dres_exact) print(err / err_old) assert err < err_old * 0.55 err_old = err print( "################################################################################" )
def subtest_boozer_penalty_constraints_hessian(self, surfacetype, stellsym, optimize_G=False): np.random.seed(1) coils, currents, ma = get_ncsx_data() stellarator = CoilCollection(coils, currents, 3, True) bs = BiotSavart(stellarator.coils, stellarator.currents) bs_tf = BiotSavart(stellarator.coils, stellarator.currents) s = get_surface(surfacetype, stellsym) s.fit_to_curve(ma, 0.1) tf = ToroidalFlux(s, bs_tf) 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 * np.sum(np.abs(bs.coil_currents)) * (4 * np.pi * 10**(-7) / (2 * np.pi)) ])) 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 err_old = 1e9 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) d2f_fd = (Jp @ h2 - J0 @ h2) / eps err = np.abs(d2f_fd - d2f) / np.abs(d2f) print(err / err_old) assert err < err_old * 0.55 err_old = err
def test_interpolated_field_close_with_symmetries(self): R0test = 1.5 B0test = 0.8 B0 = ToroidalField(R0test, B0test) coils, currents, _ = get_ncsx_data(Nt_coils=10, Nt_ma=10, ppp=5) nfp = 3 stellarator = CoilCollection(coils, currents, nfp, True) bs = BiotSavart(stellarator.coils, stellarator.currents) btotal = bs + B0 n = 12 rmin = 1.5 rmax = 1.7 rsteps = n phimin = 0 phimax = 2 * np.pi / nfp phisteps = n * 32 // nfp zmin = 0. zmax = 0.1 zsteps = n // 2 bsh = InterpolatedField(btotal, 4, [rmin, rmax, rsteps], [phimin, phimax, phisteps], [zmin, zmax, zsteps], True, nfp=nfp, stellsym=True) N = 1000 points = np.random.uniform(size=(N, 3)) points[:, 0] = points[:, 0] * (rmax - rmin) + rmin points[:, 1] = points[:, 1] * (nfp * phimax - phimin) + phimin points[:, 2] = points[:, 2] * (2 * zmax) - zmax btotal.set_points_cyl(points) dB = btotal.GradAbsB() B = btotal.B() dBc = btotal.GradAbsB_cyl() Bc = btotal.B_cyl() bsh.set_points_cyl(points) Bh = bsh.B() dBh = bsh.GradAbsB() Bhc = bsh.B_cyl() dBhc = bsh.GradAbsB_cyl() assert np.allclose(B, Bh, rtol=1e-3) assert np.allclose(dB, dBh, rtol=1e-3) assert np.allclose(Bc, Bhc, rtol=1e-3) assert np.allclose(dBc, dBhc, rtol=1e-3)
def subtest_toroidal_flux1(self, surfacetype, stellsym): coils, currents, ma = get_ncsx_data() stellarator = CoilCollection(coils, currents, 3, True) bs_tf = BiotSavart(stellarator.coils, stellarator.currents) s = get_surface(surfacetype, stellsym) tf = ToroidalFlux(s, bs_tf) coeffs = s.get_dofs() def f(dofs): s.set_dofs(dofs) return tf.J() def df(dofs): s.set_dofs(dofs) return tf.dJ_by_dsurfacecoefficients() taylor_test1(f, df, coeffs)
def subtest_qfm_penalty_constraints_gradient(self, surfacetype, stellsym): np.random.seed(1) coils, currents, ma = get_ncsx_data() stellarator = CoilCollection(coils, currents, 3, True) bs = BiotSavart(stellarator.coils, stellarator.currents) bs_tf = BiotSavart(stellarator.coils, stellarator.currents) s = get_surface(surfacetype, stellsym) s.fit_to_curve(ma, 0.1) weight = 11.1232 tf = ToroidalFlux(s, bs_tf) tf_target = 0.1 qfm_surface = QfmSurface(bs, s, tf, tf_target) x = s.get_dofs() f0, J0 = qfm_surface.qfm_penalty_constraints(x, derivatives=1, constraint_weight=weight) h = np.random.uniform(size=x.shape) - 0.5 Jex = J0 @ h err_old = 1e9 epsilons = np.power(2., -np.asarray(range(9, 17))) print( "################################################################################" ) for eps in epsilons: f1 = qfm_surface.qfm_penalty_constraints(x + eps * h, derivatives=0, constraint_weight=weight) Jfd = (f1 - f0) / eps err = np.linalg.norm(Jfd - Jex) / np.linalg.norm(Jex) print(err / err_old) assert err < err_old * 0.6 err_old = err print( "################################################################################" )
def test_get_set_points_cyl_cart(self): coils, currents, _ = get_ncsx_data(Nt_coils=5, Nt_ma=10, ppp=5) stellarator = CoilCollection(coils, currents, 3, True) bs = BiotSavart(stellarator.coils, stellarator.currents) points_xyz = np.asarray([[0.5, 0.6, 0.7]]) points_rphiz = np.zeros_like(points_xyz) points_rphiz[:, 0] = np.linalg.norm(points_xyz[:, 0:2], axis=1) points_rphiz[:, 1] = np.mod( np.arctan2(points_xyz[:, 1], points_xyz[:, 0]), 2 * np.pi) points_rphiz[:, 2] = points_xyz[:, 2] bs.set_points_cyl(points_rphiz) # import IPython; IPython.embed() # import sys; sys.exit() assert np.allclose(bs.get_points_cyl(), points_rphiz) assert np.allclose(bs.get_points_cart(), points_xyz) bs.set_points_cart(points_xyz) assert np.allclose(bs.get_points_cyl(), points_rphiz) assert np.allclose(bs.get_points_cart(), points_xyz)
def test_interpolated_field_close_no_sym(self): R0test = 1.5 B0test = 0.8 B0 = ToroidalField(R0test, B0test) coils, currents, _ = get_ncsx_data(Nt_coils=5, Nt_ma=10, ppp=5) stellarator = CoilCollection(coils, currents, 3, True) bs = BiotSavart(stellarator.coils, stellarator.currents) btotal = bs + B0 n = 8 rmin = 1.5 rmax = 1.7 rsteps = n phimin = 0 phimax = 2 * np.pi phisteps = n * 16 zmin = -0.1 zmax = 0.1 zsteps = n bsh = InterpolatedField(btotal, 4, [rmin, rmax, rsteps], [phimin, phimax, phisteps], [zmin, zmax, zsteps], True) N = 100 points = np.random.uniform(size=(N, 3)) points[:, 0] = points[:, 0] * (rmax - rmin) + rmin points[:, 1] = points[:, 1] * (phimax - phimin) + phimin points[:, 2] = points[:, 2] * (zmax - zmin) + zmin btotal.set_points_cyl(points) dB = btotal.GradAbsB() B = btotal.B() dBc = btotal.GradAbsB_cyl() Bc = btotal.B_cyl() bsh.set_points_cyl(points) Bh = bsh.B() dBh = bsh.GradAbsB() Bhc = bsh.B_cyl() dBhc = bsh.GradAbsB_cyl() assert np.allclose(B, Bh, rtol=1e-2) assert np.allclose(dB, dBh, rtol=1e-2) assert np.allclose(Bc, Bhc, rtol=1e-2) assert np.allclose(dBc, dBhc, rtol=1e-2)
def test_toroidal_flux_is_constant(self): """ this test ensures that the toroidal flux does not change, regardless of the cross section (varphi = constant) across which it is computed """ s = get_exact_surface() coils, currents, ma = get_ncsx_data() stellarator = CoilCollection(coils, currents, 3, True) bs_tf = BiotSavart(stellarator.coils, stellarator.currents) gamma = s.gamma() num_phi = gamma.shape[0] tf_list = np.zeros((num_phi, )) for idx in range(num_phi): tf = ToroidalFlux(s, bs_tf, idx=idx) tf_list[idx] = tf.J() mean_tf = np.mean(tf_list) max_err = np.max(np.abs(mean_tf - tf_list)) / mean_tf assert max_err < 1e-2
def subtest_qfm_penalty_constraints_hessian(self, surfacetype, stellsym): np.random.seed(1) coils, currents, ma = get_ncsx_data() stellarator = CoilCollection(coils, currents, 3, True) bs = BiotSavart(stellarator.coils, stellarator.currents) bs_tf = BiotSavart(stellarator.coils, stellarator.currents) s = get_surface(surfacetype, stellsym) s.fit_to_curve(ma, 0.1) tf = ToroidalFlux(s, bs_tf) tf_target = 0.5 qfm_surface = QfmSurface(bs, s, tf, tf_target) x = s.get_dofs() f0, J0, H0 = qfm_surface.qfm_penalty_constraints(x, derivatives=2) h1 = np.random.uniform(size=x.shape) - 0.5 h2 = np.random.uniform(size=x.shape) - 0.5 d2f = h1 @ H0 @ h2 err_old = 1e9 epsilons = np.power(2., -np.asarray(range(11, 18))) print( "################################################################################" ) for eps in epsilons: fp, Jp = qfm_surface.qfm_penalty_constraints(x + eps * h1, derivatives=1) d2f_fd = (Jp @ h2 - J0 @ h2) / eps err = np.abs(d2f_fd - d2f) / np.abs(d2f) print(err / err_old) # assert err < err_old * 0.6 err_old = err
def subtest_qfm_surface_optimization_convergence(self, surfacetype, stellsym): """ For each configuration, first reduce penalty objective using LBFGS at fixed volume. Then solve constrained problem using SLSQP. Repeat both steps for fixed area. Check that volume is preserved. """ coils, currents, ma = get_ncsx_data() if stellsym: stellarator = CoilCollection(coils, currents, 3, True) else: # Create a stellarator that still has rotational symmetry but # doesn't have stellarator symmetry. We do this by first applying # stellarator symmetry, then breaking this slightly, and then # applying rotational symmetry from simsopt.geo.curve import RotatedCurve coils_flipped = [RotatedCurve(c, 0, True) for c in coils] currents_flipped = [-cur for cur in currents] for c in coils_flipped: c.rotmat += 0.001 * np.random.uniform( low=-1., high=1., size=c.rotmat.shape) c.rotmatT = c.rotmat.T stellarator = CoilCollection(coils + coils_flipped, currents + currents_flipped, 3, False) bs = BiotSavart(stellarator.coils, stellarator.currents) bs_tf = BiotSavart(stellarator.coils, stellarator.currents) nfp = 3 phis = np.linspace(0, 1 / nfp, 30, endpoint=False) thetas = np.linspace(0, 1, 30, endpoint=False) constraint_weight = 1e0 s = get_surface(surfacetype, stellsym, phis=phis, thetas=thetas, ntor=3, mpol=3) s.fit_to_curve(ma, 0.2) vol = Volume(s) vol_target = vol.J() qfm_surface = QfmSurface(bs, s, vol, vol_target) # Compute surface first using LBFGS and a volume constraint res = qfm_surface.minimize_qfm_penalty_constraints_LBFGS( tol=1e-10, maxiter=10000, constraint_weight=constraint_weight) assert res['success'] assert np.linalg.norm(res['gradient']) < 1e-2 assert res['fun'] < 1e-5 assert np.abs(vol_target - vol.J()) < 1e-4 # As a second step, optimize with SLSQP res = qfm_surface.minimize_qfm_exact_constraints_SLSQP(tol=1e-11, maxiter=1000) assert res['success'] assert np.linalg.norm(res['gradient']) < 1e-3 assert res['fun'] < 1e-5 assert np.abs(vol_target - vol.J()) < 1e-5 vol_opt1 = vol.J() # Now optimize with area constraint ar = Area(s) ar_target = ar.J() qfm_surface = QfmSurface(bs, s, ar, ar_target) res = qfm_surface.minimize_qfm_penalty_constraints_LBFGS( tol=1e-10, maxiter=1000, constraint_weight=constraint_weight) assert res['success'] assert res['fun'] < 1e-5 assert np.linalg.norm(res['gradient']) < 1e-2 assert np.abs(ar_target - ar.J()) < 1e-5 res = qfm_surface.minimize_qfm_exact_constraints_SLSQP(tol=1e-11, maxiter=1000) assert res['success'] assert res['fun'] < 1e-5 assert np.linalg.norm(res['gradient']) < 1e-3 assert np.abs(ar_target - ar.J()) < 1e-4 vol_opt2 = vol.J() # Check that volume after second opt does not change assert np.abs(vol_opt2 - vol_opt1) < 1e-3
def test_to_vtk(self): coils, currents, _ = get_ncsx_data(Nt_coils=5, Nt_ma=10, ppp=5) stellarator = CoilCollection(coils, currents, 3, True) bs = BiotSavart(stellarator.coils, stellarator.currents) bs.to_vtk('/tmp/bfield')
def subtest_minimize_qfm(self, surfacetype, stellsym): """ For each configuration, test to verify that minimize_qfm() yields same result as minimize_qfm_exact_constraints_SLSQP or minimize_qfm_penalty_constraints_LBFGS separately. Test that InputError is raised if 'LBFGS' or 'SLSQP' is passed. """ coils, currents, ma = get_ncsx_data() if stellsym: stellarator = CoilCollection(coils, currents, 3, True) else: # Create a stellarator that still has rotational symmetry but # doesn't have stellarator symmetry. We do this by first applying # stellarator symmetry, then breaking this slightly, and then # applying rotational symmetry from simsopt.geo.curve import RotatedCurve coils_flipped = [RotatedCurve(c, 0, True) for c in coils] currents_flipped = [-cur for cur in currents] for c in coils_flipped: c.rotmat += 0.001 * np.random.uniform( low=-1., high=1., size=c.rotmat.shape) c.rotmatT = c.rotmat.T stellarator = CoilCollection(coils + coils_flipped, currents + currents_flipped, 3, False) bs = BiotSavart(stellarator.coils, stellarator.currents) bs_tf = BiotSavart(stellarator.coils, stellarator.currents) nfp = 3 phis = np.linspace(0, 1 / nfp, 30, endpoint=False) thetas = np.linspace(0, 1, 30, endpoint=False) constraint_weight = 1e0 s = get_surface(surfacetype, stellsym, phis=phis, thetas=thetas, ntor=3, mpol=3) s.fit_to_curve(ma, 0.2) vol = Volume(s) vol_target = vol.J() qfm_surface = QfmSurface(bs, s, vol, vol_target) # Compute surface first using LBFGS and a volume constraint res = qfm_surface.minimize_qfm_penalty_constraints_LBFGS( tol=1e-10, maxiter=10000, constraint_weight=constraint_weight) grad1 = np.linalg.norm(res['gradient']) fun1 = res['fun'] vol1 = vol.J() # Perform same calculation by calling qfm_minimize s = get_surface(surfacetype, stellsym, phis=phis, thetas=thetas, ntor=3, mpol=3) s.fit_to_curve(ma, 0.2) res = qfm_surface.minimize_qfm(method='LBFGS', tol=1e-10, maxiter=10000, constraint_weight=constraint_weight) grad2 = np.linalg.norm(res['gradient']) fun2 = res['fun'] vol2 = vol.J() # Test for preservation of results np.allclose(grad1, grad2) np.allclose(fun1, fun2) np.allclose(vol1, vol2) # Perform calculation with SLSQP s = get_surface(surfacetype, stellsym, phis=phis, thetas=thetas, ntor=3, mpol=3) s.fit_to_curve(ma, 0.2) res = qfm_surface.minimize_qfm_exact_constraints_SLSQP(tol=1e-11, maxiter=1000) grad1 = np.linalg.norm(res['gradient']) fun1 = res['fun'] vol1 = vol.J() # Perform same calculation by calling qfm_minimize s = get_surface(surfacetype, stellsym, phis=phis, thetas=thetas, ntor=3, mpol=3) s.fit_to_curve(ma, 0.2) res = qfm_surface.minimize_qfm(method='SLSQP', tol=1e-11, maxiter=1000) grad2 = np.linalg.norm(res['gradient']) fun2 = res['fun'] vol2 = vol.J() # Test for preservation of results np.allclose(grad1, grad2) np.allclose(fun1, fun2) np.allclose(vol1, vol2) # Test that InputError raised with self.assertRaises(ValueError): res = qfm_surface.minimize_qfm(method='SLSQPP', tol=1e-11, maxiter=1000)
# check whether we're in CI, in that case we make the run a bit cheaper ci = "CI" in os.environ and os.environ['CI'].lower() in ['1', 'true'] nparticles = 3 if ci else 100 degree = 2 if ci else 3 """ This examples demonstrate how to use SIMSOPT to compute guiding center trajectories of particles """ coils, currents, ma = get_ncsx_data(Nt_coils=25, Nt_ma=10) stellarator = CoilCollection(coils, currents, 3, True) coils = stellarator.coils currents = stellarator.currents bs = BiotSavart(coils, currents) print("Mean(|B|) on axis =", np.mean(np.linalg.norm(bs.set_points(ma.gamma()).B(), axis=1))) print("Mean(Axis radius) =", np.mean(np.linalg.norm(ma.gamma(), axis=1))) curves_to_vtk(coils + [ma], '/tmp/coils') mpol = 5 ntor = 5 stellsym = True 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=stellsym, nfp=nfp, quadpoints_phi=phis, quadpoints_theta=thetas)
def subtest_boozer_surface_optimisation_convergence( self, surfacetype, stellsym, optimize_G, second_stage): coils, currents, ma = get_ncsx_data() if stellsym: stellarator = CoilCollection(coils, currents, 3, True) else: # Create a stellarator that still has rotational symmetry but # doesn't have stellarator symmetry. We do this by first applying # stellarator symmetry, then breaking this slightly, and then # applying rotational symmetry from simsopt.geo.curve import RotatedCurve coils_flipped = [RotatedCurve(c, 0, True) for c in coils] currents_flipped = [-cur for cur in currents] for c in coils_flipped: c.rotmat += 0.001 * np.random.uniform( low=-1., high=1., size=c.rotmat.shape) c.rotmatT = c.rotmat.T stellarator = CoilCollection(coils + coils_flipped, currents + currents_flipped, 3, False) bs = BiotSavart(stellarator.coils, stellarator.currents) s = get_surface(surfacetype, stellsym) s.fit_to_curve(ma, 0.1) iota = -0.3 ar = Area(s) ar_target = ar.J() boozer_surface = BoozerSurface(bs, s, ar, ar_target) if optimize_G: G = 2. * np.pi * np.sum(np.abs( bs.coil_currents)) * (4 * np.pi * 10**(-7) / (2 * np.pi)) else: G = None # 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) print('Squared residual after LBFGS', res['fun']) if second_stage == 'ls': res = boozer_surface.minimize_boozer_penalty_constraints_ls( tol=1e-9, maxiter=100, constraint_weight=100., iota=res['iota'], G=res['G']) elif second_stage == 'newton': res = boozer_surface.minimize_boozer_penalty_constraints_newton( tol=1e-9, maxiter=10, constraint_weight=100., iota=res['iota'], G=res['G'], stab=1e-4) elif second_stage == 'newton_exact': res = boozer_surface.minimize_boozer_exact_constraints_newton( tol=1e-9, maxiter=10, iota=res['iota'], G=res['G']) print('Residual after second stage', np.linalg.norm(res['residual'])) assert res['success'] # 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, :] assert np.abs(gammazero[2]) < 1e-10 if stellsym: assert np.abs(gammazero[1]) < 1e-10 else: assert np.abs(gammazero[1]) > 1e-6 if surfacetype == 'SurfaceXYZTensorFourier': assert np.linalg.norm(res['residual']) < 1e-9 if second_stage == 'newton_exact' or surfacetype == 'SurfaceXYZTensorFourier': assert np.abs(ar_target - ar.J()) < 1e-9