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
A simplified interface to
AdsorbateComplexFactoryusinggenerate_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
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:
objectGenerate adsorption complexes from structures and adsorbates.
Given an adsorbate and a structure, an
AdsorbateComplexFactorygenerates all adsorption complexes on all sites of all orientations, alignments, and centers.- Variables:
site_finder – A callable that accepts an
Atomsobject and returns an iterable of sites on the structure.orientation_factory – An
OrientationFactoryresponsible for generatingMolecularOrientationsfromAdsorptionSitesand an adsorbate.center_factory – A
CenterFactorythat 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
Atomsobject and returns an iterable of sites on the structure.orientation_factory – An
OrientationFactoryresponsible for generatingAdsorbateOrientationsfromAdsorptionSites,AdsorptionCenters, and adsorbates. The default will align adsorbates to site aligments using their primary axis.center_factory – A
CenterFactorythat 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.
- 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
Atomsinstance representing the structure on which to place the adsorbate.adsorbate – An
Atomsinstance representing the adsorbate to be placed.site – An
AdsorptionSiteinstance 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
Atomsobject from a file and stores filename.The plain text description is stored in the
infodictionary 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
Atomsobject.
- 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, orAtomsobject. If passed as a string, the string will be used to retrieve the corresponding adsorbate usingccu.adsorption.adsorbates.get_adsorbate(). If passed as a path, anAtomsobject will be read from the associated file. If passed as anAtomsobject, then the"structure"key ofadsorbate.infomust map to a string.structure – The structure on which
adsorbateis to be be placed. If passed as a string or path, the structure will be read from the indicated file. If passed as anAtomsobject, then the"structure"key ofstructure.infomust 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 thatadsorbatewill be placed using its center-of-mass."special"indicates that the atoms indicated by the"special_centers"key inadsorbate.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
Atomsobject and returns an iterable of sites on the structure. Defaults toTriangulator().adsorbate_tag – The tag to give to adsorbate atoms. Defaults to
DEFAULT_ADSORBATE_TAG.
- Returns:
A list of
Atomsobjects 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.trajThe “structure”, “adsorbate”, “site”, “center”, and “orientation” components are derived from the corresponding values in
Atoms.info.Nis a zero-indexed label that is incremented so as to avoid filename clashes.- Parameters:
complexes – A list of
Atomsobjects representing complexes, such as that created byAdsorbateComplexFactory.get_complexes(). In order for the trajectory files to be templated correctly, the keys,"structure","adsorbate", and"site"must be present in theAtoms.infodictionary of eachAtomsobject incomplexes."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.