def test_Bqs():
    nfp = 2
    _, _, ma, _ = get_24_coil_data(nfp=nfp, ppp=100)
    eta_bar = -2.25
    qsf = QuasiSymmetricField(eta_bar, ma)
    iota = qsf.iota
    assert (abs(iota - 0.038138935935663) < 1e-6)

    Bqs = qsf.B
    matlab_Bqs = np.asarray(
        [[0, 0.988522982100515, -0.151070559206963],
         [-0.010321587904285, 0.988472377058748, -0.151049080152652],
         [-0.020641457945632, 0.988320578381101, -0.150984650088425]])
    assert np.all(np.abs(Bqs[:3, :] - matlab_Bqs) < 1e-6)

    dBqs_by_dX = qsf.dB_by_dX
    assert np.allclose(dBqs_by_dX[0, :, :].T, dBqs_by_dX[0, :, :])
    matlab_dBqs_by_dx = np.asarray(
        [[0.000000000000000, -1.125930207500723, 0.616014274297893],
         [0.030176925011424, -1.125619099754597, 0.615869343228699],
         [0.060336364146126, -1.124686016345258, 0.615434630935356]])
    assert np.all(np.abs(matlab_dBqs_by_dx - dBqs_by_dX[:3, 0, :]) < 2e-6)

    matlab_dBqs_by_dy = np.asarray(
        [[-1.125930207500723, -0.000000000000000, -0.000000000000000],
         [-1.125619099754597, -0.022146228771976, 0.010281638036739],
         [-1.124686016345258, -0.044277063777819, 0.020556281775495]])
    assert np.all(np.abs(matlab_dBqs_by_dy - dBqs_by_dX[:3, 1, :]) < 2e-6)
    matlab_dBqs_by_dz = np.asarray(
        [[0.616014274297891, -0.000000000000000, -0.000000000000000],
         [0.615869343228698, 0.010281638036739, -0.008030696239448],
         [0.615434630935353, 0.020556281775495, -0.016059300368306]])
    assert np.all(np.abs(matlab_dBqs_by_dz - dBqs_by_dX[:3, 2, :]) < 2e-6)
def test_biot_savart_same_results_as_matlab():
    num_coils = 6
    nfp = 2
    coils, currents, ma, eta_bar = get_24_coil_data(nfp=nfp, ppp=20)
    currents = num_coils * [1e4]
    coil_collection = CoilCollection(coils, currents, nfp, True)
    bs = BiotSavart(coil_collection.coils, coil_collection.currents)
    points = np.asarray([
        [1.079860105000000, 0., 0.],
        [1.078778093231020, 0.041861502907184, -0.006392709264512],
    ])
    matlab_res = np.asarray([
        [0, -0.044495549447737, 0.005009283509639],
        [0.002147564148695, -0.044454924339257, 0.004992777089330],
    ])
    bs.compute(points, use_cpp=True)
    print(bs.B, "\n", matlab_res)
    assert np.allclose(bs.B, matlab_res)

    J = SquaredMagneticFieldNormOnCurve(ma, bs)
    J0 = J.J()
    assert abs(0.5 * J0 - 0.007179654002556) < 1e-10

    J = SquaredMagneticFieldGradientNormOnCurve(ma, bs)
    J0 = J.J()
    assert abs(0.5 * J0 - 0.014329772542444) < 1e-10

    if __name__ == "__main__":
        ax = None
        for i in range(0, len(coils)):
            ax = coils[i].plot(ax=ax, show=False)
        ma.plot(ax=ax)
def test_magnetic_field_objective_by_dcoilcoeffs(gradient):
    nfp = 2
    (coils, _, ma, _) = get_24_coil_data(nfp=nfp, ppp=20)
    currents = len(coils) * [1e4]
    stellerator = CoilCollection(coils, currents, nfp, True)
    bs = BiotSavart(stellerator.coils, stellerator.currents)
    if gradient:
        J = SquaredMagneticFieldGradientNormOnCurve(ma, bs)
    else:
        J = SquaredMagneticFieldNormOnCurve(ma, bs)
    J0 = J.J()
    coil_dofs = stellerator.get_dofs()
    h = 1e-2 * np.random.rand(len(coil_dofs)).reshape(coil_dofs.shape)
    dJ = stellerator.reduce_coefficient_derivatives(
        J.dJ_by_dcoilcoefficients())
    assert len(dJ) == len(h)
    deriv = np.sum(dJ * h)
    err = 1e6
    for i in range(5, 10):
        eps = 0.5**i
        stellerator.set_dofs(coil_dofs + eps * h)
        Jh = J.J()
        deriv_est = (Jh - J0) / eps
        err_new = np.linalg.norm(deriv_est - deriv)
        print("err_new %s" % (err_new))
        assert err_new < 0.55 * err
        err = err_new
def test_iota():
    nfp = 2
    _, _, ma, _ = get_24_coil_data(nfp=nfp, ppp=20)
    eta_bar = -2.25
    qsf = QuasiSymmetricField(eta_bar, ma)
    iota = qsf.iota
    assert (abs(iota - 0.038138935935663) < 1e-6)
def test_taylor_test_sigma_by_coeffs():
    nfp = 2
    (_, _, ma, eta_bar) = get_24_coil_data(nfp=nfp, ppp=20)
    qsf = QuasiSymmetricField(eta_bar, ma)
    ma_dofs = ma.get_dofs()
    np.random.seed(1)
    h = 1e-1 * np.random.rand(len(ma_dofs)).reshape(ma_dofs.shape)
    qsf.solve_state()
    dJ = qsf.dsigma_by_dcoeffs
    deriv = dJ @ h
    err = 1e6
    eps = 0.01
    while err > 1e-8:
        eps *= 0.5

        ma.set_dofs(ma_dofs + eps * h)
        qsf.clear_cached_properties()
        Jhp = qsf.sigma

        ma.set_dofs(ma_dofs - eps * h)
        qsf.clear_cached_properties()
        Jhm = qsf.sigma

        deriv_est = (Jhp - Jhm) / (2 * eps)
        err_new = np.linalg.norm(deriv_est - deriv) / np.linalg.norm(deriv)
        assert err_new < 0.26 * err
        err = err_new
        print("err_new %s" % (err_new))
    assert eps < 1e-2
def test_taylor_test_coil_currents(objective):
    num_coils = 6
    nfp = 2
    (coils, _, ma, _) = get_24_coil_data(nfp=nfp, ppp=20)
    currents = len(coils) * [1e4]
    stellerator = CoilCollection(coils, currents, nfp, True)
    bs = BiotSavart(stellerator.coils, stellerator.currents)
    bs.set_points(ma.gamma)
    qsf = QuasiSymmetricField(-2.25, ma)
    J = BiotSavartQuasiSymmetricFieldDifference(qsf, bs)
    x0 = stellerator.get_currents()
    h = 1e4 * np.random.rand(len(currents))
    if objective == "l2":
        J0 = J.J_L2()
        dJ = stellerator.reduce_current_derivatives(J.dJ_L2_by_dcoilcurrents())
    else:
        J0 = J.J_H1()
        dJ = stellerator.reduce_current_derivatives(J.dJ_H1_by_dcoilcurrents())
    assert len(dJ) == len(h)
    deriv = np.sum(dJ * h)
    err = 1e6
    eps = 0.1
    while err > 1e-7:
        eps *= 0.5
        stellerator.set_currents(x0 + eps * h)
        bs.clear_cached_properties()
        Jh = J.J_L2() if objective == "l2" else J.J_H1()
        deriv_est = (Jh - J0) / eps
        err_new = np.linalg.norm(deriv_est - deriv)
        print("err_new %s" % (err_new))
        assert err_new < 0.55 * err
        err = err_new
    assert eps < 1e-2
def test_minimum_distance_taylor_test():
    nfp = 2
    (coils, currents, ma, eta_bar) = get_24_coil_data(nfp=nfp)
    currents = len(coils) * [1e4]
    stellarator = CoilCollection(coils, currents, nfp, True)
    coils = stellarator.coils
    np.random.seed(2)
    J = MinimumDistance(coils, 0.1)
    coil_dofs = stellarator.get_dofs()
    h = np.random.rand(len(coil_dofs)).reshape(coil_dofs.shape)
    dJ = stellarator.reduce_coefficient_derivatives(J.dJ_by_dcoefficients())
    deriv = np.sum(dJ * h)
    err = 1e8
    for i in range(1, 5):
        eps = 0.1**i
        stellarator.set_dofs(coil_dofs + eps * h)
        Jp = J.J()
        stellarator.set_dofs(coil_dofs - eps * h)
        Jm = J.J()
        deriv_est = 0.5 * (Jp - Jm) / eps
        err_new = np.linalg.norm(deriv_est - deriv)
        print("err_new %s" % (err_new))
        assert err_new < 0.55**2 * err
        err = err_new
    print("deriv_est %s" % (deriv_est))
def test_quasi_symmetric_difference_same_results_as_matlab():
    num_coils = 6
    nfp = 2
    coils, currents, ma, eta_bar = get_24_coil_data(nfp=nfp, ppp=20)
    currents = num_coils * [1e4]
    coil_collection = CoilCollection(coils, currents, nfp, True)
    bs = BiotSavart(coil_collection.coils, coil_collection.currents)
    bs.set_points(ma.gamma)
    qsf = QuasiSymmetricField(-2.25, ma)
    J = BiotSavartQuasiSymmetricFieldDifference(qsf, bs)
    print(0.5 * J.J_L2())
    print(0.5 * J.J_H1())
    assert abs(3.486875802492926 - 0.5 * J.J_L2()) < 1e-5
    assert abs(8.296004257157044 - 0.5 * J.J_H1()) < 1e-5
def test_taylor_test_ma_coeffs(objective):
    num_coils = 6
    nfp = 2
    (coils, _, ma, _) = get_24_coil_data(nfp=nfp, ppp=20)
    currents = len(coils) * [1e4]
    stellerator = CoilCollection(coils, currents, nfp, True)
    bs = BiotSavart(stellerator.coils, stellerator.currents)
    bs.set_points(ma.gamma)
    qsf = QuasiSymmetricField(-2.25, ma)
    J = BiotSavartQuasiSymmetricFieldDifference(qsf, bs)
    ma_dofs = ma.get_dofs()
    np.random.seed(1)
    h = np.random.rand(len(ma_dofs)).reshape(ma_dofs.shape)
    if objective == "l2":
        J0 = J.J_L2()
        dJ = J.dJ_L2_by_dmagneticaxiscoefficients()
    else:
        J0 = J.J_H1()
        dJ = J.dJ_H1_by_dmagneticaxiscoefficients()
    assert len(dJ) == len(h)
    deriv = np.sum(dJ * h)
    err = 1e6
    eps = 0.04
    while err > 1e-11:
        eps *= 0.5
        deriv_est = 0
        shifts = [-2, -1, +1, +2]
        weights = [+1 / 12, -2 / 3, +2 / 3, -1 / 12]
        for i in range(4):
            ma.set_dofs(ma_dofs + shifts[i] * eps * h)
            bs.set_points(ma.gamma)
            qsf.clear_cached_properties()
            deriv_est += weights[i] * (J.J_L2()
                                       if objective == "l2" else J.J_H1())
        deriv_est *= 1 / eps
        err_new = np.linalg.norm(deriv_est - deriv) / np.linalg.norm(deriv)
        print("err_new %s" % (err_new))
        assert err_new < (0.55)**4 * err
        err = err_new
    assert eps < 1e-3
def test_sigma():
    nfp = 2
    _, _, ma, _ = get_24_coil_data(nfp=nfp, ppp=40)
    eta_bar = -2.25
    qsf = QuasiSymmetricField(eta_bar, ma)
    sigma = qsf.sigma
    sigma_matlab = np.asarray([
        -0.000000000000000,
        -0.056185092625620,
        -0.112382986380741,
        -0.168606294739314,
        -0.224867254805832,
        -0.281177536480886,
        -0.337548048436650,
        -0.393988739822343,
        -0.450508396607183,
        -0.507114431454616,
        -0.563812666008344,
        -0.620607104459419,
        -0.677499697256753,
        -0.734490093823280,
        -0.791575383149675,
        -0.848749821160578,
        -0.906004543788638,
        -0.963327264754031,
        -1.020701957136678,
        -1.078108517951100,
        -1.135522415096348,
        -1.192914316262969,
        -1.250249699643717,
        -1.307488446623194,
        -1.364584417023181,
        -1.421485007964753,
        -1.478130697985200,
        -1.534454578727070,
        -1.590381877307561,
        -1.645829473387029,
        -1.700705415991899,
        -1.754908446313264,
        -1.808327533997705,
        -1.860841435865964,
        -1.912318287526287,
        -1.962615239972233,
        -2.011578154939745,
        -2.059041374503194,
        -2.104827582059986,
        -2.148747773417560,
        -2.190601358069108,
        -2.230176411822216,
        -2.267250102609442,
        -2.301589311429245,
        -2.332951469797540,
        -2.361085633687722,
        -2.385733811557786,
        -2.406632560578662,
        -2.423514860486942,
        -2.436112268528834,
        -2.444157351739409,
        -2.447386384385629,
        -2.445542288955833,
        -2.438377788865210,
        -2.425658730435253,
        -2.407167521167246,
        -2.382706621428404,
        -2.352102018033593,
        -2.315206601494947,
        -2.271903364568463,
        -2.222108338719867,
        -2.165773187697747,
        -2.102887383784994,
        -2.033479902503788,
        -1.957620385304120,
        -1.875419736514573,
        -1.787030139750048,
        -1.692644499001194,
        -1.592495329566807,
        -1.486853142563567,
        -1.376024382731296,
        -1.260348991572805,
        -1.140197675702519,
        -1.015968963133882,
        -0.888086127997064,
        -0.756994057124279,
        -0.623156120721537,
        -0.487051094933613,
        -0.349170167713112,
        -0.210014042374294,
        -0.070090136929009,
        0.070090136929009,
        0.210014042374294,
        0.349170167713112,
        0.487051094933614,
        0.623156120721537,
        0.756994057124279,
        0.888086127997064,
        1.015968963133882,
        1.140197675702519,
        1.260348991572805,
        1.376024382731296,
        1.486853142563567,
        1.592495329566807,
        1.692644499001194,
        1.787030139750048,
        1.875419736514573,
        1.957620385304121,
        2.033479902503789,
        2.102887383784994,
        2.165773187697748,
        2.222108338719868,
        2.271903364568463,
        2.315206601494947,
        2.352102018033593,
        2.382706621428404,
        2.407167521167246,
        2.425658730435254,
        2.438377788865211,
        2.445542288955834,
        2.447386384385629,
        2.444157351739409,
        2.436112268528835,
        2.423514860486943,
        2.406632560578662,
        2.385733811557786,
        2.361085633687722,
        2.332951469797541,
        2.301589311429245,
        2.267250102609442,
        2.230176411822216,
        2.190601358069108,
        2.148747773417560,
        2.104827582059986,
        2.059041374503194,
        2.011578154939746,
        1.962615239972234,
        1.912318287526287,
        1.860841435865964,
        1.808327533997705,
        1.754908446313264,
        1.700705415991898,
        1.645829473387029,
        1.590381877307561,
        1.534454578727070,
        1.478130697985200,
        1.421485007964753,
        1.364584417023181,
        1.307488446623194,
        1.250249699643717,
        1.192914316262969,
        1.135522415096348,
        1.078108517951100,
        1.020701957136678,
        0.963327264754031,
        0.906004543788638,
        0.848749821160577,
        0.791575383149675,
        0.734490093823280,
        0.677499697256752,
        0.620607104459418,
        0.563812666008344,
        0.507114431454616,
        0.450508396607183,
        0.393988739822343,
        0.337548048436650,
        0.281177536480886,
        0.224867254805832,
        0.168606294739314,
        0.112382986380741,
        0.056185092625620,
    ])
    assert all(np.abs(sigma - sigma_matlab) < 1e-8)
Exemple #11
0
def test_poincareplot(nparticles=12, nperiods=20):
    nfp = 2
    coils, currents, ma, eta_bar = get_24_coil_data(nfp=nfp,
                                                    ppp=20,
                                                    at_optimum=True)
    currents = [
        1e5 * x for x in [
            -2.271314992875459, -2.223774477156286, -2.091959078815509,
            -1.917569373937265, -2.115225147955706, -2.025410501731495
        ]
    ]

    # coils, currents, ma, eta_bar = get_24_coil_data(nfp=nfp, ppp=20, at_optimum=False)
    # currents = 6 * [1]

    coil_collection = CoilCollection(coils, currents, nfp, True)
    bs = BiotSavart(coil_collection.coils, coil_collection.currents)
    rphiz, xyz, _, _ = compute_field_lines(bs,
                                           nperiods=nperiods,
                                           batch_size=8,
                                           magnetic_axis_radius=1.1,
                                           max_thickness=0.6,
                                           delta=0.02)
    nparticles = rphiz.shape[0]

    try:
        import mayavi.mlab as mlab
        if not __name__ == "__main__":
            mlab.options.offscreen = True
        for coil in coil_collection.coils:
            mlab.plot3d(coil.gamma[:, 0], coil.gamma[:, 1], coil.gamma[:, 2])
        colors = [(0.298, 0.447, 0.690), (0.866, 0.517, 0.321),
                  (0.333, 0.658, 0.407), (0.768, 0.305, 0.321),
                  (0.505, 0.447, 0.701), (0.576, 0.470, 0.376),
                  (0.854, 0.545, 0.764), (0.549, 0.549, 0.549),
                  (0.800, 0.725, 0.454), (0.392, 0.709, 0.803)]
        counter = 0
        for i in range(0, nparticles, nparticles // 5):
            mlab.plot3d(xyz[i, :, 0],
                        xyz[i, :, 1],
                        xyz[i, :, 2],
                        tube_radius=0.005,
                        color=colors[counter % len(colors)])
            counter += 1
        mlab.view(azimuth=0, elevation=0)
        if __name__ == "__main__":
            mlab.show()
        else:
            mlab.savefig("/tmp/poincare-particle.png", magnification=4)
            mlab.close()
    except ModuleNotFoundError:
        pass

    import matplotlib.pyplot as plt
    plt.figure()
    for i in range(nparticles):
        plt.scatter(rphiz[i, range(0, nperiods * 100, 100), 0],
                    rphiz[i, range(0, nperiods * 100, 100), 2],
                    s=0.1)
    # plt.show()
    plt.savefig("/tmp/poincare.png", dpi=300)
    plt.close()

    assert True  # not quite sure how to test this, so we just check that it runs.