Cluster space¶
Setting up a cluster space¶
The cluster space serves as a basis for cluster expansions. Setting up a clusterspace object is commonly done via
>>> from icet import ClusterSpace
>>> from ase.build import bulk
>>> primitive_structure = bulk('Si')
>>> cs = ClusterSpace(primitive_structure, cutoffs=[7.0, 5.0], chemical_symbols=['Si', 'Ge'])
The cutoffs are set up to include pairs with an interatomic distance smaller than 7 Å and triplets for which all pair-wise interatomic distances are smaller than 5 Å. Here, Si and Ge are allowed to occupy the reference lattice.
Sublattices¶
A cluster space can also be constructed with multiple sublattices. Consider for example a rocksalt lattice, on which we want to allow mixing of Na and Li on the Na sublattice and Cl and F on the Cl sublattices. This can be achived by
>>> from ase.build import bulk
>>> atoms = bulk('NaCl', 'rocksalt', a=4.0)
>>> chemical_symbols = [['Na', 'Li'], ['Cl', 'F']]
>>> cs = ClusterSpace(atoms, [7.0, 5.0], chemical_symbols)
where chemical_symbols
now specifies which species are allowed
for each lattice site in atoms.
Inactive sites¶
The sublattice functionality also allows one to have inactive sites. For example, if we consider the system above but would like to keep the Cl lattice fixed it can be achived via
>>> chemical_symbols = [['Na', 'Li'], ['Cl']]
>>> cs = ClusterSpace(atoms, [7.0, 5.0], chemical_symbols)
2D systems¶
icet requires input structures to have periodic boundary conditions (PBCs). In order to treat two-dimensional systems, or more generally without PBCs in at least one direction, one has to surround the prototype structure with vacuum and then apply PBCs in all directions. This can easily be achived with the ASE functions
>>> from ase.build import surface
>>> atoms = surface('Cu', (1,1,1), layers=7)
which creates ase atoms object without PBC in the z-direction. The structure can be modified to have PBC in the z-direction with vacuum via
>>> atoms.pbc = [True, True, True]
>>> atoms.center(vacuum=20, axis=2)
which can now be used to create a cluster space.
Interface¶
- class icet.ClusterSpace(structure, cutoffs, chemical_symbols, symprec=1e-05, position_tolerance=None)[source]¶
This class provides functionality for generating and maintaining cluster spaces.
Note
In icet all
Atoms
objects must have periodic boundary conditions. When constructing cluster expansions for surfaces and nanoparticles it is therefore recommended to surround the structure with vacuum and use periodic boundary conditions. This can be achieved by usingAtoms.center
.- Parameters:
structure (
Atoms
) – Atomic structure.cutoffs (
List
[float
]) –Cutoff radii per order that define the cluster space.
Cutoffs are specified in units of Ångstrom and refer to the longest distance between two atoms in the cluster. The first element refers to pairs, the second to triplets, the third to quadruplets, and so on.
cutoffs=[7.0, 4.5]
thus implies that all pairs distanced 7 Å or less will be included, as well as all triplets among which the longest distance is no longer than 4.5 Å.chemical_symbols (
Union
[List
[str
],List
[List
[str
]]]) –List of chemical symbols, each of which must map to an element of the periodic table.
If a list of chemical symbols is provided, all sites on the lattice will have the same allowed occupations as the input list.
If a list of list of chemical symbols is provided then the outer list must be the same length as the
structure
object andchemical_symbols[i]
will correspond to the allowed species on lattice sitei
.symprec (
float
) – Tolerance imposed when analyzing the symmetry using spglib.position_tolerance (
Optional
[float
]) – Tolerance applied when comparing positions in Cartesian coordinates.
Examples
The following snippets illustrate several common situations:
>>> from ase.build import bulk >>> from ase.io import read >>> from icet import ClusterSpace >>> # AgPd alloy with pairs up to 7.0 A and triplets up to 4.5 A >>> prim = bulk('Ag') >>> cs = ClusterSpace(structure=prim, cutoffs=[7.0, 4.5], ... chemical_symbols=[['Ag', 'Pd']]) >>> print(cs) >>> # (Mg,Zn)O alloy on rocksalt lattice with pairs up to 8.0 A >>> prim = bulk('MgO', crystalstructure='rocksalt', a=6.0) >>> cs = ClusterSpace(structure=prim, cutoffs=[8.0], ... chemical_symbols=[['Mg', 'Zn'], ['O']]) >>> print(cs) >>> # (Ga,Al)(As,Sb) alloy with pairs, triplets, and quadruplets >>> prim = bulk('GaAs', crystalstructure='zincblende', a=6.5) >>> cs = ClusterSpace(structure=prim, cutoffs=[7.0, 6.0, 5.0], ... chemical_symbols=[['Ga', 'Al'], ['As', 'Sb']]) >>> print(cs) >>> # PdCuAu alloy with pairs and triplets >>> prim = bulk('Pd') >>> cs = ClusterSpace(structure=prim, cutoffs=[7.0, 5.0], ... chemical_symbols=[['Au', 'Cu', 'Pd']]) >>> print(cs)
- property as_list: List[dict]¶
Representation of cluster space as list with information regarding order, radius, multiplicity etc.
- assert_structure_compatibility(structure, vol_tol=1e-05)[source]¶
Raises error if structure is not compatible with this cluster space.
- Parameters:
structure (
Atoms
) – Structure to check for compatibility with cluster space.vol_tol (
float
) – Tolerance imposed when comparing volumes.
- Return type:
None
- property chemical_symbols: List[List[str]]¶
Species identified by their chemical symbols.
- copy()[source]¶
Returns copy of
ClusterSpace
instance.
- property cutoffs: List[float]¶
Cutoffs for different n-body clusters. The cutoff radius (in Ångstroms) defines the largest interatomic distance in a cluster.
- property fractional_position_tolerance: float¶
Tolerance applied when comparing positions in fractional coordinates.
- get_coordinates_of_representative_cluster(orbit_index)[source]¶
Returns the positions of the sites in the representative cluster of the selected orbit.
- Parameters:
orbit_index (
int
) – Index of the orbit for which to return the positions of the sites.- Return type:
List
[Tuple
[float
]]
- get_multiplicities()[source]¶
Get multiplicities for each cluster space element as a list.
- Return type:
List
[int
]
- get_possible_orbit_occupations(orbit_index)[source]¶
Returns possible occupations of the orbit.
- Parameters:
orbit_index (
int
) – Index of orbit of interest.- Return type:
List
[List
[str
]]
- get_sublattices(structure)[source]¶
Returns the sublattices of the input structure.
- Parameters:
structure (
Atoms
) – Atomic structure the sublattices are based on.- Return type:
- is_supercell_self_interacting(structure)[source]¶
Checks whether a structure has self-interactions via periodic boundary conditions. Returns
True
if the structure contains self-interactions via periodic boundary conditions, otherwiseFalse
.- Parameters:
structure (
Atoms
) – Structure to be tested.- Return type:
bool
- merge_orbits(equivalent_orbits, ignore_permutations=False)[source]¶
Combines several orbits into one. This allows one to make custom cluster spaces by manually declaring the clusters in two or more orbits to be equivalent. This is a powerful approach for simplifying the cluster spaces of low-dimensional structures such as surfaces or nanoparticles.
The procedure works in principle for any number of components. Note, however, that in the case of more than two components the outcome of the merging procedure inherits the treatment of the multi-component vectors of the orbit chosen as the representative one.
- Parameters:
equivalent_orbits (
Dict
[int
,List
[int
]]) – The keys of this dictionary denote the indices of the orbit into which to merge. The values are the indices of the orbits that are supposed to be merged into the orbit denoted by the key.ignore_permutations (
bool
) – IfTrue
orbits will be merged even if their multi-component vectors and/or site permutations differ. While the object will still be functional, the cluster space may not be properly spanned by the resulting cluster vectors.
- Return type:
None
Note
The orbit index should not be confused with the index shown when printing the cluster space.
Examples
The following snippet illustrates the use of this method to create a cluster space for a (111) FCC surface, in which only the singlets for the first and second layer are distinct as well as the in-plane pair interaction in the topmost layer. All other singlets and pairs are respectively merged into one orbit. After merging there aree only 3 singlets and 2 pairs left with correspondingly higher multiplicities.
>>> from icet import ClusterSpace >>> from ase.build import fcc111 >>> >>> # Create primitive surface unit cell >>> structure = fcc111('Au', size=(1, 1, 8), a=4.1, vacuum=10, periodic=True) >>> >>> # Set up initial cluster space >>> cs = ClusterSpace(structure=structure, cutoffs=[3.8], chemical_symbols=['Au', 'Ag']) >>> >>> # At this point, one can inspect the orbits in the cluster space by printing the >>> # ClusterSpace object and accessing the individial orbits. >>> # There will be 4 singlets and 8 pairs. >>> >>> # Merge singlets for the third and fourth layers as well as all pairs except for >>> # the one corresponding to the in-plane interaction in the topmost surface >>> # layer. >>> cs.merge_orbits({2: [3], 4: [6, 7, 8, 9, 10, 11]})
- property number_of_orbits_by_order: dict¶
Number of orbits by order in the form of a dictionary where keys and values represent order and number of orbits, respectively.
- property orbit_list¶
Orbit list that defines the cluster in the cluster space.
- property position_tolerance: float¶
Tolerance applied when comparing positions in Cartesian coordinates.
- prune_orbit_list(indices)[source]¶
Prunes the internal orbit list and maintains the history.
- Parameters:
indices (
List
[int
]) – Indices to all orbits to be removed.- Return type:
None
- static read(filename)[source]¶
Reads cluster space from file and returns
ClusterSpace
object.- Parameters:
filename (
str
) – Name of file from which to read cluster space.
- property space_group: str¶
Space group of the primitive structure in international notion (via spglib).
- property symprec: float¶
Tolerance imposed when analyzing the symmetry using spglib.