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_CaryHanson1986_page2469(self): """ Compare to some numbers quoted on page 2469 of Cary & Hanson (1986), for a helical coil with straight winding law. """ field = HelicalCoil(I=[0.0307,-0.0307]) # First consider the magnetic axis. # Cary & Hanson quote the axis position as 0.9822, but I get a bit higher, 0.9833 pfl = periodic_field_line(field, 31, R0=1.0) tm = tangent_map(field, pfl) #tm = tangent_map(field, R0=0.983393787292938) places = 8 # Cary & Hanson quote iota_per_period = 0.324. I get a bit lower. self.assertAlmostEqual(tm.iota_per_period, 0.3102585112979056, places=places)
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_helical_coil_axis(self): """ Tests properties of the tangent map for the magnetic axis of the helical coil with straight winding law. """ field = HelicalCoil() pfl = periodic_field_line(field, 31, periods=1, R0=0.983) #tm = tangent_map(field, R0=0.98343287162797) tm = tangent_map(field, pfl) places = 8 self.assertAlmostEqual(tm.iota_per_period, 0.11287146743203362, places=places) self.assertAlmostEqual(tm.iota, 0.5643573371601681, places=places) M = np.array([[ 0.75888781375709 , 1.37679244594353 ], [-0.308026489831821, 0.758887765057904]]) 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.12055610529625149, places=places)
def test_default_axis(self): """ Verify that we find the magnetic axis for the default coil shape """ # Reference values were computed for n = 49: R_hires = np.array([ 0.983432871627971, 0.983432637110481, 0.983431941763074, 0.983430809789212, 0.983429280179349, 0.983427404769668, 0.983425245683006, 0.98342287229987, 0.983420357934741, 0.983417776410061, 0.983415198725945, 0.983412690017407, 0.983410306972659, 0.983408095856758, 0.983406091246171, 0.983404315533822, 0.983402779213896, 0.983401481904256, 0.98340041401531, 0.983399558930964, 0.983398895533028, 0.983398400877746, 0.983398052823707, 0.983397832415222, 0.983397725844065, 0.983397725844065, 0.983397832415223, 0.983398052823707, 0.983398400877746, 0.983398895533027, 0.983399558930962, 0.983400414015308, 0.983401481904254, 0.983402779213895, 0.983404315533821, 0.98340609124617, 0.983408095856756, 0.983410306972658, 0.983412690017406, 0.983415198725943, 0.983417776410059, 0.98342035793474, 0.983422872299868, 0.983425245683005, 0.983427404769667, 0.983429280179349, 0.983430809789212, 0.983431941763074, 0.983432637110482 ]) Z_hires = np.array([ -1.927576710783598e-15, 1.549578479006169e-06, 3.107951790217735e-06, 4.681570705402376e-06, 6.272374388191400e-06, 7.875964783179601e-06, 9.480266858299624e-06, 1.106478775458612e-05, 1.260054942596720e-05, 1.405072542190359e-05, 1.537196563548557e-05, 1.651634593876635e-05, 1.743383561390542e-05, 1.807513727968615e-05, 1.839472429226737e-05, 1.835388162224446e-05, 1.792354961915406e-05, 1.708677673593750e-05, 1.584060718109755e-05, 1.419726163688332e-05, 1.218451175358510e-05, 9.845199408453483e-06, 7.235906361953032e-06, 4.424835199811507e-06, 1.489014427825223e-06, -1.489014435143462e-06, -4.424835207073913e-06, -7.235906369142757e-06, -9.845199415539471e-06, -1.218451176055259e-05, -1.419726164371854e-05, -1.584060718778514e-05, -1.708677674245766e-05, -1.792354962547727e-05, -1.835388162835712e-05, -1.839472429815877e-05, -1.807513728535725e-05, -1.743383561935318e-05, -1.651634594399496e-05, -1.537196564048871e-05, -1.405072542668870e-05, -1.260054943056144e-05, -1.106478775899604e-05, -9.480266862549242e-06, -7.875964787293520e-06, -6.272374392191317e-06, -4.681570709322471e-06, -3.107951794082374e-06, -1.549578482851101e-06 ]) n_hires = len(R_hires) phi_hires = np.linspace(0, 2 * np.pi / 5, n_hires, endpoint=False) # Create a default helical coil hc = HelicalCoil() for nphi in [7, 18, 23]: pfl = periodic_field_line(hc, nphi) 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-8) np.testing.assert_allclose(Z, Z_ref, atol=1.0e-8)
def test_default_islands(self): """ Verify that we find the island chain for the default coil shape """ # Reference values were computed for n = 199: R_hires = np.array([ 0.861650023626953, 0.861232699595767, 0.862565729312737, 0.86561786592225, 0.870235577745137, 0.876161310090455, 0.883064895122082, 0.890577631412007, 0.898320842141953, 0.905926033104876, 0.913048189554392, 0.919375597936231, 0.924639240127284, 0.928623323795728, 0.9311767393808, 0.932223736845882, 0.931771291226222, 0.92991073175724, 0.92681225849484, 0.922712637756442, 0.917898048553412, 0.912685103373573, 0.907403103234815, 0.90237964250539, 0.897930136925243, 0.894350224930459, 0.89190875136735, 0.890838557120035, 0.891322908362279, 0.893477354814611, 0.89732989511586, 0.902805356217111, 0.909720797999774, 0.917796038691242, 0.926677996734832, 0.935972713951315, 0.945277536203312, 0.95420807801622, 0.962418114527179, 0.969613242964151, 0.975560212848936, 0.980093573118811, 0.983120433698448, 0.984623263568736, 0.984660069455308, 0.983361145182478, 0.980921847646609, 0.977591438470289, 0.973658746882395, 0.969436030142245, 0.965242722708227, 0.961390656799315, 0.958171827064296, 0.955849015352708, 0.954648817977551, 0.954756057903951, 0.956308392022435, 0.959390226291012, 0.964025805870635, 0.970172382822027, 0.977715335138615, 0.98646755808231, 0.996175007918775, 1.006528961979905, 1.017183868151126, 1.027778335861865, 1.037956395219775, 1.047386630275871, 1.055777763739542, 1.062890237043925, 1.068543984330136, 1.072622883244375, 1.075076377967019, 1.075918650839182, 1.075225581695779, 1.073129645845928, 1.069812889437458, 1.065498182000291, 1.060439056920681, 1.054908575392336, 1.049187748615406, 1.043554094643558, 1.038270874925289, 1.033577456711566, 1.029681104706177, 1.026750351909233, 1.024909967964352, 1.024237456353865, 1.024760978567736, 1.026458619387117, 1.029258957730312, 1.033042970929175, 1.037647353490275, 1.042869352682951, 1.048473196730635, 1.0541981109347, 1.059767790014912, 1.06490104260244, 1.069323177793182, 1.072777597717377, 1.075037019562063, 1.075913783416582, 1.075268795821905, 1.073018782610609, 1.069141639450313, 1.063679737415737, 1.056741038515949, 1.048497796667554, 1.039182485735877, 1.029080469650757, 1.018518918143815, 1.007851714778757, 0.997440711091798, 0.987634619644069, 0.978747834623794, 0.971042037328482, 0.964713142165808, 0.959884910202121, 0.956608871875148, 0.954868801257401, 0.954587423048671, 0.95563338441059, 0.957827455281756, 0.960947970598329, 0.964736330144605, 0.968903734722742, 0.973140221649815, 0.977126543151077, 0.980548672444926, 0.983113950196807, 0.984567332536493, 0.984706038871914, 0.983391163513867, 0.980555407932428, 0.976206807843327, 0.970428940548307, 0.963378410988309, 0.955280315806093, 0.946421856026446, 0.93714341784957, 0.927825561066859, 0.918869989658662, 0.910673439328775, 0.903595924834044, 0.897928302003287, 0.893866561852751, 0.891499386741234, 0.890810984388381, 0.891695684072702, 0.893977615596004, 0.897429290102744, 0.901785785714209, 0.906754411130529, 0.912021844950935, 0.917261517641443, 0.922143636146595, 0.926349085417844, 0.929586842390819, 0.93161295727992, 0.9322481119151, 0.931390668200321, 0.929023057240477, 0.925210994341612, 0.920096710963727, 0.913888546033623, 0.90684946840075, 0.899286383977475, 0.891540648639122, 0.883978443003159, 0.87697810511146, 0.870910978060249, 0.866113855824605, 0.862855244381757, 0.861303038731174, 0.861504115418062, 0.86338325693737, 0.866760732249338, 0.871380399600587, 0.876938291899093, 0.883105117195876, 0.889541269496656, 0.895906655590685, 0.90186899733903, 0.907113785841174, 0.911357532072739, 0.914364001214922, 0.915961271466918, 0.916056276764088, 0.914643441679648, 0.911805215825427, 0.907704368219399, 0.902570010696117, 0.896680657600725, 0.890347737424598, 0.883901910948288, 0.877682756699879, 0.872030411649292, 0.867276139413533, 0.863728143372195 ]) Z_hires = np.array([ 0.016066024920397, 0.024578534418239, 0.03312769327938, 0.041290870523778, 0.048670756568778, 0.054933609688562, 0.059833823966299, 0.063222217625093, 0.065042084299021, 0.065319571888181, 0.064153594638279, 0.061707540808585, 0.058202421975815, 0.053909610003924, 0.049140989541686, 0.044235020131048, 0.039538546016805, 0.03538577552867, 0.032077124075208, 0.029861068416121, 0.028921566631444, 0.029372153768034, 0.031256075642912, 0.034550412628911, 0.039171524992758, 0.044979464912282, 0.051780140928608, 0.059325747554034, 0.067315914858273, 0.075403538980081, 0.083209322047937, 0.090346774034897, 0.096455076353526, 0.101232932863376, 0.104465252845851, 0.106037301557322, 0.105935862840213, 0.10424083309572, 0.101111833024207, 0.096773369024365, 0.091500236476955, 0.085603354821109, 0.079415486287956, 0.073276261522705, 0.06751637276624, 0.062441428184184, 0.058316544051848, 0.055353084417517, 0.053698913549753, 0.053433087683035, 0.054565189919634, 0.05703871851583, 0.060737318836179, 0.065492392893325, 0.071090801190908, 0.077281933767475, 0.083784211613501, 0.090291859243931, 0.096483300434329, 0.102032516082181, 0.106624015237484, 0.109970807065906, 0.111833358352413, 0.112036620503079, 0.110482299594079, 0.107154609100441, 0.102119262516968, 0.095516756321034, 0.087551648312516, 0.078479544434445, 0.068593125132609, 0.058208063927452, 0.047649308046671, 0.037237972200839, 0.027279027408836, 0.018049996159309, 0.00979093495599, 0.002696044070052, -0.003092745637143, -0.007489916949246, -0.010468073623569, -0.012057210387881, -0.012341720798895, -0.011455464187766, -0.009575301124239, -0.006913526045657, -0.003709583171601, -0.0002213687844, 0.003283672929809, 0.006537535366299, 0.009280639214757, 0.011270752249395, 0.012291722269527, 0.012161827504307, 0.01074145326795, 0.007939717447685, 0.003719618446096, -0.001898710048361, -0.008836973287882, -0.016960114466261, -0.026080160382109, -0.035962364997491, -0.046333371184109, -0.056891044154288, -0.067315632242824, -0.07728196511736, -0.086472470465463, -0.094590827764547, -0.101376024026142, -0.1066163782721, -0.110162737634522, -0.111939573751325, -0.111952299267075, -0.110289066724529, -0.107115878731703, -0.102665065976409, -0.097218714088253, -0.091089779170078, -0.08460385644757, -0.07808377074942, -0.071837781111157, -0.066150880592377, -0.061277900456734, -0.05743703502188, -0.054802862227804, -0.053498695871093, -0.053588902582389, -0.055072416988657, -0.05787892249791, -0.061868962132927, -0.066838660931895, -0.072528956451071, -0.078638489259941, -0.084838822442813, -0.090790563847726, -0.096159255616113, -0.100630457166821, -0.103924087178148, -0.105808566501471, -0.106115348384244, -0.104753782276359, -0.101724840426779, -0.097130391810058, -0.091173474195905, -0.084145843062376, -0.076402655372704, -0.068329089115282, -0.060306914990825, -0.052688268762331, -0.045779825044466, -0.039836076579185, -0.035057835988585, -0.031591888986009, -0.029529114518812, -0.02890031825339, -0.029670803860851, -0.031735935621283, -0.034920372339289, -0.038983147481291, -0.043629439812865, -0.048528139948113, -0.053332801053748, -0.057702842695738, -0.061322204034418, -0.063913836680894, -0.065250003686479, -0.065159752089596, -0.063535696434265, -0.060342068884053, -0.055624644325215, -0.049520649422693, -0.042263780785157, -0.034177765030991, -0.025653846333049, -0.01711383858607, -0.008967665362558, -0.001577152257794, 0.004766086306877, 0.009848158295041, 0.013530794390597, 0.015745933310031, 0.016491453401875, 0.015829639576981, 0.013887481844501, 0.010856349227616, 0.006988122070879, 0.002585507178533, -0.002014167438787, -0.006460355150181, -0.010412826463717, -0.013563533012745, -0.015653576585884, -0.016483710435032, -0.015918834245685, -0.013888606171679, -0.010387067856264, -0.005473857221384, 0.000721836531154, 0.007995814286963 ]) n_hires = len(R_hires) # Factor 8 in the next line is because we follow the line for 8 field periods phi_hires = np.linspace(0, 8 * 2 * np.pi / 5, n_hires, endpoint=False) # Create a default helical coil hc = HelicalCoil() for nphi in [49, 66, 79]: pfl = periodic_field_line(hc, nphi, periods=8, R0=0.862, Z0=0.016) 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)