def test_sim_init_m_fun(): mesh = CuboidMesh(nx=3, ny=4, nz=5) sim = Sim(mesh) sim.set_m(init_m, normalise=False) assert(sim.spin_at(1, 2, 3)[0] == 1) assert(sim.spin_at(1, 2, 3)[1] == 2) assert(sim.spin_at(1, 2, 3)[2] == 3)
def test_dynamic(): mesh = CuboidMesh(nx=1, ny=1, nz=1) sim = Sim(mesh, name='dyn_spin', driver='llg_stt_cpp') # sim.set_options(rtol=1e-10,atol=1e-14) sim.driver.gamma = 1.0 sim.mu_s = 1.0 sim.set_m((0.8, 0, -1)) Kx = Anisotropy(Ku=-0.05, axis=(0, 0, 1), name='Kz') sim.add(Kx) sim.p = (0, 0, 1) sim.a_J = 0.0052 sim.alpha = 0.1 ts = np.linspace(0, 1200, 401) for t in ts: sim.driver.run_until(t) mz = sim.spin[2] alpha, K, u = 0.1, 0.05, 0.0052 print(mz, u / (2 * alpha * K)) ######################################################### # The system used in this test can be solved analytically, which gives that mz = u/(2*alpha*K), # where K represents the easy-plane anisotropy. ### assert abs(mz - u / (2 * alpha * K)) / mz < 5e-4
def test_sim_init_m(): mesh = CuboidMesh(nx=3, ny=4, nz=5) sim = Sim(mesh) sim.set_m((0, 1, 0)) sim.spin.shape = (3, -1) spin_y = sim.spin[1] assert(spin_y.any() == 1)
def test_full_exch_hex_2_shells(): """ Test the x component of the exchange field when using 2 shells of neighbours, comparing the field manually. This is similar than the *test_full_exch_hex_9_shells* function but here we do not assume that the neighbours indexes are correct We set J=1 for NN and J=2 for NNN """ a = 1 shells = 2 mesh = HexagonalMesh(a * 0.5, nx=9, ny=9, shells=shells, alignment='square') sim = Sim(mesh) sim.spin.reshape(-1, 3)[:, 0] = np.arange(len(sim.spin.reshape(-1, 3)[:, 0])) Js = np.array([1., 2.]) exch = Exchange(Js) sim.add(exch) field = exch.compute_field() assert field[3 * 0] == 1. * (1 + 10 + 9) + 2. * (11 + 18) assert field[3 * 11] == (12 + 10 + 20 + 1 + 19 + 2) + 2. * (21 + 29 + 18 + 3)
def test_sim_init_m(): mesh = CuboidMesh(nx=3, ny=4, nz=5) sim = Sim(mesh) sim.set_m((0, 1, 0)) sim.spin.shape = (3, -1) spin_y = sim.spin[1] assert (spin_y.any() == 1)
def test_exch_1d(): """ Test the x component of the exchange field in a 1D mesh, with the spin ordering: 0 1 2 3 4 5 """ mesh = CuboidMesh(nx=5, ny=1, nz=1) sim = Sim(mesh) exch = Exchange(1.0) sim.add(exch) sim.set_m(init_m, normalise=False) field = exch.compute_field() assert field[0] == 1 assert field[1 * 3] == 2 assert field[2 * 3] == 4 assert field[3 * 3] == 6 assert field[4 * 3] == 3 assert np.max(field[2::3]) == 0 assert np.max(field[1::3]) == 0
def test_dynamic(): mesh = CuboidMesh(nx=1, ny=1, nz=1) sim = Sim(mesh, name='dyn_spin', driver='llg_stt_cpp') # sim.set_options(rtol=1e-10,atol=1e-14) sim.driver.gamma = 1.0 sim.mu_s = 1.0 sim.set_m((0.8,0,-1)) Kx = Anisotropy(Ku=-0.05, axis=(0, 0, 1), name='Kz') sim.add(Kx) sim.p = (0,0,1) sim.a_J = 0.0052 sim.alpha = 0.1 ts = np.linspace(0, 1200, 401) for t in ts: sim.driver.run_until(t) mz = sim.spin[2] alpha, K, u = 0.1, 0.05, 0.0052 print(mz, u/(2*alpha*K)) ######################################################### # The system used in this test can be solved analytically, which gives that mz = u/(2*alpha*K), # where K represents the easy-plane anisotropy. ### assert abs(mz - u/(2*alpha*K))/mz< 5e-4
def relax_neb(k, maxst, simname, init_im, interp, save_every=10000): """ Execute a simulation with the NEB function of the FIDIMAG code The simulations are made for a specific spring constant 'k' (a float), number of images 'init_im', interpolations between images 'interp' (an array) and a maximum of 'maxst' steps. 'simname' is the name of the simulation, to distinguish the output files. --> vtks and npys are saved in files starting with the 'simname' string """ # Prepare simulation sim = Sim(mesh, name=simname) sim.gamma = const.gamma # magnetisation in units of Bohr's magneton sim.mu_s = 2. * const.mu_B # Exchange constant in Joules: E = Sum J_{ij} S_i S_j J = 12. * const.meV exch = UniformExchange(J) sim.add(exch) # DMI constant in Joules: E = Sum D_{ij} S_i x S_j D = 2. * const.meV dmi = DMI(D, dmi_type='interfacial') sim.add(dmi) # Anisotropy along +z axis ku = Anisotropy(Ku=0.5 * const.meV, axis=[0, 0, 1], name='ku') sim.add(ku) # Initial images init_images = init_im # Number of images between each state specified before (here we need only # two, one for the states between the initial and intermediate state # and another one for the images between the intermediate and final # states). Thus, the number of interpolations must always be # equal to 'the number of initial states specified', minus one. interpolations = interp neb = NEB_Sundials(sim, init_images, interpolations=interpolations, spring=k, name=simname) neb.relax(max_steps=maxst, save_vtk_steps=save_every, save_npy_steps=save_every, stopping_dmdt=1e-2)
def test_demag_two_spin_xx(): mesh = CuboidMesh(nx=2, ny=1, nz=1) sim = Sim(mesh) demag = Demag() sim.add(demag) sim.set_m((1, 0, 0)) field = demag.compute_field() print field assert(field[0] == 2e-7) assert(field[3] == 2e-7)
def test_full_exch_hex_9_shells_J_rings(): """ Test the x component of the exchange field when using 9 shells of neighbours in a 11 X 11 hexagonal lattice with square and diagonal arrangement We set J=1,2,3,.. for every shell and set the s_x component of the spins as the lattice site number: [0, 1, 2, 3, ... 120] Since we set the s_x components as the lattice position indexes, the x component of the field is the sum of the indexes of the neighbours (assuming the neighbours indexing is correct) multiplied by J[i] where i is the shell (1, 2, ...9), i.e. the 1st shell of ngbs is multiplied by 1, the 2nd shell by 2, the 3rd shell by 3, and so on """ for arrang in ['square', 'diagonal']: a = 1 shells = 9 mesh = HexagonalMesh(a * 0.5, nx=11, ny=11, shells=shells, alignment=arrang) sim = Sim(mesh) # Set s_x as the lattice site number sim.spin.reshape(-1, 3)[:, 0] = np.arange(len(sim.spin.reshape(-1, 3)[:, 0])) # Exchange constants according to the shell Js = np.arange(1, 10) exch = Exchange(Js) sim.add(exch) field = exch.compute_field() # We only test for the 60th lattice site ngbs_60 = mesh.neighbours[60] sum_ngbs = mesh._sum_ngbs_shell # For every shell, find the ngb indexes in that shell and multiply the # sum by the corresponding J=1, 2, 3, ... sum_rings = 0 for i in range(1, shells + 1): ngbs_range = slice(sum_ngbs[i - 1], sum_ngbs[i]) print('J = ', Js[i - 1], ' ngbs indexes: ', ngbs_60[ngbs_range]) sum_rings += Js[i - 1] * np.sum(ngbs_60[ngbs_range]) assert field[3 * 60] == sum_rings
def test_sim_pin(): mesh = CuboidMesh(nx=3, ny=2, nz=1) sim = Sim(mesh) sim.set_m((0, 0.8, 0.6)) sim.alpha = 0.1 sim.gamma = 1.0 sim.pins = pin_fun anis = Anisotropy(Ku=1.0, axis=[0, 0, 1], name='Dx') sim.add(anis) sim.run_until(1.0) assert sim.spin[0] == 0 assert sim.spin[2] != 0
def disable_test_sim_single_spin_llg_stt(do_plot=False): ni = Nickel() mesh = CuboidMesh(nx=1, ny=1, nz=1) mesh.set_material(ni) ni.alpha = 0.1 sim = Sim(mesh, driver='llg_stt') sim.set_m((1, 0, 0)) H0 = 1 sim.add(Zeeman((0, 0, H0))) dt = 1e-12 ts = np.linspace(0, 200 * dt, 101) precession = ni.gamma / (1 + ni.alpha**2) mz_ref = [] mxyz = [] real_ts = [] for t in ts: sim.run_until(t) real_ts.append(sim.t) print(sim.t, abs(sim.spin_length()[0] - 1), sim.spin) mz_ref.append(np.tanh(precession * ni.alpha * H0 * sim.t)) mxyz.append(np.copy(sim.spin)) mxyz = np.array(mxyz) if do_plot: ts_ns = np.array(real_ts) * 1e9 plt.plot(ts_ns, mxyz[:, 0], ".-", label="mx") plt.plot(ts_ns, mxyz[:, 1], ".-", label="my") plt.plot(ts_ns, mxyz[:, 2], ".-", label="mz") plt.plot(ts_ns, mz_ref, "-", label="analytical") plt.xlabel("time (ns)") plt.ylabel("mz") plt.title("integrating a macrospin") plt.legend() plt.savefig("test_llg_stt.png") print(("Deviation = {0}".format(np.max(np.abs(mxyz[:, 2] - mz_ref))))) assert np.max(np.abs(mxyz[:, 2] - mz_ref)) < 1e-9
def test_full_exch_hex_9_shells(): """ Test the x component of the exchange field when using 9 shells of neighbours in a 9 X 9 hexagonal lattice with square and diagonal arrangement We set J=1 for every shell and set the s_x component of the spins as the lattice site number: [0, 1, 2, 3, ... 80] Since we set the s_x components as the lattice position indexes, the x component of the field is just the sum of the indexes of the neighbours (assuming the neighbours indexing is correct) because we set the exchange constants as 1 """ for arrang in ['square', 'diagonal']: a = 1 shells = 9 mesh = HexagonalMesh(a * 0.5, nx=9, ny=9, shells=shells, alignment=arrang) sim = Sim(mesh) # Set s_x as the lattice site number sim.spin.reshape(-1, 3)[:, 0] = np.arange(len(sim.spin.reshape(-1, 3)[:, 0])) Js = np.ones(shells) exch = Exchange(Js) sim.add(exch) field = exch.compute_field() # Test the x component for every lattice site, summing the neighbours # index and removing the -1 elements (their contribution is zero) for i in range(sim.mesh.n): assert field[3 * i] == np.sum( remove_negatives(sim.mesh.neighbours[i]))
def test_exch_1d_spatial(): """ Test the x component of the exchange field in a 1D mesh, with the spin ordering: 0 1 2 3 4 5 """ mesh = CuboidMesh(nx=12, ny=1, nz=1) sim = Sim(mesh) exch = Exchange(spatial_J) sim.add(exch) sim.set_m(init_m, normalise=False) field = exch.compute_field() assert exch._J[3,3] == -1.0 assert exch._J[5,1] == 0.3 assert exch._J[6,0] == 0.3 assert exch._J[8,5] == 1.0
def test_sim_init_m_fun(): mesh = CuboidMesh(nx=3, ny=4, nz=5) sim = Sim(mesh) sim.set_m(init_m, normalise=False) assert (sim.spin_at(1, 2, 3)[0] == 1) assert (sim.spin_at(1, 2, 3)[1] == 2) assert (sim.spin_at(1, 2, 3)[2] == 3)
def test_full_exch_hex_3_shells_lattice_pos(): """ Test the x component of the exchange field when using 3 shells of neighbours in a 9 x 9 hexagonal lattice with square arrangement We set the s_x and s_y spin components as the (i, j) index of the lattice positions: """ a = 1 shells = 3 mesh = HexagonalMesh(a * 0.5, nx=9, ny=9, shells=shells, alignment='square') sim = Sim(mesh) # Set the indexes (i, j) as their s_x, s_y position sim.set_m(lambda r: init_m(r, a), normalise=False) Js = np.ones(shells) exch = Exchange(Js) sim.add(exch) field = exch.compute_field() assert field[3 * 0] == (1 + 1 + 0) + (2 + 0) + (2 + 1) # f_x 1st spin assert field[3 * 11] == ((3 + 1 + 2 + 1 + 1 + 2) + (3 + 0 + 2 + 0 + 0 + 3) + (4 + 0 + 3 + 0 + 1 + 0))
def test_exch_3d(): """ Test the exchange field of the spins in this 3D mesh: bottom layer: 8 9 10 11 4 5 6 7 x 2 0 1 2 3 The assertions are the mx component of the: 0, 1, 2, .. 7 spins Remember the new new ordering: fx1, fy1, fz1, fx2, ... """ mesh = CuboidMesh(nx=4, ny=3, nz=2) sim = Sim(mesh) exch = UniformExchange(1) sim.add(exch) sim.set_m(init_m, normalise=False) field = exch.compute_field() # print field assert field[0] == 1 assert field[3] == 0 + 1 + 2 + 1 assert field[6] == 1 + 2 + 3 + 2 assert field[9] == 2 + 3 + 3 assert field[4 * 3] == 1 assert field[5 * 3] == 5 assert field[6 * 3] == 10 assert field[7 * 3] == 11
def test_exch_2d_pbc2d(): """ Test the exchange field components in a 2D mesh with PBCs The mesh sites: 3 4 5 --> (0,1,0) (1,1,0) (2,1,0) y ^ 0 1 2 (0,0,0) (1,0,0) (2,0,0) | x --> The expected components are in increasing order along x """ mesh = CuboidMesh(nx=3, ny=2, nz=1, periodicity=(True, True, False)) print mesh.neighbours sim = Sim(mesh) exch = UniformExchange(1) sim.add(exch) sim.set_m(init_m, normalise=False) field = exch.compute_field() expected_x = np.array([3, 4, 5, 3, 4, 5]) expected_y = np.array([2, 2, 2, 2, 2, 2]) # Since the field ordering is now: fx1 fy1 fz1 fx2 ... # We extract the x components jumping in steps of 3 assert np.max(abs(field[::3] - expected_x)) == 0 # For the y component is similar, now we start at the 1th # entry and jump in steps of 3 assert np.max(abs(field[1::3] - expected_y)) == 0 # Similar fot he z component assert np.max(field[2::3]) == 0
def test_exch_1d(): """ Test the x component of the exchange field in a 1D mesh, with the spin ordering: 0 1 2 3 4 5 """ mesh = CuboidMesh(nx=5, ny=1, nz=1) sim = Sim(mesh) exch = UniformExchange(1) sim.add(exch) sim.set_m(init_m, normalise=False) field = exch.compute_field() assert field[0] == 1 assert field[1 * 3] == 2 assert field[2 * 3] == 4 assert field[3 * 3] == 6 assert field[4 * 3] == 3 assert np.max(field[2::3]) == 0 assert np.max(field[1::3]) == 0
def test_sim_spins(do_plot=False): mesh = CuboidMesh(nx=10, ny=5, nz=1) sim = Sim(mesh, name='10spin') alpha = 0.1 gamma = 2.21e5 sim.driver.alpha = alpha sim.driver.gamma = gamma sim.mu_s = 1.0 sim.set_m((1, 0, 0)) print(sim.spin) H0 = 1e5 sim.add(Zeeman((0, 0, H0))) ts = np.linspace(0, 1e-9, 101) mx = [] my = [] mz = [] real_ts = [] for t in ts: sim.driver.run_until(t) real_ts.append(sim.driver.t) #print sim.driver.t, abs(sim.spin_length()[0] - 1) av = sim.compute_average() mx.append(av[0]) my.append(av[1]) mz.append(av[2]) #sim.save_vtk() mz = np.array(mz) # print mz a_mx, a_my, a_mz = single_spin(alpha, gamma, H0, ts) print(sim.driver.stat()) if do_plot: plot(real_ts, mx, my, mz, a_mx, a_my, a_mz, name='spins.pdf', title='integrating spins') print(("Max Deviation = {0}".format( np.max(np.abs(mz - a_mz))))) assert np.max(np.abs(mz - a_mz)) < 5e-7
def test_zeeman(): """ Test the x and y component of the zeeman field for the 2nd spin 6 7 8 9 10 11 0 1 2 3 4 5 ^ """ mesh = CuboidMesh(nx=5, ny=2, nz=1) sim = Sim(mesh) sim.set_m((1, 0, 0)) zeeman = Zeeman(varying_field) sim.add(zeeman) field = zeeman.compute_field() assert field[2 * 3] == 1.2 * (2 + 0.5) assert field[2 * 3 + 1] == 2.3 * 0.5
def dynamic(mesh): sim = Sim(mesh, name='dyn_spin', driver='slonczewski') # sim.set_options(rtol=1e-10,atol=1e-14) sim.driver.gamma = 1.0 sim.mu_s = 1.0 sim.set_m((0.8,0,-1)) Kx = Anisotropy(Ku=-0.05, axis=(0, 0, 1), name='Kz') sim.add(Kx) sim.p = (0,0,1) sim.u0 = 0.005 sim.driver.alpha = 0.1 ts = np.linspace(0, 1200, 401) for t in ts: sim.run_until(t) #sim.save_vtk() print t
def test_exch_3d(): """ Test the exchange field of the spins in this 3D mesh: bottom layer: 8 9 10 11 4 5 6 7 x 2 0 1 2 3 Assertions are according to the mx component of the spins, since J is set to 1 Spin components are given according to the (i, j) index position in the lattice: i lattice site [[ 0. 0. 0.] --> 0 j=0 [ 1. 0. 0.] --> 1 [ 2. 0. 0.] --> 2 [ 3. 0. 0.] --> 3 [ 0. 1. 0.] --> 4 j=1 [ 1. 1. 0.] ... Remember the field ordering: fx0, fy0, fz0, fx1, ... """ mesh = CuboidMesh(nx=4, ny=3, nz=2) sim = Sim(mesh) exch = UniformExchange(1) sim.add(exch) sim.set_m(init_m, normalise=False) field = exch.compute_field() # print field # Exchange from 0th spin assert field[0] == 1 # Exchange from 1st spin # spin: 2 0 5 13 # mx: 2 0 1 1 assert field[3] == 2 + 0 + 1 + 1 # Exchange from 2nd spin # spin: 3 1 6 14 # mx: 3 1 2 2 assert field[6] == 3 + 1 + 2 + 2 # ... assert field[9] == 2 + 3 + 3 assert field[4 * 3] == 1 assert field[5 * 3] == 5 assert field[6 * 3] == 10 assert field[7 * 3] == 11
def excite_system(mesh, time=0.1, snaps=11): # Specify the stt dynamics in the simulation sim = Sim(mesh, name='dyn', driver='llg_stt') # Set the simulation parameters sim.driver.set_tols(rtol=1e-12, atol=1e-12) sim.driver.gamma = 2.211e5 / mu0 sim.mu_s = 1e-27 / mu0 sim.alpha = 0.05 sim.set_m(np.load('m0.npy')) # Energies exch = UniformExchange(J=2e-20) sim.add(exch) anis = Anisotropy(0.01 * 2e-20, axis=(0, 0, 1)) sim.add(anis) # dmi = DMI(D=8e-4) # sim.add(dmi) # Set the current in the x direction, in A / m # beta is the parameter in the STT torque sim.driver.jz = -1e12 sim.driver.beta = 0.1 # The simulation will run for x ns and save # 'snaps' snapshots of the system in the process ts = np.linspace(0, time * 1e-9, snaps) for t in ts: print('time', t) sim.driver.run_until(t) #sim.save_vtk() np.save('m1.npy', sim.spin) print(np.load('m1.npy')[:100])
def single_spin(alpha=0.01): mat = Material() mesh = CuboidMesh(nx=1, ny=1, nz=1) sim = Sim(mesh, driver='sllg') sim.driver.alpha = alpha sim.driver.gamma = mat.gamma sim.mu_s = mat.mu_s sim.T = 10000 sim.set_m((1, 1, 1)) #sim.add(Zeeman(1,(0, 0, 1))) anis = Anisotropy(mat.K, direction=(0, 0, 1)) sim.add(anis) dt = 0.5e-12 ts = np.linspace(0, 1000 * dt, 1001) sx = [] sy = [] for t in ts: sim.run_until(t) sx.append(sim.spin[0]) sy.append(sim.spin[1]) print(t) plt.plot(sx, sy) plt.xlabel("$S_x$") plt.ylabel("$S_y$") plt.grid() plt.axis((-0.9, 0.9, -0.9, 0.9)) plt.axes().set_aspect('equal') plt.savefig("macrospin.pdf")
def relax_system(mesh): sim = Sim(mesh, name='relax') # sim.set_options(rtol=1e-10,atol=1e-14) sim.driver.alpha = 1.0 sim.driver.gamma = 1.0 sim.mu_s = 1.0 sim.set_m(init_m) # sim.set_m(random_m) # sim.set_m(np.load('m_10000.npy')) J = 1.0 exch = UniformExchange(J) sim.add(exch) Kx = Anisotropy(Ku=0.005, axis=(1, 0, 0), name='Kx') sim.add(Kx) sim.relax(dt=2.0, stopping_dmdt=1e-6, max_steps=1000, save_m_steps=100, save_vtk_steps=50) np.save('m0.npy', sim.spin)
def relax_system(mesh): sim = Sim(mesh, name='dmi_2d') sim.driver.alpha = 0.1 sim.driver.gamma=1.76e11 sim.mu_s = 1e-22 J = 1e-20 exch = UniformExchange(J) sim.add(exch) dmi = DMI(0.1 * J) sim.add(dmi) sim.set_m(init_m) ts = np.linspace(0, 5e-10, 101) for t in ts: print(t) sim.run_until(t) #sim.save_vtk() return sim.spin
def test_demag_fft_exact(): mesh = CuboidMesh(nx=5, ny=3, nz=4) sim = Sim(mesh) demag = Demag() sim.add(demag) def init_m(pos): x = pos[0] if x <= 2: return (1, 0, 0) elif x >= 4: return (0, 0, 1) else: return (0, 1, 0) sim.set_m(init_m) fft = demag.compute_field() exact = demag.compute_exact() # print fft,exact print np.max(np.abs(fft - exact)) assert np.max(np.abs(fft - exact)) < 5e-22
def create_sim(): mesh = CuboidMesh(nx=121,ny=121,nz=1) sim=Sim(mesh,name='relax') sim.driver.alpha = 1.0 sim.driver.gamma = 0.5 sim.mu_s = mu_s sim.set_m(init_m) J = 1.0 exch = UniformExchange(J) sim.add(exch) D = 0.08 dmi = DMI(D) sim.add(dmi) K = 4e-3 anis=Anisotropy(K, direction=(0,0,1),name='Ku') sim.add(anis) return sim
def test_exch_energy_1d(): mesh = CuboidMesh(nx=2, ny=1, nz=1) sim = Sim(mesh) exch = UniformExchange(1.23) sim.add(exch) sim.set_m((0, 0, 1)) energy = exch.compute_energy() assert energy == -1.23
def test_demag_two_spin_xx(): mesh = CuboidMesh(nx=2, ny=1, nz=1) sim = Sim(mesh) demag = Demag() sim.add(demag) sim.set_m((1, 0, 0)) field = demag.compute_field() print(field) assert (field[0] == 2e-7) assert (field[3] == 2e-7)
def test_sim_pin(): mesh = CuboidMesh(nx=3, ny=2, nz=1) sim = Sim(mesh) sim.set_m((0, 0.8, 0.6)) sim.driver.alpha = 0.1 sim.driver.gamma = 1.0 sim.pins = pin_fun anis = Anisotropy(Ku=1.0, axis=[0, 0, 1], name='Dx') sim.add(anis) sim.driver.run_until(1.0) assert sim.spin[0] == 0 assert sim.spin[2] != 0
def test_sim_single_spin_sllg(do_plot=False): mesh = CuboidMesh(nx=1, ny=1, nz=1) sim = Sim(mesh, name='spin', driver='sllg') alpha = 0.1 gamma = 2.21e5 sim.driver.set_options(dt=5e-15, gamma=gamma) sim.driver.alpha = alpha sim.mu_s = 1.0 sim.set_m((1, 0, 0)) H0 = 1e5 sim.add(Zeeman((0, 0, H0))) ts = np.linspace(0, 1e-10, 101) mx = [] my = [] mz = [] real_ts = [] for t in ts: sim.driver.run_until(t) real_ts.append(sim.driver.t) print(sim.driver.t, abs(sim.spin_length()[0] - 1)) mx.append(sim.spin[0]) my.append(sim.spin[1]) mz.append(sim.spin[2]) mz = np.array(mz) a_mx, a_my, a_mz = single_spin(alpha, gamma, H0, ts) if do_plot: plot(real_ts, mx, my, mz, a_mx, a_my, a_mz, name='spin_sllg.pdf', title='integrating a spin') print(("Max Deviation = {0}".format( np.max(np.abs(mz - a_mz))))) assert np.max(np.abs(mz - a_mz)) < 1e-8
def excite_system(mesh, time=0.1, snaps=11): # Specify the stt dynamics in the simulation sim = Sim(mesh, name='dyn', driver='llg_stt') # Set the simulation parameters sim.driver.set_tols(rtol=1e-12, atol=1e-12) sim.driver.gamma = 2.211e5 / mu0 sim.mu_s = 1e-27 / mu0 sim.alpha = 0.05 sim.set_m(np.load('m0.npy')) # Energies exch = UniformExchange(J=2e-20) sim.add(exch) anis = Anisotropy(0.01*2e-20, axis=(0, 0, 1)) sim.add(anis) # dmi = DMI(D=8e-4) # sim.add(dmi) # Set the current in the x direction, in A / m # beta is the parameter in the STT torque sim.driver.jz = -1e12 sim.driver.beta = 0.1 # The simulation will run for x ns and save # 'snaps' snapshots of the system in the process ts = np.linspace(0, time * 1e-9, snaps) for t in ts: print('time', t) sim.driver.run_until(t) #sim.save_vtk() np.save('m1.npy', sim.spin) print(np.load('m1.npy')[:100])
def relax_system(rtol=1e-10, atol=1e-12): """numerical solution""" mesh = CuboidMesh(nx=1, ny=1, nz=1) sim = Sim(mesh, name='relax') sim.driver.set_tols(rtol=rtol, atol=atol) sim.driver.alpha = 0.5 sim.driver.gamma = 2.21e5 sim.mu_s = 1.0 sim.set_m((1.0, 0, 0)) sim.add(Zeeman((0, 0, 1e5))) ts = np.linspace(0, 1e-9, 1001) for t in ts: sim.driver.run_until(t)
def test_exch_1d_pbc(): mesh = CuboidMesh(nx=5, ny=1, nz=1, periodicity=(True, False, False)) sim = Sim(mesh) exch = UniformExchange(1) sim.add(exch) sim.set_m(init_m, normalise=False) field = exch.compute_field() assert field[0] == 1 + 4 assert field[3] == 2 assert field[6] == 4 assert field[9] == 6 assert field[12] == 3 + 0 assert np.max(field[2::3]) == 0 assert np.max(field[1::3]) == 0
def test_exch_2d(): mesh = CuboidMesh(nx=5, ny=2, nz=1) sim = Sim(mesh) exch = UniformExchange(1) sim.add(exch) sim.set_m(init_m, normalise=False) field = exch.compute_field() assert np.max(field[2::3]) == 0 assert field[0] == 1 assert field[3] == 2 + 1 assert field[6] == 1 + 2 + 3 assert field[9] == 2 + 3 + 4 assert field[12] == 3 + 4
def test_dmi_1d(): mesh = CuboidMesh(nx=2, ny=1, nz=1) sim = Sim(mesh) sim.set_m((1, 0, 0)) dmi = DMI(D=1) sim.add(dmi) field = dmi.compute_field() expected = np.array([0, 0, 0, 0, 0, 0]) assert (field == expected).all() energy = dmi.compute_energy() assert energy == 0
def test_dmi_1d_field(): mesh = CuboidMesh(nx=2, ny=1, nz=1) sim = Sim(mesh) sim.set_m(init_m) dmi = DMI(D=1.23) sim.add(dmi) field = dmi.compute_field() expected = np.array([0, -1, 0, 0, 0, -1]) * 1.23 assert np.allclose(field, expected) energy = dmi.compute_energy() assert energy == 1.23
def test_demag_fft_exact_oommf(): mesh = CuboidMesh(nx=5, ny=3, nz=2, unit_length=1e-9) sim = Sim(mesh) demag = Demag() sim.add(demag) def init_m(pos): x = pos[0] if x <= 2: return (1, 0, 0) elif x >= 4: return (0, 0, 1) else: return (0, 1, 0) sim.set_m(init_m) fft = demag.compute_field() exact = demag.compute_exact() np.testing.assert_allclose(fft, exact, rtol=1e-10)
def test_exch_1d_spatial(): """ Test the x component of the exchange field in a 1D mesh, with the spin ordering: 0 1 2 3 4 5 """ mesh = CuboidMesh(nx=12, ny=1, nz=1) sim = Sim(mesh) exch = Exchange(spatial_J) sim.add(exch) sim.set_m(init_m, normalise=False) field = exch.compute_field() assert exch._J[3, 3] == -1.0 assert exch._J[5, 1] == 0.3 assert exch._J[6, 0] == 0.3 assert exch._J[8, 5] == 1.0
def __init__(self, image_path, image_range=[0, 21.03, 0, 17.79], mesh_a=0.2715, shells=1, # mesh_nx=79, # mesh_ny=78 sim_name='unnamed', bg_colour=(1., 1., 1.), driver='llg' ): """ Generate an object on top of the fidimag simulation class, to generate an atomistic simulation using a hexagonal mesh, where the magnetic moments are populated in the mesh according to the pixels in a PNG image, located in *image_path* The mesh size is generated automatically from the dimensions provided for the image (the *image_range* array), so that the mesh covers the whole picture. It is recommended that the image has white borders since mesh points away from the picture range will take the values from the closest boundary point (see the populate_mesh function) image_range :: An array [xmin, xmax, ymin, ymax] with the ranges of the image, given in nm """ # print 'Mesh spacings are: nx = {}, ny = {}'.format(mesh_a, # mesh_a * np.sqrt(3) * 0.5) self.image_path = image_path self.image_range = image_range mesh_nx = int(np.around(np.abs(image_range[1] - image_range[0]) / mesh_a)) mesh_ny = int(np.around( np.abs(image_range[3] - image_range[2]) / (mesh_a * np.sqrt(3) * 0.5) )) self.mesh = HexagonalMesh(mesh_a * 0.5, mesh_nx, mesh_ny, # periodicity=(True, True), alignment='square', unit_length=1e-9, shells=shells ) self.sim = Sim(self.mesh, name=sim_name, driver=driver) # Generate the 2D matrix with the image # If the image is B/W, every entry will have either [1., 1., 1.] # or [0., 0., 0.] representing the RGB data from every pixel self.image_data = mpl.image.imread(self.image_path) # We will create two new matrices, with the X and Y coordinates # of every point in the image matrix, using the range # provided in the arguments. For doing this, we use a meshgrid, which # automatically generates a 2D mesh of coordinates. The range # in the Y coordinates matrix is reversed since the image matrix # starts from top to bottom to generate the picture. # The shape is [n_rows, n_columns] --> (ny, nx) self.image_coords_x = np.linspace(self.image_range[0], self.image_range[1], self.image_data.shape[1]) self.image_coords_y = np.linspace(self.image_range[3], self.image_range[2], self.image_data.shape[0]) (self.image_coords_x, self.image_coords_y) = np.meshgrid(self.image_coords_x, self.image_coords_y) self.bg_colour = bg_colour
def relax_system(mesh): sim=Sim(mesh,name='relax') sim.set_options(rtol=1e-12,atol=1e-14) sim.do_precession = False sim.alpha = 0.5 sim.gamma = 1.0 sim.mu_s = 1.0 sim.set_m(init_m) J = 1.0 exch = UniformExchange(J) sim.add(exch) D = 0.18 dmi = DMI(D) sim.add(dmi) zeeman = Zeeman([0,0e-3,2e-2],name='H') sim.add(zeeman) sim.relax(dt=2.0, stopping_dmdt=1e-8, max_steps=10000, save_m_steps=None, save_vtk_steps=100) np.save('m0.npy',sim.spin)
def test_m_average(): mesh = CuboidMesh(nx=3, ny=4, nz=5) sim = Sim(mesh) sim.set_m((0, 0, 1)) a = sim.compute_average() assert a[2] == 1.0
def skip_test_sim_T_fun(): mesh = CuboidMesh(nx=3, ny=4, nz=5) sim = Sim(mesh) sim.set_T(init_T) assert(sim.T[0] == 1.5) assert(sim.T[-1] == 10.5)