matcalc._defect module

Calculator for neutral point-defect formation energies.

class DefectCalc(calculator: Calculator | str, *, relax_bulk: bool = True, relax_defect: bool = True, fmax: float = 0.1, optimizer: str | Optimizer = 'BFGS', max_steps: int = 500, chemical_potentials: dict[str, float] | None = None, elemental_refs: Literal['MP-PBE', 'MatPES-PBE', 'MatPES-r2SCAN'] | dict = 'MatPES-PBE', relax_calc_kwargs: dict[str, Any] | None = None)[source]

Bases: PropCalc

Calculate neutral point-defect formation energies in supercells.

calc_defects relaxes the bulk, builds a supercell and enumerates vacancies, substitutions, antisites and interstitials; calc evaluates a single defect structure. The formation energy is

E_f = E_defect - (N_defect - sum_i dn_i) * e_bulk - sum_i dn_i * mu_i,

where e_bulk is the bulk energy per atom and dn_i the number of atoms of element i added (positive) or removed (negative). Unless given in chemical_potentials, mu_i is the bulk energy per atom for the host of an elemental crystal, and the lowest energy per atom of the relaxed elemental references for an element not in the host (the element-rich limit). The chemical potentials of the host elements of a compound depend on the growth conditions and must be given, e.g. one of the limits from calc_chemical_potential_limits.

Initialize the defect protocol.

Parameters:
  • calculator – ASE calculator or universal model name.

  • relax_bulk – Relax bulk atoms and cell. When False, the bulk energy is a single point.

  • relax_defect – Relax defect atoms at fixed cell. When False, the defect energy is a single point on the unrelaxed defect structure.

  • fmax – Force convergence (eV/A) for all relaxations.

  • optimizer – ASE optimizer name or class.

  • max_steps – Maximum relaxation steps.

  • chemical_potentials – Chemical potentials (eV/atom) by element symbol, overriding the defaults described in the class docstring. Required for the host elements of a compound, and they should satisfy sum_i n_i mu_i = bulk energy per formula unit.

  • elemental_refs – "MP-PBE", "MatPES-PBE", "MatPES-r2SCAN" or a custom dict mapping element symbols to {"structure": ...}. The reference structures are relaxed with this calculator when a chemical potential is needed.

  • relax_calc_kwargs – Extra arguments for RelaxCalc, overriding the settings above for all relaxations, as in other calculators. The protocol relaxes the bulk cell (if relax_bulk) and elemental references, and keeps defect supercells at the bulk lattice; passing relax_cell or relax_atoms here overrides that.

_abc_impl = <_abc._abc_data object>[source]
_bulk_cache: dict[tuple, dict[str, Any]][source]
_bulk_cache_settings: tuple | None[source]
_chemical_potential(symbol: str, host: Composition, bulk_energy_per_atom: float) → float[source]
_elemental_energy(symbol: str) → float[source]
_reference_energies: dict[str, float][source]
_relax_bulk(structure: Structure | Atoms) → dict[str, Any][source]

Relax the conventional bulk, reusing the result for the same input and relaxation settings.

calc_chemical_potential_limits and calc_defects both need the relaxed bulk; the cache relaxes it once and guarantees that both use the same bulk energy.

calc(structure: Structure | Atoms | dict[str, Any]) → dict[str, Any][source]

Compute the formation energy of one defect structure.

Parameters:

structure – Dict with defect (defect supercell), element_changes (atoms added per element, negative for removed, e.g. {"Cu": -2} for a divacancy) and either bulk (relaxed here) or bulk_energy_per_atom with the relaxed final_bulk.

Returns:

The input dict updated with final_defect, defect_energy (eV), formation_energy (eV), chemical_potentials (eV/atom) of the changed elements, final_bulk and bulk_energy_per_atom (eV/atom).

calc_chemical_potential_limits(structure: Structure | Atoms, phase_diagram: PhaseDiagram, *, stabilize_bulk: bool = False) → dict[str, dict[str, float]][source]

Chemical potentials at the limits of the bulk’s stability region.

Following FormationEnergyDiagram.with_atomic_entries in pymatgen-analysis-defects, the formation energies of the competing phases are taken from phase_diagram (e.g. built from Materials Project entries) and referenced to the relaxed elemental references of this calculator. The bulk is relaxed as in calc_defects (and cached, so the two share one relaxation) and replaces the entries of its composition, so each limit satisfies sum_i n_i mu_i = bulk energy per formula unit.

This is a hybrid scheme: the bulk and elemental energies come from the foundation potential, while the formation energies of the competing phases carry whatever level of theory and corrections phase_diagram was built with. With Materials Project entries these include the MP2020 anion and GGA+U corrections, e.g. the O-rich limit of an oxide inherits MP’s O2 correction while the bulk energy does not. That favors agreement with experimental formation enthalpies. When internal consistency with the potential matters more, pass a phase diagram of uncorrected entries or, better, one computed with the same potential.

Parameters:
  • structure – Ordered bulk structure.

  • phase_diagram – Phase diagram of the host’s chemical system, optionally extended with other elements such as dopants. The limits are the facets of the full phase diagram that touch the host, so a dopant’s chemical potential at each limit is set by its most stable competing phase there (e.g. a dopant oxide), not by an element-rich condition.

  • stabilize_bulk – If the bulk is above the hull, lower its energy to 1 meV/atom below the hull instead of raising an error. The chemical potentials then satisfy the lowered energy, not the bulk energy used for the defects.

Returns:

Chemical potentials (eV/atom) by element at each limit, keyed by the coexisting phases, e.g. {"Li-Li2O": {...}, "Li2O-Li2O2": {...}}.

calc_defects(structure: Structure | Atoms, *, supercell_matrix: ArrayLike | None = None, min_length: float = 10.0, vacancies: bool | str | Sequence[str] = True, substitutions: Mapping[str, str | Sequence[str]] | None = None, antisites: bool = False, interstitials: str | Sequence[str] | Mapping[str, Sequence[ArrayLike]] | None = None, symprec: float = 0.01, **kwargs: Any) → list[dict[str, Any]][source]

Generate point defects in a supercell of the relaxed bulk and compute their formation energies.

Defects are placed on one site of each symmetry-inequivalent orbit of the conventional cell. The relaxed bulk is cached per input structure, so a preceding calc_chemical_potential_limits call on the same structure with the same relaxation settings is not repeated.

Parameters:
  • structure – Ordered bulk structure, converted to the conventional cell.

  • supercell_matrix – Scaling of the relaxed conventional cell. None repeats each lattice vector until the distance between the corresponding opposite faces is at least min_length.

  • min_length – Minimum supercell width (A) when supercell_matrix is None.

  • vacancies – True for vacancies of every element, False for none, or element symbols.

  • substitutions – Dopants by host element, e.g. {"Cu": ["Ni", "Zn"]}.

  • antisites – Place every other host element on each host site.

  • interstitials – Element symbols for interstitial sites found by Voronoi analysis (requires the defects extra), or fractional coordinates by element in the conventional cell of structure (structure.to_conventional(), returned relaxed as final_bulk), e.g. {"H": [[0.5, 0.5, 0.5]]}.

  • symprec – Symmetry tolerance for finding inequivalent sites.

  • **kwargs – Forwarded to calc_many.

Returns:

Per-defect calc results, each with defect_name (e.g. v_Cu, Ni_Cu, H_i; numbered when several sites share a name), element_changes, defect_frac_coords (defect position in the supercell) and supercell_matrix.

E_ABOVE_HULL_TOL = 1e-08[source]

Energy above hull (eV/atom) below which the bulk counts as on the hull, absorbing round-off.

_interstitial_sites(bulk: Structure, interstitials: str | Sequence[str] | Mapping[str, Sequence[ArrayLike]] | None) → dict[str, list[np.ndarray]][source]

Fractional interstitial coordinates in bulk by element.

_load_elemental_refs(name: str) → dict[source]

Elemental reference structures shipped with matcalc.

The cached dict is shared by all DefectCalc instances; treat it and its structures as read-only.

_site_defects(bulk: Structure, supercell: Structure, *, vacancies: bool | str | Sequence[str], substitutions: Mapping[str, str | Sequence[str]] | None, antisites: bool, symprec: float) → list[tuple[str, Structure, dict[str, int], np.ndarray]][source]

Vacancies and substitutions on one site of each inequivalent orbit, as (name, defect, changes, frac).

_site_index(supercell: Structure, coords: ndarray) → int[source]

Index of the supercell site at the Cartesian position of a unit-cell site.