Example #1
0
def get_atoms():
    zpos = cos(134.3/2.0*pi/180.0)*1.197
    xpos = sin(134.3/2.0*pi/180.0)*1.19
    no2 =Atoms('CO', positions=[(-xpos+1.2,0,-zpos), (-xpos+1.2,-1.1,-zpos)])

    # Surface slab
    slab =fcc111('Au', size=(2, 2, 4),vacuum=2*5, orthogonal = True )
    slab.center()
    add_adsorbate(slab,no2,1.5,'bridge')
    slab.set_pbc((True,True,False))

    #constraints
    constraint = FixAtoms(mask=[(a.tag == 4) or (a.tag == 3) or (a.tag==2) for a in slab])
    slab.set_constraint(constraint)
    return slab
Example #2
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
Example #3
0
    def test_vibration_on_surface(self, testdir):
        from ase.build import fcc111, add_adsorbate
        ag_slab = fcc111('Ag', (4, 4, 2), a=2)
        n2 = Atoms('N2',
                   positions=[[0., 0., 0.], [0., np.sqrt(2),
                                             np.sqrt(2)]])
        add_adsorbate(ag_slab, n2, height=1, position='fcc')

        # Add an interaction between the N atoms
        hessian_bottom_corner = np.zeros((2, 3, 2, 3))
        hessian_bottom_corner[-1, :, -2] = [1, 1, 1]
        hessian_bottom_corner[-2, :, -1] = [1, 1, 1]

        hessian = np.zeros((34, 3, 34, 3))
        hessian[32:, :, 32:, :] = hessian_bottom_corner

        ag_slab.calc = ForceConstantCalculator(hessian.reshape(
            (34 * 3, 34 * 3)),
                                               ref=ag_slab.copy(),
                                               f0=np.zeros((34, 3)))

        # Check that Vibrations with restricted indices returns correct Hessian
        vibs = Vibrations(ag_slab, indices=[-2, -1])
        vibs.run()
        vibs.read()

        assert_array_almost_equal(vibs.get_vibrations().get_hessian(),
                                  hessian_bottom_corner)

        # These should blow up if the vectors don't match number of atoms
        vibs.summary()
        vibs.write_jmol()

        for i in range(6):
            # Frozen atoms should have zero displacement
            assert_array_almost_equal(vibs.get_mode(i)[0], [0., 0., 0.])

            # The N atoms should have finite displacement
            assert np.all(vibs.get_mode(i)[-2:, :])
Example #4
0
    def test_custom_fingerprinting(self):
        """Test the custom fingerprint example"""
        atoms = fcc111('Pd', size=(2, 2, 3), vacuum=10.0)
        add_adsorbate(atoms, 'C', 1, 'fcc')

        # -1 is the tag convention to identify bonded atoms
        tags = atoms.get_tags()
        tags[-1] = -1
        atoms.set_tags(tags)

        parameters = [
            'atomic_number',
            'dband_center_slab',
            'dband_width_slab',
            'dband_skewness_slab',
            'dband_kurtosis_slab'
        ]

        def example_operation(
                atoms,
                atoms_parameters,
                connectivity):
            # This is a CatKit convention
            bond_index = np.where(atoms.get_tags() == -1)[0]

            return np.sum(connectivity[bond_index], axis=1)

        operations = [
            'bonding_convolution',
            example_operation
        ]

        fp = Fingerprinter(atoms)
        fingerprints = fp.get_fp(parameters, operations)

        truth = np.array([276.0, -1.570340288877117, 6.51684717398884,
                          -81.36785228863994, 3651.4867376228817, 3.0])

        np.testing.assert_allclose(fingerprints[0], truth)
Example #5
0
def construct_geometries(parent_calc, ml2relax):
    counter_calc = parent_calc
    # Initial structure guess
    initial_slab = fcc100("Cu", size=(2, 2, 3))
    add_adsorbate(initial_slab, "C", 1.7, "hollow")
    initial_slab.center(axis=2, vacuum=4.0)
    mask = [atom.tag > 1 for atom in initial_slab]
    initial_slab.set_constraint(FixAtoms(mask=mask))
    initial_slab.set_pbc(True)
    initial_slab.wrap(pbc=[True] * 3)
    initial_slab.set_calculator(counter_calc)

    # Final structure guess
    final_slab = initial_slab.copy()
    final_slab[-1].x += final_slab.get_cell()[0, 0] / 3
    final_slab.set_calculator(counter_calc)
    if not ml2relax:
        print("BUILDING INITIAL")
        qn = BFGS(initial_slab,
                  trajectory="initial.traj",
                  logfile="initial_relax_log.txt")
        qn.run(fmax=0.01, steps=100)
        print("BUILDING FINAL")
        qn = BFGS(final_slab,
                  trajectory="final.traj",
                  logfile="final_relax_log.txt")
        qn.run(fmax=0.01, steps=100)
        initial_slab = read("initial.traj", "-1")
        final_slab = read("final.traj", "-1")
        # If there is already a pre-existing initial and final relaxed parent state we can read
        # that to use as a starting point
        # initial_slab = read("/content/parent_initial.traj")
        # final_slab = read("/content/parent_final.traj")
    else:
        initial_slab = initial_slab
        final_slab = final_slab

    # initial_force_calls = counter_calc.force_calls
    return initial_slab, final_slab  # , initial_force_calls
Example #6
0
def test_dimer_method(testdir):
    # Set up a small "slab" with an adatoms
    atoms = fcc100('Pt', size=(2, 2, 1), vacuum=10.0)
    add_adsorbate(atoms, 'Pt', 1.611, 'hollow')

    # Freeze the "slab"
    mask = [atom.tag > 0 for atom in atoms]
    atoms.set_constraint(FixAtoms(mask=mask))

    # Calculate using EMT
    atoms.calc = EMT()
    atoms.get_potential_energy()

    # Set up the dimer
    with DimerControl(initial_eigenmode_method='displacement',
                      displacement_method='vector',
                      logfile=None,
                      mask=[0, 0, 0, 0, 1]) as d_control:
        d_atoms = MinModeAtoms(atoms, d_control)

        # Displace the atoms
        displacement_vector = [[0.0] * 3] * 5
        displacement_vector[-1][1] = -0.1
        d_atoms.displace(displacement_vector=displacement_vector)

        # Converge to a saddle point
        with MinModeTranslate(d_atoms,
                              trajectory='dimer_method.traj',
                              logfile=None) as dim_rlx:
            dim_rlx.run(fmax=0.001)

    # Test the results
    tolerance = 1e-3
    assert (d_atoms.get_barrier_energy() - 1.03733136918 < tolerance)
    assert (abs(d_atoms.get_curvature() + 0.900467048707) < tolerance)
    assert (d_atoms.get_eigenmode()[-1][1] < -0.99)
    assert (abs(d_atoms.get_positions()[-1][1]) < tolerance)
Example #7
0
def gridVasp(adsorbate, slab, directory='tempout/', spacing=0.2):
    """
    Takes in slab, adsorbate, and desired output directory.
    Writes numbered POSCAR files to output directory with adsorbate 
    placed in grid pattern

    Args:
        adsorbate: either path (str) for POS/CONTCAR or Atoms obj
        slab: either path (str) for POS/CONTCAR or Atoms obj
        directory: path (str) for desired output location
        spacing: spacing between grid points (eg, 0.2 is a 5x5 grid)
    Returns:
        None
    """
    if type(adsorbate) == str:
        adsorbate = vasp.read_vasp(adsorbate)

    if type(slab) == str:
        slab = vasp.read_vasp(slab)
    # TODO: make this work with path objects?

    i = 0  # 0 index written POSCAR{i} files
    for _x in np.arange(0, 1 - spacing, spacing):
        for _y in np.arange(0, 1 - spacing, spacing):
            s = slab.copy()
            x, y, z = slab.cell.cartesian_positions([_x, _y, 0])
            add_adsorbate(s, adsorbate, height=2, position=(x, y))
            s = Atoms(sorted(s, key=lambda x: x.symbol))
            s.cell = slab.cell
            vasp.write_vasp(directory + "POSCAR" + str(i),
                            s,
                            label='{} on {}'.format(
                                adsorbate.get_chemical_formula(),
                                slab.get_chemical_formula()),
                            vasp5=True)

            i += 1
Example #8
0
def slabgen(termination, size, adsorbate, position):
    if termination == '100':
        prim = fcc100('Cu',
                      a=3.6302862146117354,
                      size=(1, 1, 5),
                      vacuum=15,
                      orthogonal=True,
                      periodic=True)
    elif termination == '111':
        prim = fcc111_root('Cu',
                           root=3,
                           a=3.6302862146117354,
                           size=(1, 1, 5),
                           vacuum=15)

    super = make_supercell(prim, size)
    add_adsorbate(slab=super,
                  adsorbate=adsorbate,
                  height=ads_height,
                  position=position)
    constr = FixAtoms(
        indices=[atom.index for atom in super if atom.position[2] < 19])
    super.set_constraint(constr)
    return super
Example #9
0
def aual100(site, height, calc=None):
    slab = fcc100('Al', size=(2, 2, 2))
    slab.center(axis=2, vacuum=3.0)
    add_adsorbate(slab, 'Au', height, site)
    mask = [atom.symbol == 'Al' for atom in slab]
    fixlayer = FixAtoms(mask=mask)
    slab.set_constraint(fixlayer)

    if calc is None:
        calc = GPAW(mode=PW(200),
                    kpts=(2, 2, 1),
                    xc='PBE',
                    txt=site + '.txt',
                    eigensolver='rmm-diis',
                    nbands=40)

    slab.set_calculator(calc)
    qn = QuasiNewton(slab, trajectory=site + calc.name + '.traj')
    qn.run(fmax=0.05)

    if isinstance(calc, GPAW):
        calc.write(site + '.gpw')

    return slab.get_potential_energy()
Example #10
0
def test_surface():
    import numpy as np

    from ase import Atoms, Atom
    from ase.build import fcc111, fcc211, add_adsorbate, bulk, surface
    import math

    atoms = fcc211('Au', (3, 5, 8), vacuum=10.)
    assert len(atoms) == 120

    atoms = atoms.repeat((2, 1, 1))
    assert np.allclose(atoms.get_distance(0, 130), 2.88499566724)

    atoms = fcc111('Ni', (2, 2, 4), orthogonal=True)
    add_adsorbate(atoms, 'H', 1, 'bridge')
    add_adsorbate(atoms, Atom('O'), 1, 'fcc')
    add_adsorbate(atoms, Atoms('F'), 1, 'hcp')

    # The next test ensures that a simple string of multiple atoms cannot be used,
    # which should fail with a KeyError that reports the name of the molecule due
    # to the string failing to work with Atom().
    failed = False
    try:
        add_adsorbate(atoms, 'CN', 1, 'ontop')
    except KeyError as e:
        failed = True
        assert e.args[0] == 'CN'
    assert failed

    # This test ensures that the default periodic behavior remains unchanged
    cubic_fcc = bulk("Al", a=4.05, cubic=True)
    surface_fcc = surface(cubic_fcc, (1,1,1), 3)

    assert list(surface_fcc.pbc) == [True, True, False]
    assert surface_fcc.cell[2][2] == 0

    # This test checks the new periodic option
    cubic_fcc = bulk("Al", a=4.05, cubic=True)
    surface_fcc = surface(cubic_fcc, (1,1,1), 3, periodic=True)

    assert (list(surface_fcc.pbc) == [True, True, True])
    expected_length = 4.05*3**0.5 #for FCC with a=4.05
    assert math.isclose(surface_fcc.cell[2][2], expected_length)
Example #11
0
from ase.calculators.emt import EMT
from ase.constraints import FixBondLengths
from ase.optimize import BFGS
from ase.build import fcc111, add_adsorbate


for wrap in [False, True]:
    zpos = cos(134.3 / 2.0 * pi / 180.0) * 1.197
    xpos = sin(134.3 / 2.0 * pi / 180.0) * 1.19
    co2 = Atoms('COO', positions=[(-xpos + 1.2, 0, -zpos),
                                  (-xpos + 1.2, -1.1, -zpos),
                                  (-xpos + 1.2, 1.1, -zpos)])

    slab = fcc111('Au', size=(2, 2, 4), vacuum=2 * 5, orthogonal=True)
    slab.center()
    add_adsorbate(slab, co2, 1.5, 'bridge')
    slab.set_pbc((True, True, False))
    d0 = co2.get_distance(-3, -2)
    d1 = co2.get_distance(-3, -1)

    calc = EMT()
    slab.set_calculator(calc)
    if wrap:
        # Remap into the cell so bond is actually wrapped:
        slab.set_scaled_positions(slab.get_scaled_positions() % 1.0)
    constraint = FixBondLengths([[-3, -2], [-3, -1]])
    slab.set_constraint(constraint)
    dyn = BFGS(slab, trajectory='relax_%d.traj' % wrap)
    dyn.run(fmax=0.05)
    assert abs(slab.get_distance(-3, -2, mic=1) - d0) < 1e-9
    assert abs(slab.get_distance(-3, -1, mic=1) - d1) < 1e-9
Example #12
0
import numpy as np

from ase import Atoms, Atom
from ase.build import fcc111, fcc211, add_adsorbate

atoms = fcc211('Au', (3, 5, 8), vacuum=10.)
assert len(atoms) == 120

atoms = atoms.repeat((2, 1, 1))
assert np.allclose(atoms.get_distance(0, 130), 2.88499566724)

atoms = fcc111('Ni', (2, 2, 4), orthogonal=True)
add_adsorbate(atoms, 'H', 1, 'bridge')
add_adsorbate(atoms, Atom('O'), 1, 'fcc')
add_adsorbate(atoms, Atoms('F'), 1, 'hcp')

# The next test ensures that a simple string of multiple atoms cannot be used,
# which should fail with a KeyError that reports the name of the molecule due
# to the string failing to work with Atom().
failed = False
try:
    add_adsorbate(atoms, 'CN', 1, 'ontop')
except KeyError as e:
    failed = True
    assert e.args[0] == 'CN'
assert failed
Example #13
0
    write(name + '.png', slab, show_unit_cell=2, radii=radii[name[:3]],
          scale=10)

for name in surfaces:
    f = getattr(surface, name)
    for kwargs in [{}, {'orthogonal': False}, {'orthogonal': True}]:
        print(name, kwargs)
        try:
            slab = f(symbols[name[:3]], size=(3, 4, 5), vacuum=4, **kwargs)
        except (TypeError, NotImplementedError):
            continue
        try:
            for site in slab.adsorbate_info['sites']:
                if site.endswith('bridge'):
                    h = 1.5
                else:
                    h = 1.2
                surface.add_adsorbate(slab, adsorbates.get(site, 'F'), h, site)
        except KeyError:
            pass
        if kwargs.get('orthogonal', None):
            name += 'o'
        save(name, slab)

for site, symbol in adsorbates.items():
    write('%s-site.png' % site, Atoms(symbol), radii=1.08, scale=10)

fcc111_primitive = fcc111("Ag", (1, 1, 3))
fcc111_root = root_surface(fcc111_primitive, 27)
save("fcc111_root", fcc111_root)
Example #14
0
if not os.path.exists(folder):
    os.mkdir(folder)
os.chdir(folder)
slab = fcc111(symbol, size=(3,3,4), orthogonal=False)
slab.center(vacuum=15.0, axis=2)
c = FixAtoms(indices=[atom.index for atom in slab if atom.symbol == symbol])
slab.set_constraint(c)
write('POSCAR', slab, vasp5=True, direct=True)
os.chdir('..')

folder = '02-h'
if not os.path.exists(folder):
    os.mkdir(folder)
os.chdir(folder)
slab = fcc111(symbol, size=(3,3,4), orthogonal=False)
add_adsorbate(slab, 'H', 1.0, 'fcc')
slab.center(vacuum=15.0, axis=2)
c = FixAtoms(indices=[atom.index for atom in slab if atom.symbol == symbol])
slab.set_constraint(c)
write('POSCAR', slab, vasp5=True, direct=True)
os.chdir('..')

folder = '03-h2o'
if not os.path.exists(folder):
    os.mkdir(folder)
os.chdir(folder)
slab = fcc111(symbol, size=(3,3,4), orthogonal=False)
water = molecule('H2O')
water.rotate(90, 'y')
add_adsorbate(slab, water, 2.0, 'fcc')
slab.center(vacuum=15.0, axis=2)
Example #15
0
                    xc='PBE',
                    gga='RP',
                    lreal=False,
                    ediff=1e-4,
                    ispin=1,
                    nelm=100,
                    encut=400,
                    lwave=False,
                    lcharg=False,
                    nsw=0,
                    kpts=(1, 1, 1))

    # Define initial set of images, can be as few as 1. If 1, make sure to
    slab = fcc100("Cu", size=(3, 3, 3))
    ads = molecule("CO")
    add_adsorbate(slab, ads, 3, offset=(1, 1))
    cons = FixAtoms(indices=[atom.index for atom in slab if (atom.tag == 3)])
    slab.set_constraint(cons)
    slab.center(vacuum=13.0, axis=2)
    slab.set_pbc(True)
    slab.wrap(pbc=True)
    slab.set_calculator(copy.copy(dft_calc))
    sample_energy = slab.get_potential_energy(apply_constraint=False)
    sample_forces = slab.get_forces(apply_constraint=False)
    slab.set_calculator(
        sp(atoms=slab, energy=sample_energy, forces=sample_forces))
    ase.io.write("./slab.traj", slab)

    images = [slab]

    # Define symmetry functions
def test_atoms_formula():
    from ase.build import fcc111, add_adsorbate
    import warnings

    # some random system
    slab = fcc111('Al', size=(2, 2, 3))
    add_adsorbate(slab, 'C', 2.5, 'bridge')
    add_adsorbate(slab, 'C', 3.5, 'bridge')
    add_adsorbate(slab, 'H', 1.5, 'ontop')
    add_adsorbate(slab, 'H', 1.5, 'fcc')
    add_adsorbate(slab, 'C', 0.5, 'bridge')
    add_adsorbate(slab, 'C', 1.5, 'bridge')

    assert slab.get_chemical_formula(mode='hill') == 'C4H2Al12'
    assert slab.get_chemical_formula(mode='metal') == 'Al12C4H2'
    all_str = 'Al' * 12 + 'C' * 2 + 'H' * 2 + 'C' * 2
    assert slab.get_chemical_formula(mode='all') == all_str
    reduce_str = 'Al12C2H2C2'
    assert slab.get_chemical_formula(mode='reduce') == reduce_str

    assert slab.get_chemical_formula(mode='hill', empirical=True) == 'C2HAl6'
    assert slab.get_chemical_formula(mode='metal', empirical=True) == 'Al6C2H'


    # check for warning if empirical formula is not available
    for mode in ('all', 'reduce'):
        with warnings.catch_warnings(record=True) as w:
            # Cause all warnings to always be triggered.
            warnings.simplefilter('always')
            # Trigger a warning.
            slab.get_chemical_formula(mode=mode, empirical=True)
            # Verify some things
            assert len(w) == 1
            assert issubclass(w[-1].category, Warning)
Example #17
0
import sys

from ase.build import molecule, fcc111, add_adsorbate
from ase.optimize import QuasiNewton
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT
from ase.vibrations import Vibrations

sys.path.append("../..")

from __init__ import AnharmonicModes

slab = fcc111('Al', size=(2, 2, 2), vacuum=3.0)

CH3 = molecule('CH3')
add_adsorbate(slab, CH3, 2.5, 'ontop')

constraint = FixAtoms(mask=[a.symbol == 'Al' for a in slab])
slab.set_constraint(constraint)

slab.set_calculator(EMT())

dyn = QuasiNewton(slab)
dyn.run(fmax=0.05)

# Running vibrational analysis
vib = Vibrations(slab, indices=[8, 9, 10, 11])
vib.run()
vib.summary()

print('\n >> Anharmonics <<\n')
Example #18
0
# creates: io1.png io2.png io3.png

from ase import Atoms
from ase.build import fcc111, add_adsorbate
from ase.io import write, read

adsorbate = Atoms('CO')
adsorbate[1].z = 1.1
a = 3.61
slab = fcc111('Cu', (2, 2, 3), a=a, vacuum=7.0)
add_adsorbate(slab, adsorbate, 1.8, 'ontop')

write('io1.png', slab * (3, 3, 1), rotation='10z,-80x')
write('io2.pov', slab * (3, 3, 1), rotation='10z,-80x',
      transparent=False, display=False, run_povray=True)
d = a / 2**0.5
write('io3.pov', slab * (2, 2, 1),
      bbox=(d, 0, 3 * d, d * 3**0.5),
      transparent=False, display=False, run_povray=True)

write('slab.xyz', slab)
a = read('slab.xyz')
a.get_cell()
a.get_pbc()
write('slab.traj', slab)
b = read('slab.traj')
b.get_cell()
b.get_pbc()
Example #19
0
from ase.build import fcc100, add_adsorbate
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT
from ase.dimer import DimerControl, MinModeAtoms, MinModeTranslate

# Set up a small "slab" with an adatoms
atoms = fcc100('Pt', size = (2, 2, 1), vacuum = 10.0)
add_adsorbate(atoms, 'Pt', 1.611, 'hollow')

# Freeze the "slab"
mask = [atom.tag > 0 for atom in atoms]
atoms.set_constraint(FixAtoms(mask = mask))

# Calculate using EMT
atoms.set_calculator(EMT())
relaxed_energy = atoms.get_potential_energy()

# Set up the dimer
d_control = DimerControl(initial_eigenmode_method = 'displacement', \
                         displacement_method = 'vector', logfile = None, \
                         mask = [0, 0, 0, 0, 1])
d_atoms = MinModeAtoms(atoms, d_control)

# Displace the atoms
displacement_vector = [[0.0]*3]*5
displacement_vector[-1][1] = -0.1
d_atoms.displace(displacement_vector = displacement_vector)

# Converge to a saddle point
dim_rlx = MinModeTranslate(d_atoms, trajectory = 'dimer_method.traj', \
                           logfile = None)
Example #20
0
            xc='RPBE',
            kpts=(8, 6, 1),
            eigensolver='cg',
            spinpol=True,
            mixer=MixerSum(nmaxold=5, beta=0.1, weight=100),
            convergence={
                'energy': 100,
                'density': 100,
                'eigenstates': 1.0e-7,
                'bands': -10
            },
            txt=filename + '.txt')

# Import Slab with relaxed CO
slab = fcc111('Pt', size=(1, 2, 3), orthogonal=True)
add_adsorbate(slab, 'C', 2.0, 'ontop')
add_adsorbate(slab, 'O', 3.15, 'ontop')
slab.center(axis=2, vacuum=4.0)

view(slab)

molecule = slab.copy()

del molecule[:-2]

# Molecule
molecule.set_calculator(c_mol)
molecule.get_potential_energy()

# H**o wavefunction
wf_u = [kpt.psit_nG[4] for kpt in c_mol.wfs.kpt_u]
import sys

from ase.build import molecule, fcc111, add_adsorbate
from ase.optimize import QuasiNewton
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT
from ase.vibrations import Vibrations

sys.path.append("../..")

from __init__ import AnharmonicModes

slab = fcc111('Al', size=(2, 2, 2), vacuum=3.0)

CH3 = molecule('CH3')
add_adsorbate(slab, CH3, 3.0, 'ontop')

constraint = FixAtoms(mask=[a.symbol == 'Al' for a in slab])
slab.set_constraint(constraint)

slab.set_calculator(EMT())

dyn = QuasiNewton(slab, trajectory='relax.traj')
dyn.run(fmax=0.01)

vib = Vibrations(slab, indices=[8, 9, 10, 11])
vib.run()
vib.summary()
vib.write_mode()

print('\n >> Anharmonics <<\n')
Example #22
0
def build():
    p = OptionParser(usage='%prog  [options] [ads@]surf [output file]',
                     version='%prog 0.1',
                     description='Example ads/surf: fcc-CO@2x2Ru0001')
    p.add_option('-l', '--layers', type='int',
                 default=4,
                 help='Number of layers.')
    p.add_option('-v', '--vacuum', type='float',
                 default=5.0,
                 help='Vacuum.')
    p.add_option('-x', '--crystal-structure',
                 help='Crystal structure.',
                 choices=['sc', 'fcc', 'bcc', 'hcp'])
    p.add_option('-a', '--lattice-constant', type='float',
                 help='Lattice constant in Angstrom.')
    p.add_option('--c-over-a', type='float',
                 help='c/a ratio.')
    p.add_option('--height', type='float',
                 help='Height of adsorbate over surface.')
    p.add_option('--distance', type='float',
                 help='Distance between adsorbate and nearest surface atoms.')
    p.add_option('-M', '--magnetic-moment', type='float', default=0.0,
                 help='Magnetic moment.')
    p.add_option('-G', '--gui', action='store_true',
                 help="Pop up ASE's GUI.")
    p.add_option('-P', '--python', action='store_true',
                 help="Write Python script.")

    opt, args = p.parse_args()

    if not 1 <= len(args) <= 2:
        p.error("incorrect number of arguments")

    if '@' in args[0]:
        ads, surf = args[0].split('@')
    else:
        ads = None
        surf = args[0]

    if surf[0].isdigit():
        i1 = surf.index('x')
        n = int(surf[:i1])
        i2 = i1 + 1
        while surf[i2].isdigit():
            i2 += 1
        m = int(surf[i1 + 1:i2])
        surf = surf[i2:]
    else:
        n = 1
        m = 1

    if surf[-1].isdigit():
        if surf[1].isdigit():
            face = surf[1:]
            surf = surf[0]
        else:
            face = surf[2:]
            surf = surf[:2]
    else:
        face = None

    Z = atomic_numbers[surf]
    state = reference_states[Z]

    if opt.crystal_structure:
        x = opt.crystal_structure
    else:
        x = state['symmetry']
    
    if opt.lattice_constant:
        a = opt.lattice_constant
    else:
        a = estimate_lattice_constant(surf, x, opt.c_over_a)

    script = ['from ase.build import ',
              'vac = %r' % opt.vacuum,
              'a = %r' % a]
    
    if x == 'fcc':
        if face is None:
            face = '111'
        slab = fcc111(surf, (n, m, opt.layers), a, opt.vacuum)
        script[0] += 'fcc111'
        script += ['slab = fcc111(%r, (%d, %d, %d), a, vac)' %
                   (surf, n, m, opt.layers)]
        r = a / np.sqrt(2) / 2
    elif x == 'bcc':
        if face is None:
            face = '110'
        if face == '110':
            slab = bcc110(surf, (n, m, opt.layers), a, opt.vacuum)
        elif face == '100':
            slab = bcc100(surf, (n, m, opt.layers), a, opt.vacuum)
        script[0] += 'bcc' + face
        script += ['slab = bcc%s(%r, (%d, %d, %d), a, vac)' %
                   (face, surf, n, m, opt.layers)]
        r = a * np.sqrt(3) / 4
    elif x == 'hcp':
        if face is None:
            face = '0001'
        if opt.c_over_a is None:
            c = np.sqrt(8 / 3.0) * a
        else:
            c = opt.c_over_a * a
        slab = hcp0001(surf, (n, m, opt.layers), a, c, opt.vacuum)
        script[0] += 'hcp0001'
        script += ['c = %r * a' % (c / a),
                   'slab = hcp0001(%r, (%d, %d, %d), a, c, vac)' %
                   (surf, n, m, opt.layers)]
        r = a / 2
    elif x == 'diamond':
        if face is None:
            face = '111'
        slab = diamond111(surf, (n, m, opt.layers), a, opt.vacuum)
        script[0] += 'diamond111'
        script += ['slab = diamond111(%r, (%d, %d, %d), a, vac)' %
                   (surf, n, m, opt.layers)]
        r = a * np.sqrt(3) / 8
    else:
        raise NotImplementedError

    magmom = opt.magnetic_moment
    if magmom is None:
        magmom = {'Ni': 0.6, 'Co': 1.2, 'Fe': 2.3}.get(surf, 0.0)
    slab.set_initial_magnetic_moments([magmom] * len(slab))
    if magmom != 0:
        script += ['slab.set_initial_magnetic_moments([%r] * len(slab))' %
                   magmom]
    
    slab.pbc = 1
    script += ['slab.pbc = True']
    
    name = '%dx%d%s%s' % (n, m, surf, face)

    if ads:
        site = 'ontop'
        if '-' in ads:
            site, ads = ads.split('-')

        name = site + '-' + ads + '@' + name
        symbols = string2symbols(ads)
        nads = len(symbols)
        if nads == 1:
            script[:0] = ['from ase import Atoms']
            script += ['ads = Atoms(%r)' % ads]
            ads = Atoms(ads)
        else:
            script[:0] = ['from ase.build import molecule']
            script += ['ads = molecule(%r)' % ads]
            ads = molecule(ads)

        add_adsorbate(slab, ads, 0.0, site)

        d = opt.distance
        if d is None:
            d = r + covalent_radii[ads[0].number] / 2
        
        h = opt.height
        if h is None:
            R = slab.positions
            y = ((R[:-nads] - R[-nads])**2).sum(1).min()**0.5
            h = (d**2 - y**2)**0.5
        else:
            assert opt.distance is None
        
        slab.positions[-nads:, 2] += h

        script[1] += ', add_adsorbate'
        script += ['add_adsorbate(slab, ads, %r, %r)' % (h, site)]
        
    if len(args) == 2:
        write(args[1], slab)
        script[1:1] = ['from ase.io import write']
        script += ['write(%r, slab)' % args[1]]
    elif not opt.gui:
        write(name + '.traj', slab)
        script[1:1] = ['from ase.io import write']
        script += ['write(%r, slab)' % (name + '.traj')]
        
    if opt.gui:
        view(slab)
        script[1:1] = ['from ase.visualize import view']
        script += ['view(slab)']

    if opt.python:
        print('\n'.join(script))
Example #23
0
    write(name + '.png', slab, show_unit_cell=2, radii=radii[name[:3]],
          scale=10)

for name in surfaces:
    f = getattr(surface, name)
    for kwargs in [{}, {'orthogonal': False}, {'orthogonal': True}]:
        print(name, kwargs)
        try:
            slab = f(symbols[name[:3]], size=(3, 4, 5), vacuum=4, **kwargs)
        except (TypeError, NotImplementedError):
            continue
        try:
            for site in slab.info['adsorbate_info']['sites']:
                if site.endswith('bridge'):
                    h = 1.5
                else:
                    h = 1.2
                surface.add_adsorbate(slab, adsorbates.get(site, 'F'), h, site)
        except KeyError:
            pass
        if kwargs.get('orthogonal', None):
            name += 'o'
        save(name, slab)

for site, symbol in adsorbates.items():
    write('%s-site.png' % site, Atoms(symbol), radii=1.08, scale=10)

fcc111_primitive = fcc111("Ag", (1, 1, 3))
fcc111_root = root_surface(fcc111_primitive, 27)
save("fcc111_root", fcc111_root)
Example #24
0
from ase import Atom, Atoms
from ase.build import bulk, fcc100, add_adsorbate, add_vacuum
from ase.calculators.vasp import Vasp
from ase.calculators.kim.kim import KIM
from ase.calculators.qmmm import ForceQMMM, RescaledCalculator
from ase.constraints import StrainFilter
from ase.optimize import LBFGS
from ase.visualize import view

atoms = bulk("Pd", "fcc", a=3.5, cubic=True)
atoms.calc = KIM("MEAM_LAMMPS_JeongParkDo_2018_PdMo__MO_356501945107_000")
opt = LBFGS(StrainFilter(atoms), logfile=None)
opt.run(0.03, steps=30)
length = atoms.cell.cellpar()[0]

atoms = fcc100("Pd", (2,2,5), a=length, vacuum=10, periodic=True)
add_adsorbate(atoms, Atoms([Atom("Mo")]), 1.2)


qm_mask = [len(atoms)-1, len(atoms)-2]
qm_calc = Vasp(directory="./qmmm")
mm_calc = KIM("MEAM_LAMMPS_JeongParkDo_2018_PdMo__MO_356501945107_000")
mm_calc = RescaledCalculator(mm_calc, 1, 1, 1, 1)
qmmm = ForceQMMM(atoms, qm_mask, qm_calc, mm_calc, buffer_width=3)
qmmm.initialize_qm_buffer_mask(atoms)
atoms.pbc=True
atoms.calc = qmmm

print(atoms.get_forces())

    def get_site(self, plot_voronoi_sites=False):
        """Return primaty (top, bridge, hollow, 4fold) and
        secondary (chemical elements in close environment) site designation"""

        if self.dissociated:
            return 'dissociated', ''

        if self.is_desorbed():
            return 'desorbed', ''

        if self.is_subsurface():
            return 'subsurface', ''

        C0 = self.B[-1:] * (3, 3, 1)
        ads_pos = C0.positions[4]

        C = self.B.copy() * (3, 3, 1)

        # Use top layer and adsorbate to map sites
        Dict = self.get_site_dict(ads_pos[:2])
        primary_site = None
        dis = self.B.get_cell()[0][0]
        Kind = None

        values = [
            np.linalg.norm(ads_pos[:2] - d['pos'][:2])
            for d in list(Dict.values())
        ]
        if len(values) == 0:
            return 'N/A', ''
        idx = np.argmin(values)

        dis = values[idx]
        kind = list(Dict.keys())[idx]
        self.ipos = Dict[kind]['ipos']
        primary_site = kind.split('_')[0]

        if plot_voronoi_sites:  # View sampled sites
            X = self.B.copy()
            X = X * (3, 3, 1)
            del X[-1]
            for pos in Dict.values():
                add_adsorbate(X, 'X', position=(pos['pos'][:2]), height=0.2)
            view(X)

        if primary_site == 'top':
            site_type = Dict[kind]['sym']

        if primary_site == 'bridge':
            site_type = Dict[kind]['sym'] + '|' + self.get_under_bridge()

        elif primary_site == 'hollow':
            site_type = Dict[kind]['sym'] + '|' + self.get_under_hollow()

        elif primary_site == '4fold':
            site_type = Dict[kind]['sym']

        if dis > 0.5:
            primary_site += '-tilt'
            print('Warning: A strong site match could not be found!')
            print('  structure labeled as {}'.format(primary_site))

        return primary_site, site_type
Example #26
0
    arrangements are established automatically. Predict outcomes
    of symmetry operations and form a sequence before attempting
    the operations to reduce computational time.
'''
from carmm.examples.data.model_gen import get_example_slab
from ase.build import molecule, add_adsorbate
from ase import Atom
from carmm.analyse.bonds import compare_structures
from carmm.build.neb import switch_indices, switch_all_indices

# Work case for automatic neb setup
# initial geometry
initial = get_example_slab()
ad1 = molecule("CH3O")
ad1.rotate(-90, 'x')
add_adsorbate(initial, ad1, height=2.0)
bridge = initial[12].position + (
    (initial[13].position - initial[12].position) / 2)
ad2 = Atom("H", position=bridge)
initial += ad2

# final geometry
final = get_example_slab()
bridge2 = initial[13].position + (
    (initial[16].position - initial[13].position) / 2)
ad3 = molecule("CH3OH")
ad3.rotate(60, 'x')
add_adsorbate(final, ad3, 3.0, position=(bridge2[0], bridge[1]))

# scramble indices to ensure compare_structures works
final = switch_indices(final, 18, 19)
Example #27
0
slab.set_calculator(calc1)
dyn = QuasiNewton(slab, trajectory="slab.traj")
dyn.run(fmax=0.05)
e_slab = slab.get_potential_energy()
os.system("rm dftb_in.hsd")
molecule = Atoms("2N", positions=[(0.0, 0.0, 0.0), (0.0, 0.0, d)])
calc2 = Dftb(
    label="n2", Hamiltonian_MaxAngularMomentum_="", Hamiltonian_MaxAngularMomentum_N='"p"', Hamiltonian_SCC="YES"
)
molecule.set_calculator(calc2)
dyn = QuasiNewton(molecule, trajectory="n2.traj")
dyn.run(fmax=0.05)
e_N2 = molecule.get_potential_energy()

slab2 = slab
add_adsorbate(slab2, molecule, h, "ontop")
constraint = FixAtoms(mask=[a.symbol != "N" for a in slab2])
slab2.set_constraint(constraint)
calc3 = Dftb(
    label="slab2",
    kpts=[2, 2, 1],
    Hamiltonian_MaxAngularMomentum_="",
    Hamiltonian_MaxAngularMomentum_N='"p"',
    Hamiltonian_MaxAngularMomentum_Ni='"d"',
    Hamiltonian_SCC="YES",
)
slab2.set_calculator(calc3)
dyn = QuasiNewton(slab2, trajectory="slab2.traj")
dyn.run(fmax=0.05)

adsorption_energy = e_slab + e_N2 - slab2.get_potential_energy()
Example #28
0
label = 'test' # for integration with AMPTorch module
forcetraining = True # for integration with AMPTorch module. 
# if forcetraining is set to False, it will drop the derivatives of fingerprints. 
cores = 1

# Define Gs variables for fps. 
Gs = {}
Gs["G2_etas"] = np.logspace(np.log10(0.05), np.log10(5.0), num=10)
Gs["G2_rs_s"] = [0] * 10
Gs["G4_etas"] = np.logspace(np.log10(0.005), np.log10(0.5), num=4)
Gs["G4_zetas"] = [1.0]
Gs["G4_gammas"] = [+1.0, -1.0]
Gs["cutoff"] = 6.5

# Generate ase.Atoms objects. 
slab = fcc111('Al', size=(2, 2, 4))
add_adsorbate(slab, 'H', 1.5, 'ontop')
slab.center(vacuum=10.0, axis=2)

# Define elements to calculate fps for
elements = ['Al', 'H']

# Step 1: obtain output from cffi as cffi_out
traj, calculated, cffi_out = make_simple_nn_fps(slab, Gs, elements=elements, label=label) 

# Step 2: reorganize into AMP input format
fps, fp_primes = convert_simple_nn_fps(traj, Gs, cffi_out, forcetraining, cores, save=False)

# Print the output if needed. 
print(fps)
print(fp_primes)
Example #29
0
middle = atoms.positions[upper_layer_idx, :2].max(axis=0) / 2

# the dissociating oxygen... fake some dissociation curve
gas_dist = 1.1
max_height = 8.
min_height = 1.
max_dist = 6

# running index for the bonds
index = len(atoms)

for i, x in enumerate(np.linspace(0, 1.5, 6)):
    height = (max_height - min_height) * np.exp(-2 * x) + min_height
    d = np.exp(1.5 * x) / np.exp(1.5**2) * max_dist + gas_dist
    pos = middle + [0, d / 2]
    add_adsorbate(atoms, 'O', height=height, position=pos)
    pos = middle - [0, d / 2]
    add_adsorbate(atoms, 'O', height=height, position=pos)
    transmittances += [x / 2] * 2

    # we want bonds for the first two molecules
    if i < 2:
        bonded_atoms.append([len(atoms) - 1, len(atoms) - 2])

textures = ['ase3' for a in atoms]

# add some semi-transparent bath (only in x/y direction for this example)
cell = atoms.cell

idx = [a.index for a in atoms if a.symbol == 'Pt']
Example #30
0
# creates: io1.png io2.png io3.png

from ase import Atoms
from ase.build import fcc111, add_adsorbate
from ase.io import write, read

adsorbate = Atoms('CO')
adsorbate[1].z = 1.1
a = 3.61
slab = fcc111('Cu', (2, 2, 3), a=a, vacuum=7.0)
add_adsorbate(slab, adsorbate, 1.8, 'ontop')

write('io1.png', slab * (3, 3, 1), rotation='10z,-80x')
write('io2.pov',
      slab * (3, 3, 1),
      rotation='10z,-80x',
      transparent=False,
      display=False,
      run_povray=True)
d = a / 2**0.5
write('io3.pov',
      slab * (2, 2, 1),
      bbox=(d, 0, 3 * d, d * 3**0.5),
      transparent=False,
      display=False,
      run_povray=True)

write('slab.xyz', slab)
a = read('slab.xyz')
a.get_cell()
a.get_pbc()
Example #31
0
from ase.build import fcc211, add_adsorbate
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT
from ase.optimize import QuasiNewton
from ase.neb import NEBTools
from ase.autoneb import AutoNEB

# 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.set_calculator(EMT())

# Initial state:
qn = QuasiNewton(slab, trajectory='neb000.traj')
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
import sys

from ase.build import molecule, fcc111, add_adsorbate
from ase.optimize import QuasiNewton
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT
from ase.vibrations import Vibrations

sys.path.append("..")

from __init__ import AnharmonicModes

slab = fcc111('Au', size=(2, 2, 2), vacuum=4.0)
H = molecule('H')
add_adsorbate(slab, H, 3.0, 'ontop')

constraint = FixAtoms(mask=[a.symbol == 'Au' for a in slab])
slab.set_constraint(constraint)

slab.set_calculator(EMT())

QuasiNewton(slab).run(fmax=0.001)

vib = Vibrations(slab, indices=[8])
vib.run()
vib.summary()
vib.clean()

AM = AnharmonicModes(
    vibrations_object=vib,
    settings={
Example #33
0
from ase.build import fcc100, add_adsorbate
from ase.constraints import FixAtoms, FixedPlane
from ase.calculators.emt import EMT
from ase.optimize import QuasiNewton

# 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)

# Make sure the structure is correct:
#from ase.visualize import view
#view(slab)

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

# Constrain the last atom (Au atom) to move only in the yz-plane:
plane = FixedPlane(-1, (1, 0, 0))

slab.set_constraint([fixlayers, plane])

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

for i in range(5):
    qn = QuasiNewton(slab, trajectory='mep%d.traj' % i)
    qn.run(fmax=0.05)
Example #34
0
def add_graphene_layer(
    slab,
    graphene_units=1,
    graph_surf_d=3.0,
    graph_bond_d_real=1.4237,
):
    """
    Add graphene layer above surface of hexagonal unit cell slab.

    Args:
        slab:
        graphene_units:
        graph_surf_d:
        graph_bond_d_real:
    """
    #| - add_graphene_layer
    slab = copy.deepcopy(slab)

    # num_graph_units = graphene_units + 1
    graphene_units = int(graphene_units)

    num_graph_units = int(graphene_units)
    ngu = num_graph_units

    num_graph_bond_lengths = (2. + 1.) * ngu

    v1 = slab.cell[0]
    v2 = slab.cell[1]

    angle = angle_between(v1, v2)
    angle = math.degrees(angle)
    # print("Angle between lattice vectors: " + str(angle))

    mag1 = np.linalg.norm(v1)
    mag2 = np.linalg.norm(v2)

    assert round(mag1) == round(mag2)

    graph_bond_d = mag1 / num_graph_bond_lengths

    xy_cell = slab.cell[0:2, 0:2]  # x and y components of unit cell
    x_unit_v = xy_cell[0]
    y_unit_v = xy_cell[1]

    x_unit_v = x_unit_v / np.linalg.norm(x_unit_v)
    y_unit_v = y_unit_v / np.linalg.norm(y_unit_v)

    #| - STRAIN
    tmp = mag1 / num_graph_bond_lengths
    strain = 100. * (graph_bond_d_real - tmp) / graph_bond_d_real
    print("Strain: " + str(strain))
    #__|

    patt_cnt_x = 0
    patt_cnt_y = 0
    C_pos_lst = []
    for y_ind in range(graphene_units * 3):
        patt_cnt_x = patt_cnt_y
        for x_ind in range(graphene_units * 3):

            if patt_cnt_x == 0 or patt_cnt_x == 1:

                pos_x = x_ind * graph_bond_d * x_unit_v
                pos_y = y_ind * graph_bond_d * y_unit_v

                pos_i = np.array(pos_x) + np.array(pos_y)
                pos_i = np.append(pos_i, 0.)

                C_pos_lst.append(pos_i)
                # atom_cent = (origin[0] + x_ind * graph_bond_d
                # - graph_bond_d * y_ind * y_unit_v[0], origin[1] + y_ind
                # * graph_bond_d)

                add_adsorbate(
                    slab,
                    "C",
                    graph_surf_d,
                    position=(pos_i[0], pos_i[1]),
                )

                patt_cnt_x += 1

            elif patt_cnt_x == 2:
                patt_cnt_x = 0

        if patt_cnt_y == 0:
            patt_cnt_y = 2
            continue

        if patt_cnt_y == 2:
            patt_cnt_y = 1
            continue

        elif patt_cnt_y == 1:
            patt_cnt_y = 0
            continue

    C_pos_lst = np.array(C_pos_lst)

    return (slab)
Example #35
0
import sys

from ase.build import molecule, fcc111, add_adsorbate
from ase.optimize import QuasiNewton
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT
from ase.vibrations import Vibrations

sys.path.append("..")

from __init__ import AnharmonicModes

slab = fcc111('Au', size=(2, 2, 2), vacuum=4.0)
H = molecule('H')
add_adsorbate(slab, H, 3.0, 'ontop')

constraint = FixAtoms(mask=[a.symbol == 'Au' for a in slab])
slab.set_constraint(constraint)

slab.set_calculator(EMT())

QuasiNewton(slab).run(fmax=0.001)

vib = Vibrations(slab, indices=[8])
vib.run()
vib.summary()
vib.clean()

AM = AnharmonicModes(vibrations_object=vib, settings={
    'plot_mode': True,
})
import sys
sys.path.append("..")

from ase.build import molecule, fcc111, add_adsorbate
from ase.optimize import QuasiNewton
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT
from ase.vibrations import Vibrations

from __init__ import AnharmonicModes

slab = fcc111('Al', size=(2, 2, 2), vacuum=3.0)
CH3 = molecule('CH3')
add_adsorbate(slab, CH3, 2.5, 'ontop')

constraint = FixAtoms(mask=[a.symbol == 'Al' for a in slab])
slab.set_constraint(constraint)
slab.set_calculator(EMT())

dyn = QuasiNewton(slab, logfile='/dev/null')
dyn.run(fmax=0.05)

vib = Vibrations(slab, indices=[8, 9, 10, 11])
vib.run()
vib.summary(log='/dev/null')
vib.clean()

AM = AnharmonicModes(vibrations_object=vib)
rot_mode = AM.define_rotation(
    basepos=[0., 0., -1.],
    branch=[9, 10, 11],
Example #37
0
from ase.build import fcc100, add_adsorbate
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT
from ase.optimize import QuasiNewton

# 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)

# Make sure the structure is correct:
#view(slab)

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

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

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

# Final state:
slab[-1].x += slab.get_cell()[0, 0] / 2
qn = QuasiNewton(slab, trajectory='final.traj')
qn.run(fmax=0.05)
from ase.build import surface, fcc100, add_adsorbate
from ase.constraints import FixAtoms
from ase.io import read
import numpy as np
from ase.visualize import view

#bulk = read('../bulk/converged_bulk.traj')
#a=3.89
#a = np.linalg.norm(bulk.cell[0])

vac = 6

#atoms = fcc100('Pd', (2,2,4), a=a, vacuum=10)
atoms = fcc100('Pd', (2, 2, {l}), vacuum=vac)
nitrate = read('nitrate.xyz')
add_adsorbate(atoms, nitrate, 1.5, 'ontop')
c = FixAtoms(mask=[a.z < vac + 2 for a in atoms])
atoms.set_constraint(c)
#atoms *= (2,2,1)

atoms.write('structure.traj')
Example #39
0
from ase.build import fcc211, add_adsorbate
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT
from ase.optimize import QuasiNewton
from ase.neb import NEBTools
from ase.autoneb import AutoNEB

# 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.set_calculator(EMT())

# Initial state:
qn = QuasiNewton(slab, trajectory='neb000.traj')
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
# import calculator and set potential
from ase.calculators.eam import EAM
import os
pot_file = os.environ.get('LAMMPS_POTENTIALS') + '/Al_zhou.eam.alloy'
zhou = EAM(potential=pot_file)

#create structure as FCC surface with addsorbate
from ase.build import fcc111, add_adsorbate
slab = fcc111('Al', size=(2, 2, 3))
add_adsorbate(slab, 'Al', 2, 'hcp')
slab.center(vacuum=5.0, axis=2)

#view and set calculator
from ase.visualize import view
view(slab, viewer='x3d')
slab.set_calculator(zhou)
slab.get_potential_energy()
print(slab.get_calculator())
print(slab.get_potential_energy())

#relax structure
from ase.optimize import BFGS
dyn = BFGS(slab)
dyn.run(fmax=0.0001)

#make second endpoint structure, add adatom and relax
slab_2 = fcc111('Al', size=(2, 2, 3))
add_adsorbate(slab_2, 'Al', 2, 'fcc')
slab_2.center(vacuum=5.0, axis=2)
slab_2.set_calculator(EAM(potential=pot_file))
Example #41
0
from ase import Atoms
from ase.calculators.emt import EMT
from ase.constraints import FixAtoms
from ase.optimize import QuasiNewton
from ase.build import fcc111, add_adsorbate

h = 1.85
d = 1.10

slab = fcc111('Cu', size=(4, 4, 2), vacuum=10.0)

slab.set_calculator(EMT())
e_slab = slab.get_potential_energy()

molecule = Atoms('2N', positions=[(0., 0., 0.), (0., 0., d)])
molecule.set_calculator(EMT())
e_N2 = molecule.get_potential_energy()

add_adsorbate(slab, molecule, h, 'ontop')
constraint = FixAtoms(mask=[a.symbol != 'N' for a in slab])
slab.set_constraint(constraint)
dyn = QuasiNewton(slab, trajectory='N2Cu.traj')
dyn.run(fmax=0.05)

print('Adsorption energy:', e_slab + e_N2 - slab.get_potential_energy())
        for st in sites:

            ads_slab = slab.copy()
            par, chi = ads.split('-')
            print('Now working on system with the following spec:')
            print('metal: {} ads: {}, site: {}\n'.format(i, ads, st))
            h_z = get_height(i, par, st)
            #add_adsorbate(ads_slab, par, h_z, st)
            #if chi == 'H' and not par == 'S':
            #    add_adsorbate(ads_slab, chi, h_z+1.05, st)
            #elif chi == 'H' and par == 'S':
            #    add_adsorbate(ads_slab, chi, h_z+1.30, st)

            if ads == 'C-H':
                molecule = Atoms('CH', positions=[(0., 0., 0.), (0., 0., 1.1)])
                add_adsorbate(ads_slab, molecule, h_z, st)

            elif ads == 'O-H':
                molecule = Atoms('OH',
                                 positions=[(0., 0., 0.), (0., 0., 0.95)])
                add_adsorbate(ads_slab, molecule, h_z, st)

            elif ads == 'N-H':
                molecule = Atoms('NH',
                                 positions=[(0., 0., 0.), (0., 0., 1.05)])
                add_adsorbate(ads_slab, molecule, h_z, st)

            elif ads == 'S-H':
                molecule = Atoms('SH',
                                 positions=[(0., 0., 0.), (0., 0., 1.25)])
                add_adsorbate(ads_slab, molecule, h_z, st)
import sys

from ase.build import molecule, fcc111, add_adsorbate
from ase.optimize import QuasiNewton
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT
from ase.vibrations import Vibrations

sys.path.append("../..")

from __init__ import AnharmonicModes

slab = fcc111('Au', size=(2, 2, 2), vacuum=4.0)
H = molecule('H')
add_adsorbate(slab, H, 3.0, 'bridge')

constraint = FixAtoms(mask=[a.symbol == 'Au' for a in slab])
slab.set_constraint(constraint)

slab.set_calculator(EMT())

dyn = QuasiNewton(slab)
dyn.run(fmax=0.01)

# Running vibrational analysis

vib = Vibrations(slab, indices=[8])
vib.run()
vib.summary()

# Here the number of initial sampling points are increased such
            INCAR_bare['MAGMOM'][x_list[0]:(x_list[-1]+1)] = [-5.0, -5.0, 5.0, -5.0, 5.0, 5.0, -5.0, 5.0, 5.0, -5.0, -5.0, 5.0]  # activate if AFM
            """
            INCAR_bare.write_file(file_path + 'INCAR')
            KPOINTS.write_file(file_path + '/KPOINTS')
            POTCAR_bare.write_file(file_path + 'POTCAR')
            write_vasp(file_path + 'POSCAR', slab)
    
            # jobscript copy
            job_file = os.getcwd() + '/jobscript_vasp.sh'
            shutil.copy(job_file, file_path)
    
            ###### adsorbate modeling ######
            for ads_idx in range(len(adsorbates)):
                INCAR = Incar.from_file(file_path + 'INCAR')
                createFolder(file_path + '/' + adsorbate_names[ads_idx])                # Put AFM, def in the path if required
                add_adsorbate(slab = slab, adsorbate = adsorbates[ads_idx], height = 2.0,
                              position = (slab[metal_index].position[0], slab[metal_index].position[0]))
            
                elements = []
                for element in slab.get_chemical_symbols():
                    if element not in elements:
                        elements.append(element)

                for n_atom_ads in range(len(adsorbates[ads_idx])):
                    INCAR['MAGMOM'].append(0.6)
        
                mag_dic = dict(zip(slab.get_chemical_symbols(), INCAR['MAGMOM']))
        
                INCAR['MAGMOM'] = [mag_dic[x] for x in sorted(slab.get_chemical_symbols())]  
        
                """
                AFM_adsorbate modeling
Example #45
0
try:
    opts.size = tuple(map(int, opts.size.strip().split(',')))
except:
    print("Error parsing size as three comma-separated integers")
    sys.exit()

slab=fcc111(opts.electrode, opts.size)
# Needed to prevent multilayer formation
slab.info['adsorbate_info']['top layer atom index'] = len(slab.positions)-1
xyz = Parser(opts,opts.infile[0])
xyz.parseZmatrix()

if opts.tilt > 0:
    xyz.zmat.rotateAboutAxis(opts.tiltaxis,opts.tilt)

mol = xyz.getZmat()
print(mol)
for i in range(1,opts.size[0]-1,2):
    add_adsorbate(slab,mol,opts.height,position,offset=[0,i],mol_index=0)
    firstmol = len(slab.positions)
    for n in range(2,opts.size[0]-1,2):
        add_adsorbate(slab,mol,opts.height,position,offset=[n,i],mol_index=0)
if opts.topcontact:
    top = fcc111(opts.electrode, opts.size)
    del(slab.info['adsorbate_info']['top layer atom index'])
    #slab.info['adsorbate_info']['top layer atom index'] = firstmol
    add_adsorbate(slab,top,opts.height,position,offset=[0,0],mol_index=0)

write(opts.infile[0][:-4]+'_SAM.png',slab,rotation='80x,180z')
write(opts.infile[0][:-4]+'_SAM.xyz',slab)
def test_thermochemistry():
    """Tests of the major methods (HarmonicThermo, IdealGasThermo,
    CrystalThermo) from the thermochemistry module."""

    # Ideal gas thermo.
    atoms = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT())
    QuasiNewton(atoms).run(fmax=0.01)
    energy = atoms.get_potential_energy()
    vib = Vibrations(atoms, name='idealgasthermo-vib')
    vib.run()
    vib_energies = vib.get_energies()

    thermo = IdealGasThermo(vib_energies=vib_energies,
                            geometry='linear',
                            atoms=atoms,
                            symmetrynumber=2,
                            spin=0,
                            potentialenergy=energy)
    thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325.)

    # Harmonic thermo.

    atoms = fcc100('Cu', (2, 2, 2), vacuum=10.)
    atoms.set_calculator(EMT())
    add_adsorbate(atoms, 'Pt', 1.5, 'hollow')
    atoms.set_constraint(
        FixAtoms(indices=[atom.index for atom in atoms
                          if atom.symbol == 'Cu']))
    QuasiNewton(atoms).run(fmax=0.01)
    vib = Vibrations(
        atoms,
        name='harmonicthermo-vib',
        indices=[atom.index for atom in atoms if atom.symbol != 'Cu'])
    vib.run()
    vib.summary()
    vib_energies = vib.get_energies()

    thermo = HarmonicThermo(vib_energies=vib_energies,
                            potentialenergy=atoms.get_potential_energy())
    thermo.get_helmholtz_energy(temperature=298.15)

    # Crystal thermo.
    atoms = bulk('Al', 'fcc', a=4.05)
    calc = EMT()
    atoms.set_calculator(calc)
    energy = atoms.get_potential_energy()

    # Phonon calculator
    N = 7
    ph = Phonons(atoms, calc, supercell=(N, N, N), delta=0.05)
    ph.run()

    ph.read(acoustic=True)
    phonon_energies, phonon_DOS = ph.dos(kpts=(4, 4, 4), npts=30, delta=5e-4)

    thermo = CrystalThermo(phonon_energies=phonon_energies,
                           phonon_DOS=phonon_DOS,
                           potentialenergy=energy,
                           formula_units=4)
    thermo.get_helmholtz_energy(temperature=298.15)

    # Hindered translator / rotor.
    # (Taken directly from the example given in the documentation.)

    vibs = np.array([
        3049.060670, 3040.796863, 3001.661338, 2997.961647, 2866.153162,
        2750.855460, 1436.792655, 1431.413595, 1415.952186, 1395.726300,
        1358.412432, 1335.922737, 1167.009954, 1142.126116, 1013.918680,
        803.400098, 783.026031, 310.448278, 136.112935, 112.939853, 103.926392,
        77.262869, 60.278004, 25.825447
    ])
    vib_energies = vibs / 8065.54429  # Convert to eV from cm^-1.
    trans_barrier_energy = 0.049313  # eV
    rot_barrier_energy = 0.017675  # eV
    sitedensity = 1.5e15  # cm^-2
    rotationalminima = 6
    symmetrynumber = 1
    mass = 30.07  # amu
    inertia = 73.149  # amu Ang^-2

    thermo = HinderedThermo(vib_energies=vib_energies,
                            trans_barrier_energy=trans_barrier_energy,
                            rot_barrier_energy=rot_barrier_energy,
                            sitedensity=sitedensity,
                            rotationalminima=rotationalminima,
                            symmetrynumber=symmetrynumber,
                            mass=mass,
                            inertia=inertia)

    helmholtz = thermo.get_helmholtz_energy(temperature=298.15)
    target = 1.593  # Taken from documentation example.
    assert (helmholtz - target) < 0.001
Example #47
0
from ase import Atoms
from ase.calculators.emt import EMT
from ase.constraints import FixBondLengths
from ase.optimize import BFGS
from ase.build import fcc111, add_adsorbate

for wrap in [False, True]:
    zpos = cos(134.3 / 2.0 * pi / 180.0) * 1.197
    xpos = sin(134.3 / 2.0 * pi / 180.0) * 1.19
    co2 = Atoms('COO',
                positions=[(-xpos + 1.2, 0, -zpos), (-xpos + 1.2, -1.1, -zpos),
                           (-xpos + 1.2, 1.1, -zpos)])

    slab = fcc111('Au', size=(2, 2, 4), vacuum=2 * 5, orthogonal=True)
    slab.center()
    add_adsorbate(slab, co2, 1.5, 'bridge')
    slab.set_pbc((True, True, False))
    d0 = co2.get_distance(-3, -2)
    d1 = co2.get_distance(-3, -1)

    calc = EMT()
    slab.set_calculator(calc)
    if wrap:
        # Remap into the cell so bond is actually wrapped:
        slab.set_scaled_positions(slab.get_scaled_positions() % 1.0)
    constraint = FixBondLengths([[-3, -2], [-3, -1]])
    slab.set_constraint(constraint)
    dyn = BFGS(slab, trajectory='relax_%d.traj' % wrap)
    dyn.run(fmax=0.05)
    assert abs(slab.get_distance(-3, -2, mic=1) - d0) < 1e-9
    assert abs(slab.get_distance(-3, -1, mic=1) - d1) < 1e-9
Example #48
0
from ase.build import fcc111, add_adsorbate
from ase.atoms import Atoms
from ase.build import bulk
from ase.visualize import view
from blase.tools import get_bondpairs, write_blender

bulk = bulk('Pt')
bulk.write('pt.in')
adsorbate = Atoms('CO')
adsorbate[1].z = 1.1
atoms = fcc111('Pt', (2, 2, 3), a=3.96, vacuum=7.0)
add_adsorbate(atoms, adsorbate, 1.8, 'ontop')
# atoms = atoms*[5, 5, 1]
# view(atoms)

kwargs = {'show_unit_cell': 0, 
          'radii': 0.6,
          'bond_cutoff': 1.0,
          'display': True,
          'make_real': True,
          'outfile': 'figs/pt-111-co',
          }
write_blender(atoms, **kwargs)

Example #49
0
from ase.optimize import QuasiNewton

from ase.io import write

# Find the initial and final states for the reaction.

# Set up a (4 x 4) two layer slab of Cu:
slab = fcc111('Cu',size=(4,4,2))
slab.set_pbc((1,1,0))

# Initial state.
# Add the N2 molecule oriented at 60 degrees:
d = 1.10 # N2 bond length
N2mol = Atoms('N2',positions=[[0.0,0.0,0.0],[0.5*3**0.5*d,0.5*d,0.0]])
add_adsorbate(slab,N2mol,height=1.0,position='fcc')

# Use the EMT calculator for the forces and energies:
slab.set_calculator(EMT())

# We don't want to worry about the Cu degrees of freedom,
# so fix these atoms:

mask = [atom.symbol == 'Cu' for atom in slab]
slab.set_constraint(FixAtoms(mask=mask))

# Relax the structure
relax = QuasiNewton(slab)
relax.run(fmax=0.05)
print('initial state:', slab.get_potential_energy())
write('N2.traj', slab)