def test_default(self): """ Test B for the default parameters """ rf = ReimanField() BR, Bphi, BZ = rf.BR_Bphi_BZ(1.1, 0.7, 0.2) #BR_true = 0.03074843023437838 BR_true = 0.03069701258456715 Bphi_true = -1 BZ_true = -0.015359884586783487 #BZ_true = -0.015385593411689104 places = 13 print("Reiman field: diff in BR={}, Bphi={}, BZ={}".format( BR - BR_true, Bphi - Bphi_true, BZ - BZ_true)) self.assertAlmostEqual(BR, BR_true, places=places) self.assertAlmostEqual(Bphi, Bphi_true, places=places) self.assertAlmostEqual(BZ, BZ_true, places=places)
def test_default_reiman(self): """ Verify that we find the island chain for the default Reiman model field. """ # Reference values were computed for n = 31: R_hires = np.array([ 1.210161051261806, 1.205859042196043, 1.193129139755363, 1.172492507641389, 1.144794011997568, 1.111167632489991, 1.072990037046633, 1.03182422091062, 0.989355517431339, 0.947322600319092, 0.907446302139114, 0.871359163224158, 0.840538595281461, 0.816246395983861, 0.799477090824814, 0.79091721712784, 0.790917217127836, 0.799477090824802, 0.816246395983842, 0.840538595281436, 0.871359163224127, 0.907446302139079, 0.947322600319055, 0.9893555174313, 1.031824220910581, 1.072990037046597, 1.111167632489959, 1.144794011997541, 1.172492507641368, 1.193129139755349, 1.205859042196036 ]) Z_hires = np.array([ -1.871171514320581e-14, 4.230510859925994e-02, 8.287824108184585e-02, 1.200583286367612e-01, 1.523232141110329e-01, 1.783519693023813e-01, 1.970789739150235e-01, 2.077375421797886e-01, 2.098913110595882e-01, 2.034521050034265e-01, 1.886835458638171e-01, 1.661902601871677e-01, 1.368931257319292e-01, 1.019915706249662e-01, 6.291446863311645e-02, 2.126164090329064e-02, -2.126164090325258e-02, -6.291446863307985e-02, -1.019915706249327e-01, -1.368931257319001e-01, -1.661902601871442e-01, -1.886835458638002e-01, -2.034521050034169e-01, -2.098913110595865e-01, -2.077375421797946e-01, -1.970789739150372e-01, -1.783519693024019e-01, -1.523232141110595e-01, -1.200583286367927e-01, -8.287824108188092e-02, -4.230510859929714e-02 ]) n_hires = len(R_hires) # Factor 6 in the next line is because we follow the line for 6 field periods phi_hires = np.linspace(0, 6 * 2 * np.pi, n_hires, endpoint=False) # Create a default Reiman field rf = ReimanField() for nphi_float in np.linspace(9, 31, 7): nphi = int(nphi_float) pfl = periodic_field_line(rf, nphi, periods=6, R0=1.2, Z0=0) R = pfl.R phi = pfl.phi Z = pfl.Z # Interpolate the reference result to the lower-resolution phi grid: R_ref = interp1d(phi_hires, R_hires, kind='cubic')(phi) Z_ref = interp1d(phi_hires, Z_hires, kind='cubic')(phi) print('For n={}, errors in R,Z are {}, {}'.format( \ nphi, np.max(np.abs(R - R_ref)), np.max(np.abs(Z - Z_ref)))) np.testing.assert_allclose(R, R_ref, atol=1.0e-4) np.testing.assert_allclose(Z, Z_ref, atol=1.0e-4)
def test_circumference(self): """ Verify that we find the correct circumference for the Reiman field """ field = ReimanField(eps=[1e-4]) pfl = periodic_field_line(field, 11, periods=6, R0=1.2) pfl = circumference(pfl, 1.0, 0.0) iota_res = 1.0 / 6 iota_0 = 0.15 iota_1 = 0.38 circumf_analytic = 6 * np.sqrt((iota_res - iota_0) / iota_1) self.assertAlmostEqual(circumf_analytic, pfl.circumference, places=4)
def test_reiman_Opoint(self): """ Tests properties of the tangent map for the O-point of the Reiman model field. """ field = ReimanField() pfl = periodic_field_line(field, 31, periods=6, R0=1.2) #tm = tangent_map(field, R0=1.210161051261806, periods=6, rtol=1e-12, atol=1e-12) tm = tangent_map(field, pfl, rtol=1e-12, atol=1e-12) places = 10 self.assertAlmostEqual(tm.iota_per_period, 0.02892783769228813, places=places) self.assertAlmostEqual(tm.iota, 0.02892783769228813, places=places) M = np.array([[ 0.983527264227946, -0.026329866716251], [ 1.240952748303061, 0.983527264237678]]) np.testing.assert_allclose(tm.full_orbit_tangent_maps[0], M, atol=1.0e-6) self.assertAlmostEqual(tm.residue, 0.008236367883594053, places=places)
def test_reiman_axis(self): """ Tests properties of the tangent map for the magnetic axis of the Reiman model field. """ field = ReimanField() pfl = periodic_field_line(field, 11, periods=1, R0=1.0) #tm = tangent_map(field, R0=1.0, rtol=1e-12, atol=1e-12) tm = tangent_map(field, pfl, rtol=1e-12, atol=1e-12) places = 10 self.assertAlmostEqual(tm.iota_per_period, 0.15, places=places) self.assertAlmostEqual(tm.iota, 0.15, places=places) M = np.array([[ 0.587785252292183, -0.809016994374573], [ 0.809016994374573, 0.587785252292183]]) np.testing.assert_allclose(tm.full_orbit_tangent_maps[0], M, atol=1.0e-6) np.testing.assert_allclose(tm.single_period_tangent_maps[0], M, atol=1.0e-6) self.assertAlmostEqual(tm.residue, 0.20610737385390826, places=places)
def test_jacobian(self): """ Test that the Jacobian function correctly gives the derivative of func. """ field = ReimanField() for j in range(10): n = np.random.randint(1, 20) #n = 3 R = np.random.rand(n) + 0.5 Z = np.random.rand(n) - 0.5 x0 = np.concatenate((R, Z)) phi = np.random.rand(n) * 10 - 5 D = np.random.rand(n, n) print('D:') print(D) # Get analytic Jacobian: jac = jacobian(x0, n, D, phi, field) # Form finite-difference Jacobian: delta = 1e-7 jac_fd = np.zeros((2 * n, 2 * n)) for k in range(n * 2): x = np.copy(x0) x[k] = x0[k] + delta funcp = func(x, n, D, phi, field) x[k] = x0[k] - delta funcm = func(x, n, D, phi, field) jac_fd[:, k] = (funcp - funcm) / (2 * delta) print('Analytic Jacobian:') print(jac) print('Finite-difference Jacobian:') print(jac_fd) print('Difference:') print(jac - jac_fd) np.testing.assert_allclose(jac, jac_fd, atol=1.0e-6)
def test_derivatives(self): """ Test the derivatives of B. """ #rf = ReimanField(iotaj=[0]) for j in range(30): niota = np.random.randint(1,4) # 1, 2, or 3 iotaj = np.random.rand(niota) * 2 - 1 B0 = np.random.rand() + 0.5 R0 = np.random.rand() + 0.5 nm = np.random.randint(1,4) # 1, 2, or 3 ms = np.random.randint(1, 10, size=(nm,)) eps = (np.random.rand(nm) - 0.5) * 0.1 print('iotaj: ', iotaj) print('ms: ', ms) print('eps: ', eps) rf = ReimanField(iotaj=iotaj, B0=B0, R0=R0, ms=ms, eps=eps) # Pick a random location: R = np.random.rand() + 0.5 phi = np.random.rand() * 10 - 5 Z = np.random.rand() * 4 - 2 #R = 1.1 #phi = 0 #Z = 0.0 # Evaluate finite difference derivatives delta = 1e-6 delta2 = delta * 2 BRp, Bphip, BZp = rf.BR_Bphi_BZ(R + delta, phi, Z) BRm, Bphim, BZm = rf.BR_Bphi_BZ(R - delta, phi, Z) Q0p, Q1p = rf.Q0_Q1(R + delta, phi, Z) Q0m, Q1m = rf.Q0_Q1(R - delta, phi, Z) d_BR_d_R_fd = (BRp - BRm) / delta2 d_Bphi_d_R_fd = (Bphip - Bphim) / delta2 d_BZ_d_R_fd = (BZp - BZm) / delta2 d_Q0_d_R = (Q0p - Q0m) / delta2 d_Q1_d_R = (Q1p - Q1m) / delta2 print('d_Q0_d_R FD:', d_Q0_d_R) print('d_Q1_d_R FD:', d_Q1_d_R) BRp, Bphip, BZp = rf.BR_Bphi_BZ(R, phi + delta, Z) BRm, Bphim, BZm = rf.BR_Bphi_BZ(R, phi - delta, Z) Q0p, Q1p = rf.Q0_Q1(R, phi + delta, Z) Q0m, Q1m = rf.Q0_Q1(R, phi - delta, Z) d_BR_d_phi_fd = (BRp - BRm) / delta2 d_Bphi_d_phi_fd = (Bphip - Bphim) / delta2 d_BZ_d_phi_fd = (BZp - BZm) / delta2 d_Q0_d_phi = (Q0p - Q0m) / delta2 d_Q1_d_phi = (Q1p - Q1m) / delta2 BRp, Bphip, BZp = rf.BR_Bphi_BZ(R, phi, Z + delta) BRm, Bphim, BZm = rf.BR_Bphi_BZ(R, phi, Z - delta) Q0p, Q1p = rf.Q0_Q1(R, phi, Z + delta) Q0m, Q1m = rf.Q0_Q1(R, phi, Z - delta) d_BR_d_Z_fd = (BRp - BRm) / delta2 d_Bphi_d_Z_fd = (Bphip - Bphim) / delta2 d_BZ_d_Z_fd = (BZp - BZm) / delta2 d_Q0_d_Z = (Q0p - Q0m) / delta2 d_Q1_d_Z = (Q1p - Q1m) / delta2 print('d_Q0_d_Z FD:', d_Q0_d_Z) print('d_Q1_d_Z FD:', d_Q1_d_Z) print('Finite difference derivatives:') grad_B_fd = np.array([[d_BR_d_R_fd, d_BR_d_phi_fd, d_BR_d_Z_fd], [d_Bphi_d_R_fd, d_Bphi_d_phi_fd, d_Bphi_d_Z_fd], [d_BZ_d_R_fd, d_BZ_d_phi_fd, d_BZ_d_Z_fd]]) print(grad_B_fd) # Evaluate the analytic derivatives: grad_B = rf.grad_B(R, phi, Z) print('Analytic derivatives:') print(grad_B) print('Differences:') print(grad_B - grad_B_fd) places = 6 self.assertAlmostEqual(d_BR_d_R_fd, grad_B[0,0], places=places) self.assertAlmostEqual(d_BR_d_phi_fd, grad_B[0,1], places=places) self.assertAlmostEqual(d_BR_d_Z_fd, grad_B[0,2], places=places) self.assertAlmostEqual(d_Bphi_d_R_fd, grad_B[1,0], places=places) self.assertAlmostEqual(d_Bphi_d_phi_fd, grad_B[1,1], places=places) self.assertAlmostEqual(d_Bphi_d_Z_fd, grad_B[1,2], places=places) self.assertAlmostEqual(d_BZ_d_R_fd, grad_B[2,0], places=places) self.assertAlmostEqual(d_BZ_d_phi_fd, grad_B[2,1], places=places) self.assertAlmostEqual(d_BZ_d_Z_fd, grad_B[2,2], places=places)