ccu.adsorption.complexes

Generate adsorbate complexes.

Specifically, this module defines the AdsorbateComplexFactory class which combines the functionalities of the SiteFinder, OrientationFactory, and CenterFactory classes to generate adsorbate complexes.

Examples

  1. A simplified interface to AdsorbateComplexFactory using generate_complexes().

>>> import numpy as np
>>> from ase.atoms import Atoms
>>> from ase.build import fcc100
>>> from ccu.adsorption.complexes import generate_complexes
>>> from ccu.adsorption.sites import AdsorptionSite, SiteAlignment
... # Create a 3 x 3 x 1 Cu(100) surface
>>> cu100 = fcc100("Cu", (3, 3, 1))
... # "Dope" the surface with Ag
>>> cu100.set_chemical_symbols(
...     [(a.symbol if a.index % 2 == 0 else "Ag") for a in cu100]
... )
>>> cu100.center(vacuum=10, axis=2)
>>> # This site-finder always returns an adsorption site on the first atom
>>> def finder(structure: Atoms) -> list[AdsorptionSite]:
...     return [
...         AdsorptionSite(
...             position=structure[0].position,
...             description=f"on {structure[0].symbol}",
...             alignments=[SiteAlignment(np.array([1.0, 0.0, 0.0]), "x")],
...             norm=np.array([0, 0.0, 1.0]),
...         )
...     ]
>>> complexes = generate_complexes(
...     structure=cu100,
...     adsorbate="H",
...     finder=finder,
...     symmetry=True,
... )
>>> len(complexes)
1
  1. Fine-tuned control over all aspects of adsorbate complex generation using AdsorbateComplexFactory.

>>> from ase.build import fcc100
>>> from ccu.adsorption.adsorbates import get_adsorbate
>>> from ccu.adsorption.complexes import AdsorbateComplexFactory
>>> from ccu.adsorption.orientation import Transformer, atomic_centerer
>>> from ccu.adsorption.sites import HubSpokeFinder, HUB_TAG, SPOKE_TAG
>>> from ccu.structure.symmetry import Rotation
... # Create a 3 x 3 x 1 Cu(100) surface
>>> cu100 = fcc100("Cu", (3, 3, 1))
>>> tags = [0] * len(cu100)
... # Tag hub and spoke atoms
>>> tags[4] = HUB_TAG
>>> tags[1] = tags[3] = tags[5] = tags[7] = SPOKE_TAG
>>> cu100.set_tags(tags)
... # Create two adsorbate orientations per site alignment
>>> transformer = Transformer([Rotation(0), Rotation(180)])
>>> factory = AdsorbateComplexFactory(
...     site_finder=HubSpokeFinder(),
...     orientation_factory=transformer,
...     # Create adsorbate complexes centered on each atom in adsorbate
...     center_factory=atomic_centerer,
...     # Reduce minimum surface-adsorbate separation to 1.5 Angstroms
...     separation=1.5,
...     # Tag all adsorbate atoms with -50
...     adsorbate_tag=-50,
... )
>>> co2 = get_adsorbate("CO2")
>>> complexes = factory.get_complexes(cu100, co2)
>>> len(complexes)
24
class ccu.adsorption.complexes.AdsorbateComplexFactory(site_finder: SiteFinder, orientation_factory: OrientationFactory | None = None, center_factory: CenterFactory | None = None, separation: float = 1.8, adsorbate_tag: int = -99)[source]

Bases: object

Generate adsorption complexes from structures and adsorbates.

Given an adsorbate and a structure, an AdsorbateComplexFactory generates all adsorption complexes on all sites of all orientations, alignments, and centers.

Variables:
  • site_finder – A callable that accepts an Atoms object and returns an iterable of sites on the structure.

  • orientation_factory – An OrientationFactory responsible for generating MolecularOrientations from AdsorptionSites and an adsorbate.

  • center_factory – A CenterFactory that will generate displacements from adsorbates.

  • separation – The distance (in Angstroms) that the adsorbate should be placed from the surface.

  • adsorbate_tag – An integer to be used to tag adsorbate atoms in adsorbate complexes.

Create an AdsorbateComplexFactory.

Parameters:
  • site_finder – A callable that accepts an Atoms object and returns an iterable of sites on the structure.

  • orientation_factory – An OrientationFactory responsible for generating AdsorbateOrientations from AdsorptionSites, AdsorptionCenters, and adsorbates. The default will align adsorbates to site aligments using their primary axis.

  • center_factory – A CenterFactory that will generate displacements from adsorbates. The default will place adsorbates using their center-of-mass.

  • separation – The distance (in Angstroms) that the adsorbate should be placed from the surface. Defaults to 1.8.

  • adsorbate_tag – An integer to be used to tag adsorbate atoms in adsorbate complexes. Defaults to DEFAULT_ADSORBATE_TAG.

get_complexes(structure: Atoms, adsorbate: Atoms) list[Atoms][source]

Generate adsorbate-surface complexes on a given site.

Parameters:
  • structure – An Atoms object representing the structure.

  • adsorbate – An Atoms object representing the adsorbate.

Returns:

A list of adsorption complexes for the site.

place_adsorbate(structure: Atoms, adsorbate: Atoms, site: AdsorptionSite) None[source]

Center an adsorbate onto a site using the adsorbate origin.

The adsorbate is placed on the specified site while respecting the minimum specified separation.

Parameters:
  • structure – An Atoms instance representing the structure on which to place the adsorbate.

  • adsorbate – An Atoms instance representing the adsorbate to be placed.

  • site – An AdsorptionSite instance representing the site on which the adsorbate is to be placed.

ccu.adsorption.complexes.DEFAULT_ADSORBATE_TAG = -99

The default tag to use for adsorbates when creating adsorbate complexes

ccu.adsorption.complexes._get_structure_with_name(structure: str | Path, *, preserve_info: bool = False) Atoms[source]

Load an Atoms object from a file and stores filename.

The plain text description is stored in the info dictionary of the structure under the key "structure" and can be accessed as follows:

atoms = _get_structure_with_name(structure)
structure_description = atoms.info["structure"]
Parameters:
  • structure – The path to the structure to be loaded. Note that if loading the structure returns more than one structure, the last structure will be loaded.

  • preserve_info – Whether or not to preserve the structure information in the info dictionary. If False, the "structure" key will be overriden if set. Defaults to False.

Returns:

The loaded Atoms object.

ccu.adsorption.complexes.generate_complexes(adsorbate: str | Path | Atoms, structure: str | Path | Atoms, *, separation: float = 1.8, centers: Literal['com', 'special', 'all'] = 'com', symmetry: bool = False, finder: SiteFinder | None = None, adsorbate_tag: int = -99) list[Atoms][source]

A convenience wrapper around AdsorbateComplexFactory.get_complexes().

Parameters:
  • adsorbate – The adsorbate to place on structure. This can be passed as a string, path, or Atoms object. If passed as a string, the string will be used to retrieve the corresponding adsorbate using ccu.adsorption.adsorbates.get_adsorbate(). If passed as a path, an Atoms object will be read from the associated file. If passed as an Atoms object, then the "structure" key of adsorbate.info must map to a string.

  • structure – The structure on which adsorbate is to be be placed. If passed as a string or path, the structure will be read from the indicated file. If passed as an Atoms object, then the "structure" key of structure.info must map to a str.

  • separation – A float indicating how far (in Angstroms) the adsorbate should be placed from the surface. Defaults to 1.8.

  • centers – A string indicating what kind of centers will be used to place adsorbate. "com" indicates that adsorbate will be placed using its center-of-mass. "special" indicates that the atoms indicated by the "special_centers" key in adsorbate.info. "all" indicates that all atomic centers will be used.

  • symmetry – A bool indicating whether or not the symmetry of the adsorbate is to be considered when generating complexes. Defaults to False.

  • finder – A callable that accepts an Atoms object and returns an iterable of sites on the structure. Defaults to Triangulator().

  • adsorbate_tag – The tag to give to adsorbate atoms. Defaults to DEFAULT_ADSORBATE_TAG.

Returns:

A list of Atoms objects representing adsorption complexes.

ccu.adsorption.complexes.write_complexes(complexes: list[Atoms], dir_name: Path) list[Path][source]

A utility function for automatically saving adsorption complexes.

Adsorption complexes are saved with the generic format:

structure_adsorbate_site_center_orientation__N.traj

The “structure”, “adsorbate”, “site”, “center”, and “orientation” components are derived from the corresponding values in Atoms.info. N is a zero-indexed label that is incremented so as to avoid filename clashes.

Parameters:
  • complexes – A list of Atoms objects representing complexes, such as that created by AdsorbateComplexFactory.get_complexes(). In order for the trajectory files to be templated correctly, the keys, "structure", "adsorbate", and "site" must be present in the Atoms.info dictionary of each Atoms object in complexes. "orientation" may optionally be present.

  • dir_name – The directory in which to save the complexes.

Returns:

The list of files to which the adsorption complexes were written.