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 #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 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 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 #4
0
    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_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
Exemple #7
0
    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)
Exemple #8
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 #9
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 #10
0
bs_tf = BiotSavart(coils, currents)
G0 = 2. * np.pi * np.sum(np.abs(bs.coil_currents)) * (4 * np.pi * 10**(-7) / (2 * np.pi))

mpol = 5  # try increasing this to 8 or 10 for smoother surfaces
ntor = 5  # try increasing this to 8 or 10 for smoother surfaces
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 = SurfaceXYZTensorFourier(
    mpol=mpol, ntor=ntor, stellsym=stellsym, nfp=nfp, quadpoints_phi=phis, quadpoints_theta=thetas)
s.fit_to_curve(ma, 0.10, flip_theta=True)
iota = -0.4

tf = ToroidalFlux(s, bs_tf)
ar = Area(s)
ar_target = ar.J()

boozer_surface = BoozerSurface(bs, s, ar, ar_target)

# compute surface first using LBFGS, this will just be a rough initial guess
res = boozer_surface.minimize_boozer_penalty_constraints_LBFGS(tol=1e-10, maxiter=300, constraint_weight=100., iota=iota, G=G0)
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()
# 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}")
if "DISPLAY" in os.environ:
    s.plot()