def generator(group): structures = [] for position in ["ontop", "bridge"]: slab = fcc111("Au", size=group["repeats"].value(), vacuum=10.0) add_adsorbate(slab, "Au", 3, position=position) slab = fixBelow(slab, slab.positions[:, 2].min() + 1e-2) slab.set_calculator(EMT()) structures.append(slab) return structures
def addWater(cnt, centerX, centerY, centerZ): water = molecule('H2O') cnt_length = 2*centerZ nH = int(cnt_length/(distance + 1)) + 1 z = 0 delta_z = distance for n in range(0, nH): z -= delta_z add_adsorbate(cnt, water, z , position=(centerX, centerY)) return cnt
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
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
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
def slabCalculation(): 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]) print(slab.cell / Bohr)
def aual100(site, height, calc=None): slab = fcc100('Al', size=(2, 2, 1)) add_adsorbate(slab, 'Au', height, site) slab.center(axis=2, vacuum=3.0) mask = [atom.symbol == 'Al' for atom in slab] fixlayer = FixAtoms(mask=mask) slab.set_constraint(fixlayer) if calc is None: calc = GPAW(h=0.25, kpts=(2, 2, 1), xc='PBE', txt=site + '.txt') slab.set_calculator(calc) qn = QuasiNewton(slab, trajectory=site + '.traj') qn.run(fmax=0.05) if isinstance(calc, GPAW): calc.write(site + '.gpw') return slab.get_potential_energy()
def slabCalculation(): 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]) print(slab.cell / Bohr)
def ads_setup(self, calcdir, q, clus, **kwargs): c = kwargs['cov'] ads = kwargs['ads'] atoms = facet_setup(host=kwargs['host'], fac=kwargs['fac'], c=kwargs['cov'], lat=kwargs['lat'], root=kwargs['root']) if kwargs['fac'] == 211: mol = Atoms(ads, coord[ads_dict[ads][0]]) ads_call = { 'sbr': add_sbr, 'br': add_br100, 'tt': add_tt, 'hollow': add_hollow } x, y, h = ads_call[kwargs['site']](atoms, mol, c[1]) add_adsorbate(slab=atoms, adsorbate=mol, height=h, position=(x, y)) constraint = FixAtoms( indices=[atom.index for atom in atoms if atom.z < 14]) else: #111 or 100 mol = Atoms(ads, coord[ads_dict[ads][0]]) if kwargs['root'] is None: print kwargs['site'] add_adsorbate(atoms, mol, height=2.0, position=kwargs['site']) else: x, y, h = root3_111(atoms, mol, kwargs['site']) add_adsorbate(slab=atoms, adsorbate=mol, height=h, position=(x, y)) constraint = FixAtoms( mask=[True for atom in atoms if atom.position[2] < 12.2]) #if atom.position[2] < 12.2]) atoms.set_constraint(constraint) call_jasp(atoms=atoms, kp=kp_dict[c[1]], calcdir=calcdir, spin=1, nsteps=500, qe=q, cluster=clus)
from math import sqrt, pi from ase import Atoms from ase.calculators.emt import EMT from ase.constraints import FixBondLengths from ase.optimize import BFGS, QuasiNewton from ase.neb import SingleCalculatorNEB from ase.lattice.surface import fcc111, add_adsorbate from math import sqrt, cos, sin 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) constraint = FixBondLengths([[-3, -2], [-3, -1]]) slab.set_constraint(constraint) dyn = BFGS(slab, trajectory='relax.traj') dyn.run(fmax=0.05) assert abs(co2.get_distance(-3, -2) - d0) < 1e-14 assert abs(co2.get_distance(-3, -1) - d1) < 1e-14
fname = 'scratch/structure'+argv1+".xyz" tmpDir = "."#os.getenv('PBSTMPDIR') folder = 'scratch/vasp'+argv1 #lattice and initial atom setup for unit cell #slab = read("initial.xyz") #slab.set_cell([12.720823288,12.720823288,21.0]) #slab2 = hcp0001('Ru', size=(3,3,2), vacuum=10) #define adsorbate #molecule = Atoms('CO', [(0., 0., 0.), (0., 0., 1.16)]) #add adsorbate to the surface #add_adsorbate(slab2, molecule, 1.7, 'hcp') slab = fcc111('Cu', size=(2,2,2), vacuum=5.0) molecule = Atoms('2N', positions=[(0., 0., 0.), (0., 0., 1.1)]) add_adsorbate(slab, molecule, 1.85, 'ontop') #print("slab1", slab1) #print("slab2", slab2) #sys.exit() if os.path.isfile(fname): #print("\nfname:", fname) #current position read in slabatoms = read(fname) #print("after read in") slab.set_positions(slabatoms.get_positions()) #for atom in slab: # print("atom:", atom) #mask = [atom.tag > 2 for atom in slab] # MB: this needs to be adapted!!!
# compute local potential of slab with no dipole from ase.lattice.surface import fcc111, add_adsorbate from jasp import * import matplotlib.pyplot as plt from ase.io import write slab = fcc111('Al', size=(2, 2, 2), vacuum=10.0) add_adsorbate(slab, 'Na', height=1.2, position='fcc') slab.center() write('images/Na-Al-slab.png', slab, rotation='-90x', show_unit_cell=2) with jasp('surfaces/Al-Na-nodip', xc='PBE', encut=340, kpts=(2, 2, 1), lvtot=True, # write out local potential lvhar=True, # write out only electrostatic potential, not xc pot atoms=slab) as calc: calc.calculate()
import numpy as np from ase import Atoms, Atom from ase.lattice.surface import fcc111, fcc211, add_adsorbate atoms = fcc211("Au", (3, 5, 8), vacuum=10.0) 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
write(name + '.png', slab, show_unit_cell=2, radii=radii[name[:3]], scale=10) for name in ortho + hex: f = eval(name) slab = f(symbols[name[:3]], (3, 4, 5), vacuum=4) for site in slab.adsorbate_info['sites']: if site.endswith('bridge'): h = 1.5 else: h = 1.2 add_adsorbate(slab, adsorbates.get(site, 'F'), h, site) save(name, slab) for name in hex: f = eval(name) slab = f(symbols[name[:3]], (3, 4, 5), vacuum=4, orthogonal=True) for site in slab.adsorbate_info['sites']: if site.endswith('bridge'): h = 1.5 else: h = 1.2 add_adsorbate(slab, adsorbates.get(site, 'F'), h, site) save(name + 'o', slab) for site, symbol in adsorbates.items(): write('%s-site.png' % site, Atoms(symbol), radii=1.08, scale=10)
#!/usr/bin/env python from ase.calculators.aims import Aims from ase.lattice.surface import fcc111, add_adsorbate from ase.constraints import FixAtoms from ase import Atoms, Atom from ase.io import write adsorbate = Atoms('CO') adsorbate[1].z = 1.13 atoms = fcc111('Pt', size=(1, 1, 3), vacuum=10.0) # note this function only works when atoms are created by the surface module. add_adsorbate(atoms, adsorbate, height=1.2, position='fcc') constraint = FixAtoms(mask=[atom.symbol != 'O' and atom.symbol != 'C' for atom in atoms]) atoms.set_constraint(constraint) write('images/pt-fcc-site.png', atoms, show_unit_cell=2) calc = Aims(label='surfaces/pt-slab-co-fcc', xc='pbe', spin='none', relativistic = 'atomic_zora scalar', kpts=(3, 3, 1), sc_accuracy_etot=1e-5, sc_accuracy_eev=1e-2, sc_accuracy_rho=1e-4, sc_accuracy_forces=1e-2, relax_geometry = 'bfgs 1.e-2') atoms.set_calculator(calc) print('energy = {0} eV'.format(atoms.get_potential_energy())) print(atoms.get_forces())
from ase import Atoms, Atom from ase.io import write from ase.visualize import view def sortz(atoms): tags = atoms.positions[:,2] deco = sorted([(tag, i) for i, tag in enumerate(tags)]) indices = [i for tag, i in deco] return atoms[indices] adsorbate = molecule('CO') adsorbate2 = molecule('O2') atoms = fcc111('Pt', size=(4, 4, 2), vacuum=6.0) # note this function only works when atoms are created by the surface module. add_adsorbate(atoms, adsorbate, height=3.0, position='ontop') add_adsorbate(atoms, adsorbate2, height=3.0, position='fcc') atoms = sortz(atoms) atoms.translate([0, 0, -atoms[0].z]) mask=[atom.index for atom in atoms if atom.symbol == 'O' or atom.symbol == 'C'] mol = atoms[mask] del atoms[mask] mol.cell[0:2, ] = mol.cell[0:2, ]*1/3.0 mol.cell[2][2] = 3 mol[-1].z = mol[-3].z mol[-1].position = mol[-1].position + mol.cell[0]/6 + mol.cell[1]/6 mol.translate([0, 0, -mol[1].z]) mol = mol*[3, 3, 2] mol = sortz(mol)
from jasp import * from ase.lattice.surface import fcc111, add_adsorbate from ase.constraints import FixAtoms, FixScaled from ase.io import write atoms = fcc111('Pt', size=(2, 2, 3), vacuum=10.0) # note this function only works when atoms are created by the surface module. add_adsorbate(atoms, 'O', height=1.2, position='bridge') constraint1 = FixAtoms(mask=[atom.symbol != 'O' for atom in atoms]) # fix in xy-direction, free in z. actually, freeze movement in surface # unit cell, and free along 3rd lattice vector constraint2 = FixScaled(atoms.get_cell(), 12, [True, True, False]) atoms.set_constraint([constraint1, constraint2]) write('images/Pt-O-bridge-constrained-initial.png', atoms, show_unit_cell=2) print 'Initial O position: {0}'.format(atoms.positions[-1]) with jasp('surfaces/Pt-slab-O-bridge-xy-constrained', xc='PBE', kpts=(4, 4, 1), encut=350, ibrion=2, nsw=25, atoms=atoms) as calc: e_bridge = atoms.get_potential_energy() write('images/Pt-O-bridge-constrained-final.png', atoms, show_unit_cell=2) print 'Final O position : {0}'.format(atoms.positions[-1]) # now compute Hads with jasp('surfaces/Pt-slab') as calc: atoms = calc.get_atoms() e_slab = atoms.get_potential_energy() with jasp('molecules/O2-sp-triplet-350') as calc: atoms = calc.get_atoms() e_O2 = atoms.get_potential_energy()
from ase.lattice.surface import fcc100, add_adsorbate from gpaw import GPAW from gpaw.poisson import PoissonSolver from gpaw.dipole_correction import DipoleCorrection slab = fcc100('Al', (2, 2, 2), a=4.05, vacuum=7.5) add_adsorbate(slab, 'Na', 4.0) slab.center(axis=2) slab.calc = GPAW(txt='zero.txt', xc='PBE', setups={'Na': '1'}, kpts=(4, 4, 1)) e1 = slab.get_potential_energy() slab.calc.write('zero.gpw') slab.pbc = True slab.calc.set(txt='periodic.txt') e2 = slab.get_potential_energy() slab.calc.write('periodic.gpw') slab.pbc = (True, True, False) slab.calc.set(poissonsolver=DipoleCorrection(PoissonSolver(), 2), txt='corrected.txt') e3 = slab.get_potential_energy() slab.calc.write('corrected.gpw')
calc = GPAW( mode=PW(400), xc='RPBE', kpts=(12, 12, 1), eigensolver='cg', mixer=Mixer(0.05, 5, 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, 1, 3)) add_adsorbate(slab, 'C', 2.0, 'ontop') add_adsorbate(slab, 'O', 3.15, 'ontop') slab.center(axis=2, vacuum=4.0) slab.set_calculator(calc) slab.get_potential_energy() calc.write('top.gpw', mode='all') # Molecule molecule = slab.copy() del molecule[:-2] molecule.set_calculator(c_mol) molecule.get_potential_energy() c_mol.write('CO.gpw', mode='all')
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) opt = LBFGS(slab, logfile=tag + '.log', trajectory=tag + '.traj') opt.run(fmax=0.05)
def save(name, slab): print('save %s' % name) write(name + '.png', slab, show_unit_cell=2, radii=radii[name[:3]], scale=10) for name in surfaces: f = eval(name) for kwargs in [{}, {'orthogonal': False}, {'orthogonal': True}]: print name, kwargs try: slab = f(symbols[name[:3]], (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 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)
from ase.optimize import QuasiNewton from ase.constraints import FixAtoms from ase.calculators.emt import EMT from ase.vibrations import Vibrations import ase.io import chemcoord as cc if os.path.exists('CH3_Al.traj'): slab = ase.io.read('CH3_Al.traj') slab.set_calculator(EMT()) # Need to reset when loading from traj file else: 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, trajectory='QN_slab.traj') dyn.run(fmax=0.05) ase.io.write('CH3_Al.traj', slab) # Running vibrational analysis vib = Vibrations(slab, indices=[8, 9, 10, 11]) vib.run() vib.summary()
# { -1, -1}: On entry to PDLASRT parameter number 9 had an illegal value # works with 'sl_default': (2, 2, 32) from ase.lattice.surface import fcc100, add_adsorbate from gpaw import GPAW, ConvergenceError from gpaw.mpi import world from gpaw.utilities import compiled_with_sl assert world.size == 4 slab = fcc100('Cu', size=(2, 2, 2)) add_adsorbate(slab,'O', 1.1, 'hollow') slab.center(vacuum=3.0, axis=2) calc = GPAW(mode='lcao', kpts=(2, 2, 1), txt='-', maxiter=1,) if compiled_with_sl(): calc.set(parallel={'domain': (1, 1, 4), 'sl_default': (2, 2, 64)}) slab.set_calculator(calc) try: slab.get_potential_energy() except ConvergenceError: pass
# *** An error occurred in MPI_Recv # *** on communicator MPI COMMUNICATOR 36 DUP FROM 28 # *** MPI_ERR_TRUNCATE: message truncated # *** MPI_ERRORS_ARE_FATAL (your MPI job will now abort) # works with 'sl_default': (2, 2, 32) from ase.lattice.surface import fcc100, add_adsorbate from gpaw import GPAW, ConvergenceError from gpaw.mpi import world from gpaw.utilities import compiled_with_sl assert world.size == 4 slab = fcc100('Cu', size=(2, 2, 4)) add_adsorbate(slab, 'O', 1.1, 'hollow') slab.center(vacuum=3.0, axis=2) calc = GPAW( mode='lcao', kpts=(2, 2, 1), txt='-', maxiter=1, ) if compiled_with_sl(): calc.set(parallel={'domain': (1, 1, 4), 'sl_default': (2, 2, 64)}) slab.set_calculator(calc) try: slab.get_potential_energy()
from gpaw import GPAW from ase.lattice.surface import fcc111 from ase.lattice.surface import add_adsorbate atoms = fcc111('Pt', (2, 2, 6), a=4.00, vacuum=10.0) add_adsorbate(atoms, 'O', 2.0, 'fcc') calc = GPAW(mode='pw', kpts=(8, 8, 1), xc='RPBE') ncpus = 4
from ase.lattice.surface 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) # Dispalce 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)
fd = opencew(label + '.traj') if fd is None: continue traj = PickleTrajectory(label + '.traj', 'w') a = fcc[name] if category == 'fcc': atoms = bulk(name, 'fcc', a=a) site = '' else: atoms = fcc111(name, size=(2, 2, 4), a=a, vacuum=6.0) atoms.center(axis=2) site = '' if adsorbate != '': d = D[adsorbate][name]['d'] site = D[adsorbate][name]['site'] add_adsorbate(atoms, adsorbate, d, site) # relax only adsorbate atoms.set_constraint(FixAtoms(mask=atoms.get_tags() >= 1)) cell = atoms.get_cell() kpts = tuple(kpts2mp(atoms, kptdensity, even=True)) kwargs = {} id = c.reserve(name=name, adsorbate=adsorbate, category=category, site=site, ecut=ecut, kptdensity=kptdensity, width=width, relativistic=relativistic) if id is None: continue # set calculator atoms.calc = GPAW( txt=label + '.txt',
############ dimer ############################## path = os.path.dirname(os.path.abspath(__file__)) print(path) starttime = time.strftime("%y%m%d%H%M%S") a=3.9242 # Setting up the initial image: # initial = fcc111('Pt', size=(4, 4, 2), a=3.9242, vacuum=10.0) # add_adsorbate(initial, 'Pt', 1.611, 'hollow') """Pt_atoms = FaceCenteredCubic(directions=[[0,1,0], [0,0,1,], [1,0,0]], size=(4,4,1),latticeconstant=a, symbol='Pt', pbc=(1,1,1)) initial = surface(Pt_atoms, (0,0,1), 3) # [1,-1,0], [1,1,-2], [1,1,1]], # for 111 surface""" initial = fcc100('Pt', size=(4, 4, 5), a=a) add_adsorbate(initial, 'Pt', 1.611, 'hollow') #add adatom on surface at = initial[len(initial)-6] at_pos = at.position at_ind = at.index print(at) print(at_pos) print(at_ind) # del initial[len(initial)-7] # delete first atom ie create vacancy initial.center(vacuum=10.0, axis=2) # Save it # write('Molecule-%s-%s-start.xyz' % (str(11), str(1)), initial) N = len(initial) # number of atoms # Freeze the "slab" # Make a mask of zeros and ones that select fixed atoms - the two # bottom layers:
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)
#!/usr/bin/env python from jasp import * from ase.lattice.surface import fcc111, add_adsorbate from ase.constraints import FixAtoms atoms = fcc111('Pt', size=(2, 2, 3), vacuum=10.0) # note this function only works when atoms are created by the surface module. add_adsorbate(atoms, 'O', height=1.2, position='hcp') constraint = FixAtoms(mask=[atom.symbol != 'O' for atom in atoms]) atoms.set_constraint(constraint) from ase.io import write write('images/Pt-hcp-o-site.png', atoms, show_unit_cell=2) with jasp('surfaces/Pt-slab-O-hcp', xc='PBE', kpts=(4, 4, 1), encut=350, ibrion=2, nsw=25, atoms=atoms) as calc: calc.calculate()
from ase import io from ase.lattice.surface import add_adsorbate, fcc111, bcc110 # name of output trajectory file # lattice constant for fcc Pt name = 'N+N_Pt' # read in your optimized surface or cluster slab = io.read('surface.traj') # add adsorbate using add_adsorbate(surface,symbol,z,(x,y)) # where "surface" is the object containing the surface, "slab" in this case # and z is the position above the surface (from the center of the top most atom) # and x and y are the absolute coordinates # add two neighboring N atoms: add_adsorbate(slab, 'N', 1.5, (3, 1.7)) add_adsorbate(slab, 'N', 1.5, (1.5, 0.86)) ## If you are setting up the slab using the built in fcc111 or bcc110 functions, you can also directly specify the site name ## though you can only add one adsorbate per type of site with this function. e.g., # slab = fcc111(metal, a = a, size = (2,2,4), vacuum = 7.0) # add_adsorbate(slab, 'N', 1.5, 'ontop') # add_adsorbate(slab, 'N', 1.5, 'slab') # use ag to view the slab and find the right x,y position # save the trajectory file slab.write(metal + 'N+N.traj')
LAYER1 = 2 ADSORBATE = 2**7 FREE = 2**8 NEARADSORBATE = 2**9 # let us tag LAYER1 atoms to be FREE too. we can address it by LAYER1 or FREE tags = slab.get_tags() for i, tag in enumerate(tags): if tag == LAYER1: tags[i] += FREE slab.set_tags(tags) #create a CO molecule co = Atoms([ Atom('C', [0., 0., 0.], tag=ADSORBATE), Atom('O', [0., 0., 1.1], tag=ADSORBATE + FREE) ]) #we will relax only O add_adsorbate(slab, co, height=1.2, position='hollow') #the adsorbate is centered between atoms 20, 21 and 22 (use #view(slab)) and over atom12 let us label those atoms, so it is easy to #do electronic structure analysis on them later. tags = slab.get_tags() # len(tags) changed, so we reget them. tags[12] += NEARADSORBATE tags[20] += NEARADSORBATE tags[21] += NEARADSORBATE tags[22] += NEARADSORBATE slab.set_tags(tags) #update the tags slab.set_tags(tags) #extract pieces of the slab based on tags #atoms in the adsorbate ads = slab[(slab.get_tags() & ADSORBATE) == ADSORBATE] #atoms in LAYER1
from ase.lattice.surface 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) dim_rlx.run(fmax=0.001)
from ase import Atoms from ase.calculators.emt import EMT from ase.constraints import FixAtoms from ase.optimize import QuasiNewton from ase.lattice.surface 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())
from jasp import * from ase.lattice.surface import fcc111, add_adsorbate from ase.constraints import FixAtoms, FixScaled from ase.io import write atoms = fcc111('Pt', size=(2,2,3), vacuum=10.0) # note this function only works when atoms are created by the surface module. add_adsorbate(atoms, 'O', height=1.2, position='bridge') constraint1 = FixAtoms(mask=[atom.symbol != 'O' for atom in atoms]) # fix in xy-direction, free in z. actually, freeze movement in surface # unit cell, and free along 3rd lattice vector constraint2 = FixScaled(atoms.get_cell(), 12, [True, True, False]) atoms.set_constraint([constraint1, constraint2]) write('images/Pt-O-bridge-constrained-initial.png', atoms, show_unit_cell=2) print 'Initial O position: {0}'.format(atoms.positions[-1]) with jasp('surfaces/Pt-slab-O-bridge-xy-constrained', xc='PBE', kpts=(4,4,1), encut=350, ibrion=2, nsw=25, atoms=atoms) as calc: e_bridge = atoms.get_potential_energy() write('images/Pt-O-bridge-constrained-final.png', atoms, show_unit_cell=2) print 'Final O position : {0}'.format(atoms.positions[-1]) # now compute Hads with jasp('surfaces/Pt-slab') as calc: atoms = calc.get_atoms() e_slab = atoms.get_potential_energy() with jasp('molecules/O2-sp-triplet-350') as calc: atoms = calc.get_atoms() e_O2 = atoms.get_potential_energy()
from vasp import Vasp from ase.lattice.surface import fcc111, add_adsorbate from ase.constraints import FixAtoms atoms = fcc111("Pt", size=(2, 2, 3), vacuum=10.0) # note this function only works when atoms are created by the surface module. add_adsorbate(atoms, "O", height=1.2, position="hcp") constraint = FixAtoms(mask=[atom.symbol != "O" for atom in atoms]) atoms.set_constraint(constraint) from ase.io import write write("images/Pt-hcp-o-site.png", atoms, show_unit_cell=2) print( Vasp("surfaces/Pt-slab-O-hcp", xc="PBE", kpts=[4, 4, 1], encut=350, ibrion=2, nsw=25, atoms=atoms).potential_energy )
from ase.optimize import BFGS, QuasiNewton from ase.neb import SingleCalculatorNEB from ase.lattice.surface import fcc111, add_adsorbate from math import sqrt, cos, sin for mic 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 mic: # 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]], mic=True, atoms=slab) else: constraint = FixBondLengths([[-3,-2],[-3,-1]]) slab.set_constraint(constraint) dyn = BFGS(slab, trajectory='relax_%s.traj' % ('mic' if mic else 'no_mic')) dyn.run(fmax=0.05)
#!/usr/bin/env python from ase.calculators.aims import Aims from ase.lattice.surface import fcc111, add_adsorbate from ase.constraints import FixAtoms from ase import Atoms, Atom from ase.io import write adsorbate = Atoms('CO') adsorbate[1].z = 1.13 atoms = fcc111('Pt', size=(1, 1, 3), vacuum=5.0) constraint = FixAtoms(mask=[atom for atom in atoms]) atoms.set_constraint(constraint) # note this function only works when atoms are created by the surface module. add_adsorbate(atoms, adsorbate, height=1.6, position='ontop') write('images/pt-111-113-co-ontop.png', atoms, show_unit_cell=2) calc = Aims(label='surfaces/pt-111-113-co-ontop-relax', xc='pbe', spin='none', relativistic = 'atomic_zora scalar', kpts=(7, 7, 1), sc_accuracy_etot=1e-4, sc_accuracy_eev=1e-2, sc_accuracy_rho=1e-4, sc_accuracy_forces=1e-3, relax_geometry = 'bfgs 1.e-3') atoms.set_calculator(calc) print('energy = {0} eV'.format(atoms.get_potential_energy())) print(atoms.get_forces())
from jasp import * from ase.lattice.surface import fcc111, add_adsorbate from ase.constraints import FixAtoms atoms = fcc111('Pt', size=(2, 2, 3), vacuum=10.0) # note this function only works when atoms are created by the surface module. add_adsorbate(atoms, 'O', height=1.2, position='hcp') constraint = FixAtoms(mask=[atom.symbol != 'O' for atom in atoms]) atoms.set_constraint(constraint) from ase.io import write write('images/Pt-hcp-o-site.png', atoms, show_unit_cell=2) with jasp('surfaces/Pt-slab-O-hcp', xc='PBE', kpts=(4, 4, 1), encut=350, ibrion=2, nsw=25, atoms=atoms) as calc: calc.calculate()
# we had 6 layers, so we create new tags starting at 7 # Note you must use powers of two for all the tags! LAYER1 = 2 ADSORBATE = 2**7 FREE = 2**8 NEARADSORBATE = 2**9 # let us tag LAYER1 atoms to be FREE too. we can address it by LAYER1 or FREE tags = slab.get_tags() for i,tag in enumerate(tags): if tag == LAYER1: tags[i] += FREE slab.set_tags(tags) #create a CO molecule co= Atoms([Atom('C',[0., 0., 0. ], tag=ADSORBATE), Atom('O',[0., 0., 1.1], tag=ADSORBATE+FREE)]) #we will relax only O add_adsorbate(slab,co,height=1.2,position='hollow') #the adsorbate is centered between atoms 20, 21 and 22 (use #view(slab)) and over atom12 let us label those atoms, so it is easy to #do electronic structure analysis on them later. tags = slab.get_tags() # len(tags) changed, so we reget them. tags[12]+=NEARADSORBATE tags[20]+=NEARADSORBATE tags[21]+=NEARADSORBATE tags[22]+=NEARADSORBATE slab.set_tags(tags) #update the tags slab.set_tags(tags) #extract pieces of the slab based on tags #atoms in the adsorbate ads = slab[(slab.get_tags() & ADSORBATE) == ADSORBATE] #atoms in LAYER1
from ase.constraints import FixAtoms from ase.calculators.emt import EMT from ase.vibrations import Vibrations import ase.io import numpy as np import chemcoord as cc if os.path.exists('CH3_Al.traj'): slab = ase.io.read('CH3_Al.traj') slab.set_calculator(EMT()) # Need to reset when loading from traj file else: 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, trajectory='QN_slab.traj') dyn.run(fmax=0.05) ase.io.write('CH3_Al.traj', slab) # Running vibrational analysis vib = Vibrations(slab, indices=[8, 9, 10, 11]) vib.run() vib.summary()
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
# creates: io1.png io2.png io3.png from ase import Atoms from ase.lattice.surface 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') #view(slab) 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()
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))
from ase import io from ase.lattice.surface import add_adsorbate, fcc111, bcc110 # name of output trajectory file # lattice constant for fcc Pt name = 'N+N_Pt' # read in your optimized surface or cluster slab = io.read('surface.traj') # add adsorbate using add_adsorbate(surface,symbol,z,(x,y)) # where "surface" is the object containing the surface, "slab" in this case # and z is the position above the surface (from the center of the top most atom) # and x and y are the absolute coordinates # add two neighboring N atoms: add_adsorbate(slab, 'N', 1.5, (3, 1.7)) add_adsorbate(slab, 'N', 1.5, (1.5, 0.86)) ## If you are setting up the slab using the built in fcc111 or bcc110 functions, you can also directly specify the site name ## though you can only add one adsorbate per type of site with this function. e.g., # slab = fcc111(metal, a = a, size = (2,2,4), vacuum = 7.0) # add_adsorbate(slab, 'N', 1.5, 'ontop') # add_adsorbate(slab, 'N', 1.5, 'slab') # use ag to view the slab and find the right x,y position # save the trajectory file slab.write(metal+'N+N.traj')
# compute local potential of slab with no dipole from ase.lattice.surface import fcc111, add_adsorbate from jasp import * import matplotlib.pyplot as plt from ase.io import write slab = fcc111('Al', size=(2, 2, 2), vacuum=10.0) add_adsorbate(slab, 'Na', height=1.2, position='fcc') slab.center() write('images/Na-Al-slab.png', slab, rotation='-90x', show_unit_cell=2) with jasp( 'surfaces/Al-Na-nodip', xc='PBE', encut=340, kpts=(2, 2, 1), lvtot=True, # write out local potential lvhar=True, # write out only electrostatic potential, not xc pot atoms=slab) as calc: calc.calculate()
calc = GPAW(nbands=60, h=0.2, 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 = Calculator('gs.gpw').get_atoms() 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() #Find band corresponding to lumo
def save(name, slab): print('save %s' % name) write(name + '.png', slab, show_unit_cell=2, radii=radii[name[:3]], scale=10) for name in surfaces: f = eval('surface.' + name) for kwargs in [{}, {'orthogonal': False}, {'orthogonal': True}]: print(name, kwargs) try: slab = f(symbols[name[:3]], (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)
s0 = cutatoms[i2].position - cutatoms[i1].position s1 = cutatoms[i3].position - cutatoms[i1].position offset_vector = cutatoms[offset].position - cutatoms[i1].position # primitive cell cell = 3.6 / 2 * np.array([[0, 1, 1], [1, 0, 1], [1, 1, 0]], np.float) # rotated cell rcell = rotate_vector(cell, (h, k, l)) # this is the linear combination of rotated primitive vectors print 'h,k,l = (%i, %i, %i)' % (h, k, l) print ('s0 = np.array([%1.0f, %1.0f, %1.0f])' % tuple(np.dot(s0, np.linalg.inv(rcell)))) print ('s1 = np.array([%1.0f, %1.0f, %1.0f])' % tuple(np.dot(s1, np.linalg.inv(rcell)))) print ('offset = np.array([%1.0f, %1.0f, %1.0f])' % tuple(np.dot(offset_vector, np.linalg.inv(rcell)))) # slab = fcc_vicinal('Cu',3.6,'111',size=(1,1,4),vacuum=10) # view(fcc_vicinal('Cu',3.6,'110',nlayers=6,vacuum=10)) # view(fcc_vicinal('Cu',3.6,'100',nlayers=4,vacuum=10)) # view(fcc_vicinal('Cu',3.6,'211',nlayers=10,vacuum=10)) # slab = fcc_vicinal('Cu',3.6,'r3xr3-111',size=(1,1,4),vacuum=10) slab = fcc_vicinal('Cu', 3.6, '643', size=(1, 1, 40), vacuum=10) add_adsorbate(slab, 'N', 1.1, 'ontop') view(slab)
i3 = int(raw_input('Enter i3: ')) offset = int(raw_input('Enter offset: ')) s0 = cutatoms[i2].position - cutatoms[i1].position s1 = cutatoms[i3].position - cutatoms[i1].position offset_vector = cutatoms[offset].position - cutatoms[i1].position # primitive cell cell = 3.6 / 2 * np.array([[0, 1, 1], [1, 0, 1], [1, 1, 0]], np.float) # rotated cell rcell = rotate_vector(cell, (h, k, l)) # this is the linear combination of rotated primitive vectors print 'h,k,l = (%i, %i, %i)' % (h, k, l) print('s0 = np.array([%1.0f, %1.0f, %1.0f])' % tuple(np.dot(s0, np.linalg.inv(rcell)))) print('s1 = np.array([%1.0f, %1.0f, %1.0f])' % tuple(np.dot(s1, np.linalg.inv(rcell)))) print('offset = np.array([%1.0f, %1.0f, %1.0f])' % tuple(np.dot(offset_vector, np.linalg.inv(rcell)))) # slab = fcc_vicinal('Cu',3.6,'111',size=(1,1,4),vacuum=10) # view(fcc_vicinal('Cu',3.6,'110',nlayers=6,vacuum=10)) # view(fcc_vicinal('Cu',3.6,'100',nlayers=4,vacuum=10)) # view(fcc_vicinal('Cu',3.6,'211',nlayers=10,vacuum=10)) # slab = fcc_vicinal('Cu',3.6,'r3xr3-111',size=(1,1,4),vacuum=10) slab = fcc_vicinal('Cu', 3.6, '643', size=(1, 1, 40), vacuum=10) add_adsorbate(slab, 'N', 1.1, 'ontop') view(slab)
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)
import numpy as np from ase import Atoms, Atom from ase.lattice.surface 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
from __future__ import print_function from ase.visualize import view from ase.constraints import FixAtoms from ase.optimize import QuasiNewton from ase.lattice.surface import fcc100, add_adsorbate from gpaw import GPAW, PW # Initial state: # 2x2-Al(001) surface with 1 layer and an # Au atom adsorbed in a hollow site: slab = fcc100('Al', size=(2, 2, 2)) slab.center(axis=2, vacuum=3.0) add_adsorbate(slab, 'Au', 1.6, 'hollow') # Make sure the structure is correct: view(slab) # Fix the Al atoms: mask = [atom.symbol == 'Al' for atom in slab] print(mask) fixlayer = FixAtoms(mask=mask) slab.set_constraint(fixlayer) # Use GPAW: calc = GPAW(mode=PW(200), kpts=(2, 2, 1), xc='PBE', txt='hollow.txt') slab.set_calculator(calc) qn = QuasiNewton(slab, trajectory='hollow.traj') # Find optimal height. The stopping criterion is: the force on the # Au atom should be less than 0.05 eV/Ang
from ase.lattice.surface import fcc111, add_adsorbate, fcc100, fcc110, hcp0001, bcc111 import os import sys import shutil nargs = len(sys.argv) argv1 = sys.argv[1] argv2 = sys.argv[2] fname = 'scratch/structure' + argv1 tmpDir = os.getenv('PBSTMPDIR') folder = 'scratch/vasp' + argv1 #lattice and initial atom setup for unit cell slab = fcc111('Pt', size=(3, 3, 3), vacuum=10) add_adsorbate(slab, 'Au', 2.5, 'fcc') #current position read in slabatoms = read(fname) slab.set_positions(slabatoms.get_positions()) 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,