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 demag_energy(): mesh = from_geofile(os.path.join(MODULE_DIR, "sphere_fine.geo")) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1) m_function = df.interpolate(df.Constant((1, 0, 0)), S3) m = Field(S3, m_function) demag = Demag('FK') demag.setup(m, Field(df.FunctionSpace(mesh, 'DG', 0), Ms), unit_length=1) E = demag.compute_energy() rel_error = abs(E - E_analytical) / abs(E_analytical) print "Energy with FK method: {}.".format(E) return E, rel_error
def setup_finmag(): mesh = from_geofile(os.path.join(MODULE_DIR, "sphere.geo")) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1) m = Field(S3) m.set(df.Constant((1, 0, 0))) Ms = 1 demag = Demag() demag.setup(m, Field(df.FunctionSpace(mesh, 'DG', 0), Ms), unit_length=1e-9) H = demag.compute_field() return dict(m=m, H=H, Ms=Ms, S3=S3, table=start_table())
def setup_cubic(): print "Running finmag..." mesh = from_geofile(os.path.join(MODULE_DIR, "bar.geo")) coords = np.array(zip(*mesh.coordinates())) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3) m = Field(S3) m.set_with_numpy_array_debug(m_gen(coords).flatten()) S1 = df.FunctionSpace(mesh, "Lagrange", 1) Ms_cg = Field(df.FunctionSpace(mesh, 'CG', 1), Ms) anisotropy = CubicAnisotropy(u1=u1, u2=u2, K1=K1, K2=K2, K3=K3) anisotropy.setup(m, Ms_cg, unit_length=1e-9) H_anis = Field(S3) H_anis.set_with_numpy_array_debug(anisotropy.compute_field()) return dict(m=m, H=H_anis.f, S3=S3, table=start_table())
def test_field(): """ Test the demag field. H_demag should be equal to -1/3 M, and with m = (1, 0 ,0) and Ms = 1,this should give H_demag = (-1/3, 0, 0). """ # Using mesh with radius 10 nm (nmag ex. 1) mesh = from_geofile(os.path.join(MODULE_DIR, "sphere1.geo")) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1) m_function = df.interpolate(df.Constant((1, 0, 0)), S3) m = Field(S3, m_function) demag = Demag() demag.setup(m, Field(df.FunctionSpace(mesh, 'DG', 0), Ms), unit_length=1e-9) # Compute demag field H_demag = demag.compute_field() H_demag.shape = (3, -1) x, y, z = H_demag[0], H_demag[1], H_demag[2] print "Max values in direction:" print "x: %g, y: %g, z: %g" % (max(x), max(y), max(z)) print "Min values in direction:" print "x: %g, y: %g, z: %g" % (min(x), min(y), min(z)) x, y, z = average(x), average(y), average(z) print "Average values in direction" print "x: %g, y: %g, z: %g" % (x, y, z) # Compute relative erros x = abs((x + 1. / 3 * Ms) / Ms) y = abs(y / Ms) z = abs(z / Ms) print "Relative error:" print "x: %g, y: %g, z: %g" % (x, y, z) assert x < TOL, "x-average is %g, should be -1/3." % x assert y < TOL, "y-average is %g, should be zero." % y assert z < TOL, "z-average is %g, should be zero." % z
def run_simulation(verbose=False): mesh = from_geofile('bar.geo') sim = Simulation(mesh, Ms=0.86e6, unit_length=1e-9, name="finmag_bar") sim.set_m((1, 0, 1)) sim.set_tol(1e-6, 1e-6) sim.alpha = 0.5 sim.add(Exchange(13.0e-12)) sim.add(Demag()) sim.schedule('save_averages', every=5e-12) sim.schedule("eta", every=10e-12) sim.run_until(3e-10) print timer if verbose: print "The RHS was evaluated {} times, while the Jacobian was computed {} times.".format( sim.integrator.stats()['nfevals'], timer.get("sundials_jtimes", "LLG").calls)
def create_initial_s_state(): """ Creates equilibrium s-state by slowly switching off a saturating field. """ mesh = from_geofile(os.path.join(MODULE_DIR, "bar.geo")) sim = Simulation(mesh, Ms, name="relaxation", unit_length=1e-9) sim.alpha = 0.5 # good enough for relaxation sim.gamma = gamma sim.set_m((1, 1, 1)) sim.add(Demag()) sim.add(Exchange(A)) # Saturating field of Ms in the [1, 1, 1] direction, that gets reduced # every 10 picoseconds until it vanishes after one nanosecond. H_initial = Ms * np.array((1, 1, 1)) / sqrt(3) H_multipliers = list(np.linspace(0, 1)) H = Zeeman(H_initial) def lower_H(sim): try: H_mult = H_multipliers.pop() print "At t = {} s, lower external field to {} times initial field.".format( sim.t, H_mult) H.set_value(H_mult * H_initial) except IndexError: sim.remove_interaction(H.name) print "External field is off." return True sim.add(H) sim.schedule(lower_H, every=10e-12) sim.run_until(0.5e-9) sim.relax() np.save(m_0_file, sim.m) print "Saved magnetisation to {}.".format(m_0_file) print "Average magnetisation is ({:.2g}, {:.2g}, {:.2g}).".format( *sim.m_average)
def test_airbox_method(): """ Define a mesh with two regions (Permalloy and 'air'), where the Permalloy region is e.g. a sphere of radius 1.0 and the 'air' region is a cube with sides of length 10. Next set Ms in both regions, where Ms in the 'air' region is either zero or has a very low value. Then run the simulation and and check that the value of the external field in the 'air' region coincides with the field of a dipole. """ mesh = from_geofile("mesh.geo") mesh_region = df.MeshFunction("uint", mesh, "mesh_mat.xml") # Visualise mesh regions to check they look right (this will be # removed in the final test). #plot_mesh_regions(mesh_region, regions=[1, 2], colors=["green", "red"], # alphas=[1.0, 0.25]) #plt.show() # Define different values for Ms on each subdomain Ms_vals = (8.6e5, 0) Ms = piecewise_on_subdomains(mesh, mesh_region, Ms_vals) sim = sim_with(mesh, Ms=Ms, m_init=(1.0, 0.0, 0), alpha=1.0, unit_length=1e-9, A=13.0e-12, demag_solver='FK') print "Computing effective field..." H_eff = sim.effective_field() print "Computed field: {}".format(H_eff) sim.relax(save_snapshots=True, save_every=1e-11, filename="snapshots/snapshot.pvd")
import numpy as np import dolfin as df df.parameters.reorder_dofs_serial = False from dolfin import * from finmag import Simulation as Sim from finmag.field import Field from finmag.energies import Exchange, Demag, DMI from finmag.util.meshes import from_geofile, mesh_volume MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) REL_TOLERANCE = 5e-4 Ms = 8.6e5 unit_length = 1e-9 mesh = from_geofile(os.path.join(MODULE_DIR, "cylinder.geo")) def init_m(pos): x, y, z = pos r = np.sqrt(x * x + y * y + z * z) return 0, np.sin(r), np.cos(r) def exact_field(pos): x, y, z = pos r = np.sqrt(x * x + y * y + z * z) factor = 4e-3 / (4 * np.pi * 1e-7 * Ms) / unit_length return -2 * factor * np.array([ -(z * np.cos(r) + y * np.sin(r)) / r, x * np.sin(r) / r, x * np.cos(r) / r
from finmag.util.meshes import from_geofile from_geofile("embedded_disk.geo")
import os import numpy as np from math import pi, sin, cos from finmag import Simulation as Sim from finmag.energies import Exchange, Zeeman from finmag.util.meshes import from_geofile from finmag.util.consts import mu0 MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) averages_file = os.path.join(MODULE_DIR, "averages.txt") mesh = from_geofile(os.path.join(MODULE_DIR, "mesh.geo")) 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
from finmag.energies import Exchange, Demag MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) #### # Run the nmag2 example on nmag and finmag and compare timings #### # Create meshes neutralmesh = 'netgen -geofile=bar.geo -meshfiletype="Neutral Format" -meshfile=bar.neutral -batchmode' nmeshimport = 'nmeshimport --netgen bar.neutral bar.nmesh.h5' if not os.path.isfile(os.path.join(MODULE_DIR, "bar.nmesh.h5")): commands.getstatusoutput(neutralmesh) commands.getstatusoutput(nmeshimport) if not os.path.isfile(os.path.join(MODULE_DIR, "bar.xml.gz")): from_geofile(os.path.join(MODULE_DIR, "bar.geo")) # Run nmag print "Running nmag..." commands.getstatusoutput("nsim run_nmag.py --clean") print "Done." # Setup setupstart = time.time() mesh = df.Mesh(os.path.join(MODULE_DIR, "bar.xml.gz")) sim = Simulation(mesh, Ms=0.86e6, unit_length=1e-9) sim.set_m((1, 0, 1)) demag = Demag() demag.parameters["phi_1_solver"] = "minres" demag.parameters["phi_2_solver"] = "gmres" demag.parameters["phi_2_preconditioner"] = "sor"
import pylab as p import numpy as np import dolfin as df import progressbar as pb import finmag.util.helpers as h from finmag import Simulation as Sim from finmag.energies import Exchange, Demag from finmag.util.meshes import from_geofile, mesh_volume logger = logging.getLogger(name='finmag') MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) REL_TOLERANCE = 1e-4 Ms = 0.86e6 unit_length = 1e-9 mesh = from_geofile(os.path.join(MODULE_DIR, "bar30_30_100.geo")) demagsolvers = ["GCR"] def run_finmag(demagsolver): """Run the finmag simulation and store data in (demagsolvertype)averages.txt.""" sim = Sim(mesh, Ms, unit_length=unit_length) sim.alpha = 0.5 sim.set_m((1, 0, 1)) exchange = Exchange(13.0e-12) sim.add(exchange) demag = Demag(solver=demagsolver) sim.add(demag)
# df.interactive() def plot_data(): data = Tablereader('stt.ndt') ts = data['time'] fig = plt.figure() ms = 8.0e5 / 1e6 plt.plot(ts * 1e9, data['m_x'] * ms, '.-', label='m_x') plt.plot(ts * 1e9, data['m_y'] * ms, '+-', label='m_y') plt.plot(ts * 1e9, data['m_z'] * ms, '-', label='m_z') plt.xlim([0, 5]) plt.ylim([-0.3, 0.2]) plt.xlabel('Time (ns)') plt.ylabel('Average Magnetisation ($10^6$A/m)') plt.gray() plt.legend() fig.savefig('averaged_m.pdf') if __name__ == "__main__": #mesh = df.BoxMesh(df.Point(0, 0, 0), df.Point(100, 100, 10), 40, 40, 2) mesh = from_geofile('thinfilm100.geo') print mesh_info(mesh) # relax_system(mesh) with_current(mesh) plot_data()
import os import numpy as np import dolfin as df from finmag.util.meshes import from_geofile from finmag import Simulation from finmag.energies import UniaxialAnisotropy, Exchange, Demag MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) mesh = from_geofile(os.path.join(MODULE_DIR, "two-cubes.geo")) #df.plot(mesh) # #df.interactive() Ms = 0.86e6 # saturation magnetisation A/m A = 13.0e-12 # exchange coupling strength J/m init = (0, 0.1, 1) sim = Simulation(mesh, Ms, unit_length=1e-9) sim.add(Demag()) sim.add(Exchange(A)) sim.set_m(init) f = df.File(os.path.join(MODULE_DIR, 'cubes.pvd')) #same more data for paraview ns = 1e-9 dt = 0.01 * ns v = df.plot(sim.llg._m)
# Create geofile geo = """ algebraic3d solid main = sphere (0, 0, 0; 10)-maxh=%s ; tlo main;""" % str(maxh) absname = "sphere_maxh_%s" % str(maxh) geofilename = os.path.join(MODULE_DIR, absname) geofile = geofilename + '.geo' f = open(geofile, "w") f.write(geo) f.close() # Finmag data mesh = from_geofile(geofile) #mesh.coordinates()[:] = mesh.coordinates()[:]*1e-9 #this makes the results worse!!! HF print "Using mesh with %g vertices" % mesh.num_vertices() V = df.VectorFunctionSpace(mesh, "CG", 1, dim=3) DG0 = df.FunctionSpace(mesh, "DG", 0) # Old code """ M = ("1.0", "0.0", "0.0") solver = FemBemGCRSolver(mesh,M) phi = solver.solve() H_demag = df.project(-df.grad(phi), V) """ # Weiwei code
points = 1000 xs_plot = np.linspace(xmin, xmax, points) alphas = np.zeros(points) S1 = df.FunctionSpace(mesh, "CG", 1) alpha_func = df.project(expr, S1) for i, x in enumerate(xs_plot): try: alphas[i] = alpha_func(x, 0, 0) except RuntimeError: # could raise Exception due to now resolved bug in dolfin # https://bitbucket.org/fenics-project/dolfin/issue/97/function-eval-does-not-find-a-point-that alphas[i] = 0 plt.plot(xs_plot, alphas) plt.xlabel("x (nm)") plt.xlim((xmin, xmax)) plt.ylabel("damping") plt.ylim((0, 1)) plt.grid() plt.title("Spatial Profile of the Damping") plt.savefig('damping.png') print "Saved plot of damping to 'damping.png'." if __name__ == "__main__": from finmag.util.meshes import from_geofile mesh = from_geofile("film.geo") expr = damping_expression(0.02, 0, 1000, 200) plot_damping_profile(expr, mesh)