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')
Exemple #2
0
    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
Exemple #3
0
 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
Exemple #4
0
    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)
Exemple #5
0
    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.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, 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
Exemple #6
0
    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(
            "################################################################################"
        )
Exemple #7
0
 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
Exemple #8
0
    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(
            "################################################################################"
        )
Exemple #9
0
    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
Exemple #10
0
    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)
Exemple #11
0
    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(
            "################################################################################"
        )
Exemple #12
0
    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)
Exemple #13
0
    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)
Exemple #14
0
    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
Exemple #15
0
    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
Exemple #16
0
 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')
Exemple #17
0
from simsopt.geo.qfmsurface import QfmSurface
from simsopt.geo.surfaceobjectives import QfmResidual, ToroidalFlux, Area, Volume
from simsopt.geo.coilcollection import CoilCollection
from simsopt.util.zoo import get_ncsx_data
import numpy as np
import os
"""
This example demonstrate how to compute a quadratic flux minimizing surfaces
from a magnetic field induced by coils. We start with an initial guess that
is just a tube around the magnetic axis using the NCSX coils. We first reduce
the penalty objective function to target a given toroidal flux using LBFGS.
The equality constrained objective is then reduced using SLSQP. This is repeated
for fixing the area and toroidal flux.
"""

coils, currents, ma = get_ncsx_data()
stellarator = CoilCollection(coils, currents, 3, True)
coils = stellarator.coils
currents = stellarator.currents
bs = BiotSavart(coils, currents)
bs_tf = BiotSavart(coils, currents)

mpol = 5
ntor = 5
stellsym = True
nfp = 3
constraint_weight = 1e0

phis = np.linspace(0, 1 / nfp, 25, endpoint=False)
thetas = np.linspace(0, 1, 25, endpoint=False)
s = SurfaceRZFourier(mpol=mpol,
Exemple #18
0
    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)
Exemple #19
0
logger = logging.getLogger('simsopt.field.tracing')
logger.setLevel(1)

# 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)
Exemple #20
0
    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('Residual norm after LBFGS', np.sqrt(2 * res['fun']))
        if second_stage == 'ls':
            res = boozer_surface.minimize_boozer_penalty_constraints_ls(
                tol=1e-11,
                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'])
        elif second_stage == 'residual_exact':
            res = boozer_surface.solve_residual_equation_exactly_newton(
                tol=1e-12, maxiter=10, iota=res['iota'], G=res['G'])

        print('Residual norm 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

        print(ar_target, ar.J())
        print(res['residual'][-10:])
        if surfacetype == 'SurfaceXYZTensorFourier' or second_stage == 'newton_exact':
            assert np.abs(ar_target - ar.J()) < 1e-9
        else:
            assert np.abs(ar_target - ar.J()) < 1e-4