예제 #1
0
def relax_system(mesh, Dx=0.005, Dp=0.01):

    mat = UnitMaterial()

    sim = Sim(mesh, name='test_energy')
    print('Created sim')
    sim.driver.set_tols(rtol=1e-10, atol=1e-12)

    sim.alpha = mat.alpha
    sim.driver.gamma = mat.gamma
    sim.pins = pin_fun

    exch = UniformExchange(mat.J)
    sim.add(exch)
    print('Added UniformExchange')

    anis = Anisotropy(Dx, axis=[1, 0, 0], name='Dx')
    sim.add(anis)
    print('Added Anisotropy')

    anis2 = Anisotropy([0, 0, -Dp], name='Dp')
    sim.add(anis2)
    print('Added Anisotropy 2')

    sim.set_m((1, 1, 1))

    T = 100
    ts = np.linspace(0, T, 201)
    for t in ts:
        # sim.save_vtk()
        sim.driver.run_until(t)
        print(('Running -', t))

    # sim.save_vtk()
    np.save('m0.npy', sim.spin)
예제 #2
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
예제 #3
0
def dynamic(mesh):

    sim = Sim(mesh, name='dyn', driver='slonczewski')
    # sim.set_options(rtol=1e-10,atol=1e-14)
    sim.driver.gamma = 1.0
    sim.mu_s = 1.0

    sim.set_m(np.load('m0.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.p = (0, 0, 1)

    sim.u0 = 0.03
    sim.driver.alpha = 0.1

    ts = np.linspace(0, 1e3, 101)
    for t in ts:
        sim.run_until(t)
        sim.save_vtk()
        print t
예제 #4
0
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)
예제 #5
0
def relax_system(mesh):

    # Only relaxation
    sim = Sim(mesh, name='relax')

    # Simulation parameters
    sim.driver.set_tols(rtol=1e-8, atol=1e-10)
    sim.alpha = 0.5
    sim.driver.gamma = 2.211e5 / mu0
    sim.mu_s = 1e-27 / mu0
    sim.driver.do_precession = False

    # The initial state passed as a function
    sim.set_m(init_m)
    # 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)

    # Start relaxation and save the state in m0.npy
    sim.relax(dt=1e-14,
              stopping_dmdt=1e4,
              max_steps=5000,
              save_m_steps=None,
              save_vtk_steps=None)

    np.save('m0.npy', sim.spin)
예제 #6
0
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.driver.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)
예제 #7
0
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
예제 #8
0
def relax_system():

    # 1D chain of 50 spins with a lattice constant of 0.27 A
    mesh = CuboidMesh(
        nx=nx,
        dx=dx,
        unit_length=1e-9,
        # pbc='1d'
    )

    # Initiate the simulation
    sim = Sim(mesh, name=sim_name)
    sim.gamma = const.gamma

    # magnetisation in units of Bohr's magneton
    sim.mu_s = 2 * const.mu_B

    # sim.set_options(gamma=const.gamma, k_B=const.k_B)

    # Initial magnetisation profile
    sim.set_m(init_m)

    # 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)

    # Faster convergence
    sim.alpha = 0.5
    sim.do_precession = False

    sim.relax(dt=1e-13,
              stopping_dmdt=0.05,
              max_steps=700,
              save_m_steps=1000,
              save_vtk_steps=1000)

    # Save the last relaxed state
    np.save(sim_name + '.npy', sim.spin)
예제 #9
0
def test_dw_dmi_atomistic(do_plot=False):

    mesh = CuboidMesh(nx=300, ny=1, nz=1)

    sim = Sim(mesh, name='relax')
    sim.set_default_options(gamma=const.gamma)
    sim.alpha = 0.5
    sim.mu_s = const.mu_s_1
    sim.do_precession = False

    sim.set_m(m_init_dw)

    J = 50.0 * const.k_B
    exch = UniformExchange(J)
    sim.add(exch)

    D = 0.01 * J
    dmi = DMI(D)
    sim.add(dmi)

    K = 0.005 * J
    anis = Anisotropy(K, axis=[1, 0, 0])
    sim.add(anis)

    ONE_DEGREE_PER_NS = 17453292.52

    sim.relax(dt=1e-13,
              stopping_dmdt=0.01 * ONE_DEGREE_PER_NS,
              max_steps=1000,
              save_m_steps=100,
              save_vtk_steps=50)

    np.save('m0.npy', sim.spin)

    xs = np.array([p[0] for p in mesh.coordinates]) - 150

    mx, my, mz = analytical(xs, A=J / 2.0, D=-D, K=K)
    mxyz = sim.spin.copy()
    mxyz = mxyz.reshape(-1, 3).T

    assert max(abs(mxyz[0, :] - mx)) < 0.001
    assert max(abs(mxyz[1, :] - my)) < 0.001
    assert max(abs(mxyz[2, :] - mz)) < 0.0006

    if do_plot:

        save_plot(xs, mxyz, mx, my, mz)
예제 #10
0
def test_anis():
    mesh = CuboidMesh(nx=5, ny=3, nz=2)
    spin = np.zeros(90)
    anis = Anisotropy(Ku=1, axis=[1, 0, 0])
    mu_s = np.ones(90)
    anis.setup(mesh, spin, mu_s)
    field = anis.compute_field()
    assert len(mesh.coordinates) == 5 * 3 * 2
    assert np.max(field) == 0
    spin[0] = 99
    field = anis.compute_field()
    assert field[0] == 2 * 99
예제 #11
0
def create_simulation(R, B):
    mu_s = 3
    sim_hexagon = HexagonSim(
        R,  # R
        0.2715,  # a
        mu_s,  # mu_s
        name='unnamed')
    sim = sim_hexagon.sim

    # mask = (sim.mu_s / C.mu_B) > 1e-5
    exch = UniformExchange(5.881 * C.meV)
    sim.add(exch)
    dmi = DMI(D=1.557 * C.meV, dmi_type='interfacial')
    sim.add(dmi)
    sim.add(Zeeman([0., 0., B]))
    sim.add(Anisotropy(0.406 * C.meV, axis=[0, 0, 1]))

    return sim
예제 #12
0
파일: dw.py 프로젝트: takluyver/fidimag
def relax_system(mesh):

    sim = Sim(mesh, name='relax')
    sim.set_default_options(gamma=const.gamma)
    sim.alpha = 0.5
    sim.mu_s = const.mu_s_1
    sim.do_procession = False

    sim.set_m(m_init_dw)

    J = 50.0 * const.k_B
    exch = UniformExchange(J)
    sim.add(exch)

    D = 0.1 * J
    dmi = DMI(D, dmi_type='interfacial')
    sim.add(dmi)

    K = 0.02 * J
    anis = Anisotropy(K, axis=[0, 0, 1])
    sim.add(anis)

    ONE_DEGREE_PER_NS = 17453292.52

    sim.relax(dt=1e-13,
              stopping_dmdt=0.01 * ONE_DEGREE_PER_NS,
              max_steps=1000,
              save_m_steps=100,
              save_vtk_steps=50)

    np.save('m0.npy', sim.spin)

    xs = np.array([p[0] for p in mesh.pos]) - 150

    mx, my, mz = analytical(xs, A=J / 2.0, D=-D, K=K)
    mxyz = sim.spin.copy()
    mxyz.shape = (3, -1)

    save_plot(xs, mxyz, mx, my, mz)
예제 #13
0
def dynamic(mesh):

    sim = Sim(mesh, name='dyn_spin', driver='slonczewski')
    # sim.set_options(rtol=1e-10,atol=1e-14)
    sim.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.alpha = 0.1

    ts = np.linspace(0, 1200, 401)
    for t in ts:
        sim.run_until(t)
        #sim.save_vtk()
        print t
예제 #14
0
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])
예제 #15
0
def single_spin(alpha=0.01):

    mat = Material()

    mesh = CuboidMesh(nx=1, ny=1, nz=1)

    sim = Sim(mesh, driver='sllg')
    sim.alpha = alpha
    sim.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")
예제 #16
0
def create_sim():

    mesh = CuboidMesh(nx=121, ny=121, nz=1)
    sim = Sim(mesh, name='relax')

    sim.alpha = 1.0
    sim.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
예제 #17
0
def hysteresis_loop(config_file,
                    D=1.56, J=5.88, k_u=0.41, mu_s=3, B=(0, 0, 0), Demag=None,
                    ):
    """
    The config file must have the following parameters:
        D
        J
        k_u
        mu_s                :: Magnitude in Bohr magneton units. A file path
                               can be specified to load a NPY file with the
                               mu_s values, when using the mesh_from_image
                               option
        Demag               :: Set to True for Demag
        sim_name            :: Simulation name
        initial_state       :: A function or a npy file
        hysteresis_steps    ::
        mesh_from_image     :: [IMAGE_PATH, xmin, xmax, ymin, ymax]
        hexagonal_mesh      :: [nx, ny, a]
        PBC_2D              :: Set to True for Periodic boundaries
        pin_boundaries      :: Set to True to pin the spins at the boundaries.
                               Their orientations are already given from the
                               initial_state NPY file
        llg_dt              ::
        llg_stopping_dmdt   ::
        llg_max_steps       ::
        llg_do_precession   :: False as default
        llg_alpha           :: 0.01 as default

    """

    # Parameters --------------------------------------------------------------

    cf = {}
    # execfile(config_file, cf)
    # Python3:
    exec(open(config_file).read(), cf)

    D = cf["D"] * const.meV
    J = cf["J"] * const.meV
    k_u = cf["k_u"] * const.meV

    if isinstance(cf["mu_s"], int) or isinstance(cf["mu_s"], float):
        mu_s = cf["mu_s"] * const.mu_B

    if isinstance(cf["initial_state"], str):
        init_state = np.load(cf["initial_state"])
    elif isinstance(cf["initial_state"], types.FunctionType):
        init_state = cf["initial_state"]

    # Set up default arguments
    default_args = {"mesh_alignment": 'diagonal',
                    "mesh_unit_length": 1e-9,
                    "llg_dt": 1e-11,
                    "llg_stopping_dmdt": 1e-2,
                    "llg_max_steps": 4000,
                    "llg_do_precession": False,
                    "llg_alpha": 0.01
                    }

    for key in default_args.keys():
        if not cf.get(key):
            print(default_args[key])
            cf[key] = default_args[key]

    # Simulation object -------------------------------------------------------

    if cf.get("hexagonal_mesh"):
        if not cf["PBC_2D"]:
            mesh = HexagonalMesh(cf["hexagonal_mesh"][2] * 0.5,
                                 int(cf["hexagonal_mesh"][0]),
                                 int(cf["hexagonal_mesh"][1]),
                                 alignment=cf["mesh_alignment"],
                                 unit_length=cf["mesh_unit_length"]
                                 )

        else:
            mesh = HexagonalMesh(cf["hexagonal_mesh"][2] * 0.5,
                                 int(cf["hexagonal_mesh"][0]),
                                 int(cf["hexagonal_mesh"][1]),
                                 periodicity=(True, True),
                                 alignment=cf["mesh_alignment"],
                                 unit_length=cf["mesh_unit_length"]
                                 )

        sim = Sim(mesh, name=cf["sim_name"])

    elif cf.get("mesh_from_image"):
        sim_from_image = sfi.sim_from_image(
            cf["mesh_from_image"][0],
            image_range=[float(cf["mesh_from_image"][1]),
                         float(cf["mesh_from_image"][2]),
                         float(cf["mesh_from_image"][3]),
                         float(cf["mesh_from_image"][4])
                         ],
            sim_name=cf["sim_name"]
            )

        if isinstance(cf["mu_s"], str):
            sim_from_image.generate_magnetic_moments(load_file=cf["mu_s"])
        else:
            sim_from_image.generate_magnetic_moments(mu_s=(mu_s))

        sim = sim_from_image.sim

    elif cf.get("truncated_triangle"):
        if len(cf["truncated_triangle"]) == 3:
            sim_triangle = TruncatedTriangleSim(
                cf["truncated_triangle"][0],  # L
                cf["truncated_triangle"][1],  # offset
                cf["truncated_triangle"][2],  # a
                cf["mu_s"],                   # mu_s
                name=cf["sim_name"]
                )
        elif len(cf["truncated_triangle"]) == 5:
            sim_triangle = TruncatedTriangleSim(
                cf["truncated_triangle"][0],    # L
                [float(offs) for offs in cf["truncated_triangle"][1:4]],  # offsets
                cf["truncated_triangle"][4],    # a
                cf["mu_s"],                     # mu_s
                name=cf["sim_name"]
                )

        sim = sim_triangle.sim

    elif cf.get("hexagon"):
        sim_hexagon = HexagonSim(cf["hexagon"][0],    # R
                                 cf["hexagon"][1],    # a
                                 cf["mu_s"],          # mu_s
                                 name=cf["sim_name"]
                                 )
        sim = sim_hexagon.sim

    # Initial state
    sim.set_m(init_state)

    sim.driver.do_precession = cf["llg_do_precession"]
    sim.driver.alpha = cf["llg_alpha"]

    # Material parameters -----------------------------------------------------

    if cf.get("hexagonal_mesh"):
        sim.mu_s = mu_s

    exch = UniformExchange(J)
    sim.add(exch)

    dmi = DMI(D=(D), dmi_type='interfacial')
    sim.add(dmi)

    zeeman = Zeeman((0, 0, 0))
    sim.add(zeeman, save_field=True)

    if k_u:
        # Uniaxial anisotropy along + z-axis
        sim.add(Anisotropy(k_u, axis=[0, 0, 1]))

    if cf.get("Demag"):
        print('Using Demag!')
        sim.add(DemagHexagonal())

    # Pin boundaries ----------------------------------------------------------

    # We will correct the spin directions according to the specified argument,
    # in case the spins at the boundaries are pinned
    if cf.get('pin_boundaries'):
        ngbs_filter = np.zeros(sim.pins.shape[0])
        # Filter rows by checking if any of the elements is less than zero
        # This means that if any of the neighbours of the i-th lattice site is
        # -1, we pin the spin direction at that site
        ngbs_filter = np.any(sim.mesh.neighbours < 0, axis=1, out=ngbs_filter)

        sim.set_pins(ngbs_filter)

    # Hysteresis --------------------------------------------------------------

    for ext in ['npys', 'vtks']:
        if not os.path.exists('{}/{}'.format(ext, cf["sim_name"])):
            os.makedirs('{}/{}'.format(ext, cf["sim_name"]))

    for ext in ['txts', 'dats']:
        if not os.path.exists('{}/'.format(ext)):
            os.makedirs('{}'.format(ext))

    Brange = cf["hysteresis_steps"]
    print('Computing for Fields:', Brange)

    # We will save the hysteresis steps on this file with every row as:
    # step_number field_in_Tesla
    hystfile = '{}_hyst_steps.dat'.format(cf["sim_name"])
    # If the file already exists, we will append the new steps, otherwise
    # we just create a new file (useful for restarting simulations)
    if not os.path.exists(hystfile):
        nsteps = 0
        fstate = 'w'
    else:
        # Move old txt file from the previous simulation, appending an _r
        # everytime a simulation with the same name is started
        txtfile = [f for f in os.listdir('.') if f.endswith('txt')][0]
        txtfile = re.search(r'.*(?=\.txt)', txtfile).group(0)
        shutil.move(txtfile + '.txt', txtfile + '_r.txt')

        nsteps = len(np.loadtxt(hystfile))
        fstate = 'a'

    f = open(hystfile, fstate)

    for i, B in enumerate(Brange):
        sim.get_interaction('Zeeman').update_field(B)

        sim.driver.relax(dt=cf["llg_dt"],
                         stopping_dmdt=cf["llg_stopping_dmdt"],
                         max_steps=cf["llg_max_steps"],
                         save_m_steps=None,
                         save_vtk_steps=None
                         )

        print('Saving NPY for B = {}'.format(B))
        np.save('npys/{0}/step_{1}.npy'.format(cf["sim_name"], i + nsteps),
                sim.spin)

        sim.driver.save_vtk()
        shutil.move('{}_vtks/m_{}.vtk'.format(cf["sim_name"],
                                              str(sim.driver.step).zfill(6)
                                              ),
                    'vtks/{0}/step_{1}.vtk'.format(cf["sim_name"], i + nsteps)
                    )

        f.write('{} {} {} {}\n'.format(i + nsteps,
                                       B[0], B[1], B[2],
                                       )
                )
        f.flush()
        sim.driver.reset_integrator()

    os.rmdir('{}_vtks'.format(cf["sim_name"]))
    shutil.move('{}.txt'.format(cf["sim_name"]), 'txts/')
    shutil.move(hystfile, 'dats/')

    f.close()
예제 #18
0

# Data ------------------------------------------------------------------------

mesh = HexagonalMesh(0.125, 320, 185, unit_length=1e-9, alignment='square')

# Generate the linear interpolations of the NEBM band from every DMI value from
# the arguments
for D in args.D_list:

    sim = Sim(mesh)
    sim.set_mu_s(0.846 * const.mu_B)
    sim.add(DemagHexagonal())
    sim.add(UniformExchange(J=27.026 * const.meV))
    sim.add(DMI(DMIc[D] * const.meV, dmi_type='interfacial'))
    sim.add(Anisotropy(0.0676 * const.meV, axis=[0, 0, 1]))

    images = [
        np.load(os.path.join(methods(args.method, D), _file))
        for _file in sorted(os.listdir(methods(args.method, D)),
                            key=lambda f: int(re.search('\d+', f).group(0)))
    ]

    nebm = NEBM_Geodesic(sim, images, spring_constant=1e4)
    l, E = nebm.compute_polynomial_approximation(500)

    # Distances for every image from the first image (0th image)
    ll = [0]
    for i in range(len(nebm.distances)):
        ll.append(np.sum(nebm.distances[:i + 1]))
    ll = np.array(ll)
예제 #19
0
sim.mu_s = args.mu_s * const.mu_B

exch = UniformExchange(args.J * const.meV)
sim.add(exch)

dmi = DMI(D=(args.D * const.meV), dmi_type='interfacial')
sim.add(dmi)

if args.B:
    zeeman = Zeeman((0, 0, args.B))
    sim.add(zeeman, save_field=True)

if args.k_u:
    # Uniaxial anisotropy along + z-axis
    sim.add(Anisotropy(args.k_u * const.meV, axis=[0, 0, 1]))

if args.Demag:
    sim.add(DemagHexagonal())

# -----------------------------------------------------------------------------

# Debug Information -----------------------------------------------------------

print('Saturation Magnetisation: {} mu_B'.format(args.mu_s))
print('Exchange constant: {}  meV'.format(args.J))
print('DMI constant: {}  meV'.format(args.D))
if args.k_u:
    print('Anisotropy constant: {}   meV'.format(args.k_u))
if args.B:
    print('Zeeman field: (0, 0, {})  T'.format(args.B / mu0))
예제 #20
0
def test_skx_num_atomistic_hexagonal():
    """

    Test the topological charge or skyrmion number for a discrete spins
    simulation in a two dimensional hexagonal lattice, using Berg and Luscher
    definition in [Nucl Phys B 190, 412 (1981)] and simplified in [PRB 93,
    174403 (2016)], which maps a triangulated lattice (using triangles of
    neighbouring spins) area into a unit sphere.

    The areas of two triangles per lattice site cover a unit cell, thus the sum
    cover the whole area of the atomic lattice

    This test generates a skyrmion pointing down and two skyrmions pointing up
    in a PdFe sample using magnetic parameters from: PRL 114, 177203 (2015)

    """

    mesh = HexagonalMesh(0.2715, 41, 41, periodicity=(True, True))

    sim = Sim(mesh, name='skx_number_hexagonal')
    sim.driver.set_tols(rtol=1e-6, atol=1e-6)
    sim.driver.alpha = 1.0
    sim.driver.gamma = 1.0
    sim.mu_s = 3 * const.mu_B

    sim.set_m(lambda pos: init_m(pos, 16.1, 10, 2))

    sim.driver.do_precession = False

    J = 5.881 * const.meV
    exch = UniformExchange(J)
    sim.add(exch)

    D = 1.557 * const.meV
    dmi = DMI(D, dmi_type='interfacial')
    sim.add(dmi)

    sim.add(Anisotropy(0.406 * const.meV, axis=[0, 0, 1]))

    zeeman = Zeeman([0, 0, 2.5])
    sim.add(zeeman)

    sim.relax(dt=1e-13,
              stopping_dmdt=1e-2,
              max_steps=2000,
              save_m_steps=None,
              save_vtk_steps=100)

    skn_single = sim.skyrmion_number(method='BergLuscher')
    print('skx_number_hexagonal', skn_single)

    # Now we generate two skyrmions pointing up
    sim.driver.reset_integrator()
    sim.set_m(
        lambda pos: init_m_multiple_sks(pos, 1, sk_pos=[(9, 6), (18, 12)]))
    sim.get_interaction('Zeeman').update_field([0, 0, -2.5])
    sim.relax(dt=1e-13,
              stopping_dmdt=1e-2,
              max_steps=2000,
              save_m_steps=None,
              save_vtk_steps=None)

    skn_two = sim.skyrmion_number(method='BergLuscher')
    print('skx_number_hexagonal_two', skn_two)

    # Check that we get a right sk number
    assert np.abs(skn_single - (-1)) < 1e-4 and np.sign(skn_single) < 0
    assert np.abs(skn_two - (2)) < 1e-4 and np.sign(skn_two) > 0
예제 #21
0
    def generate_simulation(self,
                            do_precession=False,
                            gamma=1.76e11,
                            load_mu_s=False):
        """

        Generates a simulation according to the self.simulation option

        gamma       :: Default is the free electron gyromagnetic ratio
        load_mu_s   :: A file path to a NPY file with the mu_s information
                       (only for the experimental_sample option)

        """

        # Mesh ----------------------------------------------------------------

        if self.simulation == 'experimental_sample':
            self.sim_from_image = sfi.sim_from_image(sfi.default_image)

            if not load_mu_s:
                self.sim_from_image.generate_magnetic_moments(mu_s=self.mu_s)
            else:
                self.sim_from_image.generate_magnetic_moments(
                    load_file=load_mu_s)

            self.sim = self.sim_from_image.sim

        elif self.simulation == '2D_square':
            # A square sized hexagonal mesh
            mesh = HexagonalMesh(
                self.mesh_a * 0.5,
                self.mesh_nx,
                self.mesh_ny,
                # periodicity=(True, True),
                alignment='square',
                unit_length=1e-9)
            self.sim = Sim(mesh)

            # If we use polygon mesh tools, we can use a hexagon shaped mesh
            # self.sim.mu_s = self.mu_s_in_hexagon

            self.sim.mu_s = self.mu_s

        elif self.simulation == '1D_chain':
            # A 1D chain using a cuboid mesh
            mesh = CuboidMesh(
                dx=self.mesh_a,
                nx=self.mesh_nx,
                ny=1,
                nz=1,
                # periodicity=(True, True),
                unit_length=1e-9)
            self.sim = Sim(mesh)

            # If we use polygon mesh tools, we can use a hexagon shaped mesh
            # self.sim.mu_s = self.mu_s_in_hexagon

            self.sim.mu_s = self.mu_s

        self.sim.driver.do_precession = do_precession
        self.sim.driver.gamma = gamma

        # Interactions --------------------------------------------------------

        exch = UniformExchange(self.J)
        self.sim.add(exch)

        dmi = DMI(D=(self.D), dmi_type='interfacial')
        self.sim.add(dmi)

        zeeman = Zeeman((self.B[0], self.B[1], self.B[2]))
        self.sim.add(zeeman, save_field=True)

        if self.ku:
            # Uniaxial anisotropy along + z-axis
            self.sim.add(Anisotropy(self.ku, axis=[0, 0, 1]))

        if self.Demag:
            print('Using Demag!')
            self.sim.add(DemagHexagonal())

        # ---------------------------------------------------------------------

        self.hls = np.ones_like(self.sim.spin.reshape(-1, 3))
        self.rgbs = np.ones((self.sim.spin.reshape(-1, 3).shape[0], 4))