Skip to content

Commit

Permalink
Redefine element_changes for Defect for fast formation energy / c…
Browse files Browse the repository at this point in the history
…oncentration calculations
  • Loading branch information
kavanase committed Sep 12, 2024
1 parent 68d4e45 commit eaf96ce
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
36 changes: 35 additions & 1 deletion doped/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ def get_eigenvalue_analysis(

return get_eigenvalue_analysis(self, plot=plot, filename=filename, **kwargs)

def _get_chempot_term(self, chemical_potentials=None):
def _get_chempot_term(self, chemical_potentials=None) -> float:
chemical_potentials = chemical_potentials or {}
element_changes = {elt.symbol: change for elt, change in self.defect.element_changes.items()}
missing_elts = [elt for elt in element_changes if elt not in chemical_potentials]
Expand Down Expand Up @@ -2044,6 +2044,21 @@ def get_charge_states(self, padding: int = 1) -> list[int]:

return charges

def __setattr__(self, name, value):
"""
Handle attribute updates.
Safety function to ensure properties (``defect_site``, ``volume``,
``element_changes``) are recomputed whenever any defect attributes
are changed, to ensure consistency and correct predictions.
"""
super().__setattr__(name, value)
if name in ["site", "structure"]:
# delete internal pre-computed attributes, so they are re-computed when needed:
for attr in ["_defect_site", "_volume", "_element_changes"]:
if hasattr(self, attr):
delattr(self, attr)

@property
def defect_site(self) -> PeriodicSite:
"""
Expand Down Expand Up @@ -2084,6 +2099,25 @@ def volume(self) -> float:

return self._volume

@property
def element_changes(self) -> dict[Element, int]:
"""
The stoichiometry changes of the defect, as a dict.
e.g. {"Mg": -1, "O": +1} for a O-on-Mg antisite in MgO.
Redefined from the ``pymatgen-analysis-defects`` method
to be far more efficient when used in loops (e.g. for
calculating defect concentrations as functions of chemical
potentials, temperature etc.).
Returns:
dict[Element, int]: The species changes of the defect.
"""
if not hasattr(self, "_element_changes"):
self._element_changes = super().element_changes

return self._element_changes

def __hash__(self):
"""
Hash the ``Defect`` object, based on the defect name and site.
Expand Down
9 changes: 6 additions & 3 deletions doped/generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2213,8 +2213,8 @@ def __str__(self):

def __repr__(self):
"""
Returns a string representation of the DefectsGenerator object, and
prints the DefectsGenerator info.
Returns a string representation of the ``DefectsGenerator`` object, and
prints the ``DefectsGenerator`` info.
Note that Wyckoff letters can depend on the ordering of elements in
the conventional standard structure, for which doped uses the ``spglib``
Expand Down Expand Up @@ -2300,7 +2300,10 @@ def _sort_defect_entries(
for defect_entry in defect_entries_dict.values():
extrinsic_element_list.extend(
el.symbol
for el in defect_entry.defect.defect_structure.composition.elements
for el in [
*defect_entry.defect.structure.composition.elements,
*defect_entry.defect.site.species.elements,
]
if el.symbol not in host_element_list
)

Expand Down

0 comments on commit eaf96ce

Please sign in to comment.