Enumerate derivative structures with composition and site constraints#
This example shows how to specify a composition of derivative structures and restrict each site to be occupied by only allowed species.
Import modules#
[1]:
from pathlib import Path
import numpy as np
from pymatgen.core import Lattice, Structure
from pymatgen.core.periodic_table import DummySpecie
from dsenum import ZddStructureEnumerator
from dsenum.utils import write_cif
[2]:
from dsenum import __version__
print(f"dsenum {__version__}")
dsenum 0.3.16.dev19+gc2b1184.d20220615
Enumerate derivative structures with site constraints#
Here, we enumerate Rutile-like SnO\(_{2-x}\) derivative structures.
[3]:
def get_rutile_structure():
# rutile structure taken from mp-856
a = 4.832
c = 3.243
x_4f = 0.3066
lattice = Lattice.from_parameters(a, a, c, 90, 90, 90)
species = ["Sn", "Sn", "O", "O", "O", "O"]
frac_coords = np.array([
[0, 0, 0], # Sn(2a)
[0.5, 0.5, 0.5], # Sn(2a)
[x_4f, x_4f, 0], # O(4f)
[1 - x_4f, 1 - x_4f, 0], # O(4f)
[0.5 - x_4f, 0.5 + x_4f, 0.5], # O(4f)
[0.5 + x_4f, 0.5 - x_4f, 0.5], # O(4f)
])
structure = Structure(lattice, species, frac_coords)
return structure
base_structure = get_rutile_structure()
mapping_color_species = [DummySpecie("X"), "O", "Sn"]
# Only O sites are disordered.
base_site_constraints = [
[2], # 2a
[2], # 2a
[0, 1], # 4f
[0, 1], # 4f
[0, 1], # 4f
[0, 1], # 4f
]
[4]:
max_index = 4
# root = Path("./SnO2-x")
# root.mkdir(exist_ok=True)
for index in range(1, max_index + 1):
se = ZddStructureEnumerator(
base_structure,
index=index,
num_types=len(mapping_color_species),
mapping_color_species=mapping_color_species,
base_site_constraints=base_site_constraints,
remove_superperiodic=True,
remove_incomplete=False,
)
list_dstructs = se.generate()
for i, dstruct in enumerate(list_dstructs):
# remove void
dstruct.remove_species([mapping_color_species[0]])
# Save structure here
# filename = root / f"SnO2-x_{index}_{i}.cif"
# write_cif(filename, dstruct, refine_cell=True)
100%|██████████| 1/1 [00:00<00:00, 33.30it/s]
total: 6 (Time: 0.03666sec)
100%|██████████| 5/5 [00:00<00:00, 22.48it/s]
total: 132 (Time: 0.2258sec)
100%|██████████| 5/5 [00:00<00:00, 9.69it/s]
total: 1756 (Time: 0.5191sec)
100%|██████████| 17/17 [00:09<00:00, 1.81it/s]
total: 47827 (Time: 9.396sec)
Enumerate derivative structures with composition constraints#
Here, we enumerate oxygen-deficient derivative structures of SrTiO\(_{3-x}\) \((0 \leq x \leq 1)\) in perovskite prototype.
[5]:
def get_perovskite_structure():
lattice = Lattice(3.945 * np.eye(3))
species = ["Sr", "Ti", "O", "O", "O"]
frac_coords = np.array(
[[0, 0, 0], [0.5, 0.5, 0.5], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5], [0.5, 0.5, 0.0]]
)
return Structure(lattice, species, frac_coords)
aristo = get_perovskite_structure()
# Remove cation sites that are nothing to do with oxygen-deficient ordering!
base_structure = aristo.copy()
base_structure.remove_species(["Sr", "Ti"])
# Later append Sr and Ti sites with `additional_species` and `additional_frac_coords`
additional_species = aristo.species[:2]
additional_frac_coords = aristo.frac_coords[:2]
mapping_color_species = [DummySpecie("X"), "O"]
base_site_constraints = []
[6]:
# root = Path("./SrTiO3-x")
# root.mkdir(exist_ok=True)
max_index = 6
counts = {}
for index in range(1, max_index + 1):
# Enumerate possible compositions
list_compositions = []
for num_oxygen in range(2 * index, 3 * index + 1):
num_vacancy = 3 * index - num_oxygen
list_compositions.append([num_vacancy, num_oxygen])
poscars = []
for composition_constraints in list_compositions:
zse = ZddStructureEnumerator(
base_structure,
index=index,
num_types=len(mapping_color_species),
mapping_color_species=mapping_color_species,
composition_constraints=composition_constraints,
remove_superperiodic=True,
remove_incomplete=False,
verbose=False,
)
list_dstructs = zse.generate(
additional_species=additional_species, additional_frac_coords=additional_frac_coords,
output='poscar',
)
poscars.extend(list_dstructs)
counts[index] = len(poscars)
[7]:
assert counts[1] == 2
assert counts[2] == 11
assert counts[3] == 45
assert counts[4] == 455
assert counts[5] == 1296
assert counts[6] == 17111