예제 #1
0
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
예제 #2
0
    # All the cells should be the same.
    assert (calc.get_atoms().get_cell() == CONTCAR_Al.get_cell()).all()
    assert (Al.get_cell() == CONTCAR_Al.get_cell()).all()

    return Al

# -- Perform Volume relaxation using ASE with Vasp as force/stress calculator
def ase_ext.vol_relax():
    Al = bulk('Al', 'fcc', a=4.5, cubic=True)
    calc = Vasp(xc='LDA')
    Al.set_calculator(calc)

    from ase_ext.constraints import StrainFilter
    sf = StrainFilter(Al)
    qn = QuasiNewton(sf, logfile='relaxation.log')
    qn.run(fmax=0.1, steps=5)

    print('Stress:\n', calc.read_stress())
    print('Al post ASE volume relaxation\n', calc.get_atoms().get_cell())

    return Al

# Test function for comparing two cells
def cells_almost_equal(cellA, cellB, tol=0.01):
    return  (np.abs(cellA - cellB) < tol).all()

# Correct LDA relaxed cell
a_rel = 4.18
LDA_cell = np.diag([a_rel, a_rel, a_rel])
예제 #3
0
from ase_ext import Atoms
from ase_ext.calculators.emt import EMT
from ase_ext.optimize import QuasiNewton
from ase_ext.vibrations import Vibrations
from ase_ext.thermochemistry import IdealGasThermo

n2 = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT())
QuasiNewton(n2).run(fmax=0.01)
vib = Vibrations(n2)
vib.run()
print(vib.get_frequencies())
vib.summary()
print(vib.get_mode(-1))
vib.write_mode(-1, nimages=20)
vib_energies = vib.get_energies()

thermo = IdealGasThermo(vib_energies=vib_energies,
                        geometry='linear',
                        atoms=n2,
                        symmetrynumber=2,
                        spin=0)
thermo.get_free_energy(temperature=298.15, pressure=2 * 101325.)
예제 #4
0
from ase_ext.io import PickleTrajectory
from ase_ext.neb import NEB
from ase_ext.calculators.lj import LennardJones
from ase_ext.optimize import QuasiNewton

print([a.get_potential_energy() for a in PickleTrajectory('H.traj')])
images = [PickleTrajectory('H.traj')[-1]]
for i in range(4):
    images.append(images[0].copy())
images[-1].positions[6, 1] = 2 - images[0].positions[6, 1]
neb = NEB(images)
neb.interpolate()

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

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

dyn = QuasiNewton(neb, trajectory='mep.traj')
print(dyn.run(fmax=0.01, steps=25))
for a in neb.images:
    print(a.positions[-1], a.get_potential_energy())
예제 #5
0
# Distance between Cu atoms on a (111) surface:
a = 3.6
d = a / sqrt(2)
y = d * sqrt(3) / 2
fcc111 = Atoms('Cu',
               cell=[(d, 0, 0), (d / 2, y, 0), (d / 2, y / 3, -a / sqrt(3))],
               pbc=True)
slab = fcc111 * (2, 2, 4)
slab.set_cell([2 * d, 2 * y, 1])
slab.set_pbc((1, 1, 0))
slab.set_calculator(EMT())
Z = slab.get_positions()[:, 2]
indices = [i for i, z in enumerate(Z) if z < Z.mean()]
constraint = FixAtoms(indices=indices)
slab.set_constraint(constraint)
dyn = QuasiNewton(slab)
dyn.run(fmax=0.05)
Z = slab.get_positions()[:, 2]
print(Z[0] - Z[1])
print(Z[1] - Z[2])
print(Z[2] - Z[3])

b = 1.2
h = 2.0
slab += Atom('C', (d, 2 * y / 3, h))
slab += Atom('O', (3 * d / 2, y / 3, h))
traj = PickleTrajectory('initial.traj', 'w', slab)
dyn = QuasiNewton(slab)
dyn.attach(traj.write)
dyn.run(fmax=0.05)
#view(slab)
예제 #6
0
from ase_ext import Atoms
from ase_ext.calculators.emt import EMT
from ase_ext.optimize import QuasiNewton

n2 = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT())
QuasiNewton(n2).run(0.01)
print(n2.get_distance(0, 1), n2.get_potential_energy())
예제 #7
0
    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.set_calculator(EMT())
        #image.set_calculator(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())
예제 #8
0
# Make band:
images = [initial.copy() for i in range(6)]
neb = NEB(images, climb=True)

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

# Displace last image:
images[-1].positions[-1] += (d, 0, 0)
#images[-1].positions[-1] += (d, d, 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 = MDMin(neb, dt=0.4)
#dyn = FIRE(neb, dt=0.4)
dyn = QuasiNewton(neb, trajectory='mep.traj')
dyn.run(fmax=0.05)
예제 #9
0
# Distance between Cu atoms on a (111) surface:
a = 3.6
d = a / sqrt(2)
fcc111 = Atoms(symbols='Cu',
               cell=[(d, 0, 0), (d / 2, d * sqrt(3) / 2, 0),
                     (d / 2, d * sqrt(3) / 6, -a / sqrt(3))],
               pbc=True)
slab = fcc111 * (2, 2, 4)
slab.set_cell([2 * d, d * sqrt(3), 1])
slab.set_pbc((1, 1, 0))
slab.set_calculator(EMT())
Z = slab.get_positions()[:, 2]
indices = [i for i, z in enumerate(Z) if z < Z.mean()]
constraint = FixAtoms(indices=indices)
slab.set_constraint(constraint)
dyn = QuasiNewton(slab)
dyn.run(fmax=0.05)
Z = slab.get_positions()[:, 2]
print(Z[0] - Z[1])
print(Z[1] - Z[2])
print(Z[2] - Z[3])

b = 1.2
h = 1.5
slab += Atom('C', (d / 2, -b / 2, h))
slab += Atom('O', (d / 2, +b / 2, h))
s = slab.copy()
dyn = QuasiNewton(slab)
dyn.run(fmax=0.05)
#view(slab)
예제 #10
0
import numpy as np
from ase_ext import Atoms
from ase_ext.units import fs
from ase_ext.calculators.test import TestPotential
from ase_ext.calculators.emt import EMT
from ase_ext.md import VelocityVerlet
from ase_ext.io import PickleTrajectory, read
from ase_ext.optimize import QuasiNewton

np.seterr(all='raise')
a = Atoms('4X',
          masses=[1, 2, 3, 4],
          positions=[(0, 0, 0), (1, 0, 0), (0, 1, 0), (0.1, 0.2, 0.7)],
          calculator=TestPotential())
print(a.get_forces())
md = VelocityVerlet(a, dt=0.5 * fs, logfile='-', loginterval=500)
traj = PickleTrajectory('4N.traj', 'w', a)
md.attach(traj.write, 100)
e0 = a.get_total_energy()
md.run(steps=10000)
del traj
assert abs(read('4N.traj').get_total_energy() - e0) < 0.0001

qn = QuasiNewton(a)
qn.run(0.001)
assert abs(a.get_potential_energy() - 1.0) < 0.000002