def test_dmi_field_oommf(D=4.1e-3, Ms=2.6e5): mesh = CuboidMesh(nx=10, ny=3, nz=2, dx=0.5, unit_length=1e-9) sim = Sim(mesh) sim.Ms = Ms dmi = DMI(D=D, type='interfacial') sim.add(dmi) def init_m(pos): x, y, z = pos return (np.sin(x) + y + 2.3 * z, np.cos(x) + y + 1.3 * z, 0) sim.set_m(init_m) field = dmi.compute_field() init_m0 = ( r'return [list [expr {sin($x * 1e9) + $y * 1e9 + $z * 2.3e9}] ' + r' [expr {cos($x * 1e9) + $y * 1e9 + $z * 1.3e9}] ' + r'0 ' + r'] ') # TODO: check the sign of DMI in OOMMF. field_oommf = compute_dmi_field(mesh, Ms=Ms, init_m0=init_m0, D=-D) mx0, mx1, mx2 = compare_fields(field_oommf, field) assert max([mx0, mx1, mx2]) < 1e-12
def test_dmi_field_oommf(D=4.1e-3, Ms=2.6e5): mesh = CuboidMesh(nx=10, ny=3, nz=2, dx=0.5, unit_length=1e-9) sim = Sim(mesh) sim.Ms = Ms dmi = DMI(D=D, dmi_type='interfacial') sim.add(dmi) def init_m(pos): x, y, z = pos return (np.sin(x) + y + 2.3 * z, np.cos(x) + y + 1.3 * z, 0) sim.set_m(init_m) field = dmi.compute_field() init_m0 = """ return [list [expr {sin($x*1e9)+$y*1e9+$z*2.3e9}] [expr {cos($x*1e9)+$y*1e9+$z*1.3e9}] 0] """ # TODO: check the sign of DMI in OOMMF. #field_oommf = compute_dmi_field(mesh, Ms=Ms, init_m0=init_m0, D=-D) omf_file = os.path.join(os.path.dirname(os.path.abspath(__file__)),'omfs','test_dmi_field_oommf.ohf') ovf = OMF2(omf_file) field_oommf = ovf.get_all_mags() mx0, mx1, mx2 = compare_fields(field_oommf, field) assert max([mx0, mx1, mx2]) < 1e-12
def test_dmi_field_oommf(D=4.1e-3, Ms=2.6e5): mesh = CuboidMesh(nx=10, ny=3, nz=2, dx=0.5, unit_length=1e-9) sim = Sim(mesh) sim.Ms = Ms dmi = DMI(D=D, type='interfacial') sim.add(dmi) def init_m(pos): x, y, z = pos return (np.sin(x) + y + 2.3 * z, np.cos(x) + y + 1.3 * z, 0) sim.set_m(init_m) field = dmi.compute_field() init_m0 = (r'return [list [expr {sin($x * 1e9) + $y * 1e9 + $z * 2.3e9}] ' + r' [expr {cos($x * 1e9) + $y * 1e9 + $z * 1.3e9}] ' + r'0 ' + r'] ') # TODO: check the sign of DMI in OOMMF. field_oommf = compute_dmi_field(mesh, Ms=Ms, init_m0=init_m0, D=-D) mx0, mx1, mx2 = compare_fields(field_oommf, field) assert max([mx0, mx1, mx2]) < 1e-12
def test_energy_dmi(Ms=8e5, D=1.32e-3): mesh = CuboidMesh(nx=40, ny=50, nz=1, dx=2.5, dy=2.5, dz=3, unit_length=1e-9) sim = Sim(mesh) sim.Ms = Ms dmi = DMI(D=D, type='interfacial') #dmi = DMI(D=D, type='bulk') sim.add(dmi) def init_m(pos): x, y, z = pos return (np.sin(x) + y + 2.3 * z, np.cos(x) + y + 1.3 * z, 1) sim.set_m(init_m) dmi_energy = dmi.compute_energy() # init_m0=""" # return [list [expr {sin($x*1e9)+$y*1e9+$z*2.3e9}] [expr {cos($x*1e9)+$y*1e9+$z*1.3e9}] 1] #""" #field_oommf = compute_dmi_field(mesh, Ms=Ms, init_m0=init_m0, D=D) dmi_energy_oommf = -4.5665527749090378e-20 print 'dmi energy', dmi_energy assert abs(dmi_energy - dmi_energy_oommf) / dmi_energy_oommf < 1e-15
def test_dmi_field_oommf(D=4.1e-3, Ms=2.6e5): mesh = CuboidMesh(nx=10, ny=3, nz=2, dx=0.5, unit_length=1e-9) sim = Sim(mesh) sim.Ms = Ms dmi = DMI(D=D, type='interfacial') sim.add(dmi) def init_m(pos): x, y, z = pos return (np.sin(x) + y + 2.3 * z, np.cos(x) + y + 1.3 * z, 0) sim.set_m(init_m) field = dmi.compute_field() init_m0 = """ return [list [expr {sin($x*1e9)+$y*1e9+$z*2.3e9}] [expr {cos($x*1e9)+$y*1e9+$z*1.3e9}] 0] """ # TODO: check the sign of DMI in OOMMF. #field_oommf = compute_dmi_field(mesh, Ms=Ms, init_m0=init_m0, D=-D) omf_file = os.path.join(os.path.dirname(os.path.abspath(__file__)),'omfs','test_dmi_field_oommf.ohf') ovf = OMF2(omf_file) field_oommf = ovf.get_all_mags() mx0, mx1, mx2 = compare_fields(field_oommf, field) assert max([mx0, mx1, mx2]) < 1e-12
def relax_system(mesh): sim = Sim(mesh, name='relax') sim.driver.set_tols(rtol=1e-10, atol=1e-10) sim.driver.alpha = 0.1 sim.driver.gamma = 2.211e5 sim.Ms = spatial_Ms print(sim.Ms) sim.set_m(init_m) A = 1.3e-11 exch = UniformExchange(A=A) sim.add(exch) demag = Demag() sim.add(demag) dmi = DMI(D=4e-3) sim.add(dmi) dmi2 = DMI(D=2e-3, dmi_type="interfacial") sim.add(dmi2) anis = UniaxialAnisotropy(-3e4, axis=(0, 0, 1)) sim.add(anis) sim.relax(dt=1e-13, stopping_dmdt=5e4, max_steps=5000, save_m_steps=100, save_vtk_steps=50) #np.save('m0.npy', sim.spin) fd = demag.compute_field(sim.spin) fe = exch.compute_field(sim.spin) fdmi = dmi.compute_field(sim.spin) fdmi2 = dmi2.compute_field(sim.spin) fanis = anis.compute_field(sim.spin) np.savetxt( "test_fields.txt", np.transpose([ np.concatenate((sim.Ms, sim.Ms, sim.Ms, [0.0])), np.concatenate((sim.spin, [100])), np.concatenate((fd, [demag.compute_energy()])), np.concatenate((fe, [exch.compute_energy()])), np.concatenate((fdmi, [dmi.compute_energy()])), np.concatenate((fdmi2, [dmi2.compute_energy()])), np.concatenate((fanis, [anis.compute_energy()])) ]), header= "Generated by Fidimag. Size=20x5x3, 2.5nm x 2.5nm x 3nm, Ms=8.0e5A/m, A=1.3e-11 J/m," + " D=4e-3 J/m^2, D_int=2e-3 J/m^2, Ku=-3e4 J/m^3 axis=(0,0,1).\n Ms " + "".ljust(20) + " m0 " + "".ljust(20) + "demag" + "".ljust(20) + "exch" + "".ljust(22) + "dmi" + "".ljust(22) + "dmi_interfacial" + "".ljust(22) + "anis")
def create_simulation(mesh, simname): # Initiate a simulation object. PBCs are specified in the mesh sim = Sim(mesh, name=simname) # Use default gamma value # sim.gamma = const.gamma # Magnetisation in A/m sim.Ms = 148367 # We could change the parameters using this option # sim.set_options(gamma=const.gamma) # Initial magnetisation profile from the function sim.set_m((0, 0.2, 0.8)) # Exchange constant A = 1.602e-12 exch = UniformExchange(A) sim.add(exch) # DMI constant D = 3.84e-3 dmi = DMI(D, dmi_type='interfacial') sim.add(dmi) # Zeeman field sim.add(Zeeman((0, 0, 25. / c.mu_0))) # Tune the damping for faster convergence sim.driver.alpha = 0.5 # Remove precession sim.driver.do_precession = False sim.driver.set_tols(rtol=1e-12, atol=1e-12) return sim
def run_fidimag(mesh): mu0 = 4 * np.pi * 1e-7 Ms = 8.6e5 A = 16e-12 D = -3.6e-3 K = 510e3 sim = Sim(mesh) sim.set_tols(rtol=1e-10, atol=1e-10) sim.alpha = 0.5 sim.gamma = 2.211e5 sim.Ms = Ms sim.do_precession = False sim.set_m((0, 0, 1)) sim.add(UniformExchange(A)) sim.add(DMI(D, type='interfacial')) sim.add(UniaxialAnisotropy(K, axis=(0, 0, 1))) sim.relax(dt=1e-13, stopping_dmdt=0.01, max_steps=5000, save_m_steps=None, save_vtk_steps=50) m = sim.spin return m.copy()
def relax_system(mesh): sim = Sim(mesh, name='relax') sim.set_tols(rtol=1e-10, atol=1e-14) sim.alpha = 0.5 sim.gamma = 2.211e5 sim.Ms = 8.6e5 sim.do_precession = False sim.set_m((1,1,1)) # sim.set_m(np.load('m0.npy')) A = 1.3e-11 exch = UniformExchange(A=A) sim.add(exch) dmi = DMI(D=1e-3) sim.add(dmi) zeeman = Zeeman((0, 0, 2e4)) sim.add(zeeman, save_field=True) sim.relax(dt=1e-13, stopping_dmdt=0.01, max_steps=5000, save_m_steps=None, save_vtk_steps=50) np.save('m0.npy', sim.spin)
def relax_system(mesh): sim = Sim(mesh, name='relax') sim.set_tols(rtol=1e-6, atol=1e-6) sim.alpha = 0.5 sim.gamma = 2.211e5 sim.Ms = 8.6e5 sim.do_precession = False sim.set_m(init_m) #sim.set_m((0,0.1,1)) #sim.set_m(np.load('m0.npy')) A = 1.3e-11 exch = UniformExchange(A=A) sim.add(exch) dmi = DMI(D=1.3e-3) sim.add(dmi) anis = UniaxialAnisotropy(-3.25e4, axis=(0, 0, 1)) sim.add(anis) zeeman = Zeeman((0, 0, 6.014576e4)) sim.add(zeeman, save_field=True) sim.relax(dt=1e-13, stopping_dmdt=0.5, max_steps=5000, save_m_steps=None, save_vtk_steps=50) np.save('m0.npy', sim.spin)
def test_dw_dmi(mesh=mesh, do_plot=False): Ms = 8.0e5 sim = Sim(mesh, name='relax') sim.set_m(m_init_dw) sim.set_tols(rtol=1e-8, atol=1e-12) sim.Ms = Ms sim.alpha = 0.5 sim.do_precession = False A = 1.3e-11 D = 4e-4 Kx = 8e4 Kp = -6e5 sim.add(UniformExchange(A)) sim.add(DMI(D)) sim.add(UniaxialAnisotropy(Kx, axis=[1, 0, 0], name='Kx')) sim.relax(stopping_dmdt=0.01) xs = np.array([p[0] for p in mesh.coordinates]) mx, my, mz = analytical(xs, A=A, D=D, K=Kx) mxyz = sim.spin.copy() mxyz = mxyz.reshape(-1, 3) assert max(abs(mxyz[:, 0] - mx)) < 0.002 assert max(abs(mxyz[:, 1] - my)) < 0.002 assert max(abs(mxyz[:, 2] - mz)) < 0.0006 if do_plot: save_plot(mxyz, mx, my, mz)
def relax_system(mesh): sim = Sim(mesh, name='relax') sim.set_tols(rtol=1e-6, atol=1e-6) sim.alpha = 0.5 sim.gamma = 2.211e5 sim.Ms = 8.6e5 sim.do_precession = False sim.set_m(init_m) exch = UniformExchange(A=1.3e-11) sim.add(exch) dmi = DMI(D=-4e-3) sim.add(dmi) zeeman = Zeeman((0, 0, 4e5)) sim.add(zeeman, save_field=True) sim.relax(dt=1e-13, stopping_dmdt=1e-2, save_m_steps=None, save_vtk_steps=50) np.save('m0.npy', sim.spin)
def relax_neb(k, maxst, simname, init_im, interp, save_every=10000): """ Execute a simulation with the NEB function of the FIDIMAG code, for a nano disk 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 folders starting with the 'simname' """ # Prepare simulation # We define the small cylinder with the Magnetisation function sim = Sim(mesh) sim.Ms = cylinder # Energies # Exchange sim.add(UniformExchange(A=A)) # Bulk DMI --> This produces a Bloch DW - like skyrmion sim.add(DMI(D=D)) # No Demag, but this could have some effect # Demagnetization energy # sim.add(Demag()) # Initial images (npy files or functions) 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 # Initiate the NEB algorithm driver neb = NEB_Sundials(sim, init_images, interpolations=interpolations, spring=k, name=simname) # Start the relaxation neb.relax(max_steps=maxst, save_vtk_steps=save_every, save_npy_steps=save_every, stopping_dmdt=1)
def test_energy_dmi(Ms=8e5, D=1.32e-3): mesh = CuboidMesh(nx=40, ny=50, nz=1, dx=2.5, dy=2.5, dz=3, unit_length=1e-9) sim = Sim(mesh) sim.Ms = Ms dmi = DMI(D=D, type='interfacial') #dmi = DMI(D=D, type='bulk') sim.add(dmi) def init_m(pos): x, y, z = pos return (np.sin(x) + y + 2.3 * z, np.cos(x) + y + 1.3 * z, 1) sim.set_m(init_m) dmi_energy = dmi.compute_energy() # init_m0=""" # return [list [expr {sin($x*1e9)+$y*1e9+$z*2.3e9}] [expr {cos($x*1e9)+$y*1e9+$z*1.3e9}] 1] #""" #field_oommf = compute_dmi_field(mesh, Ms=Ms, init_m0=init_m0, D=D) dmi_energy_oommf = -4.5665527749090378e-20 print('dmi energy', dmi_energy) assert abs(dmi_energy - dmi_energy_oommf) / dmi_energy_oommf < 1e-15
def excite_system(mesh): sim = Sim(mesh, name='dyn', driver='llg_stt') sim.set_tols(rtol=1e-8, atol=1e-10) sim.alpha = 0.5 sim.gamma = 2.211e5 sim.Ms = 8.6e5 sim.set_m(np.load('m0.npy')) exch = UniformExchange(A=1.3e-11) sim.add(exch) dmi = DMI(D=-4e-3) sim.add(dmi) zeeman = Zeeman((0, 0, 4e5)) sim.add(zeeman, save_field=True) sim.jx = -5e12 sim.beta = 0 ts = np.linspace(0, 0.5e-9, 101) for t in ts: print 'time', t sim.run_until(t) sim.save_vtk()
# sim.driver.set_tols(rtol=1e-10, atol=1e-14) sim.driver.alpha = args.alpha # sim.driver.gamma = 2.211e5 if args.no_precession: sim.do_precession = False # Material parameters ----------------------------------------------------- sim.Ms = args.Ms exch = UniformExchange(A=args.A) sim.add(exch) dmi = DMI(D=(args.D * 1e-3), type='interfacial') sim.add(dmi) if args.B: zeeman = Zeeman((0, 0, args.B / mu0)) sim.add(zeeman, save_field=True) if args.k_u: # Uniaxial anisotropy along + z-axis sim.add(UniaxialAnisotropy(args.k_u, axis=(0, 0, 1))) if args.Demag: print 'Using Demag!' sim.add(Demag()) # -------------------------------------------------------------------------
def relax_neb(mesh, k, maxst, simname, init_im, interp, save_every=10000, stopping_dYdt=0.01): """ Execute a simulation with the NEBM algorithm of the FIDIMAG code Here we use always the 21x21 Spins Mesh and don't vary the material parameters. This can be changed adding those parameters as variables. We create a new Simulation object every time this function is called since it can be modified in the process k :: NEBM spring constant maxst :: Maximum number of iterations simname :: Simulation name. VTK and NPY files are saved in folders starting with the 'simname' string init_im :: A list with magnetisation states (usually loaded from NPY files or from a function) that will be used as images in the energy band, e.g. for two states: [np.load('skyrmion.npy'), np.load('ferromagnet.npy')] interp :: Array or list with the numbers of interpolations between every pair of the 'init_im' list. The length of this array is: len(__init_im) - 1 save_every :: Save VTK and NPY files every 'save_every' number of steps """ # Initialise a simulation object and set the default gamma for the LLG # equation sim = Sim(mesh, name=simname) # sim.gamma = const.gamma # Magnetisation in A/m sim.Ms = 148367 # Interactions ------------------------------------------------------------ # Exchange constant A = 1.602e-12 exch = UniformExchange(A) sim.add(exch) # DMI constant D = 3.84e-3 dmi = DMI(D, dmi_type='interfacial') sim.add(dmi) # Zeeman field sim.add(Zeeman((0, 0, 25. / c.mu_0))) # ------------------------------------------------------------------------- # Set the initial images from the list init_images = init_im # The number of interpolations must always be # equal to 'the number of initial states specified', minus one. interpolations = interp # Start a NEB simulation passing the Simulation object and all the NEB # parameters neb = NEBM_Geodesic(sim, init_images, interpolations=interpolations, spring_constant=k, name=simname, ) # Finally start the energy band relaxation neb.relax(max_iterations=maxst, save_vtks_every=save_every, save_npys_every=save_every, stopping_dYdt=stopping_dYdt ) # Produce a file with the data from a cubic interpolation for the band interp_data = np.zeros((200, 2)) interp_data[:, 0], interp_data[:, 1] = neb.compute_polynomial_approximation(200) np.savetxt(simname + 'interpolation.dat', interp_data)
# ----------------------------------------------------------------------------- A = 13e-12 # J * m**-1 D = 3e-3 # J * m**-2 Ku = 0e6 # J * m**-3 Ms = 0.86e6 # A / m B0 = 0.4 # T sim.Ms = Ms sim.add(UniformExchange(A)) sim.add(Demag()) # sim.add(UniaxialAnisotropy(Ku, (0, 0, 1))) # Periodic DMI sim.add(DMI(D, dmi_type='interfacial')) # External field along the stripe length sim.add(Zeeman((0, B0 / mu0, 0)), save_field=True) # ----------------------------------------------------------------------------- # Relax the system first sim.driver.alpha = 0.9 sim.driver.do_precession = False sim.driver.relax(stopping_dmdt=0.01) np.save('initial_state.npy', sim.spin) # Remove automatically saved files shutil.rmtree('unnamed_npys/') shutil.rmtree('unnamed_vtks/')
# We define the cylinder with the Magnetisation function sim = Sim(mesh, name='skyrmion') sim.Ms = cylinder # To get a faster relaxation, we tune the LLG equation parameters sim.do_precession = False sim.alpha = 0.5 # Initial magnetisation: sim.set_m(init_m) # Energies: # Exchange sim.add(UniformExchange(A=A)) # Bulk DMI sim.add(DMI(D=D)) # Relax the system sim.relax(dt=1e-12, stopping_dmdt=0.0001, max_steps=5000, save_m_steps=None, save_vtk_steps=None) # Save the final relaxed state and a vtk file np.save('sk_up.npy', sim.spin) sim.save_vtk()