def check_energy_for_m(m, E_expected): """ Helper function to compare the computed energy for a given magnetisation with an expected analytical value. """ m_field = Field(S3) m_field.set(df.Constant(m)) H_ext = Zeeman(H * np.array([1, 0, 0])) H_ext.setup(m_field, Ms, unit_length=unit_length) E_computed = H_ext.compute_energy() assert np.allclose(E_computed, E_expected, atol=0, rtol=1e-12)
def test_value_set_update(): """ Test to check that the value member variable updates when set_value is called. """ init_value = [1., 2., 3.] second_value = [100., 200., 400.] zeeman = Zeeman(init_value) mesh = df.RectangleMesh(df.Point(0, 0), df.Point(1, 1), 10, 10) sim = finmag.Simulation(mesh, 1e5) sim.add(zeeman) zeeman.set_value(second_value) assert zeeman.value == second_value
def test_energies_in_separated_subdomains(tmpdir): """ Create a mesh with two subdomains. For each energy class compute the energy on each subdomain and compare with the total energy on the whole mesh. Also compare with analytical expressions if feasible. """ os.chdir(str(tmpdir)) # Create a mesh consisting of two disks (with different heights) d = 30.0 h1 = 5.0 h2 = 10.0 sep = 10.0 maxh = 2.5 Ms = 8.6e5 unit_length = 1e-9 RTOL = 5e-3 # achievable relative tolerance depends on maxh zeeman = Zeeman(1e6 * np.array([1, 0, 0])) mesh = pair_of_disks(d, d, h1, h2, sep, theta=0, maxh=maxh) def get_domain_id(pt): x, y, z = pt return 1 if (np.linalg.norm([x, y]) < 0.5 * (d + sep)) else 2 m_vals = {1: [1, 0, 0], 2: [0.5, -0.8, 0]} multi_domain_test = MultiDomainTest( mesh, get_domain_id, m_vals, Ms, unit_length=unit_length) multi_domain_test.check_energy_consistency(zeeman)
def test_differentiate_heff(): ns = [2, 2, 2] mesh = df.BoxMesh(0, 0, 0, 1, 1, 1, *ns) sim = Simulation(mesh, 1.2) sim.set_m([1, 0, 0]) sim.add(Demag()) sim.add(Exchange(2.3 * mu0)) compute_H = compute_H_func(sim) # Check that H_eff is linear without Zeeman np.random.seed(1) m1 = fnormalise(np.random.randn(*sim.m.shape)) m2 = fnormalise(np.random.randn(*sim.m.shape)) # TODO: need to use a non-iterative solver here to increase accuracy assert np.max( np.abs(compute_H(m1) + compute_H(m2) - compute_H(m1 + m2))) < 1e-6 # Add the zeeman field now sim.add(Zeeman([2.5, 3.5, 4.3])) # Check that both fd2 and fd4 give the same result assert np.max( np.abs( differentiate_fd4(compute_H, m1, m2) - differentiate_fd2(compute_H, m1, m2))) < 1e-10
def run_sim_with_stt(): sim = Sim(mesh, Ms=8.6e5) sim.set_m((1, 0.01, 0.01)) sim.alpha = 0.014 sim.gamma = 221017 H_app_mT = np.array([0.2, 0.2, 10.0]) H_app_SI = H_app_mT / (1000 * mu0) sim.add(Zeeman(tuple(H_app_SI))) sim.add(Exchange(1.3e-11)) sim.add(UniaxialAnisotropy(1e5, (0, 0, 1))) I = 5e-5 # current in A J = I / (L * W) # current density in A/m^2 theta = 40.0 * pi / 180 phi = pi / 2 # polarisation direction p = (sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)) sim.llg.use_slonczewski(J=J, P=0.4, d=5e-9, p=(0, 1, 0)) with open(averages_with, "w") as f: dt = 5e-12 t_max = 10e-9 for t in np.arange(0, t_max, dt): sim.run_until(t) f.write("{} {} {} {}\n".format(t, *sim.m_average))
def example3(Ms): x0 = y0 = z0 = 0 x1 = 500 y1 = 10 z1 = 500 nx = 50 ny = 1 nz = 1 mesh = df.Box(x0, y0, z0, x1, y1, z1, nx, ny, nz) sim = Sim(mesh, Ms, unit_length=1e-9) sim.alpha = 0.01 sim.set_m((1, 0, 0.1)) H_app = Zeeman((0, 0, 5e5)) sim.add(H_app) exch = fe.Exchange(13.0e-12) sim.add(exch) demag = Demag(solver="FK") sim.add(demag) llg = sim.llg max_time = 1 * np.pi / (llg.gamma * 1e5) ts = np.linspace(0, max_time, num=100) for t in ts: print t sim.run_until(t) df.plot(llg._m) df.interactive()
def run_simulation(): L = 3e-8 W = 1e-8 H = 1e-8 mesh = df.BoxMesh(df.Point(0, 0, 0), df.Point(L, W, H), 10, 4, 4) Ms = 0.86e6 # A/m A = 1.3e-11 # J/m sim = Sim(mesh, Ms) sim.set_m(("2*x[0]/L - 1", "2*x[1]/W - 1", "1"), L=3e-8, H=1e-8, W=1e-8) sim.alpha = 0.1 sim.add(Zeeman((Ms / 2, 0, 0))) sim.add(Exchange(A)) t = 0 dt = 1e-11 tmax = 1e-9 # s fh = open(os.path.join(MODULE_DIR, "averages.txt"), "w") while t <= tmax: mx, my, mz = sim.m_average fh.write(str(t) + " " + str(mx) + " " + str(my) + " " + str(mz) + "\n") t += dt sim.run_until(t) fh.close()
def run_simulation(): L = W = 12.5e-9 H = 2.5e-9 sim = Sim(mesh, Ms=8.6e5, unit_length=1e-9) sim.set_m((1, 0.01, 0.01)) sim.alpha = 0.014 sim.gamma = 221017 H_app_mT = np.array([0.0, 0.0, 10.0]) H_app_SI = H_app_mT / (1000 * mu0) sim.add(Zeeman(tuple(H_app_SI))) sim.add(Exchange(1.3e-11)) I = 5e-5 # current in A J = I / (L * W) # current density in A/m^2 theta = 40.0 * pi / 180 phi = pi / 2 # polarisation direction p = (sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)) sim.llg.use_slonczewski(J=J, P=0.4, d=H, p=p) with open(averages_file, "w") as f: dt = 10e-12 t_max = 10e-9 for t in np.arange(0, t_max, dt): sim.run_until(t) f.write("{} {} {} {}\n".format(t, *sim.m_average))
def test_compute_skyrmion_number_2d_pbc(): mesh = df.RectangleMesh(df.Point(0, 0), df.Point(100, 100), 40, 40) Ms = 8.6e5 sim = Simulation(mesh, Ms, pbc='2d', unit_length=1e-9) sim.set_m(init_skx_down) sim.add(Exchange(1.3e-11)) sim.add(DMI(D=4e-3)) sim.add(Zeeman((0, 0, 0.45 * Ms))) sim.do_precession = False sim.relax(stopping_dmdt=1, dt_limit=1e-9) #df.plot(sim.m_field.f) #df.interactive() print np.max(sim.m_field.as_array()) sky_num = compute_skyrmion_number_2d(sim.m_field.f) print 'sky_num = %g' % sky_num assert sky_num < -0.95 and sky_num > -1.0
def test_energy_density_function(): """ Compute the Zeeman energy density over the entire mesh, integrate it, and compare it to the expected result. """ mesh = df.RectangleMesh(df.Point(-50, -50), df.Point(50, 50), 10, 10) unit_length = 1e-9 H = 1e6 # Create simulation object. sim = finmag.Simulation(mesh, 1e5, unit_length=unit_length) # Set uniform magnetisation. def m_ferromagnetic(pos): return np.array([0., 0., 1.]) sim.set_m(m_ferromagnetic) # Assign zeeman object to simulation sim.add(Zeeman(H * np.array([0., 0., 1.]))) # Get energy density function edf = sim.get_interaction('Zeeman').energy_density_function() # Integrate it over the mesh and compare to expected result. total_energy = df.assemble(edf * df.dx) * unit_length expected_energy = -mu0 * H assert (total_energy + expected_energy) < 1e-6
def test_dmdt_computation_with_oommf(): # set up finmag llg = LLG(S1, S3) llg.set_m((-3, -2, 1)) Ms = llg.Ms.vector().array()[0] Ms = float(Ms) h = Ms / 2 H_app = (h / np.sqrt(3), h / np.sqrt(3), h / np.sqrt(3)) zeeman = Zeeman(H_app) zeeman.setup(llg.m_field, llg.Ms, 1) llg.effective_field.add(zeeman) dmdt_finmag = df.Function(llg.S3) dmdt_finmag.vector()[:] = llg.solve(0) # set up oommf msh = mesh.Mesh((nL, nW, nH), size=(L, W, H)) m0 = msh.new_field(3) m0.flat[0] += -3 m0.flat[1] += -2 m0.flat[2] += 1 m0.flat /= np.sqrt(m0.flat[0] * m0.flat[0] + m0.flat[1] * m0.flat[1] + m0.flat[2] * m0.flat[2]) dmdt_oommf = oommf_dmdt(m0, Ms, A=0, H=H_app, alpha=0.5, gamma_G=llg.gamma).flat # extract finmag data for comparison with oommf dmdt_finmag_like_oommf = msh.new_field(3) for i, (x, y, z) in enumerate(msh.iter_coords()): dmdt_x, dmdt_y, dmdt_z = dmdt_finmag(x, y, z) dmdt_finmag_like_oommf.flat[0, i] = dmdt_x dmdt_finmag_like_oommf.flat[1, i] = dmdt_y dmdt_finmag_like_oommf.flat[2, i] = dmdt_z # compare difference = np.abs(dmdt_finmag_like_oommf.flat - dmdt_oommf) relative_difference = difference / np.max( np.sqrt(dmdt_oommf[0]**2 + dmdt_oommf[1]**2 + dmdt_oommf[2]**2)) print "comparison with oommf, dm/dt, relative difference:" print stats(relative_difference) assert np.max(relative_difference) < TOLERANCE return difference, relative_difference
def example2(Ms): x0 = y0 = z0 = 0 x1 = 500 y1 = 10 z1 = 100 nx = 50 ny = 1 nz = 1 mesh = df.Box(x0, y0, z0, x1, y1, z1, nx, ny, nz) S1 = df.FunctionSpace(mesh, "Lagrange", 1) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3) llb = LLB(S1, S3) llb.alpha = 0.01 llb.beta = 0.0 llb.M0 = Ms llb.set_M((Ms, 0, 0)) llb.set_up_solver(jacobian=False) llb.chi = 1e-4 H_app = Zeeman((0, 0, 5e5)) H_app.setup(S3, llb._M, Ms=1) llb.interactions.append(H_app) exchange = Exchange(13.0e-12, 1e-2) exchange.chi = 1e-4 exchange.setup(S3, llb._M, Ms, unit_length=1e-9) llb.interactions.append(exchange) demag = Demag("FK") demag.setup(S3, llb._M, Ms=1) llb.interactions.append(demag) max_time = 1 * np.pi / (llb.gamma * 1e5) ts = np.linspace(0, max_time, num=100) for t in ts: print t llb.run_until(t) df.plot(llb._M) df.interactive()
def example1(Ms=8.6e5): x0 = y0 = z0 = 0 x1 = y1 = z1 = 10 nx = ny = nz = 1 mesh = df.Box(x0, x1, y0, y1, z0, z1, nx, ny, nz) S1 = df.FunctionSpace(mesh, "Lagrange", 1) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3) vis = df.Function(S3) llb = LLB(S1, S3) llb.alpha = 0.01 llb.beta = 0.0 llb.M0 = Ms llb.set_M((Ms, 0, 0)) llb.set_up_solver(jacobian=False) llb.chi = 1e-4 H_app = Zeeman((0, 0, 1e5)) H_app.setup(S3, llb._M, Ms=1) llb.interactions.append(H_app) exchange = Exchange(13.0e-12, 1e-2) exchange.chi = 1e-4 exchange.setup(S3, llb._M, Ms, unit_length=1e-9) llb.interactions.append(exchange) max_time = 2 * np.pi / (llb.gamma * 1e5) ts = np.linspace(0, max_time, num=100) mlist = [] Ms_average = [] for t in ts: llb.run_until(t) mlist.append(llb.M) vis.vector()[:] = mlist[-1] Ms_average.append(llb.M_average) df.plot(vis) time.sleep(0.00) print 'llb times', llb.call_field_times save_plot(ts, Ms_average, 'Ms_%g-time.png' % Ms) df.interactive()
def test_deviations_over_alpha_and_tol(number_of_alphas=5, do_plot=False): alphas = numpy.linspace(0.01, 1.00, number_of_alphas) max_deviationss = [] for rtol_power_of_ten in rtols_powers_of_ten: rtol = pow(10, rtol_power_of_ten) print "#### New series for rtol={0}. ####".format(rtol) # One entry in this array corresponds to the maximum deviation between # the analytical solution and the computed solution for one value of alpha. max_deviations = [] for alpha in alphas: print "Solving for alpha={0}.".format(alpha) sim = Simulation(mesh, 1, unit_length=1e-9) sim.alpha = alpha sim.set_m((1, 0, 0)) sim.add(Zeeman((0, 0, 1e5))) ts = numpy.linspace(0, 1e-9, num=50) ys = odeint(sim.llg.solve_for, sim.llg._m_field.get_numpy_array_debug(), ts, rtol=rtol, atol=rtol) # One entry in this array corresponds to the deviation between the two # solutions for one particular moment during the simulation. deviations = [] M_analytical = make_analytic_solution(1e5, alpha, sim.gamma) for i in range(len(ts)): M_computed = numpy.mean(ys[i].reshape((3, -1)), 1) M_ref = M_analytical(ts[i]) # The difference of the two vectors has 3 components. The # deviation is the average over these components. deviation = numpy.mean(numpy.abs(M_computed - M_ref)) assert deviation < TOLERANCE deviations.append(deviation) # This represents the addition of one point to the graph. max_deviations.append(numpy.max(deviations)) # This represents one additional series in the graph. max_deviationss.append(max_deviations) if do_plot: for i in range(len(rtols_powers_of_ten)): label = r"$rtol=1\cdot 10^{" + str(rtols_powers_of_ten[i]) + r"}$" plt.plot(alphas, max_deviationss[i], ".", label=label) plt.legend() plt.title(r"Influence of $\alpha$ and rtol on the Deviation") plt.ylabel("deviation") plt.xlabel(r"$\alpha$") plt.ylim((0, 1e-6)) plt.savefig(os.path.join(MODULE_DIR, "deviation_over_alpha_rtols.pdf"))
def example_simulation(): Ms = 8.6e5 mesh = df.BoxMesh(df.Point(0, 0, 0), df.Point(40, 20, 20), 10, 5, 5) example = Simulation(mesh, Ms, name="sim_with_scheduling") example.set_m((0.1, 1, 0)) example.add(Exchange(13.0e-12)) example.add(Demag()) example.add(Zeeman((Ms/2, 0, 0))) return example
def run_simulation(stop_when_mx_eq_zero): """ Runs the simulation using field #1 from the problem description. Stores the average magnetisation components regularly, as well as the magnetisation when the x-component of the average magnetisation crosses the value 0 for the first time. """ mesh = from_geofile(os.path.join(MODULE_DIR, "bar.geo")) sim = Simulation(mesh, Ms, name="dynamics", unit_length=1e-9) sim.alpha = alpha sim.gamma = gamma sim.set_m(np.load(m_0_file)) sim.add(Demag()) sim.add(Exchange(A)) """ Conversion between mu0 * H in mT and H in A/m. mu0 * H = 1 mT = 1 * 1e-3 T = 1 * 1e-3 Vs/m^2 divide by mu0 with mu0 = 4pi * 1e-7 Vs/Am gives H = 1 / 4pi * 1e4 A/m with the unit A/m which is indeed what we want. Consequence: Just divide the value of mu0 * H in Tesla by mu0 to get the value of H in A/m. """ Hx = -24.6e-3 / mu0 Hy = 4.3e-3 / mu0 Hz = 0 sim.add(Zeeman((Hx, Hy, Hz))) def check_if_crossed(sim): mx, _, _ = sim.m_average if mx <= 0: print "The x-component of the spatially averaged magnetisation first crossed zero at t = {}.".format( sim.t) np.save(m_at_crossing_file, sim.m) # When this function returns True, it means this event is done # and doesn't need to be triggered anymore. # When we return False, it means we want to stop the simulation. return not stop_when_mx_eq_zero sim.schedule(check_if_crossed, every=1e-12) sim.schedule('save_averages', every=10e-12, at_end=True) sim.schedule('save_vtk', every=10e-12, at_end=True, overwrite=True) sim.run_until(2.0e-9) return sim.t
def test_relax_two_times(): """ Test whether we can call the relax method on Sim two times in a row. """ mesh = df.BoxMesh(df.Point(0, 0, 0), df.Point(10, 10, 10), 2, 2, 2) Ms = 0.86e6 sim = Simulation(mesh, Ms) sim.set_m((1, 0, 0)) external_field = Zeeman((0, Ms, 0)) sim.add(external_field) sim.relax() t0 = sim.t # time needed for first relaxation external_field.set_value((0, 0, Ms)) sim.relax() t1 = sim.t - t0 # time needed for second relaxation assert sim.t > t0 assert abs(t1 - t0) < 1e-10
def example1_sundials(Ms): x0 = y0 = z0 = 0 x1 = y1 = z1 = 10 nx = ny = nz = 1 mesh = df.Box(x0, x1, y0, y1, z0, z1, nx, ny, nz) S1 = df.FunctionSpace(mesh, "Lagrange", 1) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3) vis = df.Function(S3) llb = LLB(S1, S3) llb.alpha = 0.00 llb.set_m((1, 1, 1)) llb.Ms = Ms H_app = Zeeman((0, 0, 1e5)) H_app.setup(S3, llb._m, Ms=Ms) llb.interactions.append(H_app) exchange = BaryakhtarExchange(13.0e-12, 1e-2) exchange.setup(S3, llb._m, llb._Ms) llb.interactions.append(exchange) integrator = llg_integrator(llb, llb.M, abstol=1e-10, reltol=1e-6) max_time = 2 * np.pi / (llb.gamma * 1e5) ts = np.linspace(0, max_time, num=50) mlist = [] Ms_average = [] for t in ts: integrator.advance_time(t) mlist.append(integrator.m.copy()) llb.M = mlist[-1] vis.vector()[:] = mlist[-1] Ms_average.append(llb.M_average) df.plot(vis) time.sleep(0.0) print llb.count save_plot(ts, Ms_average, 'Ms_%g-time-sundials.png' % Ms) df.interactive()
def test_llb_sundials(do_plot=False): mesh = df.BoxMesh(df.Point(0, 0, 0), df.Point(2, 2, 2), 1, 1, 1) mat = Material(mesh, name='FePt', unit_length=1e-9) mat.set_m((1, 0, 0)) mat.T = 10 mat.alpha = 0.1 sim = LLB(mat) sim.set_up_solver() H0 = 1e5 sim.add(Zeeman((0, 0, H0))) dt = 1e-12 ts = np.linspace(0, 1000 * dt, 101) precession_coeff = sim.gamma_LL mz_ref = [] mxyz = [] mz = [] real_ts = [] for t in ts: sim.run_until(t) real_ts.append(sim.t) mz_ref.append(np.tanh(precession_coeff * mat.alpha * H0 * sim.t)) mz.append(sim.m[-1]) # same as m_average for this macrospin problem sim.m.shape = (3, -1) mxyz.append(sim.m[:, -1].copy()) sim.m.shape = (-1,) mxyz = np.array(mxyz) mz = np.array(mz) print np.sum(mxyz ** 2, axis=1) - 1 if do_plot: ts_ns = np.array(real_ts) * 1e9 plt.plot(ts_ns, mz, "b.", label="computed") plt.plot(ts_ns, mz_ref, "r-", label="analytical") plt.xlabel("time (ns)") plt.ylabel("mz") plt.title("integrating a macrospin") plt.legend() plt.savefig(os.path.join(MODULE_DIR, "test_llb.png")) print("Deviation = {}".format(np.max(np.abs(mz - mz_ref))))
def excite_system(): Ms = 8.6e5 sim = Simulation(mesh, Ms, pbc='1d', unit_length=1e-9) sim.alpha = 0.0001 sim.set_m(np.load('relaxed.npy')) alpha_expr = AlphaExpression() alpha_mult = df.interpolate(alpha_expr, sim.llg.S1) sim.spatial_alpha(0.0001, alpha_mult) #df.plot(alpha_mult) #df.interactive() #xs=find_skyrmion_center(sim.llg._m) # #assert(1==2) A = 1.3e-11 D = 4e-3 sim.add(Exchange(A)) sim.add(DMI(D)) sim.add(Zeeman((0, 0, 0.4 * Ms))) GHz = 1e9 omega = 50 * 2 * np.pi * GHz def time_fun(t): return np.sinc(omega * (t - 50e-12)) h0 = 1e3 kc = 1.0 / 45.0 H0 = MyExpression(h0, kc) sim.add(TimeZeemanPython(H0, time_fun)) xs = find_skyrmion_center(sim.llg._m) ts = np.linspace(0, 8e-9, 4001) np.save('xs.npy', xs) sim.create_integrator() sim.integrator.integrator.set_scalar_tolerances(1e-8, 1e-8) index = 0 for t in ts: sim.run_until(t) np.save('data/m_%d.npy' % index, sim.llg.m) index += 1
def test_llb(do_plot=False): #mesh = df.BoxMesh(0, 0, 0, 2, 2, 2, 1, 1, 1) mesh = df.IntervalMesh(1,0,2) Ms = 8.6e5 sim = LLB(mesh) sim.alpha = 0.5 sim.beta = 0.0 sim.M0 = Ms sim.set_M((Ms,0,0)) sim.set_up_solver(reltol=1e-7, abstol=1e-7) sim.add(Exchange(1.3e-11,chi=1e-7)) H0 = 1e5 sim.add(Zeeman((0, 0, H0))) steps = 100 dt = 1e-12; ts = np.linspace(0, steps * dt, steps+1) precession_coeff = sim.gamma mz_ref = [] mz = [] real_ts=[] for t in ts: print t,sim.Ms sim.run_until(t) real_ts.append(sim.t) mz_ref.append(np.tanh(precession_coeff * sim.alpha * H0 * sim.t)) #mz.append(sim.M[-1]/Ms) # same as m_average for this macrospin problem mz.append(sim.m[-1]) mz=np.array(mz) if do_plot: ts_ns = np.array(real_ts) * 1e9 plt.plot(ts_ns, mz, "b.", label="computed") plt.plot(ts_ns, mz_ref, "r-", label="analytical") plt.xlabel("time (ns)") plt.ylabel("mz") plt.title("integrating a macrospin") plt.legend() plt.savefig(os.path.join(MODULE_DIR, "test_sllg.png")) print("Deviation = {}, total value={}".format( np.max(np.abs(mz - mz_ref)), mz_ref)) assert np.max(np.abs(mz - mz_ref)) < 2e-7
def __init__(self, mesh): self.mesh = mesh self.S1 = df.FunctionSpace(mesh, 'CG', 1) self.S3 = df.VectorFunctionSpace(mesh, 'CG', 1, dim=3) #zero = df.Expression('0.3') m_init = df.Constant([1, 1, 1.0]) self.m = df.interpolate(m_init, self.S3) self.field = df.interpolate(m_init, self.S3) self.dmdt = df.interpolate(m_init, self.S3) self.spin = self.m.vector().array() self.t = 0 #It seems it's not safe to specify rank in df.interpolate??? self._alpha = df.interpolate(df.Constant("0.001"), self.S1) self._alpha.vector().set_local(self._alpha.vector().array()) print 'dolfin', self._alpha.vector().array() self.llg = LLG(self.S1, self.S3, unit_length=1e-9) #normalise doesn't work due to the wrong order self.llg.set_m(m_init, normalise=True) parameters = { 'absolute_tolerance': 1e-10, 'relative_tolerance': 1e-10, 'maximum_iterations': int(1e5) } demag = Demag() demag.parameters['phi_1'] = parameters demag.parameters['phi_2'] = parameters self.exchange = Exchange(13e-12) self.zeeman = Zeeman([0, 0, 1e5]) self.llg.effective_field.add(self.exchange) #self.llg.effective_field.add(demag) self.llg.effective_field.add(self.zeeman) self.m_petsc = df.as_backend_type(self.llg.m_field.f.vector()).vec() self.h_petsc = df.as_backend_type(self.field.vector()).vec() self.alpha_petsc = df.as_backend_type(self._alpha.vector()).vec() self.dmdt_petsc = df.as_backend_type(self.dmdt.vector()).vec() alpha = 0.001 gamma = 2.21e5 LLG1 = -gamma / (1 + alpha * alpha) * df.cross( self.m, self.field) - alpha * gamma / (1 + alpha * alpha) * df.cross( self.m, df.cross(self.m, self.field)) self.L = df.dot(LLG1, df.TestFunction(self.S3)) * df.dP
def test_uniform_external_field(): TOLERANCE = 3.5e-10 mesh = df.UnitCubeMesh(2, 2, 2) sim = Sim(mesh, Ms) sim.set_m((1, 0, 0)) sim.add(Zeeman((0, Ms, 0))) sim.alpha = 1.0 sim.run_until(1e-9) m = sim.m.reshape((3, -1)).mean(-1) expected_m = np.array([0, 1, 0]) diff = np.abs(m - expected_m) assert np.max(diff) < TOLERANCE
def test_interaction_accepts_name(): """ Check that the interaction accepts a 'name' argument and has a 'name' attribute. """ field_expr = df.Expression(("0", "t", "0"), t=0, degree=1) zeeman = Zeeman([0, 0, 1], name='MyZeeman') assert hasattr(zeeman, 'name') zeeman = TimeZeeman(field_expr, name='MyTimeZeeman') assert hasattr(zeeman, 'name') zeeman = DiscreteTimeZeeman(field_expr, dt_update=2, name='MyDiscreteTimeZeeman') assert hasattr(zeeman, 'name')
def excite_system(): Ms = 8.0e5 sim = Simulation(mesh, Ms, unit_length=1e-9, name='dy') sim.alpha = 0.001 sim.set_m((1, 0, 0)) sim.set_tol(1e-6, 1e-6) A = 1.3e-11 sim.add(Exchange(A)) sim.add(Zeeman(varying_field)) sim.schedule('save_ndt', every=2e-12) sim.run_until(0.5e-9)
def example1(Ms=8.6e5): x0 = y0 = z0 = 0 x1 = y1 = z1 = 10 nx = ny = nz = 1 mesh = df.Box(x0, x1, y0, y1, z0, z1, nx, ny, nz) S1 = df.FunctionSpace(mesh, "Lagrange", 1) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3) vis = df.Function(S3) llb = LLB(S1, S3, rtol=1e-6, atol=1e-10) llb.Ms = Ms llb.alpha = 0.0 llb.set_m((1, 1, 1)) H_app = Zeeman((0, 0, 1e5)) H_app.setup(S3, llb._m, Ms=Ms) llb.interactions.append(H_app) exchange = BaryakhtarExchange(13.0e-12, 1e-5) exchange.setup(S3, llb._m, llb._Ms) llb.interactions.append(exchange) max_time = 2 * np.pi / (llb.gamma * 1e5) ts = np.linspace(0, max_time, num=100) mlist = [] Ms_average = [] for t in ts: llb.run_until(t) mlist.append(llb.M) vis.vector()[:] = mlist[-1] Ms_average.append(llb.M_average) df.plot(vis) time.sleep(0.00) print llb.count save_plot(ts, Ms_average, 'Ms_%g-time.png' % Ms) df.interactive()
def test_llb_save_data(): mesh = df.BoxMesh(df.Point(0, 0, 0), df.Point(10, 10, 5), 2, 2, 1) def region1(coords): if coords[2] < 0.5: return True else: return False def region2(coords): return not region1(coords) def init_Ms(coords): if region1(coords) > 0: return 8.6e5 else: return 8.0e5 def init_T(pos): return 1 * pos[2] mat = Material(mesh, name='FePt', unit_length=1e-9) mat.Ms = init_Ms mat.set_m((1, 0, 0)) mat.T = init_T mat.alpha = 0.1 assert(mat.T[0] == 0) sim = LLB(mat, name='test_llb') sim.set_up_solver() ts = np.linspace(0, 1e-11, 11) H0 = 1e6 sim.add(Zeeman((0, 0, H0))) sim.add(Exchange(mat)) demag = Demag(solver='FK') sim.add(demag) sim.save_m_in_region(region1, name='bottom') sim.save_m_in_region(region2, name='top') sim.schedule('save_ndt', every=1e-12) for t in ts: print 't===', t sim.run_until(t)
def setup_sim(self, m0): Hz = [8e4, 0, 0] # A/m A = 1.3e-11 # J/m Ms = 800e3 # A/m alpha = 1. mesh = df.BoxMesh(0, 0, 0, *(self.box_size + self.box_divisions)) sim = Simulation(mesh, Ms) sim.alpha = alpha sim.set_m(m0) sim.add(Demag()) sim.add(Exchange(A)) sim.add(Zeeman(Hz)) return sim
def test_negative_uniform_external_field(): TOLERANCE = 1e-10 mesh = df.UnitCubeMesh(2, 2, 2) sim = Sim(mesh, Ms) sim.set_m((1, 0.1, 0)) # slightly misaligned sim.add(Zeeman((-1.0 * Ms, 0, 0))) sim.alpha = 1.0 sim.run_until(1e-9) m = sim.m.reshape((3, -1)).mean(-1) print "Average magnetisation ({:.2g}, {:.2g}, {:.2g}).".format(*m) expected_m = np.array([-1, 0, 0]) diff = np.abs(m - expected_m) TOLERANCE = 1e-5 assert np.max(diff) < TOLERANCE
def test_compute_main(): Ms = 1700e3 A = 2.5e-6 * 1e-5 Hz = [10e3 * Oersted_to_SI(1.), 0, 0] mesh = df.BoxMesh(0, 0, 0, 50, 50, 10, 6, 6, 2) mesh = df.BoxMesh(0, 0, 0, 5, 5, 5, 1, 1, 1) print mesh # Find the ground state sim = Simulation(mesh, Ms) sim.set_m([1, 0, 0]) sim.add(Demag()) sim.add(Exchange(A)) sim.add(Zeeman(Hz)) sim.relax()