예제 #1
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
예제 #2
0
    def run(self, calc, filename):
        """
        Runs NEB calculations.
        Parameters
        ----------
        calc: object. Calculator to be used to run method.
        filename: str. Label to save generated trajectory files."""

        initial = self.starting_images[0].copy()
        final = self.starting_images[-1].copy()
        if self.ml2relax:
            # Relax initial and final images
            ml_initial = initial
            ml_initial.set_calculator(calc)
            ml_final = final
            ml_final.set_calculator(calc)
            print("BUILDING INITIAL")
            qn = BFGS(ml_initial,
                      trajectory="initial.traj",
                      logfile="initial_relax_log.txt")
            qn.run(fmax=0.01, steps=100)
            print("BUILDING FINAL")
            qn = BFGS(ml_final,
                      trajectory="final.traj",
                      logfile="final_relax_log.txt")
            qn.run(fmax=0.01, steps=100)
            initial = ml_initial.copy()
            final = ml_final.copy()

        initial.set_calculator(calc)
        final.set_calculator(calc)

        images = [initial]
        for i in range(self.intermediate_samples):
            image = initial.copy()
            image.set_calculator(calc)
            images.append(image)
        images.append(final)

        print("NEB BEING BUILT")
        neb = SingleCalculatorNEB(images)
        neb.interpolate()
        print("NEB BEING OPTIMISED")
        opti = BFGS(neb,
                    trajectory=filename + ".traj",
                    logfile="al_neb_log.txt")
        opti.run(fmax=0.01, steps=100)
        print("NEB DONE")
        """
      The following code is used to visualise the NEB at every iteration
      """

        built_neb = NEBTools(images)
        barrier, dE = built_neb.get_barrier()
        # max_force = built_neb.get_fmax()
        # fig = built_neb.plot_band()
        plt.show()
예제 #3
0
def prepare_graph(transition_states, lmdf, trandir, log='@-7:'):
    Ed = []
    for ts in transition_states:
        outputs = read(trandir + ts + log)
        for output in outputs:
            add_tip4p_const(output)
        nebtools = NEBTools(outputs)
        Ef, dE = nebtools.get_barrier()
        Ed.append([ts[:-5], Ef, Ed])
    Ed = pd.DataFrame(Ed, columns=['images', 'Ed', 'deltaE'])
    mins = Ed['images'].apply(lambda x: x.split("_"))
    min1 = []
    min2 = []
    revers = []
    for line in mins:
        min1.append(line[0])
        min2.append(line[1])
        revers.append(line[1] + "_" + line[0])
    db = pd.DataFrame(columns=["m1", "m2", "Ed", "images"])

    db['m1'] = min1
    db['m2'] = min2
    db['Ed'] = Ed['Ed']
    db['images'] = Ed['images']
    db = db.merge(lmdf[['m2', 'E2']], how='left', on='m2')

    db = db.merge(lmdf[['m1', 'E1']], how='left', on='m1')
    db['ET'] = db['Ed'] + db['E1']
    db2 = pd.DataFrame(columns=["m1", "m2", "Ed", "images", "E2", "E1", "ET"])

    db2['m1'] = db["m2"]
    db2['m2'] = db["m1"]
    db2['ET'] = db['ET']
    db2['Ed'] = db['Ed']
    db2['E1'] = db["E2"]
    db2['E2'] = db["E1"]
    db2['images'] = revers
    new = pd.concat([db, db2])

    new = new[new["ET"] <= 0]
    new = new[new["E1"] <= new["ET"]]
    new = new[new["E2"] <= new["ET"]]
    dbnp = new.values

    g = nx.Graph()
    g.add_nodes_from(new['m1'])
    g.add_nodes_from(new['m2'])
    for line in dbnp:
        line[3] = line[0][4:] + '_' + line[1][4:]
        if line[2] != np.nan:
            g.add_edge(line[0], line[1], ts=[line[0], line[1], line[6]])
    return g, new
예제 #4
0
def _ref_vacancy_global(_setup_images_global):
    # use distance from moving atom to one of its neighbours as reaction coord
    # relax intermediate image to the saddle point using a bondlength constraint
    images, i1, i2 = _setup_images_global
    initial, saddle, final = (images[0].copy(), images[2].copy(),
                              images[4].copy())
    initial.calc = calc()
    saddle.calc = calc()
    final.calc = calc()
    saddle.set_constraint(FixBondLength(i1, i2))
    opt = ODE12r(saddle)
    opt.run(fmax=1e-2)
    nebtools = NEBTools([initial, saddle, final])
    Ef_ref, dE_ref = nebtools.get_barrier(fit=False)
    print('REF:', Ef_ref, dE_ref)
    return Ef_ref, dE_ref, saddle
예제 #5
0
def test_autoneb(asap3):
    EMT = asap3.EMT
    fmax = 0.02

    # Pt atom adsorbed in a hollow site:
    slab = fcc211('Pt', size=(3, 2, 2), vacuum=4.0)
    add_adsorbate(slab, 'Pt', 0.5, (-0.1, 2.7))

    # Fix second and third layers:
    slab.set_constraint(FixAtoms(range(6, 12)))

    # Use EMT potential:
    slab.calc = EMT()

    # Initial state:
    qn = QuasiNewton(slab, trajectory='neb000.traj')
    qn.run(fmax=fmax)

    # Final state:
    slab[-1].x += slab.get_cell()[0, 0]
    slab[-1].y += 2.8
    qn = QuasiNewton(slab, trajectory='neb001.traj')
    qn.run(fmax=fmax)

    # Stops PermissionError on Win32 for access to
    # the traj file that remains open.
    del qn

    def attach_calculators(images):
        for i in range(len(images)):
            images[i].calc = EMT()

    autoneb = AutoNEB(attach_calculators,
                      prefix='neb',
                      optimizer='BFGS',
                      n_simul=3,
                      n_max=7,
                      fmax=fmax,
                      k=0.5,
                      parallel=False,
                      maxsteps=[50, 1000])
    autoneb.run()

    nebtools = NEBTools(autoneb.all_images)
    assert abs(nebtools.get_barrier()[0] - 0.937) < 1e-3
예제 #6
0
def test_ethene_rotation(tmpdir):

    tmpdir.chdir()

    # Optimise molecule
    initial = molecule('C2H6')
    smart_cell(initial, vac=4.0, h=0.01)
    initial.set_calculator(iEspresso(pw=300, dw=4000, kpts='gamma'))
    qn = QuasiNewton(initial, 'initial.traj')
    qn.run(fmax=0.01)

    # Create final state
    final = initial.copy()
    final.positions[2:5] = initial.positions[[3, 4, 2]]
    final.set_calculator(iEspresso(pw=300, dw=4000, kpts='gamma'))
    final.get_potential_energy()

    # Generate blank images
    images = [initial]
    nimage = 7

    for i in range(nimage):
        image = initial.copy()
        image.set_calculator(iEspresso(pw=300, dw=4000, kpts='gamma'))
        images.append(image)
    images.append(final)

    # Run IDPP interpolation
    neb = NEBEspresso(images)
    neb.interpolate('idpp')

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

    nt = NEBTools(neb.images)
    print('fmax: ', nt.get_fmax())
    print('Ef, dE: ', nt.get_barrier())
예제 #7
0
def test_neb_tr():
    nimages = 3
    fmax = 0.01

    for remove_rotation_and_translation in [True, False]:
        # Define coordinates for initial and final states
        initial = Atoms('O4', [(1.94366484, 2.24788196, 2.32204726),
                               (3.05353823, 2.08091038, 2.30712548),
                               (2.63770601, 3.05694348, 2.67368242),
                               (2.50579418, 2.12540646, 3.28585811)])

        final = Atoms('O4', [(1.95501370, 2.22270649, 2.33191017),
                             (3.07439495, 2.13662682, 2.31948449),
                             (2.44730550, 1.26930465, 2.65964947),
                             (2.52788189, 2.18990240, 3.29728667)])

        final.set_cell((5, 5, 5))
        initial.set_cell((5, 5, 5))
        final.calc = LennardJones()
        initial.calc = LennardJones()

        images = [initial]

        # Set calculator
        for i in range(nimages):
            image = initial.copy()
            image.calc = 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
        idpp_interpolate(neb, fmax=0.1, optimizer=BFGS)

        qn = FIRE(neb, dt=0.005, maxstep=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, maxstep=0.05, dtmax=0.1)
        qn.run(fmax=fmax)

        images = neb.images

        nebtools = NEBTools(images)
        Ef_neb, dE_neb = nebtools.get_barrier(fit=False)
        nsteps_neb = qn.nsteps
        if remove_rotation_and_translation:
            Ef_neb_0 = Ef_neb
            nsteps_neb_0 = nsteps_neb

    assert abs(Ef_neb - Ef_neb_0) < 1e-2
    assert nsteps_neb_0 < nsteps_neb * 0.7
예제 #8
0
print('\nSummary of the results: \n')

atoms_ase = read('neb_ase.traj', ':')
n_eval_ase = int(len(atoms_ase) - 2 * (len(atoms_ase) / n_images))

print('Number of function evaluations CI-NEB implemented in ASE:', n_eval_ase)

# ML-NEB:
atoms_catlearn = read('evaluated_structures.traj', ':')
n_eval_catlearn = len(atoms_catlearn) - 2
print('Number of function evaluations CatLearn:', n_eval_catlearn)

# Comparison:
print(
    '\nThe ML-NEB algorithm required ', (n_eval_ase / n_eval_catlearn),
    'times less number of function evaluations than '
    'the standard NEB algorithm.')

# Plot ASE NEB:
nebtools_ase = NEBTools(images_ase)

Sf_ase = nebtools_ase.get_fit()[2]
Ef_ase = nebtools_ase.get_fit()[3]

Ef_neb_ase, dE_neb_ase = nebtools_ase.get_barrier(fit=False)
nebtools_ase.plot_band()

plt.show()

# Plot ML-NEB predicted path and show images along the path:
plotneb(trajectory='ML-NEB.traj', view_path=False)
예제 #9
0
파일: neb_tr.py 프로젝트: essil1/ase-laser
    # 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)

    images = neb.images

    nebtools = NEBTools(images)
    Ef_neb, dE_neb = nebtools.get_barrier(fit=False)
    nsteps_neb = qn.nsteps
    if remove_rotation_and_translation:
        Ef_neb_0 = Ef_neb
        nsteps_neb_0 = nsteps_neb

assert abs(Ef_neb - Ef_neb_0) < 1e-2
assert nsteps_neb_0 < nsteps_neb * 0.7
예제 #10
0
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())

neb.climb = True
dyn.run(fmax=fmax)

# Check NEB tools.
nt_images = read('mep.traj@-4:')
nebtools = NEBTools(nt_images)
nt_fmax = nebtools.get_fmax(climb=True)
Ef, dE = nebtools.get_barrier()
print(Ef, dE, fmax, nt_fmax)
assert nt_fmax < fmax
assert abs(Ef - 1.389) < 0.001
예제 #11
0
import matplotlib.pyplot as plt
from ase.neb import NEBTools
from ase.io import read

images = read('neb.traj@-5:')

nebtools = NEBTools(images)

# Get the calculated barrier and the energy change of the reaction.
Ef, dE = nebtools.get_barrier()

# Get the barrier without any interpolation between highest images.
Ef, dE = nebtools.get_barrier(fit=False)

# Get the actual maximum force at this point in the simulation.
max_force = nebtools.get_fmax()

# Create a figure like that coming from ASE-GUI.
fig = nebtools.plot_band()
fig.savefig('diffusion-barrier.png')

# Create a figure with custom parameters.
fig = plt.figure(figsize=(5.5, 4.0))
ax = fig.add_axes((0.15, 0.15, 0.8, 0.75))
nebtools.plot_band(ax)
fig.savefig('diffusion-barrier.png')
예제 #12
0
    # 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)

    images = neb.images

    nebtools = NEBTools(images)
    Ef_neb, dE_neb = nebtools.get_barrier(fit=False)
    nsteps_neb = qn.nsteps
    if remove_rotation_and_translation:
        Ef_neb_0 = Ef_neb
        nsteps_neb_0 = nsteps_neb

assert abs(Ef_neb - Ef_neb_0) < 1e-2
assert nsteps_neb_0 < nsteps_neb * 0.7
예제 #13
0
print(" -> set calculator")
for image in images:
    image.set_calculator(
        PySCF_simple(atoms=image, method='MP2', basis='6-31g*'))

neb = NEB(images, climb=True, k=0.6)
nebTools = NEBTools(images)

neb.interpolate('idpp')

print(" -> start neb run")
opt = FIRE(neb)
opt.run(fmax=0.05)

print(nebTools.get_barrier())

# get IRC data
Ef, dE = nebTools.get_barrier()
max_force = nebTools.get_fmax()
x, y, x_fit, y_fit, forces = nebTools.get_fit()

# save IRC data
np.save("x_claisen_mp2.npy", x)
np.save("y_claisen_mp2.npy", y)
np.save("x_claisen_fit_mp2.npy", x_fit)
np.save("y_claisen_fit_mp2.npy", y_fit)

# write NEB guess of interpolation
for i, image in enumerate(images):
    out_name = "claisen_{:03d}.xyz".format(i)
예제 #14
0
qn.run(fmax=0.05)

# Final state:
slab[-1].x += slab.get_cell()[0, 0]
slab[-1].y += 2.8
qn = QuasiNewton(slab, trajectory='neb001.traj')
qn.run(fmax=0.05)

# Stops PermissionError on Win32 for access to
# the traj file that remains open.
del qn


def attach_calculators(images):
    for i in range(len(images)):
        images[i].set_calculator(EMT())


autoneb = AutoNEB(attach_calculators,
                  prefix='neb',
                  n_simul=3,
                  n_max=7,
                  fmax=0.05,
                  k=0.5,
                  parallel=False,
                  maxsteps=[50, 1000])
autoneb.run()

nebtools = NEBTools(autoneb.all_images)
assert abs(nebtools.get_barrier()[0] - 0.938) < 1e-3
# Generate blank images.
images = [initial]
for i in range(9):
    images.append(initial.copy())
for image in images:
    image.calc = EMT()
images.append(final)

neb = NEB(images, climb=True)
neb.interpolate(method='idpp')  #idpp插值,设置初猜

# set calculator
for atoms in images:
    atoms.calc = EMT()
    atoms.get_potential_energy()

# Optimize:
py_fname = os.path.splitext(sys.argv[0])[0]
traj_fname = "{}.traj".format(py_fname)
log_fname = "{}.log".format(py_fname)
optimizer = FIRE(neb, trajectory=traj_fname, logfile=log_fname)
optimizer.run(fmax=0.04)

neb_result = list(iread(traj_fname))
for i in neb_result:
    #print(i.get_potential_energy())
    pass
neb_result = NEBTools(neb_result)
neb_result.plot_bands(True, True, label=py_fname)
print(neb_result.get_barrier(), neb_result.get_fmax())
예제 #16
0
파일: neb.py 프로젝트: essil1/ase-laser
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())

neb.climb = True
dyn.run(fmax=fmax)

# Check NEB tools.
nt_images = read('mep.traj@-4:')
nebtools = NEBTools(nt_images)
nt_fmax = nebtools.get_fmax(climb=True)
Ef, dE = nebtools.get_barrier()
print(Ef, dE, fmax, nt_fmax)
assert nt_fmax < fmax
assert abs(Ef - 1.389) < 0.001
예제 #17
0
# Final state:
slab[-1].x += slab.get_cell()[0, 0]
slab[-1].y += 2.8
qn = QuasiNewton(slab, trajectory='neb001.traj')
qn.run(fmax=0.05)

# Stops PermissionError on Win32 for access to
# the traj file that remains open.
del qn


def attach_calculators(images):
    for i in range(len(images)):
        images[i].set_calculator(EMT())


autoneb = AutoNEB(attach_calculators,
                  prefix='neb',
                  optimizer='BFGS',
                  n_simul=3,
                  n_max=7,
                  fmax=0.05,
                  k=0.5,
                  parallel=False,
                  maxsteps=[50, 1000])
autoneb.run()

nebtools = NEBTools(autoneb.all_images)
assert abs(nebtools.get_barrier()[0] - 0.938) < 1e-3
예제 #18
0
def test_neb(plt):
    from ase import Atoms
    from ase.constraints import FixAtoms
    import ase.io
    from ase.neb import NEB, NEBTools
    from ase.calculators.morse import MorsePotential
    from ase.optimize import BFGS, QuasiNewton

    def calc():
        # Common calculator for all images.
        return MorsePotential()

    # Create and relax initial and final states.
    initial = Atoms('H7',
                    positions=[(0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0),
                               (0, 2, 0), (1, 2, 0), (0.5, 0.5, 1)],
                    constraint=[FixAtoms(range(6))],
                    calculator=calc())
    dyn = QuasiNewton(initial)
    dyn.run(fmax=0.01)

    final = initial.copy()
    final.calc = calc()
    final.positions[6, 1] = 2 - initial.positions[6, 1]
    dyn = QuasiNewton(final)
    dyn.run(fmax=0.01)

    # Run NEB without climbing image.
    fmax = 0.05
    nimages = 4

    images = [initial]
    for index in range(nimages - 2):
        images += [initial.copy()]
        images[-1].calc = calc()
    images += [final]

    neb = NEB(images)
    neb.interpolate()

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

        # Check climbing image.
        neb.climb = True
        dyn.run(fmax=fmax)

    # Check NEB tools.
    nt_images = ase.io.read('mep.traj', index='-{:d}:'.format(nimages))
    nebtools = NEBTools(nt_images)
    nt_fmax = nebtools.get_fmax(climb=True)
    Ef, dE = nebtools.get_barrier()
    print(Ef, dE, fmax, nt_fmax)
    assert nt_fmax < fmax
    assert abs(Ef - 1.389) < 0.001
    # Plot one band.
    nebtools.plot_band()
    # Plot many (ok, 2) bands.
    nt_images = ase.io.read('mep.traj', index='-{:d}:'.format(2 * nimages))
    nebtools = NEBTools(nt_images)
    nebtools.plot_bands()