Beispiel #1
0
def main():
    '''Main driver routine.'''

    initial = read('NH3_initial.traj')
    final = read('NH3_final.traj')

    images = [initial]
    images += [initial.copy() for ii in range(NIMAGES)]
    images += [final]

    neb = NEB(images)
    neb.interpolate()

    opt = BFGS(neb, trajectory='i2f.traj')

    calcs = [
        Dftb(label='NH3_inversion',
             Hamiltonian_SCC='Yes',
             Hamiltonian_SCCTolerance='1.00E-06',
             Hamiltonian_MaxAngularMomentum_N='"p"',
             Hamiltonian_MaxAngularMomentum_H='"s"') for ii in range(NIMAGES)
    ]

    for ii, calc in enumerate(calcs):
        images[ii + 1].set_calculator(calc)

    opt.run(fmax=1.00E-02)
Beispiel #2
0
def nebmake(initial_atoms,final_atoms,n_images):
	"""
	Make interpolated images for NEB
	Args:
		initial_atoms (ASE Atoms object): initial MOF structure
		
		final_atoms (ASE Atoms object): final MOF structure

		n_images (int): number of NEB images
	"""
	pwd = os.getcwd()
	neb_path = os.path.join(pwd,'neb')
	if os.path.exists(neb_path):
		rmtree(neb_path)
	os.makedirs(neb_path)
	os.chdir(neb_path)

	images = [initial_atoms]
	for i in range(n_images):
		images.append(initial_atoms.copy())
	images.append(final_atoms)

	neb = NEB(images)
	neb.interpolate('idpp',mic=True)
	for i, neb_image in enumerate(neb.images):
		if i < 10:
			ii = '0'+str(i)
		else:
			ii = str(i)
		os.mkdir(os.path.join(neb_path,ii))
		write(os.path.join(neb_path,ii,'POSCAR'),neb_image,format='vasp')
	write_dummy_outcar(os.path.join(neb_path,'00','OUTCAR'),initial_atoms.get_potential_energy())
	write_dummy_outcar(os.path.join(neb_path,ii,'OUTCAR'),final_atoms.get_potential_energy())
Beispiel #3
0
def create_lst_images(freactant, fproduct, nimages=11, mic=False):
    """create images with original LST algorithm without NEB force projection as in IDPP

    Parameters
    ----------
    freactant : path to initial atoms
    fproduct  : path to final atoms
    nimages   : the number of images to be interpolated including two endpoints
    mic       : apply mic or not (PBC)
    """
    from ase.neb import IDPP
    from ase.optimize import BFGS
    from ase.build import minimize_rotation_and_translation

    # create linearly interpolated images
    images = _create_images(freactant, fproduct, nimages)
    neb = NEB(images, remove_rotation_and_translation=True)
    neb.interpolate()

    # refine images with LST algorithm
    d1 = images[0].get_all_distances(mic=mic)
    d2 = images[-1].get_all_distances(mic=mic)
    d = (d2 - d1) / (nimages - 1)
    for i, image in enumerate(images):
        image.set_calculator(IDPP(d1 + i * d, mic=mic))
        qn = BFGS(image)
        qn.run(fmax=0.1)
    # apply optimal translation and rotation
    for i in range(nimages - 1):
        minimize_rotation_and_translation(images[i], images[i + 1])

    return images
Beispiel #4
0
    def test_path(self):
        n_images = 8
        images = [initial_structure]
        for i in range(1, n_images - 1):
            image = initial_structure.copy()
            image.set_calculator(copy.deepcopy(ase_calculator))
            images.append(image)
        images.append(final_structure)

        neb = NEB(images, climb=True)
        neb.interpolate(method='linear')

        neb_catlearn = MLNEB(start=initial_structure,
                             end=final_structure,
                             interpolation=images,
                             ase_calc=ase_calculator,
                             restart=False)

        neb_catlearn.run(fmax=0.05, trajectory='ML-NEB.traj')

        atoms_catlearn = read('evaluated_structures.traj', ':')
        n_eval_catlearn = len(atoms_catlearn) - 2

        self.assertEqual(n_eval_catlearn, 12)
        print('Checking number of function calls using 8 images...')
        np.testing.assert_array_equal(n_eval_catlearn, 12)
        max_unc = np.max(neb_catlearn.uncertainty_path)
        unc_test = 0.022412729039317382
        print('Checking uncertainty on the path (8 images):')
        np.testing.assert_array_almost_equal(max_unc, unc_test, decimal=4)
Beispiel #5
0
def check_interpolation(initial, final, n_max, interpolation="linear", verbose=True, save=True):
    '''
    Interpolates the provided geometries with n_max total images
    and checks whether any bond lengths are below sane defaults.
    Saves the interpolation in interpolation.traj

    Parameters:

    initial: Atoms object or string
        Starting geometry for interpolation.
    final: Atoms object or string
        End point geometry for interpolation
    n_max: integer
        Desired total number of images for the interpolation
        including start and end point.
    interpolation: string
        "linear" or "idpp". First better for error identification, latter for
        use in NEB calculation
    verbose: boolean
        If verbose output of information is required
    save: boolean
        Whether to save the trajectory for transfer on to an NEB calculation
    '''

    from ase.neb import NEB
    from carmm.analyse.bonds import search_abnormal_bonds
    from ase.io.trajectory import Trajectory
    from ase.io import read

    # Pre-requirements
    if not isinstance(n_max, int):
        raise ValueError
        print("Max number of images must be an integer.")

    # Make a band consisting of 10 images:
    images = [initial]
    images += [initial.copy() for i in range(n_max-2)]
    images += [final]
    neb = NEB(images)
    # Interpolate linearly the potisions of the middle images:
    neb.interpolate(interpolation, apply_constraint=True)

    #TODO: Tidy up this horrible mix of if statements.
    if save:
        t = Trajectory('interpolation.traj', 'w')

    flag = True
    for i in range(0, n_max):
        if verbose:
            print("Assessing image", str(i+1) + '.')
        updated_flag = search_abnormal_bonds(images[i], verbose)
        if save:
            t.write(images[i])
        if (not updated_flag):
            flag = updated_flag

    if save:
        t.close()

    return flag
Beispiel #6
0
def do_vasp(pos1, pos2, snimgs):
    nimgs = int(snimgs)
    ini = read(pos1)
    fin = read(pos2)
    ini.wrap()
    fin.wrap()
    traj = [ini]
    traj += [ini.copy() for i in range(nimgs)]
    traj += [fin]
    neb = NEB(traj)
    neb.interpolate('idpp')
    images = neb.images
    if not os.path.exists('00'):
        os.mkdir('00')
    if not os.path.exists(i2str(nimgs + 1)):
        os.mkdir(i2str(nimgs + 1))
    images[0].write('00/POSCAR', vasp5=True, direct=True)
    images[-1].write(i2str(nimgs + 1) + '/POSCAR', vasp5=True, direct=True)
    for i in range(nimgs):
        if not os.path.exists(i2str(i + 1)):
            os.mkdir(i2str(i + 1))
        images[i + 1].write(i2str(i + 1) + '/POSCAR', vasp5=True, direct=True)
    traj = Trajectory('images.tarj', 'w')
    for i in images:
        traj.write(i)
Beispiel #7
0
    def write(self):
        method = self.method()
        images = self.getOriginalImages()
        new_images = []
        for i in range(len(images)-1):
            initial, final = images[i:i+2]
            diff = final.positions - initial.positions
            diff = vectorLength(diff, 1)
            n_images = int(np.ceil(diff.max()/0.3)) - 1
            print 'n_images=%d' % n_images
            t_images = [initial]
            for j in range(n_images):
                temp = t_images[0].copy()
                t_images.append(temp)
            t_images.append(final)
            neb = NEB(t_images)
            neb.interpolate()
            new_images.extend(neb.images[:-1])

        new_images.append(images[-1])
        neb = NEB(new_images)
        kpts = self.baseTask().parameters().kpts()
        self.method().writeNEB(
                runfile=self.runFile(),
                neb=neb,
                kpts=kpts,
                )
def test_single_precon_initialisation(setup_images):
    images, _, _ = setup_images
    precon = Exp()
    mep = NEB(images, method='spline', precon=precon)
    mep.get_forces()
    assert len(mep.precon) == len(mep.images)
    assert mep.precon[0].mu == mep.precon[1].mu
Beispiel #9
0
def test_Ag_Cu100():
    from math import sqrt
    from ase import Atom, Atoms
    from ase.neb import NEB
    from ase.constraints import FixAtoms
    from ase.vibrations import Vibrations
    from ase.calculators.emt import EMT
    from ase.optimize import QuasiNewton, BFGS

    # Distance between Cu atoms on a (100) surface:
    d = 3.6 / sqrt(2)
    initial = Atoms('Cu',
                    positions=[(0, 0, 0)],
                    cell=(d, d, 1.0),
                    pbc=(True, True, False))
    initial *= (2, 2, 1)  # 2x2 (100) surface-cell

    # Approximate height of Ag atom on Cu(100) surfece:
    h0 = 2.0
    initial += Atom('Ag', (d / 2, d / 2, h0))

    # Make band:
    images = [initial.copy() for i in range(6)]
    neb = NEB(images, climb=True)

    # Set constraints and calculator:
    constraint = FixAtoms(range(len(initial) - 1))
    for image in images:
        image.calc = EMT()
        image.set_constraint(constraint)

    # Displace last image:
    images[-1].positions[-1] += (d, 0, 0)

    # Relax height of Ag atom for initial and final states:
    dyn1 = QuasiNewton(images[0])
    dyn1.run(fmax=0.01)
    dyn2 = QuasiNewton(images[-1])
    dyn2.run(fmax=0.01)

    # Interpolate positions between initial and final states:
    neb.interpolate()

    for image in images:
        print(image.positions[-1], image.get_potential_energy())

    dyn = BFGS(neb, trajectory='mep.traj')
    dyn.run(fmax=0.05)

    for image in images:
        print(image.positions[-1], image.get_potential_energy())

    a = images[0]
    vib = Vibrations(a, [4])
    vib.run()
    print(vib.get_frequencies())
    vib.summary()
    print(vib.get_mode(-1))
    vib.write_mode(-1, nimages=20)
Beispiel #10
0
def test_turbomole_h3o2m():
    # http://jcp.aip.org/resource/1/jcpsa6/v97/i10/p7507_s1
    doo = 2.74
    doht = 0.957
    doh = 0.977
    angle = radians(104.5)
    initial = Atoms('HOHOH',
                    positions=[(-sin(angle) * doht, 0., cos(angle) * doht),
                               (0., 0., 0.), (0., 0., doh), (0., 0., doo),
                               (sin(angle) * doht, 0., doo - cos(angle) * doht)
                               ])
    if 0:
        view(initial)

    final = Atoms('HOHOH',
                  positions=[(-sin(angle) * doht, 0., cos(angle) * doht),
                             (0., 0., 0.), (0., 0., doo - doh), (0., 0., doo),
                             (sin(angle) * doht, 0., doo - cos(angle) * doht)])
    if 0:
        view(final)

    # Make band:
    images = [initial.copy()]
    for i in range(3):
        images.append(initial.copy())
    images.append(final.copy())
    neb = NEB(images, climb=True)

    # Write all commands for the define command in a string
    define_str = ('\n\na coord\n\n*\nno\nb all 3-21g '
                  'hondo\n*\neht\n\n-1\nno\ns\n*\n\ndft\non\nfunc '
                  'pwlda\n\n\nscf\niter\n300\n\n*')

    # Set constraints and calculator:
    constraint = FixAtoms(indices=[1,
                                   3])  # fix OO BUG No.1: fixes atom 0 and 1
    # constraint = FixAtoms(mask=[0,1,0,1,0]) # fix OO    #Works without patch
    for image in images:
        image.calc = Turbomole(define_str=define_str)
        image.set_constraint(constraint)

    # Relax initial and final states:
    if 1:
        dyn1 = QuasiNewton(images[0])
        dyn1.run(fmax=0.10)
        dyn2 = QuasiNewton(images[-1])
        dyn2.run(fmax=0.10)

    # Interpolate positions between initial and final states:
    neb.interpolate()
    if 1:
        for image in images:
            print(image.get_distance(1, 2), image.get_potential_energy())

    dyn = BFGS(neb, trajectory='turbomole_h3o2m.traj')
    dyn.run(fmax=0.10)

    for image in images:
        print(image.get_distance(1, 2), image.get_potential_energy())
Beispiel #11
0
def test_h3o2m():
    # http://jcp.aip.org/resource/1/jcpsa6/v97/i10/p7507_s1
    doo = 2.74
    doht = 0.957
    doh = 0.977
    angle = radians(104.5)
    initial = Atoms('HOHOH',
                    positions=[(-sin(angle) * doht, 0, cos(angle) * doht),
                               (0., 0., 0.), (0., 0., doh), (0., 0., doo),
                               (sin(angle) * doht, 0., doo - cos(angle) * doht)
                               ])
    if 0:
        view(initial)

    final = Atoms('HOHOH',
                  positions=[(-sin(angle) * doht, 0., cos(angle) * doht),
                             (0., 0., 0.), (0., 0., doo - doh), (0., 0., doo),
                             (sin(angle) * doht, 0., doo - cos(angle) * doht)])
    if 0:
        view(final)

    # Make band:
    images = [initial.copy()]
    for i in range(3):
        images.append(initial.copy())
    images.append(final.copy())
    neb = NEB(images, climb=True)

    def calculator():
        return NWChem(task='gradient', theory='scf', charge=-1)

    # Set constraints and calculator:
    constraint = FixAtoms(indices=[1, 3])  # fix OO
    for image in images:
        image.calc = calculator()
        image.set_constraint(constraint)

    # Relax initial and final states:
    if 1:
        dyn1 = QuasiNewton(images[0])
        dyn1.run(fmax=0.10)
        dyn2 = QuasiNewton(images[-1])
        dyn2.run(fmax=0.10)

    # Interpolate positions between initial and final states:
    neb.interpolate()

    if 1:
        for image in images:
            print(image.get_distance(1, 2), image.get_potential_energy())

    dyn = BFGS(neb, trajectory='nwchem_h3o2m.traj')
    dyn.run(
        fmax=0.10)  # use better basis (e.g. aug-cc-pvdz) for NEB to converge

    for image in images:
        print(image.get_distance(1, 2), image.get_potential_energy())
Beispiel #12
0
def check_interpolation(initial, final, n_max):
    '''
    Interpolates the provided geometries with n_max total images
    and checks whether any bond lengths below 0.74 Angstrom exist
    saves the interpolation in interpolation.traj

    # TODO: incorporate ase.neighborlist.natural_cutoff
    # for abnormal bond lengths based on typical A-B bonds

    Parameters:

    initial: Atoms object or string
        If a string, e.g. 'initial.traj', a file of this name will
        be read. Starting geometry for interpolation.
    final: Atoms object or string
        If a string, e.g. 'final.traj', a file of this name will
        be read. End point geometry for interpolation
    n_max: integer
        Desired total number of images for the interpolation
        including start and end point.
    '''

    from ase.neb import NEB
    from software.analyse.Interatomic_distances.analyse_bonds import search_abnormal_bonds
    from ase.io.trajectory import Trajectory
    from ase.io import read

    # Pre-requirements
    if isinstance(initial, str) is True:
        initial = read(initial)
    if isinstance(final, str) is True:
        final = read(final)
    if not isinstance(n_max, int):
        raise ValueError
        print("Max number of images must be an integer.")

    # Make a band consisting of 10 images:
    images = [initial]
    images += [initial.copy() for i in range(n_max - 2)]
    images += [final]
    neb = NEB(images, climb=True)
    # Interpolate linearly the potisions of the middle images:
    neb.interpolate()

    t = Trajectory('interpolation.traj', 'w')

    for i in range(0, n_max):
        print("Assessing image", str(i + 1) + '.')
        search_abnormal_bonds(images[i])
        t.write(images[i])

    t.close()
Beispiel #13
0
def test_precon_assembly(setup_images):
    images, _, _ = setup_images
    neb = NEB(images, method='spline', precon='Exp')
    neb.get_forces()  # trigger precon assembly

    # check precon for each image is symmetric positive definite
    for image, precon in zip(neb.images, neb.precon):
        assert isinstance(precon, Exp)
        P = precon.asarray()
        N = 3 * len(image)
        assert P.shape == (N, N)
        assert np.abs(P - P.T).max() < 1e-6
        assert np.all(np.linalg.eigvalsh(P)) > 0
Beispiel #14
0
def _setup_images_global():
    N_intermediate = 3
    N_cell = 2
    initial = bulk('Cu', cubic=True)
    initial *= N_cell

    # place vacancy near centre of cell
    D, D_len = get_distances(np.diag(initial.cell) / 2,
                             initial.positions,
                             initial.cell, initial.pbc)
    vac_index = D_len.argmin()
    vac_pos = initial.positions[vac_index]
    del initial[vac_index]

    # identify two opposing nearest neighbours of the vacancy
    D, D_len = get_distances(vac_pos,
                             initial.positions,
                             initial.cell, initial.pbc)
    D = D[0, :]
    D_len = D_len[0, :]

    nn_mask = np.abs(D_len - D_len.min()) < 1e-8
    i1 = nn_mask.nonzero()[0][0]
    i2 = ((D + D[i1])**2).sum(axis=1).argmin()

    print(f'vac_index={vac_index} i1={i1} i2={i2} '
          f'distance={initial.get_distance(i1, i2, mic=True)}')

    final = initial.copy()
    final.positions[i1] = vac_pos

    initial.calc = calc()
    final.calc = calc()

    qn = ODE12r(initial)
    qn.run(fmax=1e-3)
    qn = ODE12r(final)
    qn.run(fmax=1e-3)

    images = [initial]
    for image in range(N_intermediate):
        image = initial.copy()
        image.calc = calc()
        images.append(image)
    images.append(final)

    neb = NEB(images)
    neb.interpolate()

    return neb.images, i1, i2
Beispiel #15
0
def test_spline_fit(setup_images):
    images, _, _ = setup_images
    neb = NEB(images)
    fit = neb.spline_fit()

    # check spline points are equally spaced
    assert np.allclose(fit.s, np.linspace(0, 1, len(images)))

    # check spline matches target at fit points
    assert np.allclose(fit.x(fit.s), fit.x_data)

    # ensure derivative is smooth across central fit point
    eps = 1e-4
    assert np.allclose(fit.dx_ds(fit.s[2] + eps), fit.dx_ds(fit.s[2] + eps))
Beispiel #16
0
Datei: neb.py Projekt: lqcata/ase
def get_atoms():
    # 2x2-Al(001) surface with 3 layers and an
    # Au atom adsorbed in a hollow site:
    slab = fcc100('Al', size=(2, 2, 3))
    add_adsorbate(slab, 'Au', 1.7, 'hollow')
    slab.center(axis=2, vacuum=4.0)

    # Fix second and third layers:
    mask = [atom.tag > 1 for atom in slab]
    slab.set_constraint(FixAtoms(mask=mask))

    # Use EMT potential:
    slab.set_calculator(EMT())

    # Initial state:
    qn = QuasiNewton(slab, logfile=None)
    qn.run(fmax=0.05)
    initial = slab.copy()

    # Final state:
    slab[-1].x += slab.get_cell()[0, 0] / 2
    qn = QuasiNewton(slab, logfile=None)
    qn.run(fmax=0.05)
    final = slab.copy()

    # Setup a NEB calculation
    constraint = FixAtoms(mask=[atom.tag > 1 for atom in initial])

    images = [initial]
    for i in range(3):
        image = initial.copy()
        image.set_constraint(constraint)
        images.append(image)

    images.append(final)

    neb = NEB(images, parallel=mpi.parallel)
    neb.interpolate()

    def set_calculator(calc):
        i = 0
        for image in neb.images[1:-1]:
            if not mpi.parallel or mpi.rank // (mpi.size // 3) == i:
                image.set_calculator(calc)
            i += 1

    neb.set_calculator = set_calculator

    return neb
Beispiel #17
0
def run_neb_calculation(cpu):
    images = [PickleTrajectory('H.traj')[-1]]
    for i in range(nimages):
        images.append(images[0].copy())
    images[-1].positions[6, 1] = 2 - images[0].positions[6, 1]
    neb = NEB(images, parallel=True, world=cpu)
    neb.interpolate()

    images[cpu.rank + 1].set_calculator(Calculator())

    dyn = BFGS(neb)
    dyn.run(fmax=fmax)

    if cpu.rank == 1:
        results.append(images[2].get_potential_energy())
Beispiel #18
0
def create_idpp_images(freactant, fproduct, nimages=11):
    """ create images interpolated using IDPP algorithm

    Parameters
    ----------
    freactant : path to initial atoms
    fproduct  : path to final atoms
    nimages   :   the number of images to be interpolated including two endpoints
    """
    images = _create_images(freactant, fproduct, nimages)

    # Interpolate intermediate images
    neb = NEB(images, remove_rotation_and_translation=True)
    neb.interpolate("idpp")
    return images
Beispiel #19
0
Datei: neb.py Projekt: grhawk/ASE
def run_neb_calculation(cpu):
    images = [PickleTrajectory('H.traj')[-1]]
    for i in range(nimages):
        images.append(images[0].copy())
    images[-1].positions[6, 1] = 2 - images[0].positions[6, 1]
    neb = NEB(images, parallel=True, world=cpu)
    neb.interpolate()

    images[cpu.rank + 1].set_calculator(MorsePotential())

    dyn = BFGS(neb)
    dyn.run(fmax=fmax)

    if cpu.rank == 1:
        results.append(images[2].get_potential_energy())
Beispiel #20
0
Datei: neb.py Projekt: jboes/ase
def get_atoms():
    # 2x2-Al(001) surface with 3 layers and an
    # Au atom adsorbed in a hollow site:
    slab = fcc100('Al', size=(2, 2, 3))
    add_adsorbate(slab, 'Au', 1.7, 'hollow')
    slab.center(axis=2, vacuum=4.0)

    # Fix second and third layers:
    mask = [atom.tag > 1 for atom in slab]
    slab.set_constraint(FixAtoms(mask=mask))

    # Use EMT potential:
    slab.set_calculator(EMT())

    # Initial state:
    qn = QuasiNewton(slab, logfile=None)
    qn.run(fmax=0.05)
    initial = slab.copy()

    # Final state:
    slab[-1].x += slab.get_cell()[0, 0] / 2
    qn = QuasiNewton(slab, logfile=None)
    qn.run(fmax=0.05)
    final = slab.copy()

    # Setup a NEB calculation
    constraint = FixAtoms(mask=[atom.tag > 1 for atom in initial])

    images = [initial]
    for i in range(3):
        image = initial.copy()
        image.set_constraint(constraint)
        images.append(image)

    images.append(final)

    neb = NEB(images, parallel=mpi.parallel)
    neb.interpolate()

    def set_calculator(calc):
        i = 0
        for image in neb.images[1:-1]:
            if not mpi.parallel or mpi.rank // (mpi.size // 3) == i:
                image.set_calculator(calc)
            i += 1
    neb.set_calculator = set_calculator

    return neb
Beispiel #21
0
def nudged_elastic_band(images,
                        fmax=0.01,
                        algo='BFGS',
                        trajectory='path-neb.traj',
                        final='neb.traj'):

    calc = cline.gen_active_calc()
    load1 = calc.size[0]
    master = calc.rank == 0

    for image in images:
        image.calc = calc

    # calculate for the first and last images
    # (for more efficient ML)
    images[0].get_potential_energy()
    images[-1].get_potential_energy()

    # define and run NEB
    neb = NEB(images, allow_shared_calculator=True)
    Min = getattr(optimize, algo)
    dyn = Min(neb, trajectory=trajectory, master=master)
    dyn.run(fmax)

    load2 = calc.size[0]
    if master:
        print(f'\tTotal number of Ab initio calculations: {load2-load1}\n')

    # output
    if master:
        out = Trajectory(final, 'w')
    for image in images:
        image.get_potential_energy()
        if master:
            out.write(image)
Beispiel #22
0
def test_integrate_forces(setup_images):
    images, _, _ = setup_images
    forcefit = fit_images(images)

    neb = NEB(images)
    spline_points = 1000  # it is the default value
    s, E, F = neb.integrate_forces(spline_points=spline_points)
    # check the difference between initial and final images
    np.testing.assert_allclose(E[0] - E[-1],
                               forcefit.energies[0] - forcefit.energies[-1],
                               atol=1.0e-10)
    # assert the maximum Energy value is in the middle
    assert np.argmax(E) == spline_points // 2 - 1
    # check the maximum values (barrier value)
    # tolerance value is rather high since the images are not relaxed
    np.testing.assert_allclose(E.max(), forcefit.energies.max(), rtol=2.5e-2)
Beispiel #23
0
def test_neb_methods(method, optimizer, precon, optmethod, ref_vacancy,
                     setup_images):
    # unpack the reference result
    Ef_ref, dE_ref, saddle_ref = ref_vacancy

    # now relax the MEP for comparison
    images, _, _ = setup_images

    fmax_history = []

    def save_fmax_history(mep):
        fmax_history.append(mep.get_residual())

    k = 0.1
    if precon == 'Exp':
        k = 0.01
    mep = NEB(images, k=k, method=method, precon=precon)

    if optmethod is not None:
        opt = optimizer(mep, method=optmethod)
    else:
        opt = optimizer(mep)
    opt.attach(save_fmax_history, 1, mep)
    opt.run(fmax=1e-2)

    nebtools = NEBTools(images)
    Ef, dE = nebtools.get_barrier(fit=False)
    print(f'{method},{optimizer.__name__},{precon} '
          f'=> Ef = {Ef:.3f}, dE = {dE:.3f}')

    forcefit = fit_images(images)

    output_dir = os.path.dirname(__file__)
    with open(
            f'{output_dir}/MEP_{method}_{optimizer.__name__}_{optmethod}'
            f'_{precon}.json', 'w') as f:
        json.dump(
            {
                'fmax_history': fmax_history,
                'method': method,
                'optmethod': optmethod,
                'precon': precon,
                'optimizer': optimizer.__name__,
                'path': forcefit.path,
                'energies': forcefit.energies.tolist(),
                'fit_path': forcefit.fit_path.tolist(),
                'fit_energies': forcefit.fit_energies.tolist(),
                'lines': np.array(forcefit.lines).tolist(),
                'Ef': Ef,
                'dE': dE
            }, f)

    centre = 2  # we have 5 images total, so central image has index 2
    vdiff, _ = find_mic(images[centre].positions - saddle_ref.positions,
                        images[centre].cell)
    print(f'Ef error {Ef - Ef_ref} dE error {dE - dE_ref} '
          f'position error at saddle {abs(vdiff).max()}')
    assert abs(Ef - Ef_ref) < 1e-2
    assert abs(dE - dE_ref) < 1e-2
    assert abs(vdiff).max() < 1e-2
Beispiel #24
0
def get_neb(in_file='input.traj'):
    """Performs a ASE NEB optimization with the ase-espresso
    calculator with the keywords defined inside the atoms object information.

    Parameters
    ----------
    in_file : str
        Name of the input file to load from the local directory.
    """
    images = read(in_file, ':')

    for atoms in images[1:-1]:
        calc = espresso(**atoms.info)
        atoms.set_calculator(calc)

    neb = NEB(images)
    opt = BFGS(neb, trajectory='output.traj', logfile=None)
    opt.run(fmax=atoms.info.get('fmax'))
    out_images = read('output.traj', ':')

    # Save the calculator to the local disk for later use.
    try:
        calc.save_flev_output()
    except (RuntimeError):
        calc.save_output()

    return atoms_to_encode(out_images)
Beispiel #25
0
def interp_by_neb(initial, final, n_images, interp='idpp',
                  calculator=None, constraint=None, fmax=0.5, steps=10,
                  **kwargs):
    """Interpolate between the initial and final points by NEB method.

    :param initial: The initial image.
    :param final: The final image.
    :param int n_images: The number of image between the initial and final
        images.
    :param string interp: The interpolation method.

    :param Callable calculator: The callable to generate calculators for the
        images.  It can be set to None if no real optimization is intended.
    :param constraint: The constraint for the images.
    :param fmax: The maximal force to stop the optimization.
    :param steps: The number of optimization steps allowed.

    :param kwargs:  All other keyword arguments are forwarded to the
        initializer of the ASE NEB class.

    :return: The list of images between the points.
    """

    # To circumvent the error from interpolation when we have no middle images.
    if n_images == 0:
        return [initial, final]

    images = [initial]
    for _ in range(n_images):
        image = initial.copy()
        images.append(image)
        if calculator is not None:
            image.set_calculator(calculator())
        if constraint is not None:
            image.set_constraint(constraint)
        continue
    images.append(final)

    neb = NEB(images, **kwargs)
    neb.interpolate(method=interp)

    if calculator is not None:
        dyn = MDMin(neb)
        dyn.run(fmax=fmax, steps=steps)

    return neb.images
Beispiel #26
0
def getPath(Reac,Prod,gl):
    xyzfile3 = open(("IRC3.xyz"), "w")
    Path = []
    Path.append(Reac.copy())
    for i in range(0,30):
        image = Reac.copy()
        image = tl.setCalc(image,"DOS/", gl.lowerMethod, gl.lowerLevel)
        Path.append(image)
    image = Prod.copy()
    image = tl.setCalc(image,"DOS/", gl.lowerMethod, gl.lowerLevel)
    Path.append(image)

    neb1 = NEB(Path,k=1.0,remove_rotation_and_translation = True)
    try:
        neb1.interpolate('idpp',optimizer="MDMin",k=1.0)
    except:
        neb1.interpolate()

    optimizer = FIRE(neb1)
    optimizer.run(fmax=0.07, steps = 500)
    neb2 = NEB(Path,k=1.0, climb=True, remove_rotation_and_translation = True )
    optimizer = FIRE(neb2)
    optimizer.run(fmax=0.07, steps = 1500)
    for i in range(0,len(Path)):
        tl.printTraj(xyzfile3, Path[i])
    xyzfile3.close()



    return Path
Beispiel #27
0
def test_idpp():
    initial = molecule('C2H6')
    final = initial.copy()
    final.positions[2:5] = initial.positions[[3, 4, 2]]

    images = [initial]
    for i in range(5):
        images.append(initial.copy())
    images.append(final)

    neb = NEB(images)
    d0 = images[3].get_distance(2, 3)
    neb.interpolate()
    d1 = images[3].get_distance(2, 3)
    idpp_interpolate(neb, fmax=0.005)
    d2 = images[3].get_distance(2, 3)
    print(d0, d1, d2)
    assert abs(d2 - 1.74) < 0.01
Beispiel #28
0
def test_vacancy():
    from ase import Atoms
    from ase.optimize import QuasiNewton
    from ase.neb import NEB
    from ase.optimize.mdmin import MDMin
    try:
        from asap3 import EMT
    except ImportError:
        pass
    else:

        a = 3.6
        b = a / 2
        initial = Atoms('Cu4',
                        positions=[(0, 0, 0),
                                   (0, b, b),
                                   (b, 0, b),
                                   (b, b, 0)],
                        cell=(a, a, a),
                        pbc=True)
        initial *= (4, 4, 4)
        del initial[0]
        images = [initial] + [initial.copy() for i in range(6)]
        images[-1].positions[0] = (0, 0, 0)
        for image in images:
            image.calc = EMT()
            #image.calc = ASAP()

        for image in [images[0], images[-1]]:
            QuasiNewton(image).run(fmax=0.01)
        neb = NEB(images)
        neb.interpolate()

        for a in images:
            print(a.positions[0], a.get_potential_energy())

        dyn = MDMin(neb, dt=0.1, trajectory='mep1.traj')
        #dyn = QuasiNewton(neb)
        print(dyn.run(fmax=0.01, steps=25))
        for a in images:
            print(a.positions[0], a.get_potential_energy())
Beispiel #29
0
def main():
    '''Main driver routine.'''

    system = read(GEO_PATH, format='gen')
    write('dummy.gen', system, format='gen')

    initial = read('NH3_initial.traj')
    final = read('NH3_final.traj')

    images = [initial]
    images += [initial.copy() for ii in range(NIMAGES)]
    images += [final]

    neb = NEB(images)
    neb.interpolate()

    opt = BFGS(neb, trajectory='i2f.traj')

    socketids = range(1, NIMAGES + 1)
    wdirs = ['_calc/image_{:d}'.format(socket) for socket in socketids]
    unixsockets = ['dftbplus_{:d}'.format(socket) for socket in socketids]

    write_modhsd(socketids)

    calcs = [
        SocketIOCalculator(log='socket.log', unixsocket=unixsocket)
        for unixsocket in unixsockets
    ]

    for ii, calc in enumerate(calcs):
        images[ii + 1].set_calculator(calc)

    for cwd in wdirs:
        Popen(DFTBP_PATH, cwd=cwd)

    opt.run(fmax=1.00E-02)

    for calc in calcs:
        calc.close()
Beispiel #30
0
def test_emt_h3o2m(initial, final, testdir):
    # Make band:
    images = [initial.copy()]
    for i in range(3):
        images.append(initial.copy())
    images.append(final.copy())
    neb = NEB(images, climb=True)

    # Set constraints and calculator:
    constraint = FixAtoms(indices=[1, 3])  # fix OO
    for image in images:
        image.calc = EMT()
        image.set_constraint(constraint)

    for image in images:  # O-H(shared) distance
        print(image.get_distance(1, 2), image.get_potential_energy())

    # Relax initial and final states:
    # One would have to optimize more tightly in order to get
    # symmetric anion from both images[0] and [1], but
    # if one optimizes tightly one gets rotated(H2O) ... OH- instead
    dyn1 = QuasiNewton(images[0])
    dyn1.run(fmax=0.01)
    dyn2 = QuasiNewton(images[-1])
    dyn2.run(fmax=0.01)

    # Interpolate positions between initial and final states:
    neb.interpolate()

    for image in images:
        print(image.get_distance(1, 2), image.get_potential_energy())

    with BFGS(neb, trajectory='emt_h3o2m.traj') as dyn:
        dyn.run(fmax=0.05)

    for image in images:
        print(image.get_distance(1, 2), image.get_potential_energy())
Beispiel #31
0
def test_neb_optimizers(setup_images, method):
    images, _, _ = setup_images
    mep = NEB(images, method='spline', precon='Exp')
    mep.get_forces()  # needed so residuals are available
    R0 = mep.get_residual()
    opt = NEBOptimizer(mep, method=method)
    opt.run(steps=2)  # take two steps
    R1 = mep.get_residual()
    # check residual has got smaller
    assert R1 < R0
Beispiel #32
0
def method_ASE(RIGID_ROTATION, FPTR="../xyz/CNH_HCN.xyz"):
    from ase.io import read, write
    from ase.neb import NEB
    from ase.calculators.orca import orca
    from ase.optimize import SD
    from os import mkdir, chdir
    from os.path import isdir

    # Read in frames
    if not isdir("ASE"):
        mkdir("ASE")
    chdir("ASE")

    start, images = [], []
    FPTR = "../" + FPTR
    if not FPTR.endswith(".xyz"):
        FPTR += ".xyz"

    for a in read(FPTR, ':'):
        start += [a]
        images += [a.copy()]

    # Setup neb
    neb = NEB(images,
              parallel=False,
              remove_rotation_and_translation=RIGID_ROTATION,
              method="improvedtangent")
    # Set the calculator
    for image in images:
        image.set_calculator(orca(label="CNH_HCN", RunTyp="Gradient"))

    # Run neb
    dyn = SD(neb, trajectory='CNH_HCN.traj')
    dyn.run(fmax=FMAX)

    # Save?
    traj = read("CNH_HCN.traj", ':-1')
    write("../CNH_HCN_opt_ASE.xyz", traj)

    chdir("..")
    print("\nDONE WITH ASE SIMULATION...\n")
Beispiel #33
0
def saddlepoint(min1, min2, name):
    images=[LM[min1]]
    images += [LM[min1].copy() for i in range(5)]
    images += [LM[min2]]
    for image in images:
        image.set_calculator(TIP4P())
        add_tip4p_const(image)
    neb = NEB(images, climb=True, parallel=True) 
    try:
        neb.interpolate()
    except:
        try:
            print("try idpp interpolate")
            neb.interpolate(method="idpp")
        except:
            return
    optimize(neb, name)
Beispiel #34
0
images = [slab]
for i in range(6):
    image = slab.copy()
    # Set constraints and calculator:
    image.set_constraint(constraint)
    image.calc = EMT()
    images.append(image)

# Displace last image:
image[-2].position = image[-1].position
image[-1].x = d
image[-1].y = d / sqrt(3)

dyn = QuasiNewton(images[-1])
dyn.run(fmax=0.05)
neb = NEB(images, climb=not True)

# Interpolate positions between initial and final states:
neb.interpolate(method='idpp')

for image in images:
    print(image.positions[-1], image.get_potential_energy())

dyn = BFGS(neb, maxstep=0.04, trajectory='mep.traj')
dyn.run(fmax=0.05)

for image in images:
    print(image.positions[-1], image.get_potential_energy())

if locals().get('display'):
    import os
Beispiel #35
0
from ase.build import molecule
from ase.neb import NEB

initial = molecule('C2H6')
final = initial.copy()
final.positions[2:5] = initial.positions[[3, 4, 2]]

images = [initial]
for i in range(5):
    images.append(initial.copy())
images.append(final)

neb = NEB(images)
d0 = images[3].get_distance(2, 3)
neb.interpolate()
d1 = images[3].get_distance(2, 3)
neb.idpp_interpolate(fmax=0.005)
d2 = images[3].get_distance(2, 3)
print(d0, d1, d2)
assert abs(d2 - 1.74) < 0.01
Beispiel #36
0
def nebmake(directory, start, final, images, tolerance=0, ci=False, poscar_override=[], linear=False, write=True):

    if type(start) == str:
        start_POSCAR = os.path.join(start, 'CONTCAR') if os.path.exists(os.path.join(start, 'CONTCAR')) and os.path.getsize(os.path.join(start, 'CONTCAR')) > 0 else os.path.join(start, 'POSCAR')
        final_POSCAR = os.path.join(final, 'CONTCAR') if os.path.exists(os.path.join(final, 'CONTCAR')) and os.path.getsize(os.path.join(final, 'CONTCAR')) > 0 else os.path.join(final, 'POSCAR')
        p1 = Poscar.from_file(start_POSCAR)
        p2 = Poscar.from_file(final_POSCAR)
        s1 = p1.structure
        s2 = p2.structure
    else:
        s1 = start
        s2 = final
    # s1.sort()
    # s2.sort()
    atoms = []
    if poscar_override:
        for i in range(int(len(poscar_override)/2)):
            atoms.append( (poscar_override[i*2], poscar_override[i*2+1]) )
        (s1, s2) = reorganize_structures(s1, s2, atoms=atoms, autosort_tol=tolerance)
        tolerance=0
    try:
        structures = s1.interpolate(s2, images, autosort_tol=tolerance)
    except Exception as e:
        a=input('Failed.  Type y to sort --> ')
        if a=='y':
            s1.sort()
            s2.sort()
        else:
            raise e
        structures = s1.interpolate(s2, images, autosort_tol=tolerance)


    if not linear:
        from pymatgen.io.ase import AseAtomsAdaptor
        from ase.neb import NEB
        structures_ase = [ AseAtomsAdaptor.get_atoms(struc) for struc in structures ]
        neb = NEB(structures_ase)
        neb.interpolate('idpp') # type: NEB
        structures = [ AseAtomsAdaptor.get_structure(atoms) for atoms in neb.images ]

    if write:
        start_OUTCAR = os.path.join(start, 'OUTCAR')
        final_OUTCAR = os.path.join(final, 'OUTCAR')
        incar = Incar.from_file(os.path.join(start, 'INCAR'))
        kpoints = Kpoints.from_file(os.path.join(start, 'KPOINTS'))
        potcar = Potcar.from_file(os.path.join(start, 'POTCAR'))
        incar['ICHAIN'] = 0
        incar['IMAGES'] = images-1
        incar['LCLIMB'] = ci

        for i, s in enumerate(structures):
            folder = os.path.join(directory, str(i).zfill(2))
            os.mkdir(folder)
            Poscar(s, selective_dynamics=p1.selective_dynamics).write_file(os.path.join(folder, 'POSCAR'))
            if i == 0:
                shutil.copy(start_OUTCAR, os.path.join(folder, 'OUTCAR'))
            if i == images:
                shutil.copy(final_OUTCAR, os.path.join(folder, 'OUTCAR'))
            i += 1

        incar.write_file(os.path.join(directory, 'INCAR'))
        kpoints.write_file(os.path.join(directory, 'KPOINTS'))
        potcar.write_file(os.path.join(directory, 'POTCAR'))
    return structures
Beispiel #37
0
# Approximate height of Ag atom on Cu(100) surfece:
h0 = 2.2373
initial += Atom('Pt', (10.96, 11.074, h0))
initial += Atom('Pt', (13.7, 11.074, h0))
initial += Atom('Pt', (9.59, 8.701, h0))
initial += Atom('Pt', (12.33, 8.701, h0))
initial += Atom('Pt', (15.07, 8.701, h0))
initial += Atom('Pt', (10.96, 6.328, h0))
initial += Atom('Pt', (13.7, 6.328, h0))

if 0:
    view(initial)

# Make band:
images = [initial.copy() for i in range(7)]
neb = NEB(images)

# Set constraints and calculator:
indices = np.compress(initial.positions[:, 2] < -5.0, range(len(initial)))
constraint = FixAtoms(indices)
for image in images:
    image.set_calculator(ASAP())
    image.constraints.append(constraint)

# Displace last image:
for i in xrange(1,8,1):
    images[-1].positions[-i] += (d/2, -h1/3, 0)

write('initial.traj', images[0])
# Relax height of Ag atom for initial and final states:
for image in [images[0], images[-1]]:
Beispiel #38
0
Datei: idpp.py Projekt: jboes/ase
from ase.structure import molecule
from ase.neb import NEB

initial = molecule('C2H6')
final = initial.copy()
final.positions[2:5] = initial.positions[[3, 4, 2]]

images = [initial]
for i in range(5):
    images.append(initial.copy())
images.append(final)

neb = NEB(images)
d0 = images[3].get_distance(2, 3)
neb.interpolate()
d1 = images[3].get_distance(2, 3)
neb.idpp_interpolate()
d2 = images[3].get_distance(2, 3)
print(d0, d1, d2)
assert abs(d2 - 1.74) < 0.01
Beispiel #39
0
    def execute_one_neb(self, n_cur, to_run, climb=False, many_steps=False):
        '''Internal method which executes one NEB optimization.'''
        self.iteration += 1
        # First we copy around all the images we are not using in this
        # neb (for reproducability purposes)
        if self.world.rank == 0:
            for i in range(n_cur):
                if i not in to_run[1: -1]:
                    filename = '%s%03d.traj' % (self.prefix, i)
                    self.all_images[i].write(filename)
                    filename_ref = self.iter_folder + \
                        '/%s%03diter%03d.traj' % (self.prefix, i,
                                                  self.iteration)
                    if os.path.isfile(filename):
                        shutil.copy2(filename, filename_ref)
        if self.world.rank == 0:
            print('Now starting iteration %d on ' % self.iteration, to_run)
        # Attach calculators to all the images we will include in the NEB
        self.attach_calculators([self.all_images[i] for i in to_run[1: -1]])
        neb = NEB([self.all_images[i] for i in to_run],
                  k=[self.k[i] for i in to_run[0:-1]],
                  method=self.method,
                  parallel=self.parallel,
                  remove_rotation_and_translation=self
                  .remove_rotation_and_translation,
                  climb=climb)

        # Do the actual NEB calculation
        qn = self.optimizer(neb,
                            logfile=self.iter_folder +
                            '/%s_log_iter%03d.log' % (self.prefix,
                                                      self.iteration))

        # Find the ranks which are masters for each their calculation
        if self.parallel:
            nneb = to_run[0]
            nim = len(to_run) - 2
            n = self.world.size // nim      # number of cpu's per image
            j = 1 + self.world.rank // n    # my image number
            assert nim * n == self.world.size
            traj = Trajectory('%s%03d.traj' % (self.prefix, j + nneb), 'w',
                              self.all_images[j + nneb],
                              master=(self.world.rank % n == 0))
            filename_ref = self.iter_folder + \
                '/%s%03diter%03d.traj' % (self.prefix,
                                          j + nneb, self.iteration)
            trajhist = Trajectory(filename_ref, 'w',
                                  self.all_images[j + nneb],
                                  master=(self.world.rank % n == 0))
            qn.attach(traj)
            qn.attach(trajhist)
        else:
            num = 1
            for i, j in enumerate(to_run[1: -1]):
                filename_ref = self.iter_folder + \
                    '/%s%03diter%03d.traj' % (self.prefix, j, self.iteration)
                trajhist = Trajectory(filename_ref, 'w', self.all_images[j])
                qn.attach(seriel_writer(trajhist, i, num).write)

                traj = Trajectory('%s%03d.traj' % (self.prefix, j), 'w',
                                  self.all_images[j])
                qn.attach(seriel_writer(traj, i, num).write)
                num += 1

        if isinstance(self.maxsteps, (list, tuple)) and many_steps:
            steps = self.maxsteps[1]
        elif isinstance(self.maxsteps, (list, tuple)) and not many_steps:
            steps = self.maxsteps[0]
        else:
            steps = self.maxsteps

        if isinstance(self.fmax, (list, tuple)) and many_steps:
            fmax = self.fmax[1]
        elif isinstance(self.fmax, (list, tuple)) and not many_steps:
            fmax = self.fmax[0]
        else:
            fmax = self.fmax
        qn.run(fmax=fmax, steps=steps)

        # Remove the calculators and replace them with single
        # point calculators and update all the nodes for
        # preperration for next iteration
        neb.distribute = types.MethodType(store_E_and_F_in_spc, neb)
        neb.distribute()
Beispiel #40
0
    initial.set_calculator(LennardJones())

    images = [initial]

    # Set calculator
    for i in range(nimages):
        image = initial.copy()
        image.set_calculator(LennardJones())
        images.append(image)

    images.append(final)

    # Define the NEB and make a linear interpolation
    # with removing translational
    # and rotational degrees of freedom
    neb = NEB(images,
              remove_rotation_and_translation=remove_rotation_and_translation)
    neb.interpolate()
    # Test used these old defaults which are not optimial, but work
    # in this particular system
    neb.idpp_interpolate(fmax=0.1, optimizer=BFGS)

    qn = FIRE(neb, dt=0.005, maxmove=0.05, dtmax=0.1)
    qn.run(steps=20)

    # Switch to CI-NEB, still removing the external degrees of freedom
    # Also spesify the linearly varying spring constants
    neb = NEB(images, climb=True,
              remove_rotation_and_translation=remove_rotation_and_translation)
    qn = FIRE(neb, dt=0.005, maxmove=0.05, dtmax=0.1)
    qn.run(fmax=fmax)
import os

from ase.io import read
from ase.neb import NEB
from ase.calculators.turbomole import Turbomole
from ase.optimize import BFGS

initial = read('initial.coord')
final = read('final.coord')
os.system('rm -f coord; cp initial.coord coord')

# Make a band consisting of 5 configs:
configs = [initial]
configs += [initial.copy() for i in range(3)]
configs += [final]

band = NEB(configs, climb=True)
# Interpolate linearly the positions of the not-endpoint-configs:
band.interpolate()

#Set calculators
for config in configs:
    config.set_calculator(Turbomole())

# Optimize the Path:
relax = BFGS(band, trajectory='neb.traj')
relax.run(fmax=0.05)


Beispiel #42
0
    def __init__(self, images, control, k=1.0, climb=False, parallel=False, minmodes=None, decouple_modes=False):
        self.control = control
        NEB.__init__(self, images, k, climb, parallel)

        self.spring_force = 'full'

        # Set up MinModeAtoms objects for each image and make individual logfiles for each
        # NB: Shouldn't there be a ERM_Control class that takes care of this crap?
        self.images = []
        for i in range(self.nimages):
            min_control = control.copy()

            i_num = ('%0' + str(len(str(self.nimages))) + 'i') % i
            d_logfile_old = self.control.get_logfile()
            m_logfile_old = self.control.get_eigenmode_logfile()
            if d_logfile_old not in ['-', None]:
                if type(d_logfile_old) == str:
                    d_logfile_old = d_logfile_old.split('.')
                else:
                    d_logfile_old = d_logfile_old.name.split('.')
                d_logfile_old.insert(-1, i_num)
                d_logfile_new = '-'.join(['.'.join(d_logfile_old[:-2]), '.'.join(d_logfile_old[-2:])])
            else:
                d_logfile_new = d_logfile_old
            if m_logfile_old not in ['-', None]:
                if type(m_logfile_old) == str:
                    m_logfile_old = m_logfile_old.split('.')
                else:
                    m_logfile_old = m_logfile_old.name.split('.')
                m_logfile_old.insert(-1, i_num)
                m_logfile_new = '-'.join(['.'.join(m_logfile_old[:-2]), '.'.join(m_logfile_old[-2:])])
            else:
                m_logfile_new = m_logfile_old

            if i in [0, self.nimages - 1]:
                write_rank = 0
            else:
                write_rank = (i - 1) * size // (self.nimages - 2)

            min_control.set_write_rank(write_rank)
            min_control.initialize_logfiles(logfile = d_logfile_new, eigenmode_logfile = m_logfile_new)
            if minmodes is None:
                minmode = None
            else:
                minmodes = np.array(minmodes)
                if minmodes.shape == (self.nimages, self.natoms, 3):
                    # Assume one minmode for each image
                    raise NotImplementedError()
                elif minmodes.shape == (2, self.natoms, 3):
                    # Assume end images minmodes and interpolate
                    raise NotImplementedError()
                elif minmodes.shape == (self.natoms, 3):
                    minmode = [minmodes.copy()]
                else:
                    raise ValueError('ERM did not understand the minmodes given to it.')

            image = MinModeAtoms(images[i], min_control, eigenmodes = minmode)
            self.images.append(image)

        self.forces['dimer'] = np.zeros((self.nimages, self.natoms, 3))

        # Populate the tangents
        for i in range(1, self.nimages - 1):
            p_m = self.images[i - 1].get_positions()
            p_p = self.images[i + 1].get_positions()
            t = (p_p - p_m) / 2.0
            if 0.0 in t:
                # Assume a linear interpolation
                # HACK/BUG: Currently the last or first "free" image will yield p[-1] - p[0]
                t = self.images[-1].get_positions() - self.images[0].get_positions()
                t /= (self.nimages - 1.0)
            self.tangents[i] = t
        self.tangents[0] = t
        self.tangents[-1] = -t

        # Save user variables
        self.decouple_modes = decouple_modes # Release the orthogonality constraint of the minmode and tanget.

        # Development stuff
        self.plot_devplot = False
        self.plot_subplot = False
        self.plot_animate = 0
        self.plot_x = None
        self.plot_y = None
        self.plot_e = None
        self.xrange = None
        self.yrange = None
Beispiel #43
0
del atoms[5]
print(atoms)
assert len(atoms.constraints[0].index) == 5




fmax = 0.05
nimages = 3

print([a.get_potential_energy() for a in Trajectory('H.traj')])
images = [Trajectory('H.traj')[-1]]
for i in range(nimages):
    images.append(images[0].copy())
images[-1].positions[6, 1] = 2 - images[0].positions[6, 1]
neb = NEB(images)
neb.interpolate()
if 0:  # verify that initial images make sense
    from ase.visualize import view
    view(neb.images)

for image in images:
    image.set_calculator(MorsePotential())

dyn = BFGS(neb, trajectory='mep.traj')  # , logfile='mep.log')

dyn.run(fmax=fmax)

for a in neb.images:
    print(a.positions[-1], a.get_potential_energy())
Beispiel #44
0
    def run(self):
        '''Run the AutoNEB optimization algorithm.'''
        n_cur = self.__initialize__()
        while len(self.all_images) < self.n_simul + 2:
            if isinstance(self.k, (float, int)):
                self.k = [self.k] * (len(self.all_images) - 1)
            if self.world.rank == 0:
                print('Now adding images for initial run')
            # Insert a new image where the distance between two images is
            # the largest
            spring_lengths = []
            for j in range(n_cur - 1):
                spring_vec = self.all_images[j + 1].get_positions() - \
                    self.all_images[j].get_positions()
                spring_lengths.append(np.linalg.norm(spring_vec))
            jmax = np.argmax(spring_lengths)

            if self.world.rank == 0:
                print('Max length between images is at ', jmax)

            # The interpolation used to make initial guesses
            # If only start and end images supplied make all img at ones
            if len(self.all_images) == 2:
                n_between = self.n_simul
            else:
                n_between = 1

            toInterpolate = [self.all_images[jmax]]
            for i in range(n_between):
                toInterpolate += [toInterpolate[0].copy()]
            toInterpolate += [self.all_images[jmax + 1]]

            neb = NEB(toInterpolate)
            neb.interpolate(method=self.interpolate_method)

            tmp = self.all_images[:jmax + 1]
            tmp += toInterpolate[1:-1]
            tmp.extend(self.all_images[jmax + 1:])

            self.all_images = tmp

            # Expect springs to be in equilibrium
            k_tmp = self.k[:jmax]
            k_tmp += [self.k[jmax] * (n_between + 1)] * (n_between + 1)
            k_tmp.extend(self.k[jmax + 1:])
            self.k = k_tmp

            # Run the NEB calculation with the new image included
            n_cur += n_between

        # Determine if any images do not have a valid energy yet
        energies = self.get_energies()

        n_non_valid_energies = len([e for e in energies if e != e])

        if self.world.rank == 0:
            print('Start of evaluation of the initial images')

        while n_non_valid_energies != 0:
            if isinstance(self.k, (float, int)):
                self.k = [self.k] * (len(self.all_images) - 1)

            # First do one run since some energie are non-determined
            to_run, climb_safe = self.which_images_to_run_on()
            self.execute_one_neb(n_cur, to_run, climb=False)

            energies = self.get_energies()
            n_non_valid_energies = len([e for e in energies if e != e])

        if self.world.rank == 0:
            print('Finished initialisation phase.')

        # Then add one image at a time until we have n_max images
        while n_cur < self.n_max:
            if isinstance(self.k, (float, int)):
                self.k = [self.k] * (len(self.all_images) - 1)
            # Insert a new image where the distance between two images
            # is the largest OR where a higher energy reselution is needed
            if self.world.rank == 0:
                print('****Now adding another image until n_max is reached',
                      '({0}/{1})****'.format(n_cur, self.n_max))
            spring_lengths = []
            for j in range(n_cur - 1):
                spring_vec = self.all_images[j + 1].get_positions() - \
                    self.all_images[j].get_positions()
                spring_lengths.append(np.linalg.norm(spring_vec))

            total_vec = self.all_images[0].get_positions() - \
                self.all_images[-1].get_positions()
            tl = np.linalg.norm(total_vec)

            fR = max(spring_lengths) / tl

            e = self.get_energies()
            ed = []
            emin = min(e)
            enorm = max(e) - emin
            for j in range(n_cur - 1):
                delta_E = (e[j + 1] - e[j]) * (e[j + 1] + e[j] - 2 *
                                               emin) / 2 / enorm
                ed.append(abs(delta_E))

            gR = max(ed) / enorm

            if fR / gR > self.space_energy_ratio:
                jmax = np.argmax(spring_lengths)
                t = 'spring length!'
            else:
                jmax = np.argmax(ed)
                t = 'energy difference between neighbours!'

            if self.world.rank == 0:
                print('Adding image between {0} and'.format(jmax),
                      '{0}. New image point is selected'.format(jmax + 1),
                      'on the basis of the biggest ' + t)

            toInterpolate = [self.all_images[jmax]]
            toInterpolate += [toInterpolate[0].copy()]
            toInterpolate += [self.all_images[jmax + 1]]

            neb = NEB(toInterpolate)
            neb.interpolate(method=self.interpolate_method)

            tmp = self.all_images[:jmax + 1]
            tmp += toInterpolate[1:-1]
            tmp.extend(self.all_images[jmax + 1:])

            self.all_images = tmp

            # Expect springs to be in equilibrium
            k_tmp = self.k[:jmax]
            k_tmp += [self.k[jmax] * 2] * 2
            k_tmp.extend(self.k[jmax + 1:])
            self.k = k_tmp

            # Run the NEB calculation with the new image included
            n_cur += 1
            to_run, climb_safe = self.which_images_to_run_on()

            self.execute_one_neb(n_cur, to_run, climb=False)

        if self.world.rank == 0:
            print('n_max images has been reached')

        # Do a single climb around the top-point if requested
        if self.climb:
            if isinstance(self.k, (float, int)):
                self.k = [self.k] * (len(self.all_images) - 1)
            if self.world.rank == 0:
                print('****Now doing the CI-NEB calculation****')
            to_run, climb_safe = self.which_images_to_run_on()

            assert climb_safe, 'climb_safe should be true at this point!'
            self.execute_one_neb(n_cur, to_run, climb=True, many_steps=True)

        if not self.smooth_curve:
            return self.all_images

        # If a smooth_curve is requsted ajust the springs to follow two
        # gaussian distributions
        e = self.get_energies()
        peak = self.get_highest_energy_index()
        k_max = 10

        d1 = np.linalg.norm(self.all_images[peak].get_positions() -
                            self.all_images[0].get_positions())
        d2 = np.linalg.norm(self.all_images[peak].get_positions() -
                            self.all_images[-1].get_positions())
        l1 = -d1 ** 2 / log(0.2)
        l2 = -d2 ** 2 / log(0.2)

        x1 = []
        x2 = []
        for i in range(peak):
            v = (self.all_images[i].get_positions() +
                 self.all_images[i + 1].get_positions()) / 2 - \
                self.all_images[0].get_positions()
            x1.append(np.linalg.norm(v))

        for i in range(peak, len(self.all_images) - 1):
            v = (self.all_images[i].get_positions() +
                 self.all_images[i + 1].get_positions()) / 2 - \
                self.all_images[0].get_positions()
            x2.append(np.linalg.norm(v))
        k_tmp = []
        for x in x1:
            k_tmp.append(k_max * exp(-((x - d1) ** 2) / l1))
        for x in x2:
            k_tmp.append(k_max * exp(-((x - d1) ** 2) / l2))

        self.k = k_tmp
        # Roll back to start from the top-point
        if self.world.rank == 0:
            print('Now moving from top to start')
        highest_energy_index = self.get_highest_energy_index()
        nneb = highest_energy_index - self.n_simul - 1
        while nneb >= 0:
            self.execute_one_neb(n_cur, range(nneb, nneb + self.n_simul + 2),
                                 climb=False)
            nneb -= 1

        # Roll forward from the top-point until the end
        nneb = self.get_highest_energy_index()

        if self.world.rank == 0:
            print('Now moving from top to end')
        while nneb <= self.n_max - self.n_simul - 2:
            self.execute_one_neb(n_cur, range(nneb, nneb + self.n_simul + 2),
                                 climb=False)
            nneb += 1
        return self.all_images
Beispiel #45
0
final = Atoms('HOHOH',
              positions=[(-sin(angle) * doht, 0., cos(angle) * doht),
                         (0., 0., 0.),
                         (0., 0., doo - doh),
                         (0., 0., doo),
                         (sin(angle) * doht, 0., doo - cos(angle) * doht)])
if 0:
    view(final)

# Make band:
images = [initial.copy()]
for i in range(3):
    images.append(initial.copy())
images.append(final.copy())
neb = NEB(images, climb=True)

# Set constraints and calculator:
constraint = FixAtoms(indices=[1, 3])  # fix OO
for image in images:
    image.set_calculator(EMT())
    image.set_constraint(constraint)

for image in images:  # O-H(shared) distance
    print(image.get_distance(1, 2), image.get_potential_energy())

# Relax initial and final states:
if 1:
    # XXX: Warning:
    # One would have to optimize more tightly in order to get
    # symmetric anion from both images[0] and [1], but
Beispiel #46
0
#optimise the initial state
# Atom above step
slab[-1].position = (x3,y2+1,z2+3.5)
final = slab.copy()
final.set_calculator(EMT())
relax = QuasiNewton(final)
relax.run(fmax=0.05)
view(final)

#create a list of images for interpolation
images = [initial]
for i in range(nimages):
    images.append(initial.copy())

for image in images:
    image.set_calculator(EMT())

images.append(final)
view(images)

#carry out idpp interpolation
neb = NEB(images)
neb.interpolate('idpp')

#Run NEB calculation
qn = QuasiNewton(neb, trajectory='N_diffusion.traj',  logfile='N_diffusion.log')
qn.run(fmax=0.05)