def fcc211(symbol, size, a=None, vacuum=None, orthogonal=True): """FCC(211) surface. Does not currently support special adsorption sites. Currently only implemented for *orthogonal=True* with size specified as (i, j, k), where i, j, and k are number of atoms in each direction. i must be divisible by 3 to accommodate the step width. """ if not orthogonal: raise NotImplementedError('Only implemented for orthogonal ' 'unit cells.') if size[0] % 3 != 0: raise NotImplementedError('First dimension of size must be ' 'divisible by 3.') atoms = FaceCenteredCubic(symbol, directions=[[1, -1, -1], [0, 2, -2], [2, 1, 1]], miller=(None, None, (2, 1, 1)), latticeconstant=a, size=(1, 1, 1), pbc=True) z = (size[2] + 1) // 2 atoms = atoms.repeat((size[0] // 3, size[1], z)) if size[2] % 2: # Odd: remove bottom layer and shrink cell. remove_list = [atom.index for atom in atoms if atom.z < atoms[1].z] del atoms[remove_list] dz = atoms[0].z atoms.translate((0., 0., -dz)) atoms.cell[2][2] -= dz atoms.cell[2] = 0.0 atoms.pbc[2] = False if vacuum: atoms.center(vacuum, axis=2) # Renumber systematically from top down. orders = [(atom.index, round(atom.x, 3), round(atom.y, 3), -round(atom.z, 3), atom.index) for atom in atoms] orders.sort(key=itemgetter(3, 1, 2)) newatoms = atoms.copy() for index, order in enumerate(orders): newatoms[index].position = atoms[order[0]].position.copy() # Add empty 'sites' dictionary for consistency with other functions newatoms.info['adsorbate_info'] = {'sites': {}} return newatoms
def test_center(): # flake8: noqa "Test that atoms.center() works when adding vacuum ()" import numpy as np from math import pi, sqrt, cos from ase import data from ase.lattice.cubic import FaceCenteredCubic def checkang(a, b, phi): "Check the angle between two vectors." cosphi = np.dot(a, b) / sqrt(np.dot(a, a) * np.dot(b, b)) assert np.abs(cosphi - cos(phi)) < 1e-10 symb = "Cu" Z = data.atomic_numbers[symb] a0 = data.reference_states[Z]['a'] # (100) oriented block atoms = FaceCenteredCubic(size=(5, 5, 5), symbol="Cu", pbc=(1, 1, 0)) assert len(atoms) == 5 * 5 * 5 * 4 c = atoms.get_cell() checkang(c[0], c[1], pi / 2) checkang(c[0], c[2], pi / 2) checkang(c[1], c[2], pi / 2) assert np.abs(5 * a0 - c[2, 2]) < 1e-10 # Add vacuum in one direction vac = 10.0 atoms.center(axis=2, vacuum=vac) c = atoms.get_cell() checkang(c[0], c[1], pi / 2) checkang(c[0], c[2], pi / 2) checkang(c[1], c[2], pi / 2) assert np.abs(4.5 * a0 + 2 * vac - c[2, 2]) < 1e-10 # Add vacuum in all directions vac = 4.0 atoms.center(vacuum=vac) c = atoms.get_cell() checkang(c[0], c[1], pi / 2) checkang(c[0], c[2], pi / 2) checkang(c[1], c[2], pi / 2) assert np.abs(4.5 * a0 + 2 * vac - c[0, 0]) < 1e-10 assert np.abs(4.5 * a0 + 2 * vac - c[1, 1]) < 1e-10 assert np.abs(4.5 * a0 + 2 * vac - c[2, 2]) < 1e-10 # Now a general unit cell atoms = FaceCenteredCubic(size=(5, 5, 5), directions=[[1, 0, 0], [0, 1, 0], [1, 0, 1]], symbol="Cu", pbc=(1, 1, 0)) assert len(atoms) == 5 * 5 * 5 * 2 c = atoms.get_cell() checkang(c[0], c[1], pi / 2) checkang(c[0], c[2], pi / 4) checkang(c[1], c[2], pi / 2) assert np.abs(2.5 * a0 - c[2, 2]) < 1e-10 # Add vacuum in one direction vac = 10.0 atoms.center(axis=2, vacuum=vac) c = atoms.get_cell() checkang(c[0], c[1], pi / 2) checkang(c[0], c[2], pi / 4) checkang(c[1], c[2], pi / 2) assert np.abs(2 * a0 + 2 * vac - c[2, 2]) < 1e-10 # Recenter without specifying vacuum atoms.center() c = atoms.get_cell() checkang(c[0], c[1], pi / 2) checkang(c[0], c[2], pi / 4) checkang(c[1], c[2], pi / 2) assert np.abs(2 * a0 + 2 * vac - c[2, 2]) < 1e-10 a2 = atoms.copy() # Add vacuum in all directions vac = 4.0 atoms.center(vacuum=vac) c = atoms.get_cell() checkang(c[0], c[1], pi / 2) checkang(c[0], c[2], pi / 4) checkang(c[1], c[2], pi / 2) assert np.abs(4.5 * a0 + 2 * vac - c[1, 1]) < 1e-10 assert np.abs(2 * a0 + 2 * vac - c[2, 2]) < 1e-10 # One axis at the time: for i in range(3): a2.center(vacuum=vac, axis=i) assert abs(atoms.positions - a2.positions).max() < 1e-12 assert abs(atoms.cell - a2.cell).max() < 1e-12
x1 = 1.379 x2 = 4.137 x3 = 2.759 y1 = 0.0 y2 = 2.238 z1 = 7.165 z2 = 6.439 #Add the adatom to the list of atoms and set constraints of surface atoms. slab += Atoms('N', [((x2 + x1) / 2, y1, z1 + 1.5)]) mask = [atom.symbol == 'Pt' for atom in slab] slab.set_constraint(FixAtoms(mask=mask)) #optimise the initial state # Atom below step initial = slab.copy() initial.set_calculator(EMT()) relax = QuasiNewton(initial) relax.run(fmax=0.05) view(initial) #optimise the initial state # Atom above step slab[-1].position = (x3, y2 + 1, z2 + 3.5) final = slab.copy() final.set_calculator(EMT()) relax = QuasiNewton(final) relax.run(fmax=0.05) view(final) #create a list of images for interpolation
raise ValueError("Argument to pbc should be a string of three digits.") pbc = [] for i in (0, 1, 2): pbc.append(int(pbcch[i])) print "Periodic boundary conditions forced!" else: pbc = tuple(random.randint(0, 2, 3)) print "Periodic boundaries:", pbc #Verbose(1) atoms = FaceCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], size=(10, 10, 10), symbol=element, pbc=pbc) atoms2 = atoms.copy() atoms = MonteCarloAtoms(atoms) print "Number of atoms:", len(atoms) # Replace 10% of the atoms with element2 newz = where(greater(random.random((len(atoms), )), 0.9), element2number, elementnumber) atoms.set_atomic_numbers(newz) atoms2.set_atomic_numbers(newz) atoms.set_calculator(MonteCarloEMT()) atoms2.set_calculator(EMT()) atoms.get_potential_energy() for e in ((element, elementnumber), (element2, element2number)): print("Number of %s atoms (Z=%d): %d" % (e[0], e[1], sum(equal(atoms.get_atomic_numbers(), e[1]))))
t.write() return e def checktraj(t, e): i = 0 for atoms in t: atoms.set_calculator(EMT()) ReportTest("Checking frame %d" % (i, ), atoms.get_potential_energy(), e[i], precision) i += 1 initial = FaceCenteredCubic(size=(10, 10, 10), symbol="Cu", pbc=(1, 0, 0)) atoms = initial.copy() atoms.set_calculator(EMT()) print "Writing trajectory" traj = PickleTrajectory("traj1.traj", "w", atoms) traj.write() energies = maketraj(atoms, traj, 10) traj.close() print "Reading trajectory" traj = PickleTrajectory("traj1.traj") checktraj(traj, energies) print "Repeating simulation" atoms = traj[5] atoms.set_calculator(EMT()) energies2 = maketraj(atoms, None, 5)
import random ref_atoms = FaceCenteredCubic(size=(7, 7, 7), symbol="Cu", pbc=(True, False, True)) ref_atoms.set_calculator(EMT()) ref_energy = ref_atoms.get_potential_energy() ref_energies = ref_atoms.get_potential_energies() ref_forces = ref_atoms.get_forces() passes = 5 for ps in range(passes): print "Pass", ps, "of", passes atoms = ref_atoms.copy() atoms.set_calculator(EMT()) nat = random.randint(0, len(atoms)) assert nat < len(atoms) pos0 = atoms[nat].position cell = atoms.get_cell() for d in range(1, 4): for dx in (-d, 0, d): #for dy in (-d, 0, d): for dy in (0, ): for dz in (-d, 0, d): deltar = dx * cell[0] + dy * cell[1] + dz * cell[2] atoms[nat].position = pos0 + deltar label = "(%2d, %2d, %2d)" % (dx, dy, dz) ReportTest("Pot. energy " + label, atoms.get_potential_energy(), ref_energy, 1e-6)
else: boundaries = ((1, 1, 1), (0, 0, 0), (0, 0, 1)) for pbc in boundaries: txt = nbltype + (" PBC=%1i%1i%1i " % pbc) # Test that EMT reimported through OpenKIM gives the right results. atoms_kim = FaceCenteredCubic(size=(10, 10, 10), symbol='Cu') #atoms_kim = FaceCenteredCubic(directions=[[1,0,0],[0,1,0],[0,0,1]], # size=(30, 30, 30), # symbol="Cu") natoms = len(atoms_kim) atoms_kim.set_pbc(pbc) r = atoms_kim.get_positions() r.flat[:] += 0.1 * np.sin(np.arange(3 * natoms)) atoms_kim.set_positions(r) atoms_emt = atoms_kim.copy() kim = OpenKIMcalculator(openkimmodel, allowed=nbltype) emt = EMT() emt.set_subtractE0(False) atoms_kim.set_calculator(kim) atoms_emt.set_calculator(emt) ek = atoms_kim.get_potential_energy() ee = atoms_emt.get_potential_energy() ReportTest(txt + "Total energy", ek, ee, 1e-8) ek = atoms_kim.get_potential_energies() ee = atoms_emt.get_potential_energies() for i in range(0, natoms, step): ReportTest(txt + "Energy of atom %i" % (i, ), ek[i], ee[i], 1e-8) fk = atoms_kim.get_forces() fe = atoms_emt.get_forces() n = 0
atoms2.set_calculator(emt) f3 = atoms1.get_forces() maxdev = abs(f3 - f1).max() print maxdev ReportTest("Max error 1:", maxdev, 0.0, 1e-6) atoms1 = FaceCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], size=(6, 6, 6), symbol="Pt") emt = pot() atoms1.set_calculator(emt) f1 = atoms1.get_forces() atoms2 = FaceCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], size=(5, 5, 5), symbol="Pt") atoms2.set_calculator(emt) atoms3 = atoms2.copy() atoms3.set_calculator(pot()) f0 = atoms3.get_forces() f2 = atoms2.get_forces() f3 = atoms1.get_forces() maxdev = abs(f2 - f0).max() print maxdev ReportTest("Max error 2:", maxdev, 0.0, 1e-6) maxdev = abs(f3 - f1).max() print maxdev ReportTest("Max error 3:", maxdev, 0.0, 1e-6) ReportTest.Summary()