ASE doesn't support adding multiple adsorbates. If you use the ase.build.add_adsorbate
function multiple times, it will unfortunately add adsorbates to the same pre-defined position. This is a typical situation where you may consider using ACAT. For your example, this can be simply achieved by the following code:
from ase.build import surface
from ase.visualize import view
from acat.build.adlayer import max_dist_coverage_pattern as mdcp
from acat.settings import site_heights
# Create the copper surface
slab = surface('Cu', (1, 1, 1), 4)
slab = slab.repeat((4, 4, 1))
slab.center(vacuum=10, axis=2)
# Add more heights to the CHOO*
heights = {k: v+0.5 for k, v in site_heights.items()}
# Generate a random surface coverage pattern with 10 CHOO*
atoms = mdcp(slab, adsorbate_species='CHOO', coverage=10/64,
surface='fcc111', heights=heights)
view(atoms)
Now if you want to rotate the bidentate adsorbates, you can use ASE-GUI to do that, or if you want completely random generation, including the rotation of multidentate adsorbate species, you can use acat.build.RandomPatternGenerator
. It also allows you to specify which sites are not allowed to adsorb, and the minimum distance between two adsorbates. Below is an example:
from ase.io import read
from ase.build import surface
from ase.visualize import view
from acat.build.adlayer import RandomPatternGenerator as RPG
from acat.settings import site_heights
# Create the copper surface
slab = surface('Cu', (1, 1, 1), 4)
slab = slab.repeat((4, 4, 1))
slab.center(vacuum=10, axis=2)
# Add more heights to the CHOO*
heights = {k: v+0.5 for k, v in site_heights.items()}
gen = RPG(slab, adsorbate_species='CHOO',
min_adsorbate_distance=1.5,
surface='fcc111',
heights=heights,
species_forbidden_sites={'CHOO': ['ontop','bridge']},
trajectory='Cu_111_10CHOO.traj')
gen.run(num_gen=1, action='add', num_act=10)
atoms = read('Cu_111_10CHOO.traj')
view(atoms)
Disclaimer: I am the developer of ACAT.