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)
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.