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
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
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
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
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)
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))
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)
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)
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
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)
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)])
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)
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
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)
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],
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),
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])
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)
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