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 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 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_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 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_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 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 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 check_energies(m=None, theta=None): """ Helper function to compare the computed energy for a given magnetisation with an expected analytical value. The argument theta is the angle between the magnetisation vector and the x-axis. """ # Exactly one of m, theta must be given assert ((m is None or theta is None) and not (m is None and theta is None)) if m is None: if theta is None: raise ValueError("Exactly one of m, theta must be given.") theta_rad = theta * pi / 180. m = (cos(theta_rad), sin(theta_rad), 0) else: if theta != None: raise ValueError("Exactly one of m, theta must be given.") m = m / np.linalg.norm(m) m_field = Field(S3) m_field.set(df.Constant(m)) H_ext = Zeeman(H * np.array([1, 0, 0])) H_ext.setup(m_field, Field(df.FunctionSpace(mesh, 'DG', 0), Ms), unit_length=unit_length) #E_analytical_1 = -mu0 * Ms * H * volume_1 * cos(theta_rad) E_analytical_1 = -mu0 * Ms * H * volume_1 * np.dot(m, [1, 0, 0]) E_analytical_2 = -mu0 * Ms * H * volume_2 * np.dot(m, [1, 0, 0]) E_analytical_total = E_analytical_1 + E_analytical_2 E_computed_1 = H_ext.compute_energy(dx=dx_disk_1) E_computed_2 = H_ext.compute_energy(dx=dx_disk_2) E_computed_total = H_ext.compute_energy(dx=df.dx) # Check that the sum of the computed energies for disk #1 and #2 equals # the total computed energy assert np.allclose(E_computed_1 + E_computed_2, E_computed_total, atol=0, rtol=1e-12) # Check that the computed energies are within the tolerance of the # analytical expressions assert np.allclose(E_computed_1, E_analytical_1, atol=0, rtol=RTOL) assert np.allclose(E_computed_2, E_analytical_2, atol=0, rtol=RTOL) assert np.allclose(E_computed_total, E_analytical_total, atol=0, rtol=RTOL)
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 __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_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 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_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 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 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_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()
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 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 test_sim(do_plot=False): mesh = df.BoxMesh(0, 0, 0, 2, 2, 2, 1, 1, 1) sim = Sim(mesh, 8.6e5, unit_length=1e-9) alpha = 0.1 sim.alpha = alpha sim.set_m((1, 0, 0)) sim.set_up_solver() H0 = 1e5 sim.add(Zeeman((0, 0, H0))) exchange = Exchange(13.0e-12) sim.add(exchange) dt = 1e-12 ts = np.linspace(0, 500 * dt, 100) precession_coeff = sim.gamma / (1 + alpha**2) mz_ref = [] mz = [] real_ts = [] for t in ts: sim.run_until(t) real_ts.append(sim.t) mz_ref.append(np.tanh(precession_coeff * alpha * H0 * sim.t)) mz.append(sim.m[-1]) # same as m_average for this macrospin problem 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)) < 8e-7
def compare_with_analytic_solution(alpha=0.5, max_t=1e-9): """ Compares the C/dolfin/odeint solution to the analytical one. """ print "Running comparison with alpha={0}.".format(alpha) # define 3d mesh x0 = y0 = z0 = 0 x1 = y1 = z1 = 10e-9 nx = ny = nz = 1 mesh = dolfin.BoxMesh(dolfin.Point(x0, x1, y0), dolfin.Point(y1, z0, z1), nx, ny, nz) sim = Simulation(mesh, Ms=1) sim.alpha = alpha sim.set_m((1, 0, 0)) sim.add(Zeeman((0, 0, 1e6))) # plug in an integrator with lower tolerances sim.set_tol(abstol=1e-12, reltol=1e-12) ts = numpy.linspace(0, max_t, num=100) ys = numpy.array([(sim.advance_time(t), sim.m.copy())[1] for t in ts]) tsfine = numpy.linspace(0, max_t, num=1000) m_analytical = make_analytic_solution(1e6, alpha, sim.gamma) save_plot(ts, ys, tsfine, m_analytical, alpha) TOLERANCE = 1e-6 # tolerance on Ubuntu 11.10, VM Hans, 25/02/2012 rel_diff_maxs = list() for i in range(len(ts)): m = numpy.mean(ys[i].reshape((3, -1)), axis=1) m_ref = m_analytical(ts[i]) diff = numpy.abs(m - m_ref) diff_max = numpy.max(diff) rel_diff_max = numpy.max(diff / numpy.max(m_ref)) rel_diff_maxs.append(rel_diff_max) print "t= {0:.3g}, diff_max= {1:.3g}.".format(ts[i], diff_max) msg = "Diff at t= {0:.3g} too large.\nAllowed {1:.3g}. Got {2:.3g}." assert diff_max < TOLERANCE, msg.format(ts[i], TOLERANCE, diff_max) print "Maximal relative difference: " print numpy.max(numpy.array(rel_diff_maxs))
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 t_test_sim_ode_parallel(do_plot=False): mesh = df.BoxMesh(df.Point(0, 0, 0), df.Point(2, 2, 2), 1, 1, 1) sim = Sim(mesh, 8.6e5, unit_length=1e-9, pbc='2d', parallel=True) sim.alpha = alpha sim.set_m((1, 0, 0)) sim.set_tol(1e-10, 1e-14) H0 = 1e5 sim.add(Zeeman((0, 0, H0))) # sim.add(Exchange(1.3e-11)) dt = 1e-12 ts = np.linspace(0, 500 * dt, 100) precession_coeff = sim.gamma / (1 + alpha**2) mz_ref = np.tanh(precession_coeff * alpha * H0 * ts) mzs = [] length_error = [] for t in ts: sim.run_until(t) mm = sim.m.copy() # mm.shape=(3,-1) # mx,my,mz = mm[:,0] # same as m_average for this macrospin problem mzs.append(mm[-1]) #length = np.sqrt(mx**2+my**2+mz**2) # length_error.append(abs(length-1.0)) if do_plot: ts_ns = ts * 1e9 plt.plot(ts_ns, mzs, "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_sim_ode.png")) print("Deviation = {}, total value={}".format(np.max(np.abs(mzs - mz_ref)), mz_ref)) assert np.max(np.abs(mzs - mz_ref)) < 1e-9