Au7 on Cu(111) with EMT

In this tutorial we carry out a search for Au7-clusters on the Cu(111) surface.

In this search we will utilize an OperationConstraint to constraint the RattleMutation to only rattle the atoms within a certain box in space that we define.

The following script Au7_on_Cu111.py is used to carry out the constrainted search:

import numpy as np

from ase.build import fcc111
from ase.constraints import FixAtoms
from ase.calculators.emt import EMT

from gofee.candidates import CandidateGenerator, StartGenerator, RattleMutation, PermutationMutation
from gofee.utils import OperationConstraint
from gofee import GOFEE

### Define calculator ###
calc = EMT()

### Set up system ###
# 1-layer fixed Cu(111) slab
template = fcc111('Cu', size=(5, 5, 1), vacuum=10.0)
c = FixAtoms(indices=np.arange(len(template)))
template.set_constraint(c)

# Stoichiometry of atoms to be placed
stoichiometry = 7*[79]

## Box for startgenerator and rattle-mutation
k = 0.2  # Shrinkage fraction from each side of the box in v[0] and v[1] directions.
cell = template.get_cell()
# Initialize box with cell
v = np.copy(cell)
# Set height of box
v[2][2] = 5
# Shrink box in v[0] and v[1] directions
v[0] *= (1-2*k)
v[1] *= (1-2*k)
# Chose anker point p0 so box in centered in v[0] and v[1] directions.
z_max_slab = np.max(template.get_positions()[:,2])
p0 = np.array((0, 0, z_max_slab+0.3)) + k*(cell[0]+cell[1])
# Make box
box = [p0, v]

# initialize startgenerator (used to generate initial structures)
sg = StartGenerator(template, stoichiometry, box)

### Set up candidate generation operations ###
# Set up constraint for rattle-mutation
box_constraint = OperationConstraint(box=box)

# initialize rattle-mutation
n_to_optimize = len(stoichiometry)
rattle = RattleMutation(n_to_optimize, Nrattle=2, rattle_range=4)

candidate_generator = CandidateGenerator([0.2, 0.8], [sg, rattle])

### Initialize and run search ###
search = GOFEE(calc=calc,
               startgenerator=sg,
               candidate_generator=candidate_generator,
               max_steps=150,
               population_size=5,
               position_constraint=box_constraint)
search.run()

And run using:

mpiexec python Au7_on_Cu111.py

What follows is a description of the elements of the python code above, which relates to consraining the atomix position during the search.

Box setup

As previously in the Cu15 cluster search, we define a box in which initial atoms are placed. In this example we will also use this box to constrain the position of the “free” atoms during the search. Defining a box positioned 0.3Å above the slab, with a height of 5Å and with xy-dimensions shrunk, from all sides by a fraction “k”, relative to the cell xy-dimensions, can be achieved by:

## Box for startgenerator and rattle-mutation
k = 0.2  # Shrinkage fraction from each side of the box in v[0] and v[1] directions.
cell = template.get_cell()
# Initialize box with cell
v = np.copy(cell)
# Set height of box
v[2][2] = 5
# Shrink box in v[0] and v[1] directions
v[0] *= (1-2*k)
v[1] *= (1-2*k)
# Chose anker point p0 so box in centered in v[0] and v[1] directions.
z_max_slab = np.max(template.get_positions()[:,2])
p0 = np.array((0, 0, z_max_slab+0.3)) + k*(cell[0]+cell[1])
# Make box
box = [p0, v]

Constraint object

The constrraint object is made using:

from gofee.utils import OperationConstraint
box_constraint = OperationConstraint(box=box)