Skip to content

Commit 0378541

Browse files
authored
Merge pull request #49 from materialsproject/patch_gen
Patch generators
2 parents 2227243 + 02755b7 commit 0378541

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

pymatgen/analysis/defects/generators.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,15 @@ def __init__(self, symprec: float = 0.01, angle_tolerance: float = 5):
111111
self.angle_tolerance = angle_tolerance
112112

113113
def generate(
114-
self, structure: Structure, substitution: dict[str, list[str]], **kwargs
114+
self, structure: Structure, substitution: dict[str, str | list], **kwargs
115115
) -> Generator[Substitution, None, None]:
116116
"""Generate subsitutional defects.
117117
118118
Args:
119119
structure: The bulk structure the vacancies are generated from.
120120
substitution: The substitutions to be made given as a dictionary.
121-
e.g. {"Ga": ["Mg", "Ca"]} means that Ga is substituted with Mg or Ca.
121+
e.g. {"Ga": "Ca"} means that Ga is substituted with Ca. You
122+
can also specify a list of elements to substitute with.
122123
**kwargs: Additional keyword arguments for the ``Substitution`` constructor.
123124
124125
Returns:
@@ -131,14 +132,24 @@ def generate(
131132
el_str = _element_str(site.specie)
132133
if el_str not in substitution.keys():
133134
continue
134-
for sub_el in substitution[el_str]:
135+
sub_el = substitution[el_str]
136+
if isinstance(sub_el, str):
135137
sub_site = PeriodicSite(
136138
Species(sub_el),
137139
site.frac_coords,
138140
structure.lattice,
139141
properties=site.properties,
140142
)
141143
yield Substitution(structure, sub_site, **kwargs)
144+
elif isinstance(sub_el, list):
145+
for el in sub_el:
146+
sub_site = PeriodicSite(
147+
Species(el),
148+
site.frac_coords,
149+
structure.lattice,
150+
properties=site.properties,
151+
)
152+
yield Substitution(structure, sub_site, **kwargs)
142153

143154

144155
class AntiSiteGenerator(DefectGenerator):
@@ -152,6 +163,7 @@ class AntiSiteGenerator(DefectGenerator):
152163
def __init__(self, symprec: float = 0.01, angle_tolerance: float = 5):
153164
self.symprec = symprec
154165
self.angle_tolerance = angle_tolerance
166+
self._sub_gen = SubstitutionGenerator(symprec, angle_tolerance)
155167

156168
def generate(
157169
self,
@@ -162,14 +174,17 @@ def generate(
162174
163175
Args:
164176
structure: The bulk structure the anti-site defects are generated from.
177+
**kwargs: Additional keyword arguments for the ``Substitution.generate`` function.
165178
"""
166179
all_species = [*map(_element_str, structure.composition.elements)]
167180
subs = collections.defaultdict(list)
168181
for u, v in combinations(all_species, 2):
169182
subs[u].append(v)
170183
subs[v].append(u)
171184
logger.debug(f"All anti-site pairings: {subs}")
172-
return SubstitutionGenerator.generate(self, structure, subs)
185+
for site, species in subs.items():
186+
for sub in species:
187+
yield from self._sub_gen.generate(structure, {site: sub}, **kwargs)
173188

174189

175190
class InterstitialGenerator(DefectGenerator):

tests/test_generators.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ def test_substitution_generators(gan_struct):
3838
replaced_atoms.add(defect.site.specie.symbol)
3939
assert replaced_atoms == {"Mg", "Ca"}
4040

41+
sub_generator = SubstitutionGenerator().get_defects(gan_struct, {"Ga": "Mg"})
42+
replaced_atoms = set()
43+
for defect in sub_generator:
44+
assert isinstance(defect, Substitution)
45+
replaced_atoms.add(defect.site.specie.symbol)
46+
assert replaced_atoms == {
47+
"Mg",
48+
}
49+
4150

4251
def test_antisite_generator(gan_struct):
4352
anti_gen = AntiSiteGenerator().get_defects(gan_struct)

0 commit comments

Comments
 (0)