Exemplo n.º 1
0
def asesurf2xxyz(symb, lattice, index, size=(1,1,3), vac=15.0, orthogonal=0):
    """
    An interface function for ase.lattice.surface

    Usage:
    >>> atoms = asesurf2xxyz(symb, lattice, index, size, 
                             vac=15.0, orthogonal=0))

    Parameters:
    symb: atomic symbol
    lattice: 'fcc', 'bcc', or 'hcp0001'
    index: '100', '111' or '110' (if lattice is 'hcp0001', this will not work.)
    size: the number of atoms per each vector
    
    Optional Parameters:
    vac (default: 15.0 angstron): the thickness of space normal to the surface
    orthogonal (default: False) : if True, two lateral cell vectors will be 
    orthogonal.

    Example:
    >>> Fe_100_1x1 = asesurf2xxyz('Fe', 'bcc', '100', (1,1,2))
    >>> Au_111_2x2 = asesurf2xxyz('Au', 'fcc', '111', (1,1,3))
    """
    if lattice == 'fcc':
        if index   == '100': at_ase = AS.fcc100(symb, size, vacuum=vac)
        elif index == '111': at_ase = AS.fcc111(symb, size,
                                                orthogonal=orthogonal,
                                                vacuum=vac)
        elif index == '110': at_ase = AS.fcc110(symb, size, vacuum=vac)
        else: raise ValueError, "100, 111, or 110 surface is supported."
    elif lattice == 'bcc':
        if index   == '100': at_ase = AS.bcc100(symb, size, vacuum=vac)
        elif index == '111': at_ase = AS.bcc111(symb, size,
                                                orthogonal=orthogonal,
                                                vacuum=vac)
        elif index == '110': at_ase = AS.bcc110(symb, size,
                                                orthogonal=orthogonal,
                                                vacuum=vac)
        else: raise ValueError, "100, 111, or 110 surface is supported."
    elif lattice == 'hcp0001':
        at_ase = AS.hcp0001(symb, size, orthogonal=orthogonal, vacuum=vac)
    else: raise ValueError, "fcc, bcc, or hcp0001 surface is supported."
    
    symbols = at_ase.get_chemical_symbols()
    posits  = at_ase.get_positions()
    cell    = at_ase.get_cell()
    pbc     = at_ase.get_pbc()
    atoms = []; i=0
    for sym in symbols:
        temp_at = Atom(sym, list(posits[i]))
        atoms.append(temp_at.copy()); i+=1
    at_xxyz = AtomsSystem(atoms, cell=cell, pbc=pbc)
    return at_xxyz
Exemplo n.º 2
0
def asesurf2xxyz(symb, lattice, index, size=(1,1,3), vac=15.0, orthogonal=0):
    """
    An interface function for ase.lattice.surface

    Usage:
    >>> atoms = asesurf2xxyz(symb, lattice, index, size, 
                             vac=15.0, orthogonal=0))

    Parameters:
    symb: atomic symbol
    lattice: 'fcc', 'bcc', or 'hcp0001'
    index: '100', '111' or '110' (if lattice is 'hcp0001', this will not work.)
    size: the number of atoms per each vector
    
    Optional Parameters:
    vac (default: 15.0 angstron): the thickness of space normal to the surface
    orthogonal (default: False) : if True, two lateral cell vectors will be 
    orthogonal.

    Example:
    >>> Fe_100_1x1 = asesurf2xxyz('Fe', 'bcc', '100', (1,1,2))
    >>> Au_111_2x2 = asesurf2xxyz('Au', 'fcc', '111', (1,1,3))
    """
    if lattice == 'fcc':
        if index   == '100': at_ase = AS.fcc100(symb, size, vacuum=vac)
        elif index == '111': at_ase = AS.fcc111(symb, size,
                                                orthogonal=orthogonal,
                                                vacuum=vac)
        elif index == '110': at_ase = AS.fcc110(symb, size, vacuum=vac)
        else: raise ValueError("100, 111, or 110 surface is supported.")
    elif lattice == 'bcc':
        if index   == '100': at_ase = AS.bcc100(symb, size, vacuum=vac)
        elif index == '111': at_ase = AS.bcc111(symb, size,
                                                orthogonal=orthogonal,
                                                vacuum=vac)
        elif index == '110': at_ase = AS.bcc110(symb, size,
                                                orthogonal=orthogonal,
                                                vacuum=vac)
        else: raise ValueError("100, 111, or 110 surface is supported.")
    elif lattice == 'hcp0001':
        at_ase = AS.hcp0001(symb, size, orthogonal=orthogonal, vacuum=vac)
    else: raise ValueError("fcc, bcc, or hcp0001 surface is supported.")
    
    symbols = at_ase.get_chemical_symbols()
    posits  = at_ase.get_positions()
    cell    = at_ase.get_cell()
    pbc     = at_ase.get_pbc()
    atoms = []; i=0
    for sym in symbols:
        temp_at = Atom(sym, list(posits[i]))
        atoms.append(temp_at.copy()); i+=1
    at_xxyz = AtomsSystem(atoms, cell=cell, pbc=pbc)
    return at_xxyz
Exemplo n.º 3
0
def get_surface_slabs(symbol,
                      surfacetype,
                      surfacesize,
                      layers,
                      latticeconstants,
                      vacuum=10.0):
    images = []
    if surfacetype == 'fcc100' or surfacetype == 'fcc111':
        nlayeratoms = surfacesize[0] * surfacesize[1]
        if isinstance(latticeconstants, (list, tuple)):
            if not len(latticeconstants) == 1:
                raise ValueError("Too many latticeconstants")
            a = latticeconstants[0]
        else:
            a = latticeconstants
    elif surfacetype == 'hcp0001':
        nlayeratoms = surfacesize[0] * surfacesize[1]
        if isinstance(latticeconstants, (list, tuple)):
            if not len(latticeconstants) == 2:
                raise ValueError("Latticeconstants must be on the form [a, c]")
            a = latticeconstants[0]
            c = latticeconstants[1]
        else:
            raise ValueError("Latticeconstants must be on the form [a, c]")
    else:
        raise ValueError("Surface type '%s' is not supported" %
                         (surfacetype, ))

    for n in layers:
        size = surfacesize + (n, )
        if surfacetype == 'fcc100':
            images.append(fcc100(symbol=symbol, size=size, a=a, vacuum=vacuum))
        elif surfacetype == 'fcc111':
            images.append(
                fcc111(symbol=symbol,
                       size=size,
                       a=a,
                       vacuum=vacuum,
                       orthogonal=True))
        elif surfacetype == 'hcp0001':
            images.append(
                hcp0001(symbol=symbol,
                        size=size,
                        a=a,
                        c=c,
                        vacuum=vacuum,
                        orthogonal=True))

    return images, nlayeratoms
Exemplo n.º 4
0
def get_surface_slabs(symbol, surfacetype, surfacesize, layers, latticeconstants,
                      vacuum=10.0):
    images = []
    if surfacetype == 'fcc100' or surfacetype == 'fcc111':
        nlayeratoms = surfacesize[0] * surfacesize[1]
        if isinstance(latticeconstants, (list, tuple)):
            if not len(latticeconstants) == 1:
                raise ValueError("Too many latticeconstants")
            a = latticeconstants[0]
        else:
            a = latticeconstants
    elif surfacetype == 'hcp0001':
        nlayeratoms = surfacesize[0] * surfacesize[1]
        if isinstance(latticeconstants, (list, tuple)):
            if not len(latticeconstants) == 2:
                raise ValueError("Latticeconstants must be on the form [a, c]")
            a = latticeconstants[0]
            c = latticeconstants[1]
        else:
            raise ValueError("Latticeconstants must be on the form [a, c]")
    else:
        raise ValueError("Surface type '%s' is not supported" % (surfacetype,))


    for n in layers:
        size = surfacesize + (n,)
        if surfacetype == 'fcc100':
            images.append(fcc100(symbol=symbol, size=size, a=a, vacuum=vacuum))
        elif surfacetype == 'fcc111':
            images.append(fcc111(symbol=symbol, size=size, a=a, vacuum=vacuum,
                                 orthogonal=True))
        elif surfacetype == 'hcp0001':
            images.append(hcp0001(symbol=symbol, size=size, a=a, c=c,
                                  vacuum=vacuum, orthogonal=True))

    return images, nlayeratoms
Exemplo n.º 5
0
cu = Atoms('Cu', cell=[(0,b,b),(b,0,b),(b,b,0)], pbc=1) * (6, 6, 6)
try:
    import Asap
except ImportError:
    pass
else:
    cu.set_calculator(ASAP())
    f = UnitCellFilter(cu, [1, 1, 1, 0, 0, 0])
    opt = QuasiNewton(f)
    t = PickleTrajectory('Cu-fcc.traj', 'w', cu)
    opt.attach(t)
    opt.run(0.01)

# HCP:
from ase.lattice.surface import hcp0001
cu = hcp0001('Cu', (1, 1, 2), a=a / sqrt(2))
cu.cell[1,0] += 0.05
cu *= (6, 6, 3)
try:
    import Asap
except ImportError:
    pass
else:
    cu.set_calculator(ASAP())
    print cu.get_forces()
    print cu.get_stress()
    f = UnitCellFilter(cu)
    opt = MDMin(f,dt=0.01)
    t = PickleTrajectory('Cu-hcp.traj', 'w', cu)
    opt.attach(t)
    opt.run(0.02)
Exemplo n.º 6
0
Arquivo: adsorb.py Projeto: jboes/ase
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.lattice.surface 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.structure 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))
Exemplo n.º 7
0
cu = Atoms("Cu", cell=[(0, b, b), (b, 0, b), (b, b, 0)], pbc=1) * (6, 6, 6)
try:
    import Asap
except ImportError:
    pass
else:
    cu.set_calculator(ASAP())
    f = StrainFilter(cu, [1, 1, 1, 0, 0, 0])
    opt = MDMin(f, dt=0.01)
    t = PickleTrajectory("Cu.traj", "w", cu)
    opt.attach(t)
    opt.run(0.001)

# HCP:
from ase.lattice.surface import hcp0001

cu = hcp0001("Cu", (1, 1, 2), a=a / sqrt(2))
cu.cell[1, 0] += 0.05
cu *= (6, 6, 3)
try:
    import Asap
except ImportError:
    pass
else:
    cu.set_calculator(ASAP())
    f = StrainFilter(cu)
    opt = MDMin(f, dt=0.01)
    t = PickleTrajectory("Cu.traj", "w", cu)
    opt.attach(t)
    opt.run(0.01)
Exemplo n.º 8
0
import sys
sys.path.append('/export/zimmerman/paulzim/ase')

from ase import Atoms
from ase.calculators.vasp import Vasp
from ase.constraints import FixAtoms
from ase.optimize import QuasiNewton
from ase.lattice.surface import fcc111,add_adsorbate, fcc110, bcc100, bcc110, hcp0001, bcc111, diamond100, diamond111, fcc100
from ase.io import write


slab = hcp0001('Ru', size=(4,5,3), vacuum=10)
#add_adsorbate(slab, 'Au', 2.5, 'fcc')

#mask = [atom.tag > 2 for atom in slab]
#slab.set_constraint(FixAtoms(mask=mask))
#calc = Vasp(xc='PBE',lreal='Auto',kpts=[2,2,1],ismear=1,sigma=0.2,algo='fast',istart=0,npar=8,encut=300)
#slab.set_calculator(calc)

#dyn = QuasiNewton(slab, trajectory='PtAu-fcc.traj')
#dyn.run(fmax=0.05)

write('test-hcp0001-2.xyz', slab)
Exemplo n.º 9
0
    def get_structure(self, name, elements, a=None, c=None, l=None):
        # Check number of elements
        if name[:3] in ['fcc', 'hcp']:
            if len(elements) != 1:
                raise ValueError("Tuple of elements must be of length one")
        if name[:3] in ['l12', 'l10'] or name[:2] == 'B2':
            if len(elements) != 2:
                raise ValueError("Tuple of elements must be of length two")

        # Get lattice constants
        if a is None:
            if name[:2] == 'B2':
                a = self.get_lattice_constant_a(name[:2], elements)
            elif name[:3] in ['fcc', 'hcp', 'bcc', 'l12', 'l10']:
                a = self.get_lattice_constant_a(name[:3], elements)

        if c is None:
            if name[:3] in ['hcp', 'l10']:
                c = self.get_lattice_constant_c(name[:3], elements)

        # Get size
        if name in ['fcc', 'hcp', 'bcc', 'l12', 'l10', 'B2']:
            size = self.properties[name + '_size']
        elif name in ['fcc100', 'fcc111', 'hcp0001']:
            size = self.properties[name + '_size'][:2] + (l, )

        # Make structure
        if name == 'fcc':
            atoms = FaceCenteredCubic(symbol=elements[0],
                                      size=size,
                                      latticeconstant=a)
        elif name == 'hcp':
            atoms = HexagonalClosedPacked(symbol=elements[0],
                                          size=size,
                                          directions=[[2, -1, -1, 0],
                                                      [0, 1, -1, 0],
                                                      [0, 0, 0, 1]],
                                          latticeconstant=(a, c))
        elif name == 'bcc':
            atoms = BodyCenteredCubic(symbol=elements[0],
                                      size=size,
                                      latticeconstant=a)
        elif name == 'B2':
            atoms = B2(symbol=elements, size=size, latticeconstant=a)
        elif name == 'l12':
            atoms = L1_2(symbol=elements, size=size, latticeconstant=a)
        elif name == 'l10':
            atoms = L1_0(symbol=elements, size=size, latticeconstant=(a, c))
        elif name == 'fcc100':
            atoms = fcc100(symbol=elements[0], size=size, a=a, vacuum=10.0)
        elif name == 'fcc111':
            atoms = fcc111(symbol=elements[0],
                           size=size,
                           a=a,
                           vacuum=10.0,
                           orthogonal=True)
        elif name == 'hcp0001':
            atoms = hcp0001(symbol=elements[0],
                            size=size,
                            a=a,
                            c=c,
                            vacuum=10.0,
                            orthogonal=True)
        elif name == 'hcp1010A':
            raise ValueError("Structure '%s' not supported" % (name, ))
            atoms = None
        elif name == 'hcp1010B':
            raise ValueError("Structure '%s' not supported" % (name, ))
            atoms = None
        elif name == 'l12100':
            n = (l + 1) / 2
            atoms = L1_2(symbol=elements, size=(8, 8, n), latticeconstant=a)
            atoms.set_pbc([True, True, False])
            # Remove layers
            atoms = atoms[atoms.get_positions()[:, 2] > 0.1 * a]
            # Set vacuum
            atoms.center(axis=2, vacuum=10.0)
        elif name == 'l12111':
            if l % 3 == 0:
                n = l / 3
                c = 0
            else:
                n = l / 3 + 1
                c = 3 - l % 3
            atoms = L1_2(
                symbol=elements,
                size=(8, 4, n),
                #directions=[[1,-1,0],[1,0,-1],[1,1,1]], latticeconstant=a)
                directions=[[1, -1, 0], [1, 1, -2], [1, 1, 1]],
                latticeconstant=a)
            atoms.set_pbc([True, True, False])
            # Wrap positions
            scpos = atoms.get_scaled_positions()
            scpos[scpos > (1.0 - 1e-12)] = 0.0
            atoms.set_scaled_positions(scpos)
            # Remove layers
            if c > 0:
                atoms = atoms[atoms.get_positions()[:, 2] > (c - 0.5) * a /
                              np.sqrt(3.0)]
            # Set vacuum
            atoms.center(axis=2, vacuum=10.0)
        else:
            raise ValueError("Structure '%s' not supported" % (name, ))
        return atoms
Exemplo n.º 10
0
from ase.lattice.surface import fcc111,hcp0001
from ase.lattice.hexagonal import *
from ase import io
from os import system
import math


POSCAR_string = "B  N  Al"
lattice_constant_Al = 4.050
a_lattice_constant_BN = 2.5040
c_lattice_constant_BN = 6.6612


slab = fcc111('Al',size=(7,7,3), a=lattice_constant_Al, orthogonal=False,vacuum=0.0)

bn= hcp0001('B',size=(8,8,2), a=a_lattice_constant_BN, c=0.0000001, vacuum=0.0)
cell = bn.get_cell()
#cell[2][2]=20.0

bn.translate([0,0,10])
num_each = bn.get_number_of_atoms() / 2

bn.set_atomic_numbers([5]*num_each + [7]*num_each)

bn.extend(slab)
bn.set_cell(cell)
bn.center(vacuum=10, axis=2)
bn.translate([0,0,-10])

io.write('POSCAR',bn)
Exemplo n.º 11
0
import numpy as np
from math import sqrt
from ase import Atoms
from ase.lattice.surface import hcp0001
from gpaw import GPAW
from gpaw.test import equal

# Vacuum and hcp lattice parameter for graphene
d = 4.0
a = 2.4437

calc = GPAW(h=0.15, width=0.1, xc='LDA', nbands=-4, txt='-',
            basis='dzp', convergence={'energy': 1e-5, 'density': 1e-5})

# Calculate potential energy per atom for orthogonal unitcell
atoms = hcp0001('C', a=a/sqrt(3), vacuum=d, size=(3,2,1), orthogonal=True)
del atoms[[1,-1]]
atoms.center(axis=0)
atoms.set_calculator(calc)

kpts_c = np.ceil(50 / np.sum(atoms.get_cell()**2, axis=1)**0.5).astype(int)
kpts_c[~atoms.get_pbc()] = 1
calc.set(kpts=kpts_c)
eppa1 = atoms.get_potential_energy() / len(atoms)
F1_av = atoms.get_forces()
equal(np.abs(F1_av).max(), 0, 5e-3)

# Redo calculation with non-orthogonal unitcell
atoms = Atoms(symbols='C2', pbc=(True,True,False),
              positions=[(a/2,-sqrt(3)/6*a,d), (a/2,sqrt(3)/6*a,d)],
              cell=[(a/2,-sqrt(3)/2*a,0), (a/2,sqrt(3)/2*a,0), (0,0,2*d)])
Exemplo n.º 12
0
from sys import argv
from ase.lattice.surface import hcp0001, add_adsorbate
from ase.constraints import FixAtoms
from ase.optimize.lbfgs import LBFGS
from gpaw import GPAW, Mixer, FermiDirac

tag = 'Ru001_Ru8'

adsorbate_heights = {'H': 1.0, 'N': 1.108, 'O': 1.257}

slab = hcp0001('Ru', size=(2, 2, 4), a=2.72, c=1.58*2.72, vacuum=7.0,
               orthogonal=True)
slab.center(axis=2)

if len(argv) > 1:
    adsorbate = argv[1]
    tag = adsorbate + tag
    add_adsorbate(slab, adsorbate, adsorbate_heights[adsorbate], 'hcp')

slab.set_constraint(FixAtoms(mask=slab.get_tags() >= 3))

calc = GPAW(xc='PBE',
            h=0.2,
            mixer=Mixer(0.1, 5, weight=100.0),
            stencils=(3, 3),
            occupations=FermiDirac(width=0.1),
            kpts=[4, 4, 1],
            setups={'Ru': '8'},
            txt=tag + '.txt')
slab.set_calculator(calc)
  
Exemplo n.º 13
0
def initlatticepositions(params, nlayers):
    """
    Return nlayers of positions according to lattice type/plane and
    shift positions so that no atoms are on the edges of the box.
    """

    lxsurf = params['lxsurf']
    lysurf = params['lysurf']
    alat = params['alat']

    if params['surftype'] == 'fcc':

        if params['plane'] == '111':
            surf = ase.fcc111('O',
                              a=alat,
                              size=(lxsurf, lysurf, nlayers),
                              orthogonal=True)
            positions = surf.positions
            positions[:, 0] = positions[:, 0] + (alat / 2.0**0.5) / 4.0
            positions[:, 1] = (positions[:, 1] + (1.0 / 2.0) * (3.0**0.5) *
                               (alat / 2.0**0.5) / 4.0)

        elif params['plane'] == '100':
            surf = ase.fcc100('O', a=alat, size=(lxsurf, lysurf, nlayers))
            positions = surf.positions
            positions[:, 0] = positions[:, 0] + (alat / 2.0**0.5) / 4.0
            positions[:, 1] = positions[:, 1] + (alat / 2.0**0.5) / 4.0

        elif params['plane'] == '110':
            surf = ase.fcc110('O', a=alat, size=(lxsurf, lysurf, nlayers))
            positions = surf.positions
            positions[:, 0] = positions[:, 0] + alat / 4.0
            positions[:, 1] = positions[:, 1] + (alat / 2.0**0.5) / 4.0

    elif params['surftype'] == 'bcc':

        if params['plane'] == '100':
            surf = ase.bcc100('O', a=alat, size=(lxsurf, lysurf, nlayers))
            positions = surf.positions
            positions[:, 0] = positions[:, 0] + alat / 2.0
            positions[:, 1] = positions[:, 1] + alat / 2.0

    elif params['surftype'] == 'hcp':

        clat = params['clat']
        if params['plane'] == '0001':
            surf = ase.hcp0001('O',
                               a=alat,
                               c=clat,
                               size=(lxsurf, lysurf, nlayers),
                               orthogonal=True)
            positions = surf.positions
            positions[:, 0] = positions[:, 0] + alat / 4.0
            positions[:,
                      1] = positions[:,
                                     1] + (1.0 / 2.0) * (3.0**0.5) * alat / 4.0

        elif params['plane'] == '1010':
            surf = ase.hcp10m10('O',
                                a=alat,
                                c=clat,
                                size=(lxsurf, lysurf, nlayers))
            positions = surf.positions
            positions[:, 0] = positions[:, 0] + alat / 4.0
            positions[:, 1] = positions[:, 1] + clat / 4.0

    return positions
Exemplo n.º 14
0
from ase.optimize.lbfgs import LBFGS
from ase.optimize.mdmin import MDMin
try:
    from asap3 import EMT
except ImportError:
    pass
else:
    a = 3.6
    b = a / 2
    cu = Atoms('Cu', cell=[(0, b, b), (b, 0, b), (b, b, 0)], pbc=1) * (6, 6, 6)
    cu.set_calculator(EMT())
    f = UnitCellFilter(cu, [1, 1, 1, 0, 0, 0])
    opt = LBFGS(f)
    t = PickleTrajectory('Cu-fcc.traj', 'w', cu)
    opt.attach(t)
    opt.run(5.0)

    # HCP:
    from ase.lattice.surface import hcp0001
    cu = hcp0001('Cu', (1, 1, 2), a=a / sqrt(2))
    cu.cell[1, 0] += 0.05
    cu *= (6, 6, 3)
    cu.set_calculator(EMT())
    print cu.get_forces()
    print cu.get_stress()
    f = UnitCellFilter(cu)
    opt = MDMin(f, dt=0.01)
    t = PickleTrajectory('Cu-hcp.traj', 'w', cu)
    opt.attach(t)
    opt.run(0.2)
Exemplo n.º 15
0
from sys import argv
from ase.lattice.surface import hcp0001, add_adsorbate
from ase.constraints import FixAtoms
from ase.optimize.lbfgs import LBFGS
from gpaw import GPAW, Mixer, FermiDirac

tag = 'Ru001_Ru8'

adsorbate_heights = {'H': 1.0, 'N': 1.108, 'O': 1.257}

slab = hcp0001('Ru',
               size=(2, 2, 4),
               a=2.72,
               c=1.58 * 2.72,
               vacuum=7.0,
               orthogonal=True)
slab.center(axis=2)

if len(argv) > 1:
    adsorbate = argv[1]
    tag = adsorbate + tag
    add_adsorbate(slab, adsorbate, adsorbate_heights[adsorbate], 'hcp')

slab.set_constraint(FixAtoms(mask=slab.get_tags() >= 3))

calc = GPAW(xc='PBE',
            h=0.2,
            mixer=Mixer(0.1, 5, weight=100.0),
            stencils=(3, 3),
            occupations=FermiDirac(width=0.1),
            kpts=[4, 4, 1],
Exemplo n.º 16
0
d = 4.0
a = 2.4437

calc = GPAW(h=0.15,
            width=0.1,
            xc='LDA',
            nbands=-4,
            txt='-',
            basis='dzp',
            convergence={
                'energy': 1e-5,
                'density': 1e-5
            })

# Calculate potential energy per atom for orthogonal unitcell
atoms = hcp0001('C', a=a / sqrt(3), vacuum=d, size=(3, 2, 1), orthogonal=True)
del atoms[[1, -1]]
atoms.center(axis=0)
atoms.set_calculator(calc)

kpts_c = np.ceil(50 / np.sum(atoms.get_cell()**2, axis=1)**0.5).astype(int)
kpts_c[~atoms.get_pbc()] = 1
calc.set(kpts=kpts_c)
eppa1 = atoms.get_potential_energy() / len(atoms)
F1_av = atoms.get_forces()
equal(np.abs(F1_av).max(), 0, 5e-3)

# Redo calculation with non-orthogonal unitcell
atoms = Atoms(symbols='C2',
              pbc=(True, True, False),
              positions=[(a / 2, -sqrt(3) / 6 * a, d),
Exemplo n.º 17
0
import math

POSCAR_string = "B  N  Al"
lattice_constant_Al = 4.050
a_lattice_constant_BN = 2.5040
c_lattice_constant_BN = 6.6612

slab = fcc111('Al',
              size=(7, 7, 3),
              a=lattice_constant_Al,
              orthogonal=False,
              vacuum=0.0)

bn = hcp0001('B',
             size=(8, 8, 2),
             a=a_lattice_constant_BN,
             c=0.0000001,
             vacuum=0.0)
cell = bn.get_cell()
#cell[2][2]=20.0

bn.translate([0, 0, 10])
num_each = bn.get_number_of_atoms() / 2

bn.set_atomic_numbers([5] * num_each + [7] * num_each)

bn.extend(slab)
bn.set_cell(cell)
bn.center(vacuum=10, axis=2)
bn.translate([0, 0, -10])
Exemplo n.º 18
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.")

    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'].lower()
    
    if opt.lattice_constant:
        a = opt.lattice_constant
    else:
        a = estimate_lattice_constant(surf, x, opt.c_over_a)

    if x == 'fcc':
        if face is None:
            face = '111'
        slab = fcc111(surf, (n, m, opt.layers), a, opt.vacuum)
        r = a / np.sqrt(2) / 2
    elif x == 'bcc':
        if face is None:
            face = '110'
        slab = bcc110(surf, (n, m, opt.layers), a, opt.vacuum)
        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)
        r = a / 2
    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))
    
    slab.pbc = 1

    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:
            ads = Atoms(ads)
        else:
            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
            print y
            h = (d**2 - y**2)**0.5
            print h
        else:
            assert opt.distance is None
        
        slab.positions[-nads:, 2] += h

    if len(args) == 2:
        write(args[1], slab)
    elif not opt.gui:
        write(name + '.traj', slab)
        
    if opt.gui:
        view(slab)
Exemplo n.º 19
0
def run_slab(adsorbate, geometry, xc, code):

    parameters = initialize_parameters(code, 0.1, h)
    parameters['xc'] = xc

    tag = 'Ru001'

    if adsorbate != 'None':
        name = adsorbate + tag
    else:
        name = tag

    if geometry == 'fix':
        slab = read_trajectory(code + '_' + name + '.traj')
    else:
        adsorbate_heights = {'N': 1.108, 'O': 1.257}

        slab = hcp0001('Ru',
                       size=(2, 2, 4),
                       a=2.72,
                       c=1.58 * 2.72,
                       vacuum=5.0 + add_vacuum,
                       orthogonal=True)
        slab.center(axis=2)

        if adsorbate != 'None':
            add_adsorbate(slab, adsorbate, adsorbate_heights[adsorbate], 'hcp')

    slab.set_constraint(FixAtoms(mask=slab.get_tags() >= 3))

    if code != 'elk':
        parameters['nbands'] = 80
        parameters['kpts'] = [4, 4, 1]
    #
    if code == 'gpaw':
        from gpaw import GPAW as Calculator
        from gpaw.mpi import rank
        parameters['txt'] = code + '_' + name + '.txt'
        from gpaw.mixer import Mixer, MixerSum
        parameters['mixer'] = Mixer(beta=0.2, nmaxold=5, weight=100.0)
    if code == 'dacapo':
        from ase.calculators.dacapo import Dacapo as Calculator
        rank = 0
        parameters['txtout'] = code + '_' + name + '.txt'
    if code == 'abinit':
        from ase.calculators.abinit import Abinit as Calculator
        rank = 0
        parameters['label'] = code + '_' + name
    if code == 'elk':
        from ase.calculators.elk import ELK as Calculator
        rank = 0
        parameters['autokpt'] = True
        elk_dir = 'elk_' + str(parameters['rgkmax'])
        conv_param = 1.0
        parameters['dir'] = elk_dir + '_' + name
    #
    calc = Calculator(**parameters)
    #
    slab.set_calculator(calc)
    try:
        if geometry == 'fix':
            slab.get_potential_energy()
            traj = PickleTrajectory(code + '_' + name + '.traj', mode='w')
            traj.write(slab)
        else:
            opt = QuasiNewton(slab,
                              logfile=code + '_' + name + '.qn',
                              trajectory=code + '_' + name + '.traj')
            opt.run(fmax=fmax)
    except:
        raise