コード例 #1
0
def test_full_exch_hex_3_shells_lattice_pos():
    """
    Test the x component of the exchange field when using 3 shells of
    neighbours in a 9 x 9 hexagonal lattice with square arrangement

    We set the s_x and s_y spin components as the (i, j) index of the
    lattice positions:
    """
    a = 1
    shells = 3
    mesh = HexagonalMesh(a * 0.5,
                         nx=9,
                         ny=9,
                         shells=shells,
                         alignment='square')
    sim = Sim(mesh)
    # Set the indexes (i, j) as their s_x, s_y position
    sim.set_m(lambda r: init_m(r, a), normalise=False)

    Js = np.ones(shells)
    exch = Exchange(Js)
    sim.add(exch)

    field = exch.compute_field()
    assert field[3 * 0] == (1 + 1 + 0) + (2 + 0) + (2 + 1)  # f_x 1st spin
    assert field[3 * 11] == ((3 + 1 + 2 + 1 + 1 + 2) +
                             (3 + 0 + 2 + 0 + 0 + 3) + (4 + 0 + 3 + 0 + 1 + 0))
コード例 #2
0
ファイル: test_exch.py プロジェクト: fangohr/fidimag
def test_exch_1d():
    """
    Test the x component of the exchange field
    in a 1D mesh, with the spin ordering:

    0 1 2 3 4 5

    """
    mesh = CuboidMesh(nx=5, ny=1, nz=1)
    sim = Sim(mesh)
    exch = Exchange(1.0)
    sim.add(exch)

    sim.set_m(init_m, normalise=False)

    field = exch.compute_field()

    assert field[0] == 1
    assert field[1 * 3] == 2
    assert field[2 * 3] == 4
    assert field[3 * 3] == 6
    assert field[4 * 3] == 3

    assert np.max(field[2::3]) == 0
    assert np.max(field[1::3]) == 0
コード例 #3
0
def test_full_exch_hex_2_shells():
    """
    Test the x component of the exchange field when using 2 shells of
    neighbours, comparing the field manually.
    This is similar than the *test_full_exch_hex_9_shells* function but
    here we do not assume that the neighbours indexes are correct
    We set J=1 for NN and J=2 for NNN
    """
    a = 1
    shells = 2
    mesh = HexagonalMesh(a * 0.5,
                         nx=9,
                         ny=9,
                         shells=shells,
                         alignment='square')
    sim = Sim(mesh)
    sim.spin.reshape(-1, 3)[:,
                            0] = np.arange(len(sim.spin.reshape(-1, 3)[:, 0]))
    Js = np.array([1., 2.])
    exch = Exchange(Js)
    sim.add(exch)
    field = exch.compute_field()
    assert field[3 * 0] == 1. * (1 + 10 + 9) + 2. * (11 + 18)
    assert field[3 *
                 11] == (12 + 10 + 20 + 1 + 19 + 2) + 2. * (21 + 29 + 18 + 3)
コード例 #4
0
def test_exch_1d():
    """
    Test the x component of the exchange field
    in a 1D mesh, with the spin ordering:

    0 1 2 3 4 5

    """
    mesh = CuboidMesh(nx=5, ny=1, nz=1)
    sim = Sim(mesh)
    exch = Exchange(1.0)
    sim.add(exch)

    sim.set_m(init_m, normalise=False)

    field = exch.compute_field()

    assert field[0] == 1
    assert field[1 * 3] == 2
    assert field[2 * 3] == 4
    assert field[3 * 3] == 6
    assert field[4 * 3] == 3

    assert np.max(field[2::3]) == 0
    assert np.max(field[1::3]) == 0
コード例 #5
0
def test_full_exch_hex_9_shells_J_rings():
    """
    Test the x component of the exchange field when using 9 shells of
    neighbours in a 11 X 11 hexagonal lattice with square and diagonal
    arrangement

    We set J=1,2,3,.. for every shell and set the s_x component of the spins as
    the lattice site number:
    [0, 1, 2, 3, ... 120]

    Since we set the s_x components as the lattice position indexes, the x
    component of the field is the sum of the indexes of the neighbours
    (assuming the neighbours indexing is correct) multiplied by J[i] where i is
    the shell (1, 2, ...9), i.e. the 1st shell of ngbs is multiplied by 1,
    the 2nd shell by 2, the 3rd shell by 3, and so on
    """

    for arrang in ['square', 'diagonal']:
        a = 1
        shells = 9
        mesh = HexagonalMesh(a * 0.5,
                             nx=11,
                             ny=11,
                             shells=shells,
                             alignment=arrang)
        sim = Sim(mesh)
        # Set s_x as the lattice site number
        sim.spin.reshape(-1,
                         3)[:,
                            0] = np.arange(len(sim.spin.reshape(-1, 3)[:, 0]))

        # Exchange constants according to the shell
        Js = np.arange(1, 10)
        exch = Exchange(Js)
        sim.add(exch)

        field = exch.compute_field()

        # We only test for the 60th lattice site
        ngbs_60 = mesh.neighbours[60]
        sum_ngbs = mesh._sum_ngbs_shell

        # For every shell, find the ngb indexes in that shell and multiply the
        # sum by the corresponding J=1, 2, 3, ...
        sum_rings = 0
        for i in range(1, shells + 1):
            ngbs_range = slice(sum_ngbs[i - 1], sum_ngbs[i])
            print('J = ', Js[i - 1], '  ngbs indexes: ', ngbs_60[ngbs_range])
            sum_rings += Js[i - 1] * np.sum(ngbs_60[ngbs_range])

        assert field[3 * 60] == sum_rings
コード例 #6
0
def test_full_exch_hex_9_shells():
    """
    Test the x component of the exchange field when using 9 shells of
    neighbours in a 9 X 9 hexagonal lattice with square and diagonal
    arrangement

    We set J=1 for every shell and set the s_x component of the spins as the
    lattice site number:
    [0, 1, 2, 3, ... 80]

    Since we set the s_x components as the lattice position indexes, the x
    component of the field is just the sum of the indexes of the neighbours
    (assuming the neighbours indexing is correct) because we set the exchange
    constants as 1
    """

    for arrang in ['square', 'diagonal']:
        a = 1
        shells = 9
        mesh = HexagonalMesh(a * 0.5,
                             nx=9,
                             ny=9,
                             shells=shells,
                             alignment=arrang)
        sim = Sim(mesh)
        # Set s_x as the lattice site number
        sim.spin.reshape(-1,
                         3)[:,
                            0] = np.arange(len(sim.spin.reshape(-1, 3)[:, 0]))

        Js = np.ones(shells)
        exch = Exchange(Js)
        sim.add(exch)

        field = exch.compute_field()

        # Test the x component for every lattice site, summing the neighbours
        # index and removing the -1 elements (their contribution is zero)
        for i in range(sim.mesh.n):
            assert field[3 * i] == np.sum(
                remove_negatives(sim.mesh.neighbours[i]))
コード例 #7
0
def test_exch_1d_spatial():
    """
    Test the x component of the exchange field
    in a 1D mesh, with the spin ordering:

    0 1 2 3 4 5

    """
    mesh = CuboidMesh(nx=12, ny=1, nz=1)
    sim = Sim(mesh)
    exch = Exchange(spatial_J)
    sim.add(exch)

    sim.set_m(init_m, normalise=False)

    field = exch.compute_field()

    assert exch._J[3, 3] == -1.0
    assert exch._J[5, 1] == 0.3
    assert exch._J[6, 0] == 0.3
    assert exch._J[8, 5] == 1.0
コード例 #8
0
ファイル: test_exch.py プロジェクト: fangohr/fidimag
def test_exch_1d_spatial():
    """
    Test the x component of the exchange field
    in a 1D mesh, with the spin ordering:

    0 1 2 3 4 5

    """
    mesh = CuboidMesh(nx=12, ny=1, nz=1)
    sim = Sim(mesh)
    exch = Exchange(spatial_J)
    sim.add(exch)

    sim.set_m(init_m, normalise=False)

    field = exch.compute_field()

    assert exch._J[3,3] == -1.0
    assert exch._J[5,1] == 0.3
    assert exch._J[6,0] == 0.3
    assert exch._J[8,5] == 1.0
コード例 #9
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))
コード例 #10
0
# Fidimag simulation options ------------------------------------------------

# sim.set_tols(rtol=1e-10, atol=1e-14)
sim.driver.alpha = args.alpha
# sim.driver.gamma = 1.76e11

if args.no_precession:
    sim.driver.do_precession = False

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

if args.hexagonal_mesh:
    sim.mu_s = float(args.mu_s) * const.mu_B

if shells == 1:
    exch = Exchange(args.J[0] * const.meV)
else:
    exch = Exchange(np.array(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]))
コード例 #11
0
                      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

    # Zeeman_int = sim.get_interaction('Zeeman')
    # Zeeman_int.update_field((0.0, 0.0, B_sweep * 1e-3))
コード例 #12
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))
コード例 #13
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))