def test_dBdX_by_dcoilcoeff_reverse_taylortest(self):
        np.random.seed(1)
        coil = get_coil()
        bs = BiotSavart([coil], [1e4])
        points = np.asarray(
            17 * [[-1.41513202e-03, 8.99999382e-01, -3.14473221e-04]])
        points += 0.001 * (np.random.rand(*points.shape) - 0.5)

        bs.set_points(points)
        coil_dofs = np.asarray(coil.get_dofs())
        B = bs.B()
        dBdX = bs.dB_by_dX()
        J0 = np.sum(dBdX**2)
        dJ = bs.B_and_dB_vjp(B, dBdX)

        h = 1e-2 * np.random.rand(len(coil_dofs)).reshape(coil_dofs.shape)
        dJ_dh = 2 * np.sum(dJ[1][0] * h)
        err = 1e6
        for i in range(5, 10):
            eps = 0.5**i
            coil.set_dofs(coil_dofs + eps * h)
            bs.clear_cached_properties()
            dBdXh = bs.dB_by_dX()
            Jh = np.sum(dBdXh**2)
            deriv_est = (Jh - J0) / eps
            err_new = np.linalg.norm(deriv_est - dJ_dh)
            assert err_new < 0.55 * err
            err = err_new
    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
Beispiel #3
0
 def stdBonAxis(self):
     bs = BiotSavart(self.coils, self.currents)
     bs.set_points(self.axis.gamma())
     Bfield = bs.B()
     devBstrength = [
         sqrt(dot(Bfieldi, Bfieldi)) - self.stel.B0 for Bfieldi in Bfield
     ]
     return std(devBstrength)
 def subtest_biotsavart_gradient_symmetric_and_divergence_free(self, idx):
     coil = get_coil()
     bs = BiotSavart([coil], [1e4])
     points = np.asarray(
         17 * [[-1.41513202e-03, 8.99999382e-01, -3.14473221e-04]])
     points += 0.001 * (np.random.rand(*points.shape) - 0.5)
     bs.set_points(points)
     dB = bs.dB_by_dX()
     assert abs(dB[idx][0, 0] + dB[idx][1, 1] + dB[idx][2, 2]) < 1e-14
     assert np.allclose(dB[idx], dB[idx].T)
    def subtest_biotsavart_dAdX_taylortest(self, idx):
        coil = get_coil()
        bs = BiotSavart([coil], [1e4])
        points = np.asarray(
            17 * [[-1.41513202e-03, 8.99999382e-01, -3.14473221e-04]])
        points += 0.001 * (np.random.rand(*points.shape) - 0.5)
        bs.set_points(points)
        A0 = bs.A()[idx]
        dA = bs.dA_by_dX()[idx]

        for direction in [
                np.asarray((1., 0, 0)),
                np.asarray((0, 1., 0)),
                np.asarray((0, 0, 1.))
        ]:
            deriv = dA.T.dot(direction)
            err = 1e6
            for i in range(5, 10):
                eps = 0.5**i
                bs.set_points(points + eps * direction)
                Aeps = bs.A()[idx]
                deriv_est = (Aeps - A0) / (eps)
                new_err = np.linalg.norm(deriv - deriv_est)
                assert new_err < 0.55 * err
                err = new_err
 def subtest_d2B_by_dXdX_is_symmetric(self, idx):
     coil = get_coil()
     bs = BiotSavart([coil], [1e4])
     points = np.asarray(
         17 * [[-1.41513202e-03, 8.99999382e-01, -3.14473221e-04]])
     points += 0.001 * (np.random.rand(*points.shape) - 0.5)
     bs.set_points(points)
     d2B_by_dXdX = bs.d2B_by_dXdX()
     for i in range(3):
         assert np.allclose(d2B_by_dXdX[idx, :, :, i],
                            d2B_by_dXdX[idx, :, :, i].T)
    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 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(
            "################################################################################"
        )
Beispiel #9
0
def pyoculusPoincare(stel,
                     qvfilename,
                     Rbegin=1.55,
                     Rend=1.62,
                     nPpts=50,
                     nPtrj=5):
    from axisOptFuncs import importCoils, getFourierCurve
    from pyoculus.solvers import PoincarePlot
    import matplotlib.pyplot as plt
    _, current = importCoils("coils." + qvfilename)
    outputFile = qvfilename + "_coil_coeffs.dat"
    coils, currents = getFourierCurve(outputFile, current)
    bs = BiotSavart(coils, currents)
    sbsp = SimsgeoBiotSavart(bs, R0=sum(stel.rc), Z0=0, Nfp=stel.nfp)
    params = dict()
    Rbegin = 1.01 * sum(stel.rc)
    params["Rbegin"] = Rbegin
    params["Rend"] = Rend
    params["nPpts"] = nPpts
    params["nPtrj"] = nPtrj
    p = PoincarePlot(sbsp, params)
    poincare_output = p.compute()
    p.plot(s=1)
    plt.savefig("poincarePyoculus_" + qvfilename + '.pdf',
                bbox_inches='tight',
                pad_inches=0)
    iota = p.compute_iota()
    p.plot_iota()
    plt.savefig("iotaPyoculus_" + qvfilename + '.pdf',
                bbox_inches='tight',
                pad_inches=0)
    plt.show()
Beispiel #10
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.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
Beispiel #11
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
Beispiel #12
0
 def test_biotsavart_both_interfaces_give_same_result(self):
     coils = [get_coil()]
     currents = [1e4]
     points = np.asarray(
         10 * [[-1.41513202e-03, 8.99999382e-01, -3.14473221e-04]])
     B1 = BiotSavart(coils, currents).set_points(points).B()
     from simsoptpp import biot_savart_B
     B2 = biot_savart_B(points, [c.gamma() for c in coils],
                        [c.gammadash() for c in coils], currents)
     assert np.linalg.norm(B1) > 1e-5
     assert np.allclose(B1, B2)
Beispiel #13
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)
Beispiel #14
0
def CoilsBonAxis(axis, qvfilename, NFP):
    from axisOptFuncs import importCoils, getFourierCurve, plot_stellarator
    from simsopt.geo.biotsavart import BiotSavart
    from numpy import sqrt, dot
    import matplotlib.pyplot as plt
    _, current = importCoils("coils." + qvfilename)
    outputFile = qvfilename + "_coil_coeffs.dat"
    coils, currents = getFourierCurve(outputFile, current)
    print("Look at resulting coils")
    plot_stellarator("coils_FOURIER_", qvfilename, coils, NFP, axis,
                     "quasisymmetry_out." + qvfilename + ".nc")
    print("Plot on-axis B from these coils")
    bs = BiotSavart(coils, currents)
    bs.set_points(axis.gamma())
    Bfield = bs.B()
    Bstrength = [sqrt(dot(Bfieldi, Bfieldi)) for Bfieldi in Bfield]
    plt.figure()
    plt.plot(Bstrength)
    plt.xlabel('phi')
    plt.ylabel('B')
    plt.savefig("Bonaxis" + qvfilename + '.pdf',
                bbox_inches='tight',
                pad_inches=0)
Beispiel #15
0
 def residue(self, guess=1.6, pp=3, qq=8, sbegin=1.58, send=1.62):
     bs = BiotSavart(self.coils, self.currents)
     sbsp = SimsgeoBiotSavart(bs, R0=sum(self.stel.rc), Z0=0, Nfp=self.nfp)
     fp = FixedPoint(sbsp, {"Z": 0.0})
     output = fp.compute(guess=guess,
                         pp=pp,
                         qq=qq,
                         sbegin=sbegin,
                         send=send)
     try:
         residue = output.GreenesResidue
     except:
         residue = 0
     return residue
Beispiel #16
0
    def test_biotsavart_exponential_convergence(self):
        coil = get_coil()
        from time import time
        # points = np.asarray(17 * [[-1.41513202e-03,  8.99999382e-01, -3.14473221e-04 ]])
        points = np.asarray(
            10 * [[-1.41513202e-03, 8.99999382e-01, -3.14473221e-04]])
        tic = time()
        btrue = BiotSavart([get_coil(1000)], [1e4]).set_points(points).B()
        # print(btrue)
        bcoarse = BiotSavart([get_coil(10)], [1e4]).set_points(points).B()
        bfine = BiotSavart([get_coil(20)], [1e4]).set_points(points).B()
        assert np.linalg.norm(btrue -
                              bfine) < 1e-4 * np.linalg.norm(bcoarse - bfine)
        # print(time()-tic)

        tic = time()
        dbtrue = BiotSavart([get_coil(1000)],
                            [1e4]).set_points(points).dB_by_dX()
        # print(dbtrue)
        dbcoarse = BiotSavart([get_coil(10)],
                              [1e4]).set_points(points).dB_by_dX()
        dbfine = BiotSavart([get_coil(20)],
                            [1e4]).set_points(points).dB_by_dX()
        assert np.linalg.norm(btrue -
                              bfine) < 1e-4 * np.linalg.norm(bcoarse - bfine)
        # print(time()-tic)

        tic = time()
        dbtrue = BiotSavart([get_coil(1000)],
                            [1e4]).set_points(points).d2B_by_dXdX()
        # print("dbtrue", dbtrue)
        dbcoarse = BiotSavart([get_coil(10)],
                              [1e4]).set_points(points).d2B_by_dXdX()
        dbfine = BiotSavart([get_coil(20)],
                            [1e4]).set_points(points).d2B_by_dXdX()
        assert np.linalg.norm(btrue -
                              bfine) < 1e-4 * np.linalg.norm(bcoarse - bfine)
Beispiel #17
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)
Beispiel #18
0
 def test_helicalcoil_Bfield(self):
     point = [[-1.41513202e-03, 8.99999382e-01, -3.14473221e-04]]
     field = [[-0.00101961, 0.20767292, -0.00224908]]
     derivative = [[[0.47545098, 0.01847397, 1.10223595],
                    [0.01847426, -2.66700072, 0.01849548],
                    [1.10237535, 0.01847085, 2.19154973]]]
     coils = [CurveHelical(100, 2, 5, 2, 1., 0.3) for i in range(2)]
     coils[0].set_dofs(np.concatenate(([0, 0], [0, 0])))
     coils[1].set_dofs(np.concatenate(([np.pi / 2, 0], [0, 0])))
     currents = [-3.07e5, 3.07e5]
     Bhelical = BiotSavart(coils, currents)
     Bhelical.set_points(point)
     assert np.allclose(Bhelical.B(), field)
     assert np.allclose(Bhelical.dB_by_dX(), derivative)
Beispiel #19
0
 def test_biotsavart_B_is_curlA(self):
     coil = get_coil()
     bs = BiotSavart([coil], [1e4])
     points = np.asarray(
         17 * [[-1.41513202e-03, 8.99999382e-01, -3.14473221e-04]])
     bs.set_points(points)
     B, dA_by_dX = bs.B(), bs.dA_by_dX()
     curlA1 = dA_by_dX[:, 1, 2] - dA_by_dX[:, 2, 1]
     curlA2 = dA_by_dX[:, 2, 0] - dA_by_dX[:, 0, 2]
     curlA3 = dA_by_dX[:, 0, 1] - dA_by_dX[:, 1, 0]
     curlA = np.concatenate(
         (curlA1[:, None], curlA2[:, None], curlA3[:, None]), axis=1)
     err = np.max(np.abs(curlA - B))
     assert err < 1e-14
Beispiel #20
0
def getResidue(stel,
               axis,
               qvfilename,
               guess=1.6,
               pp=3,
               qq=8,
               sbegin=1.58,
               send=1.62):
    from axisOptFuncs import importCoils, getFourierCurve
    from pyoculus.solvers import FixedPoint
    _, current = importCoils("coils." + qvfilename)
    outputFile = qvfilename + "_coil_coeffs.dat"
    coils, currents = getFourierCurve(outputFile, current)
    bs = BiotSavart(coils, currents)
    sbsp = SimsgeoBiotSavart(bs, R0=sum(stel.rc), Z0=0, Nfp=stel.nfp)
    fp = FixedPoint(sbsp, {"Z": 0.0})
    #sbegin=1.01*sum(stel.rc)
    output = fp.compute(guess=guess, pp=pp, qq=qq, sbegin=sbegin, send=send)
    residue = output.GreenesResidue
    print(residue)
Beispiel #21
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
Beispiel #22
0
    def test_interpolated_field_close(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 = 10
        rmin = 1.5
        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, 4, [rmin, rmax, rsteps],
                                [phimin, phimax, phisteps],
                                [zmin, zmax, zsteps], True)
        N = 10
        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
        bsh.set_points_cyl(points)
        btotal.set_points_cyl(points)
        B = btotal.B()
        Bh = bsh.B()
        dB = btotal.GradAbsB()
        dBh = bsh.GradAbsB()
        print("btotal.B()", B)
        print("bsh.B()", Bh)
        print("btotal.GradAbsB(()", dB)
        print("bsh.GradAbsB()", dBh)
        assert np.allclose(B, Bh, rtol=1e-3)
        assert np.allclose(dB, dBh, rtol=1e-3)
Beispiel #23
0
    def test_sum_Bfields(self):
        pointVar = 1e-1
        npoints = 20
        points = np.asarray(
            npoints * [[-1.41513202e-03, 8.99999382e-01, -3.14473221e-04]])
        points += pointVar * (np.random.rand(*points.shape) - 0.5)
        # Set up helical field
        coils = [CurveHelical(101, 2, 5, 2, 1., 0.3) for i in range(2)]
        coils[0].set_dofs(np.concatenate(([np.pi / 2, 0], [0, 0])))
        coils[1].set_dofs(np.concatenate(([0, 0], [0, 0])))
        currents = [-2.1e5, 2.1e5]
        Bhelical = BiotSavart(coils, currents)
        # Set up toroidal fields
        Btoroidal1 = ToroidalField(1., 1.)
        Btoroidal2 = ToroidalField(1.2, 0.1)
        # Set up sum of the three in two different ways
        Btotal1 = MagneticFieldSum([Bhelical, Btoroidal1, Btoroidal2])
        Btotal2 = Bhelical + Btoroidal1 + Btoroidal2
        Btotal3 = Btoroidal1 + Btoroidal2
        # Evaluate at a given point
        Bhelical.set_points(points)
        Btoroidal1.set_points(points)
        Btoroidal2.set_points(points)
        Btotal1.set_points(points)
        Btotal2.set_points(points)
        Btotal3.set_points(points)
        # Verify
        assert np.allclose(Btotal1.B(), Btotal2.B())
        assert np.allclose(Bhelical.B() + Btoroidal1.B() + Btoroidal2.B(),
                           Btotal1.B())
        assert np.allclose(Btotal1.dB_by_dX(), Btotal2.dB_by_dX())
        assert np.allclose(
            Bhelical.dB_by_dX() + Btoroidal1.dB_by_dX() +
            Btoroidal2.dB_by_dX(), Btotal1.dB_by_dX())

        assert np.allclose(Btoroidal1.d2B_by_dXdX() + Btoroidal2.d2B_by_dXdX(),
                           Btotal3.d2B_by_dXdX())
        assert np.allclose(Btoroidal1.A() + Btoroidal2.A(), Btotal3.A())
        assert np.allclose(Btoroidal1.dA_by_dX() + Btoroidal2.dA_by_dX(),
                           Btotal3.dA_by_dX())
        assert np.allclose(Btoroidal1.d2A_by_dXdX() + Btoroidal2.d2A_by_dXdX(),
                           Btotal3.d2A_by_dXdX())
Beispiel #24
0
 def BonAxis(self):
     bs = BiotSavart(self.coils, self.currents)
     bs.set_points(self.axis.gamma())
     Bfield = bs.B()
     Bstrength = [sqrt(dot(Bfieldi, Bfieldi)) for Bfieldi in Bfield]
     return Bstrength
Beispiel #25
0
 def test_circularcoil_Bfield(self):
     current = 1.2e7
     radius = 1.12345
     center = [0.12345, 0.6789, 1.23456]
     pointVar = 1e-1
     npoints = 1
     ## verify the field at the center of a coil in the xy plane
     Bfield = CircularCoil(I=current, r0=radius)
     points = np.array([[1e-10, 0, 0.]])
     Bfield.set_points(points)
     assert np.allclose(Bfield.B(),
                        [[0, 0, current / 1e7 * 2 * np.pi / radius]])
     # 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)))
     # Verify that, as a vacuum field, grad B=grad grad phi so that grad_i B_j = grad_j B_i
     transpGradB1 = [dBdx.T for dBdx in dB1_by_dX]
     assert np.allclose(dB1_by_dX, transpGradB1)
     ### compare to biosavart(circular_coil)
     ## at these points
     points = np.asarray(
         npoints * [[-1.41513202e-03, 8.99999382e-01, -3.14473221e-04]])
     points += pointVar * (np.random.rand(*points.shape) - 0.5)
     ## verify with a x^2+z^2=radius^2 circular coil
     normal = [np.pi / 2, 0]
     coils = [CurveXYZFourier(300, 1)]
     coils[0].set_dofs(
         [center[0], radius, 0., center[1], 0., 0., center[2], 0., radius])
     Bcircular = BiotSavart(coils, [current])
     Bfield = CircularCoil(I=current,
                           r0=radius,
                           normal=normal,
                           center=center)
     Bfield.set_points(points)
     Bcircular.set_points(points)
     dB1_by_dX = Bfield.dB_by_dX()
     transpGradB1 = [dBdx.T for dBdx in dB1_by_dX]
     assert np.allclose(Bfield.B(), Bcircular.B())
     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)
     # use normal = [0, 1, 0]
     normal = [0, 1, 0]
     coils = [CurveXYZFourier(300, 1)]
     coils[0].set_dofs(
         [center[0], radius, 0., center[1], 0., 0., center[2], 0., radius])
     Bcircular = BiotSavart(coils, [current])
     Bfield = CircularCoil(I=current,
                           r0=radius,
                           normal=normal,
                           center=center)
     Bfield.set_points(points)
     Bcircular.set_points(points)
     dB1_by_dX = Bfield.dB_by_dX()
     transpGradB1 = [dBdx.T for dBdx in dB1_by_dX]
     assert np.allclose(Bfield.B(), Bcircular.B())
     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)
     ## verify with a y^2+z^2=radius^2 circular coil
     normal = [np.pi / 2, np.pi / 2]
     coils = [CurveXYZFourier(300, 1)]
     coils[0].set_dofs(
         [center[0], 0, 0., center[1], radius, 0., center[2], 0., radius])
     Bcircular = BiotSavart(coils, [current])
     Bfield = CircularCoil(I=current,
                           r0=radius,
                           normal=normal,
                           center=center)
     Bfield.set_points(points)
     Bcircular.set_points(points)
     dB1_by_dX = Bfield.dB_by_dX()
     transpGradB1 = [dBdx.T for dBdx in dB1_by_dX]
     assert np.allclose(Bfield.B(), Bcircular.B())
     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
     Bfield.set_points([[0.1, 0.2, 0.3]])
     Afield = Bfield.A()
     assert np.allclose(Afield, [[0, 5.15786, -2.643056]])
     # use normal=[1,0,0]
     normal = [1, 0, 0]
     coils = [CurveXYZFourier(300, 1)]
     coils[0].set_dofs(
         [center[0], 0, 0., center[1], radius, 0., center[2], 0., radius])
     Bcircular = BiotSavart(coils, [current])
     Bfield = CircularCoil(I=current,
                           r0=radius,
                           normal=normal,
                           center=center)
     Bfield.set_points(points)
     Bcircular.set_points(points)
     dB1_by_dX = Bfield.dB_by_dX()
     transpGradB1 = [dBdx.T for dBdx in dB1_by_dX]
     assert np.allclose(Bfield.B(), Bcircular.B())
     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
     ## verify with a x^2+y^2=radius^2 circular coil
     center = [0, 0, 0]
     normal = [0, 0]
     coils = [CurveXYZFourier(300, 1)]
     coils[0].set_dofs(
         [center[0], 0, radius, center[1], radius, 0., center[2], 0., 0.])
     Bcircular = BiotSavart(coils, [current])
     coils2 = [CurveRZFourier(300, 1, 1, True)]
     coils2[0].set_dofs([radius, 0, 0])
     Bcircular2 = BiotSavart(coils, [current])
     Bfield = CircularCoil(I=current,
                           r0=radius,
                           normal=normal,
                           center=center)
     Bfield.set_points(points)
     Bcircular.set_points(points)
     Bcircular2.set_points(points)
     dB1_by_dX = Bfield.dB_by_dX()
     transpGradB1 = [dBdx.T for dBdx in dB1_by_dX]
     assert np.allclose(Bfield.B(), Bcircular.B())
     assert np.allclose(Bfield.B(), Bcircular2.B())
     assert np.allclose(Bfield.dB_by_dX(), Bcircular.dB_by_dX())
     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
     # use normal = [0, 0, 1]
     center = [0, 0, 0]
     normal = [0, 0, 1]
     coils = [CurveXYZFourier(300, 1)]
     coils[0].set_dofs(
         [center[0], 0, radius, center[1], radius, 0., center[2], 0., 0.])
     Bcircular = BiotSavart(coils, [current])
     coils2 = [CurveRZFourier(300, 1, 1, True)]
     coils2[0].set_dofs([radius, 0, 0])
     Bcircular2 = BiotSavart(coils, [current])
     Bfield = CircularCoil(I=current,
                           r0=radius,
                           normal=normal,
                           center=center)
     Bfield.set_points(points)
     Bcircular.set_points(points)
     Bcircular2.set_points(points)
     dB1_by_dX = Bfield.dB_by_dX()
     transpGradB1 = [dBdx.T for dBdx in dB1_by_dX]
     assert np.allclose(Bfield.B(), Bcircular.B())
     assert np.allclose(Bfield.B(), Bcircular2.B())
     assert np.allclose(Bfield.dB_by_dX(), Bcircular.dB_by_dX())
     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
Beispiel #26
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('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
Beispiel #27
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')
Beispiel #28
0
    def subtest_biotsavart_d2A_by_dXdX_taylortest(self, idx):
        coil = get_coil()
        bs = BiotSavart([coil], [1e4])
        points = np.asarray(
            17 * [[-1.41513202e-03, 8.99999382e-01, -3.14473221e-04]])
        bs.set_points(points)
        dA_by_dX, d2A_by_dXdX = bs.dA_by_dX(), bs.d2A_by_dXdX()
        for d1 in range(3):
            for d2 in range(3):
                second_deriv = d2A_by_dXdX[idx, d1, d2]
                err = 1e6
                for i in range(5, 10):
                    eps = 0.5**i

                    ed2 = np.zeros((1, 3))
                    ed2[0, d2] = 1.

                    bs.set_points(points + eps * ed2)
                    dA_dXp = bs.dA_by_dX()[idx, d1]

                    bs.set_points(points - eps * ed2)
                    dA_dXm = bs.dA_by_dX()[idx, d1]

                    second_deriv_est = (dA_dXp - dA_dXm) / (2. * eps)

                    new_err = np.linalg.norm(second_deriv - second_deriv_est)
                    print("new_err", new_err)
                    assert new_err < 0.30 * err
                    err = new_err
Beispiel #29
0
"""
This example demonstrate how to compute surfaces in Boozer coordinates for a
magnetic field induced by coils.
We start with an initial guess that is just a tube around the magnetic axis,
then we reduce the Boozer residual with BFGS first, then drive it to machine
zero with a Levenberg-Marquardt algorithm. All of this is done while keeping
the surface area constant.  We then switch the label to the Toroidal Flux, and
aim for a Boozer surface with three times larger 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)
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
Beispiel #30
0
    def test_biotsavart_coil_current_taylortest(self):
        coil0 = get_coil()
        current0 = 1e4
        coil1 = get_coil(perturb=True)
        current1 = 1e3
        bs = BiotSavart([coil0, coil1], [current0, current1])
        points = np.asarray(
            17 * [[-1.41513202e-03, 8.99999382e-01, -3.14473221e-04]])
        bs.set_points(points)
        B = bs.B()
        J = bs.dB_by_dX()
        H = bs.d2B_by_dXdX()
        dB = bs.dB_by_dcoilcurrents()
        dJ = bs.d2B_by_dXdcoilcurrents()
        dH = bs.d3B_by_dXdXdcoilcurrents()

        h = 1.
        bs.currents_optim[0].set_dofs(1e4 + h)
        bs.invalidate_cache()
        Bp = bs.B()
        Jp = bs.dB_by_dX()
        Hp = bs.d2B_by_dXdX()
        bs.currents_optim[0].set_dofs(1e4 - h)
        bs.invalidate_cache()
        Bm = bs.B()
        Jm = bs.dB_by_dX()
        Hm = bs.d2B_by_dXdX()
        dB_approx = (Bp - Bm) / (2 * h)
        dJ_approx = (Jp - Jm) / (2 * h)
        dH_approx = (Hp - Hm) / (2 * h)
        assert np.linalg.norm(dB[0] - dB_approx) < 1e-15
        assert np.linalg.norm(dJ[0] - dJ_approx) < 1e-15
        assert np.linalg.norm(dH[0] - dH_approx) < 1e-13