def dynamic(mesh):

    sim = Sim(mesh, name='dyn_spin', driver='slonczewski')
    # 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.u0 = 0.005
    sim.driver.alpha = 0.1

    ts = np.linspace(0, 1200, 401)
    for t in ts:
        sim.run_until(t)
        #sim.save_vtk()
        print t
Beispiel #2
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])
Beispiel #3
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")
Beispiel #4
0
def relax_system(mesh):

    sim = Sim(mesh, name='relax')
    # sim.set_options(rtol=1e-10,atol=1e-14)
    sim.alpha = 1.0
    sim.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)
Beispiel #5
0
def relax_system(mesh):

    sim = Sim(mesh, name='dmi_2d')
    sim.driver.alpha = 0.1
    sim.driver.gamma=1.76e11
    sim.mu_s = 1e-22

    J = 1e-20
    exch = UniformExchange(J)
    sim.add(exch)

    dmi = DMI(0.1 * J)
    sim.add(dmi)

    sim.set_m(init_m)    

    ts = np.linspace(0, 5e-10, 101)
    for t in ts:
        print(t)
        sim.run_until(t)
        #sim.save_vtk()

    return sim.spin
Beispiel #6
0
def test_demag_fft_exact():
    mesh = CuboidMesh(nx=5, ny=3, nz=4)
    sim = Sim(mesh)

    demag = Demag()
    sim.add(demag)

    def init_m(pos):
        x = pos[0]
        if x <= 2:
            return (1, 0, 0)
        elif x >= 4:
            return (0, 0, 1)
        else:
            return (0, 1, 0)

    sim.set_m(init_m)
    fft = demag.compute_field()
    exact = demag.compute_exact()
    # print fft,exact
    print np.max(np.abs(fft - exact))

    assert np.max(np.abs(fft - exact)) < 5e-22
Beispiel #7
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
Beispiel #8
0
def simulation(nx,
               ny,
               nz,
               dx,
               dy,
               dz,
               j,
               d,
               kc,
               mu_s,
               sim_name,
               bz_min,
               bz_max,
               bz_steps,
               bz_hysteresis=False,
               initial_state_one_bobber=None,
               initial_state_two_bobbers=None,
               initial_state_two_bobbers_asymm=None,
               initial_state_sk_tube=None,
               initial_state_one_dim_mod=None,
               initial_state_helix_angle_x=(None, None),
               stopping_dmdt=1e-5,
               max_steps=4000,
               save_initial_state=None):

    mesh = CuboidMesh(nx=nx,
                      ny=ny,
                      nz=nz,
                      dx=dx,
                      dy=dy,
                      dz=dz,
                      x0=-nx * 0.5,
                      y0=-ny * 0.5,
                      z0=-nz * 0.5,
                      unit_length=1.,
                      periodicity=(True, True, False))

    # J = 1.
    # D = 0.628  # L_D = 2 PI a J / D = 10 * a => D / J = 2 PI / 10.
    # Bz = 0.2   # B_z == (B_z mu_s / J)
    # mu_s = 1.

    sim = Sim(mesh, name=sim_name, integrator='sundials_openmp')

    sim.mu_s = mu_s
    sim.add(Exchange(j))
    sim.add(DMI(d, dmi_type='bulk'))
    sim.add(Zeeman((0.0, 0.0, bz_min * 1e-3)), save_field=True)
    if np.abs(kc) > 0.0:
        sim.add(CubicAnisotropy(kc))

    # .........................................................................

    sim.driver.alpha = 0.9
    sim.driver.do_precession = False

    if not os.path.exists('npys/{}'.format(sim_name)):
        os.makedirs('npys/{}'.format(sim_name))

    if not os.path.exists('txts'):
        os.makedirs('txts')

    for i, B_sweep in enumerate(np.linspace(bz_min, bz_max, bz_steps)):

        print('Bz = {:.0f} mT '.format(B_sweep).ljust(80, '-'))

        Zeeman_int = sim.get_interaction('Zeeman')
        Zeeman_int.update_field((0.0, 0.0, B_sweep * 1e-3))

        if (not bz_hysteresis) or (bz_hysteresis and i < 1):

            if initial_state_one_dim_mod:
                sim.set_m(lambda r: one_dim_mod(r, B_sweep * 1e-3, d))
            elif initial_state_helix_angle_x[0]:
                angle = initial_state_helix_angle_x[0] * np.pi / 180.
                periodic = initial_state_helix_angle_x[1]
                sim.set_m(lambda r: helix_angle_x(r, angle, periodic))
            elif initial_state_sk_tube:
                sk_rad = initial_state_sk_tube
                sim.set_m(
                    lambda r: sk_tube(r, B_sweep * 1e-3, d, sk_rad=sk_rad))
            elif initial_state_two_bobbers:
                bobber_length = initial_state_two_bobbers
                sim.set_m(lambda r: two_bobbers(r,
                                                B_sweep * 1e-3,
                                                d,
                                                mesh.Lz,
                                                bobber_rad=3.,
                                                bobber_length=bobber_length))
            elif initial_state_two_bobbers_asymm:
                bobber_length = initial_state_two_bobbers_asymm
                sim.set_m(
                    lambda r: two_bobbers_asymm(r,
                                                B_sweep * 1e-3,
                                                d,
                                                mesh.Lz,
                                                bobber_rad=3.,
                                                bobber_length=bobber_length))
            elif initial_state_one_bobber:
                bobber_length = initial_state_one_bobber
                sim.set_m(lambda r: one_bobber(r,
                                               B_sweep * 1e-3,
                                               d,
                                               mesh.Lz,
                                               bobber_rad=3.,
                                               bobber_length=bobber_length))
            else:
                raise Exception('Not a valid initial state')

        if save_initial_state:
            save_vtk(sim, sim_name + '_INITIAL', field_mT=B_sweep)
            name = 'npys/{}/m_{}_INITIAL_Bz_{:06d}.npy'.format(
                sim.driver.name, sim_name, int(B_sweep))
            np.save(name, sim.spin)

        # .....................................................................

        sim.relax(stopping_dmdt=stopping_dmdt,
                  max_steps=max_steps,
                  save_m_steps=None,
                  save_vtk_steps=None)

        # .....................................................................

        save_vtk(sim, sim_name, field_mT=B_sweep)
        name = 'npys/{}/m_{}_Bz_{:06d}.npy'.format(sim.driver.name, sim_name,
                                                   int(B_sweep))
        np.save(name, sim.spin)

        sim.driver.reset_integrator()

    shutil.move(sim_name + '.txt', 'txts/{}.txt'.format(sim_name))
Beispiel #9
0
        return base_folder_ba(D)
    elif method == 'linear_interpolations':
        return base_folder(D)
    elif method == 'climbing':
        return base_folder_ci(D, climbing_image[D])


# 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)
Beispiel #10
0
def test_skx_num_atomistic():
    """
    Test the *finite spin chirality* or skyrmion number for
    a discrete spins simulation in a two dimensional lattice

    The expression is (PRL 108, 017601 (2012)) :

    Q =     S_i \dot ( S_{i+1}  X  S_{j+1} )
         +  S_i \dot ( S_{i-1}  X  S_{j-1} )

    which measures the chirality taking two triangles of spins
    per lattice site i:
        S_{i} , S_{i + x} , S_{i + y}    and
        S_{i} , S_{i - x} , S_{i - y}

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

    We also test the Berg and Luscher definition for a topological
    charge (see the hexagonal mesh test for details) in a
    square lattice.

    This test generate a skyrmion pointing down with unrealistic
    paremeters.

    """

    mesh = CuboidMesh(nx=120, ny=120, nz=1, periodicity=(True, True, False))

    sim = Sim(mesh, name='skx_num')
    sim.driver.set_tols(rtol=1e-6, atol=1e-6)
    sim.driver.alpha = 1.0
    sim.driver.gamma = 1.0
    sim.mu_s = 1.0

    sim.set_m(lambda pos: init_m(pos, 60, 60, 20))

    sim.do_precession = False

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

    D = 0.09
    dmi = DMI(D)
    sim.add(dmi)

    zeeman = Zeeman([0, 0, 5e-3])
    sim.add(zeeman)

    sim.relax(dt=2.0,
              stopping_dmdt=1e-2,
              max_steps=1000,
              save_m_steps=None,
              save_vtk_steps=None)

    skn = sim.skyrmion_number()
    print('skx_number', skn)

    skn_BL = sim.skyrmion_number(method='BergLuscher')
    print('skx_number_BergLuscher', skn_BL)

    # Test the finite chirality method
    assert skn > -1 and skn < -0.99

    # Test the Berg-Luscher method
    assert np.abs(skn_BL - (-1)) < 1e-4 and np.sign(skn_BL) < 0

    # Test guiding center
    Rx, Ry = compute_RxRy(mesh, sim.spin)
    print('Rx=%g, Ry=%g' % (Rx, Ry))
    assert Rx < 60 and Rx > 58
    assert Ry < 60 and Ry > 58
Beispiel #11
0
if not args.PBC_2D:
    mesh = HexagonalMesh(args.hex_a,
                         args.hex_nx,
                         args.hex_ny,
                         alignment=args.alignment,
                         unit_length=args.unit_length)
else:
    mesh = HexagonalMesh(args.hex_a,
                         args.hex_nx,
                         args.hex_ny,
                         periodicity=(True, True),
                         alignment=args.alignment,
                         unit_length=args.unit_length)

# Initiate Fidimag simulation -------------------------------------------------
sim = Sim(mesh, name=args.sim_name)

# sim.set_tols(rtol=1e-10, atol=1e-14)
if args.alpha:
    sim.driver.alpha = args.alpha
# sim.gamma = 2.211e5

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

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)
Beispiel #12
0
from fidimag.atomistic import Sim
from fidimag.common.cuboid_mesh import CuboidMesh
from fidimag.atomistic import UniformExchange, Zeeman
import fidimag.common.constant as const

mesh = CuboidMesh(nx=1, ny=1, dx=1, dy=1)

sim = Sim(mesh, name='relax_sk')
sim.gamma = const.gamma
sim.set_m((1, 0, 0))
sim.add(Zeeman((0, 0, 25.)))

sim.run_until(1e-11)
sim.set_tols(rtol=1e-10, atol=1e-12)
sim.run_until(2e-11)
Beispiel #13
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
Beispiel #14
0
    nx, ny, nz = 30, 30, 30
    dx, dy, dz = 1, 1, 1
    mesh = CuboidMesh(nx=nx,
                      ny=ny,
                      nz=nz,
                      dx=dx,
                      dy=dy,
                      dz=dz,
                      x0=-nx * 0.5,
                      y0=-ny * 0.5,
                      z0=-nz * 0.5,
                      unit_length=1.,
                      periodicity=(True, True, False))

    sim_name = 'sk_helix'
    sim = Sim(mesh, name=sim_name, integrator='sundials_openmp')

    sim.mu_s = 1
    sim.add(Exchange(1))
    sim.add(DMI(0.727, dmi_type='bulk'))
    bz_min = FIELD
    sim.add(Zeeman((0.0, 0.0, bz_min * 1e-3)), save_field=True)
    kc = -0.05
    if np.abs(kc) > 0.0:
        sim.add(CubicAnisotropy(kc))

    # .........................................................................

    sim.driver.alpha = 0.9
    sim.driver.do_precession = False
Beispiel #15
0
    if not args.PBC_2D:
        mesh = HexagonalMesh(args.hexagonal_mesh[2] * 0.5,
                             int(args.hexagonal_mesh[0]),
                             int(args.hexagonal_mesh[1]),
                             alignment=args.alignment,
                             unit_length=args.unit_length,
                             shells=shells
                             )
    else:
        mesh = HexagonalMesh(args.hex_a, args.hex_nx, args.hex_ny,
                             periodicity=(True, True),
                             alignment=args.alignment,
                             unit_length=args.unit_length,
                             shells=shells
                             )
    sim = Sim(mesh, name=args.sim_name, driver=args.driver)

elif args.mesh_from_image:
    sim_from_image = sfi.sim_from_image(args.mesh_from_image[0],
                                        image_range=[float(args.mesh_from_image[1]),
                                                     float(args.mesh_from_image[2]),
                                                     float(args.mesh_from_image[3]),
                                                     float(args.mesh_from_image[4])
                                                     ],
                                        sim_name=args.sim_name,
                                        shells=shells,
                                        driver=args.driver
                                        )

    if args.mu_s.endswith('.npy'):
        sim_from_image.generate_magnetic_moments(load_file=str(args.mu_s))
Beispiel #16
0
def simulation(nx,
               ny,
               nz,
               dx,
               dy,
               dz,
               j,
               d,
               kc,
               bz,
               mu_s,
               sim_name,
               add_image=None,
               add_interpolations=None,
               add_images_folder=None,
               stopping_dydt=None,
               max_steps=None,
               save_m_every=None,
               integrator='sundials',
               integrator_stepsize=1e-3,
               interpolation_method='rotation',
               variable_spring_forces=None,
               interpolation_energy='polynomial'):

    if add_interpolations:
        if (len(add_image) - 1) != len(add_interpolations):
            raise Exception('(N interpolations) != (N images - 1)')

    mesh = CuboidMesh(nx=nx,
                      ny=ny,
                      nz=nz,
                      dx=dx,
                      dy=dy,
                      dz=dz,
                      x0=-nx * 0.5,
                      y0=-ny * 0.5,
                      z0=-nz * 0.5,
                      unit_length=1.,
                      periodicity=(True, True, False))

    # Simulation
    sim = Sim(mesh, name=sim_name)
    sim.mu_s = mu_s
    sim.add(Exchange(j))
    sim.add(DMI(d, dmi_type='bulk'))
    sim.add(Zeeman((0.0, 0.0, bz * 1e-3)))
    if np.abs(kc) > 0.0:
        sim.add(CubicAnisotropy(kc))

    # GNEBM simulation ........................................................

    if add_interpolations:
        # Set the initial images from the list
        init_images = [np.load(image) for image in add_image]
        interpolations = [i for i in add_interpolations]
    elif add_images_folder:
        if add_images_folder.endswith('_LAST'):
            dir_list = glob.glob(add_images_folder[:-5] + '*')
            dir_list = sorted(
                dir_list,
                key=lambda f: int(re.search(r'(?<=_)[0-9]+$', f).group(0)))
            add_images_folder = dir_list[-1]

        flist = sorted(os.listdir(add_images_folder))
        init_images = [
            np.load(os.path.join(add_images_folder, image)) for image in flist
        ]
        interpolations = []
    else:
        raise Exception('Specify an option to add images')

    # Start a NEB simulation passing the Simulation object and all the NEB
    # parameters
    string = StringMethod(sim,
                          init_images,
                          interpolations=interpolations,
                          name=sim_name,
                          openmp=True,
                          integrator=integrator,
                          interpolation_method=interpolation_method)

    if integrator == 'verlet':
        string.integrator.mass = 1
        string.integrator.stepsize = integrator_stepsize
        dt = integrator_stepsize * 10
    else:
        dt = integrator_stepsize

    # .........................................................................

    for fdir in ['interpolations', 'ndts']:
        if not os.path.exists(fdir):
            os.makedirs(fdir)

    # Finally start the energy band relaxation
    string.relax(max_iterations=max_steps,
                 save_vtks_every=save_m_every,
                 save_npys_every=save_m_every,
                 stopping_dYdt=stopping_dydt,
                 dt=dt)

    # Produce a file with the data from a cubic interpolation for the band
    interp_data = np.zeros((200, 2))
    if interpolation_energy == 'polynomial':
        string.compute_polynomial_factors()
        (interp_data[:, 0],
         interp_data[:,
                     1]) = string.compute_polynomial_approximation_energy(200)
    elif interpolation_energy == 'Bernstein':
        string.compute_Bernstein_polynomials()
        (interp_data[:, 0],
         interp_data[:,
                     1]) = string.compute_Bernstein_approximation_energy(200)
    else:
        raise Exception('No valid interpolation method')

    np.savetxt('interpolations/{}_interpolation.dat'.format(sim_name),
               interp_data)

    # Clean files
    shutil.move(sim_name + '_energy.ndt',
                'ndts/{}_energy.ndt'.format(sim_name))
    shutil.move(sim_name + '_dYs.ndt', 'ndts/{}_dYs.ndt'.format(sim_name))
Beispiel #17
0
# MESH
mesh = HexagonalMesh(a, nx, ny, alignment='square', unit_length=1e-9)

vtk_saver = SaveVTK(mesh, name='sk_displ')

centre_x = (np.max(mesh.coordinates[:, 0]) +
            np.min(mesh.coordinates[:, 0])) * 0.5

centre_y = (np.max(mesh.coordinates[:, 1]) +
            np.min(mesh.coordinates[:, 1])) * 0.5

lx = (np.max(mesh.coordinates[:, 0]) - np.min(mesh.coordinates[:, 0]))
ly = (np.max(mesh.coordinates[:, 1]) - np.min(mesh.coordinates[:, 1]))

# Create a simulation for the FM state and one for the skyrmion
sim = Sim(mesh, name='sk_displ')
sim.mu_s = mu_s
sim_sk = Sim(mesh)
sim_sk.mu_s = mu_s


# Manipulate the initial state
# Generate the skyrmion in the middle of the nanotrack
def generate_skyrmion(pos, i, x_c, y_c, radius, vector_field, sk_field):
    """

    Returns a spin direction for the i-th lattice site, which has coordinates
    *pos*

    Basically:
Beispiel #18
0
def simulation(nx,
               ny,
               nz,
               dx,
               dy,
               dz,
               j,
               d,
               kc,
               bz,
               mu_s,
               sim_name,
               add_image=None,
               add_interpolations=None,
               add_images_folder=None,
               spring_constant=None,
               stopping_dydt=None,
               max_steps=None,
               keep_sim_climbing_image_steps=None,
               save_m_every=None,
               climbing_image=None,
               keep_sim_climbing_image=None,
               keep_sim_climbing_image_again=None,
               integrator='sundials',
               integrator_stepsize=1e-3,
               interpolation_method='rotation',
               variable_spring_forces=None,
               interpolation_energy='polynomial'):

    if add_interpolations:
        if (len(add_image) - 1) != len(add_interpolations):
            raise Exception('(N interpolations) != (N images - 1)')

    mesh = CuboidMesh(nx=nx,
                      ny=ny,
                      nz=nz,
                      dx=dx,
                      dy=dy,
                      dz=dz,
                      x0=-nx * 0.5,
                      y0=-ny * 0.5,
                      z0=-nz * 0.5,
                      unit_length=1.,
                      periodicity=(True, True, False))

    # Simulation
    sim = Sim(mesh, name=sim_name)
    sim.mu_s = mu_s
    sim.add(Exchange(j))
    sim.add(DMI(d, dmi_type='bulk'))
    sim.add(Zeeman((0.0, 0.0, bz * 1e-3)))
    if np.abs(kc) > 0.0:
        sim.add(CubicAnisotropy(kc))

    # GNEBM simulation ........................................................

    if add_interpolations:
        # Set the initial images from the list
        init_images = [np.load(image) for image in add_image]
        interpolations = [i for i in add_interpolations]
    elif add_images_folder:
        if add_images_folder.endswith('_LAST'):
            dir_list = glob.glob(add_images_folder[:-5] + '*')
            dir_list = sorted(
                dir_list,
                key=lambda f: int(re.search(r'(?<=_)[0-9]+$', f).group(0)))
            add_images_folder = dir_list[-1]

        flist = sorted(os.listdir(add_images_folder))
        init_images = [
            np.load(os.path.join(add_images_folder, image)) for image in flist
        ]
        interpolations = []
    else:
        raise Exception('Specify an option to add images')

    if climbing_image:
        if climbing_image.isdigit():
            climbing_image = int(climbing_image)
        else:
            try:
                energies = np.loadtxt(climbing_image)[-1][1:]
                energies = energies - energies[0]
                climbing_image = np.where(energies == np.max(energies))[0][0]
            except OSError:
                raise Exception('Err trying to compute climb image from file')

        print('Using climbing image: {}'.format(climbing_image))

    # Start a NEB simulation passing the Simulation object and all the NEB
    # parameters
    neb = NEBM_Geodesic(sim,
                        init_images,
                        interpolations=interpolations,
                        spring_constant=spring_constant,
                        name=sim_name,
                        openmp=True,
                        climbing_image=climbing_image,
                        integrator=integrator,
                        interpolation_method=interpolation_method)

    if integrator == 'verlet':
        neb.integrator.mass = 1
        neb.integrator.stepsize = integrator_stepsize
        dt = integrator_stepsize * 10
    else:
        dt = integrator_stepsize

    # .........................................................................

    for fdir in ['interpolations', 'ndts']:
        if not os.path.exists(fdir):
            os.makedirs(fdir)

    # Finally start the energy band relaxation
    neb.relax(max_iterations=max_steps,
              save_vtks_every=save_m_every,
              save_npys_every=save_m_every,
              stopping_dYdt=stopping_dydt,
              dt=dt)

    if variable_spring_forces:
        neb.variable_k = True
        neb.dk = spring_constant * 0.9

        neb.relax(max_iterations=max_steps,
                  save_vtks_every=save_m_every,
                  save_npys_every=save_m_every,
                  stopping_dYdt=stopping_dydt,
                  dt=dt,
                  save_initial_state=False)

    # Continue with climbing image if specified
    if keep_sim_climbing_image:

        if not keep_sim_climbing_image_steps:
            keep_sim_climbing_image_steps = max_steps

        # Find all local maxima
        largest_E_im_idx = []
        for i in range(2, neb.n_images - 2):
            if (neb.energies[i] > neb.energies[i - 1]
                    and neb.energies[i - 1] > neb.energies[i - 2]
                    and neb.energies[i] > neb.energies[i + 1]
                    and neb.energies[i + 1] > neb.energies[i + 2]):

                largest_E_im_idx.append(i)
            elif (neb.energies[i] < neb.energies[i - 1]
                  and neb.energies[i - 1] < neb.energies[i - 2]
                  and neb.energies[i] < neb.energies[i + 1]
                  and neb.energies[i + 1] < neb.energies[i + 2]):

                largest_E_im_idx.append(-i)

        neb.climbing_image = largest_E_im_idx

        print('Continuing simulation with CI = {}'.format(largest_E_im_idx))

        neb.name += '_CI'
        # Data will be appended to the initial NDT file, at least we create a
        # new one with the CI appended to the sim name:
        # neb.create_tablewriter()
        # last_step_relax = neb.iterations

        # Variable dk for better resolution around saddle points
        # neb.variable_k = True
        # neb.dk = spring_constant

        neb.relax(max_iterations=keep_sim_climbing_image_steps,
                  save_vtks_every=save_m_every,
                  save_npys_every=save_m_every,
                  stopping_dYdt=keep_sim_climbing_image,
                  dt=dt,
                  save_initial_state=False)

        # Remove initial state (same as final state from the prev relaxation)
        # shutil.rmtree('vtks/{}_{}'.format(neb.name, last_step_relax))

    # Continue with climbing image if specified
    if keep_sim_climbing_image_again:

        if not keep_sim_climbing_image_steps:
            keep_sim_climbing_image_steps = max_steps

        # Find all local maxima
        largest_E_im_idx = []
        for i in range(2, neb.n_images - 2):
            if (neb.energies[i] > neb.energies[i - 1]
                    and neb.energies[i - 1] > neb.energies[i - 2]
                    and neb.energies[i] > neb.energies[i + 1]
                    and neb.energies[i + 1] > neb.energies[i + 2]):

                largest_E_im_idx.append(i)
            elif (neb.energies[i] < neb.energies[i - 1]
                  and neb.energies[i - 1] < neb.energies[i - 2]
                  and neb.energies[i] < neb.energies[i + 1]
                  and neb.energies[i + 1] < neb.energies[i + 2]):

                largest_E_im_idx.append(-i)

        neb.climbing_image = largest_E_im_idx
        print('Continuing simulation with CI = {}'.format(largest_E_im_idx))
        neb.name += '_CI'
        neb.relax(max_iterations=keep_sim_climbing_image_steps,
                  save_vtks_every=save_m_every,
                  save_npys_every=save_m_every,
                  stopping_dYdt=keep_sim_climbing_image_again,
                  dt=dt,
                  save_initial_state=False)

    # Produce a file with the data from a cubic interpolation for the band
    interp_data = np.zeros((200, 2))
    if interpolation_energy == 'polynomial':
        neb.compute_polynomial_factors()
        (interp_data[:, 0],
         interp_data[:, 1]) = neb.compute_polynomial_approximation_energy(200)
    elif interpolation_energy == 'Bernstein':
        neb.compute_Bernstein_polynomials()
        (interp_data[:, 0],
         interp_data[:, 1]) = neb.compute_Bernstein_approximation_energy(200)
    else:
        raise Exception('No valid interpolation method')

    np.savetxt('interpolations/{}_interpolation.dat'.format(sim_name),
               interp_data)

    # Clean files
    shutil.move(sim_name + '_energy.ndt',
                'ndts/{}_energy.ndt'.format(sim_name))
    shutil.move(sim_name + '_dYs.ndt', 'ndts/{}_dYs.ndt'.format(sim_name))
Beispiel #19
0
def test_m_average():
    mesh = CuboidMesh(nx=3, ny=4, nz=5)
    sim = Sim(mesh)
    sim.set_m((0, 0, 1))
    a = sim.compute_average()
    assert a[2] == 1.0
Beispiel #20
0
def skip_test_sim_T_fun():
    mesh = CuboidMesh(nx=3, ny=4, nz=5)
    sim = Sim(mesh)
    sim.set_T(init_T)
    assert (sim.T[0] == 1.5)
    assert (sim.T[-1] == 10.5)
Beispiel #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))
Beispiel #22
0
# Transform to colormaps
BlOr = mpl.colors.LinearSegmentedColormap('BlOr', cdict_BlOr, 256)
BlOr_r = cm.revcmap(BlOr._segmentdata)
BlOr_r = mpl.colors.LinearSegmentedColormap('BlOr', BlOr_r, 256)

# mesh = CuboidMesh(nx=21, ny=21,
#                   dx=0.5, dy=0.5,
#                   unit_length=1e-9,
#                   periodicity=(True, True, False)
#                   )

mesh = HexagonalMesh(.5, 41, 41, periodicity=(True, True))

# Initialise a simulation object and load the skyrmion
# or ferromagnetic states
sim = Sim(mesh, name='neb_21x21-spins_fm-sk_atomic')

sk = '../hexagonal_system/relaxation/npys/2Dhex_41x41_FePd-Ir_B-15e-1_J588e-2_sk-up_npys/m_689.npy'
fm = '../../npys/neb_21x21-spins_fm-sk_atomic_k1e10_216/image_17.npy'
ds = '../../npys/neb_21x21-spins_fm-sk_atomic_k1e10_216/image_11.npy'

# For now we will just generate a skyrmion
states = {
    'skyrmion': sk,
    # 'ferromagnetic': fm,
    # 'destruction': ds
}

for key in states.keys():
    sim.set_m(np.load(states[key]))
Beispiel #23
0
    def __init__(self,
                 image_path,
                 image_range=[0, 21.03, 0, 17.79],
                 mesh_a=0.2715,
                 shells=1,
                 # mesh_nx=79,
                 # mesh_ny=78
                 sim_name='unnamed',
                 bg_colour=(1., 1., 1.),
                 driver='llg'
                 ):

        """

        Generate an object on top of the fidimag simulation class, to generate
        an atomistic simulation using a hexagonal mesh, where the magnetic
        moments are populated in the mesh according to the pixels in a PNG
        image, located in *image_path* The mesh size is generated automatically
        from the dimensions provided for the image (the *image_range* array),
        so that the mesh covers the whole picture. It is recommended that the
        image has white borders since mesh points away from the picture range
        will take the values from the closest boundary point (see the
        populate_mesh function)

        image_range  :: An array [xmin, xmax, ymin, ymax] with the ranges
                        of the image, given in nm

        """

        # print 'Mesh spacings are: nx = {}, ny = {}'.format(mesh_a,
        #                                                    mesh_a * np.sqrt(3) * 0.5)

        self.image_path = image_path
        self.image_range = image_range

        mesh_nx = int(np.around(np.abs(image_range[1] - image_range[0]) / mesh_a))
        mesh_ny = int(np.around(
            np.abs(image_range[3] - image_range[2]) / (mesh_a * np.sqrt(3) * 0.5)
            ))

        self.mesh = HexagonalMesh(mesh_a * 0.5, mesh_nx, mesh_ny,
                                  # periodicity=(True, True),
                                  alignment='square',
                                  unit_length=1e-9,
                                  shells=shells
                                  )

        self.sim = Sim(self.mesh, name=sim_name, driver=driver)

        # Generate the 2D matrix with the image
        # If the image is B/W, every entry will have either [1., 1., 1.]
        # or [0., 0., 0.] representing the RGB data from every pixel
        self.image_data = mpl.image.imread(self.image_path)

        # We will create two new matrices, with the X and Y coordinates
        # of every point in the image matrix, using the range
        # provided in the arguments. For doing this, we use a meshgrid, which
        # automatically generates a 2D mesh of coordinates. The range
        # in the Y coordinates matrix is reversed since the image matrix
        # starts from top to bottom to generate the picture.
        # The shape is [n_rows, n_columns]  --> (ny, nx)
        self.image_coords_x = np.linspace(self.image_range[0],
                                          self.image_range[1],
                                          self.image_data.shape[1])

        self.image_coords_y = np.linspace(self.image_range[3],
                                          self.image_range[2],
                                          self.image_data.shape[0])

        (self.image_coords_x,
         self.image_coords_y) = np.meshgrid(self.image_coords_x,
                                            self.image_coords_y)

        self.bg_colour = bg_colour
Beispiel #24
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()