This notebook demonstrates how to carry out an ordering of a disordered structure using pymatgen.
# Uncomment the subsequent lines in this cell to install dependencies for Google Colab.
# !pip install pymatgen==2022.7.19
# Let us start by creating a disordered CuAu fcc structure.
from pymatgen.core import Lattice, Structure
specie = {"Cu0+": 0.5, "Au0+": 0.5}
cuau = Structure.from_spacegroup("Fm-3m", Lattice.cubic(3.677), [specie], [[0, 0, 0]])
print(cuau)
Full Formula (Cu2 Au2) Reduced Formula: CuAu abc : 3.677000 3.677000 3.677000 angles: 90.000000 90.000000 90.000000 Sites (4) # SP a b c --- ---------------------- --- --- --- 0 Cu0+:0.500, Au0+:0.500 0 0 0 1 Cu0+:0.500, Au0+:0.500 0 0.5 0.5 2 Cu0+:0.500, Au0+:0.500 0.5 0 0.5 3 Cu0+:0.500, Au0+:0.500 0.5 0.5 0
Note that each site is now 50% occupied by Cu and Au. Because the ordering algorithms uses an Ewald summation to rank the structures, you need to explicitly specify the oxidation state for each species, even if it is 0. Let us now perform ordering of these sites using two methods.
The first method is to use the OrderDisorderedStructureTransformation.
from pymatgen.transformations.standard_transformations import (
OrderDisorderedStructureTransformation,
)
trans = OrderDisorderedStructureTransformation()
ss = trans.apply_transformation(cuau, return_ranked_list=100)
print(len(ss))
print(ss[0])
6 {'energy': 0.0, 'energy_above_minimum': 0.0, 'structure': Structure Summary Lattice abc : 3.677 3.677 3.677 angles : 90.0 90.0 90.0 volume : 49.714249733 A : 3.677 0.0 0.0 B : 0.0 3.677 0.0 C : 0.0 0.0 3.677 PeriodicSite: Cu0+ (1.8385, 0.0000, 1.8385) [0.5000, 0.0000, 0.5000] PeriodicSite: Cu0+ (1.8385, 1.8385, 0.0000) [0.5000, 0.5000, 0.0000] PeriodicSite: Au0+ (0.0000, 0.0000, 0.0000) [0.0000, 0.0000, 0.0000] PeriodicSite: Au0+ (0.0000, 1.8385, 1.8385) [0.0000, 0.5000, 0.5000]}
Note that the OrderDisorderedTransformation (with a sufficiently large return_ranked_list parameter) returns all orderings, including duplicates without accounting for symmetry. A computed ewald energy is returned together with each structure. To eliminate duplicates, the best way is to use StructureMatcher's group_structures method, as demonstrated below.
from pymatgen.analysis.structure_matcher import StructureMatcher
matcher = StructureMatcher()
groups = matcher.group_structures([d["structure"] for d in ss])
print(len(groups))
print(groups[0][0])
1 Full Formula (Cu2 Au2) Reduced Formula: CuAu abc : 3.677000 3.677000 3.677000 angles: 90.000000 90.000000 90.000000 Sites (4) # SP a b c --- ---- --- --- --- 0 Cu0+ 0.5 0 0.5 1 Cu0+ 0.5 0.5 0 2 Au0+ 0 0 0 3 Au0+ 0 0.5 0.5
If you have enumlib installed, you can use the EnumerateStructureTransformation. This automatically takes care of symmetrically equivalent orderings and can enumerate supercells, but is much more prone to parameter sensitivity and cannot handle very large structures. The example below shows an enumerate of CuAu up to cell sizes of 4.
from pymatgen.transformations.advanced_transformations import (
EnumerateStructureTransformation,
)
specie = {"Cu": 0.5, "Au": 0.5}
cuau = Structure.from_spacegroup("Fm-3m", Lattice.cubic(3.677), [specie], [[0, 0, 0]])
trans = EnumerateStructureTransformation(max_cell_size=3)
ss = trans.apply_transformation(cuau, return_ranked_list=1000)
print(len(ss))
print("cell sizes are %s" % ([len(d["structure"]) for d in ss]))
94 cell sizes are [4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12]
# The following two lines write all the structures to CIF files with names CuAu_0.cif, CuAu_1.cif, ...
for i, d in enumerate(ss):
d["structure"].to(filename="CuAu_%d.cif" % i)
Note that structures with cell sizes ranging from 1-3x the unit cell size is generated.
This notebook illustrates two basic ordering/enumeration approaches. In general, OrderDisorderedTransformation works better for large cells and is useful if you need just any quick plausible ordering. EnumerateStructureTransformation is more rigorous, but is prone to sensitivity errors and may require fiddling with various parameters.