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
def test_dB_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() J0 = np.sum(B**2) dJ = bs.B_vjp(B) h = 1e-2 * np.random.rand(len(coil_dofs)).reshape(coil_dofs.shape) dJ_dh = 2 * np.sum(dJ[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() Bh = bs.B() Jh = np.sum(Bh**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 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 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)
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
def subtest_biotsavart_dBdX_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) B0 = bs.B()[idx] dB = bs.dB_by_dX()[idx] for direction in [ np.asarray((1., 0, 0)), np.asarray((0, 1., 0)), np.asarray((0, 0, 1.)) ]: deriv = dB.T.dot(direction) err = 1e6 for i in range(5, 10): eps = 0.5**i bs.set_points(points + eps * direction) Beps = bs.B()[idx] deriv_est = (Beps - B0) / (eps) new_err = np.linalg.norm(deriv - deriv_est) assert new_err < 0.55 * err err = new_err
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())
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)
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
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