doped.chemical_potentials module

Functions for setting up and parsing competing phase calculations, in order to determine and analyse elemental chemical potential limits for a given host system.

class doped.chemical_potentials.ChemicalPotentialGrid(chempots: dict[str, Any], format_chempot_labels: bool = True)[source]

Bases: MSONable

A class to represent a grid in chemical potential space and to perform operations such as generating a grid within the convex hull of given vertices (chemical potential limits).

This class provides methods for handling and manipulating chemical potential data, including the creation of a grid that spans a specified chemical potential space.

Initializes the ChemicalPotentialGrid with chemical potential data.

This constructor takes a dictionary of chemical potentials and sets up the initial vertices of the grid.

Parameters:
  • chempots (dict) –

    Dictionary of chemical potentials for the grid. This can have the form of {"limits": [{'limit': [chempot_dict]}], ...} (the format generated by doped's chemical potential parsing functions), or alternatively can be a dictionary of the form {'limit': [chempot_dict, ...]} (i.e. matching the format of chempots["limits_wrt_el_refs"] from the doped chempots dict) where the keys are the limit names (e.g. “Cd-CdTe”, “Cd-rich” etc) and the values are dictionaries of a single chemical potential limit in the format: {element symbol: chemical potential}.

    If chempots in the doped format is supplied, then the chemical potentials with respect to the elemental reference energies will be used (i.e. chempots["limits_wrt_el_refs"])!

  • format_chempot_labels (bool) – Whether to format the elemental chemical potential labels as “µ_{elt} (eV)” (default) or just “{elt}” (if False).

as_dict() dict[source]
Returns:

JSON-serializable dict representation of ChemicalPotentialGrid.

classmethod from_dataframe(vertices: DataFrame) ChemicalPotentialGrid[source]

Create a ChemicalPotentialGrid object from a dataframe of the chemical potential limits (i.e. vertices).

Parameters:

vertices (pd.DataFrame) – A DataFrame of the chemical potential limits (i.e. vertices). The columns should be the chemical potentials of the elements, and the rows should be the limits.

Returns:

A ChemicalPotentialGrid object.

Return type:

ChemicalPotentialGrid

classmethod from_dict(d: dict) ChemicalPotentialGrid[source]

Reconstitute a ChemicalPotentialGrid object from a dict representation created using as_dict().

Parameters:

d (dict) – dict representation of ChemicalPotentialGrid.

Returns:

ChemicalPotentialGrid object

get_constrained_grid(fixed_elements: dict[str, float], n_points: int = 1000, cartesian: bool = False, resolution: float | None = None, max_points: int | None = None, decimal_places: int = 4, drop_duplicates: bool = True, include_vertices: bool = True, sort: bool = True) DataFrame[source]

Generates a grid of points that spans the chemical potential space defined by the vertices, constrained by a set of fixed chemical potentials.

By default, the grid is generated in barycentric coordinates (i.e. in ‘relative’ coordinates, as weighted averages of the chemical potential limits). This is far more efficient than generating a Cartesian grid, but means that the grid is evenly spaced in barycentric (‘relative’) coordinates, and not necessarily in Cartesian coordinates. If cartesian is set to True, then a regular grid in Cartesian coordinates is generated (however this can be much slower).

Parameters:
  • fixed_elements (dict) – A dictionary of chemical potentials to fix (in the format: {column_name: value}; e.g. {"Li": -2}). At least two chemical potentials must be left free (i.e. a ternary or higher system, with at most n_elements - 2 fixed), otherwise no chemical potential range remains to grid over.

  • n_points (int | None) – Minimum number of grid points to generate, within the constrained subspace. The output grid will contain at least this many points (regularly spaced in barycentric or Cartesian space depending cartesian), in addition to the vertices of the constrained subspace (if include_vertices is True; default), then with any duplicate / overlapping points dropped. Default is 1000. Note that large values (>= 1e5) with multinary systems can explode, crashing system memory (especially with cartesian=True).

  • cartesian (bool) – Whether to generate the grid in Cartesian coordinates. If False (default), the grid is generated in barycentric coordinates, which is far more efficient, but means that the grid is evenly spaced in barycentric (‘relative’) coordinates, and not necessarily in Cartesian coordinates. Irrelevant if it is a 1D chemical potential space.

  • resolution (float | None) – If set (and finite), used as the target grid spacing in eV within the constrained subspace, overriding n_points – see the get_grid docstring. Default is None (use n_points).

  • max_points (int | None) – If set (with resolution), used as a hard cap on the number of generated grid points – see the get_grid docstring. Default is None (no cap).

  • decimal_places (int) – The number of decimal places to round the grid coordinates to. Default is 4.

  • drop_duplicates (bool) – Whether to drop duplicate points in the generated grid. With barycentric coordinate generation, there can be duplicate points in the generated grid from overlapping simplices, and with either generation scheme from decimal_places rounding (when the grid spacing is finer than 10^[-decimal_places]). If duplicates are acceptable (likely true for most downstream usages; e.g. plotting etc) then this can be set to False to speed up runtime and reduce peak memory. Default is True.

  • include_vertices (bool) – Whether to include the vertices themselves in the generated grid. Default is True.

  • sort (bool) – Whether to sort the output rows along the largest-span chemical potential coordinate (e.g. so 1D chemical potential spaces are path-ordered along the line). Only worth disabling for extremely large grids, where this can speed up runtime and reduce peak memory. Default is True.

Returns:

A DataFrame containing the points within the convex hull, constrained by the fixed chemical potentials. Each row represents a point in the grid, with rows sorted along the largest-span chemical potential coordinate (if sort is True).

Return type:

pd.DataFrame

get_grid(n_points: int = 1000, fixed_elements: dict[str, float] | None = None, cartesian: bool = False, resolution: float | None = None, max_points: int | None = None, decimal_places: int = 4, drop_duplicates: bool = True, include_vertices: bool = True, sort: bool = True) DataFrame[source]

Generates a grid of points that spans the chemical potential space defined by the vertices. It ensures that the generated points lie within the convex hull of the provided vertices and interpolates the chemical potential values at these points.

By default, the grid is generated in barycentric coordinates (i.e. in ‘relative’ coordinates, as weighted averages of the chemical potential limits). This is far more efficient than generating a Cartesian grid, but means that the grid is evenly spaced in barycentric (‘relative’) coordinates, and not necessarily in Cartesian coordinates. If cartesian is set to True, then a regular grid in Cartesian coordinates is generated (however this can be much slower).

1D chemical potential spaces – i.e. any collinear set of vertices, such as a binary system or two chemical potential limits of a multinary system – are handled as line segments, with points uniformly spaced between the two endpoints.

Parameters:
  • n_points (int | None) – Minimum number of grid points to generate. The output grid will contain at least this many points (regularly spaced in barycentric or Cartesian space depending cartesian), in addition to the vertices themselves (if include_vertices is True; default), then with any duplicate / overlapping points dropped. Default is 1000. Note that large values (>= 1e5) with multinary systems can explode, crashing system memory (especially with cartesian=True).

  • fixed_elements (dict | None) – A dictionary of chemical potentials to fix (in the format: {column_name: value}; e.g. {"Li": -2}), if a reduced / constrained chemical potential grid is desired. If provided, the get_constrained_grid method is used.

  • cartesian (bool) – Whether to generate the grid in Cartesian coordinates. If False (default), the grid is generated in barycentric coordinates, which is far more efficient, but means that the grid is evenly spaced in barycentric (‘relative’) coordinates, and not necessarily in Cartesian coordinates. Irrelevant if it is a 1D chemical potential space.

  • resolution (float | None) – If set (and finite), used as the target grid spacing in eV, overriding n_points. With barycentric generation, the number of subdivisions along each simplex dimension is set to ceil(max_vertex_separation / resolution) (so the spacing along the longest hull edge is at most resolution); with cartesian=True, the Cartesian grid step is set to resolution directly. Default is None (use n_points).

  • max_points (int | None) – If set (with resolution), hard cap on the number of generated grid points. A warning stating the achieved vs requested resolution is thrown if this cap is hit. Default is None (no cap).

  • decimal_places (int) – The number of decimal places to round the grid coordinates to. Note that the tolerance for grid-point matching is 10^[-decimal_places]. Default is 4.

  • drop_duplicates (bool) – Whether to drop duplicate points in the generated grid. With barycentric coordinate generation, there can be duplicate points in the generated grid from overlapping simplices, and with either generation scheme from decimal_places rounding (when the grid spacing is finer than 10^[-decimal_places]). If duplicates are acceptable (likely true for most downstream usages; e.g. plotting etc) then this can be set to False to speed up runtime and reduce peak memory. Default is True.

  • include_vertices (bool) – Whether to include the vertices themselves in the generated grid. Default is True.

  • sort (bool) – Whether to sort the output rows along the largest-span chemical potential coordinate (e.g. so 1D chemical potential spaces are path-ordered along the line). Only worth disabling for extremely large grids, where this can speed up runtime and reduce peak memory. Default is True.

Returns:

A DataFrame containing the points within the convex hull. Each row represents a point in the grid, with rows sorted along the largest-span chemical potential coordinate (if sort is True).

Return type:

pd.DataFrame

class doped.chemical_potentials.CompetingPhases(composition: str | Composition | Structure, energy_above_hull: float = 0.05, extrinsic: str | Element | Iterable[str] | Iterable[Element] | None = None, full_phase_diagram: bool = False, single_extrinsic_phase_limits: bool = False, codoping: bool = False, expected_polymorphs: bool = False, MP_doc_dicts: bool = False, api_key: str | None = None, **kwargs: Any)[source]

Bases: _EntriesMixin, MSONable

Class to generate VASP input files for competing phases on the phase diagram for the host material (and any extrinsic (dopant/impurity) elements), which determine the chemical potential limits for elements in that compound.

For this, the Materials Project (MP) database is queried using the MPRester API, and any calculated compounds which could border the host material within an error tolerance for the semi-local DFT (mixed GGA/GGA+U/r2SCAN) database energies (energy_above_hull, 0.05 eV/atom by default) are generated, along with the elemental reference phases. Diatomic gaseous molecules are generated as molecules-in-a-box as appropriate (e.g. for O2, F2, H2 etc).

Materials Project energies are taken from the mixed GGA/GGA+U/r2SCAN thermodynamic data by default (thermo_type = "GGA_GGA+U_R2SCAN"; the MP default since mp-api 0.46.5), where the MP mixing scheme gives one corrected energy per material on a single mixed phase diagram (hull). Other thermo types (e.g. GGA/GGA+U-only or r2SCAN-only data) can be queried by passing e.g. additional_criteria={"thermo_types": ["GGA_GGA+U"]} via **kwargs.

Often energy_above_hull can be lowered (e.g. to 0) to reduce the number of calculations while retaining good accuracy relative to the typical error of defect calculations.

The default energy_above_hull of 50 meV/atom works well in accounting for MP formation energy inaccuracies in most known cases. However, some critical thinking is key (as always!) and so if there are any obvious missing phases or known failures of the Materials Project energetics in your chemical space of interest, you should adjust this parameter to account for this (or alternatively manually include these known missing phases in your competing phase calculations, to be included in parsing and chemical potential analysis later on).

Particular attention should be paid for materials containing transition metals, (inter)metallic systems, mixed oxidation states, van der Waals (vdW) binding and/or large spin-orbit coupling (SOC) effects, for which the Materials Project energetics are typically less reliable. The mixed GGA/GGA+U/r2SCAN data (the current default) improves on the older GGA/GGA+U-only energetics in many such cases, but can still be inaccurate under various circumstances.

Parameters:
  • composition (str, Composition, Structure) – Composition of the host material (e.g. 'LiFePO4', or Composition('LiFePO4'), or Composition({"Li":1, "Fe":1, "P":1, "O":4})). Alternatively a pymatgen Structure object for the host material can be supplied (recommended), in which case the primitive structure will be used as the only host composition phase, reducing the number of calculations.

  • energy_above_hull (float) – Maximum energy above hull (in eV/atom) of Materials Project entries to be considered as competing phases. This is an uncertainty range for the MP-calculated formation energies (mixed GGA/GGA+U/r2SCAN data by default), which may not be accurate due to functional choice (semi-local vs hybrid DFT / RPA / CCSD), lack of vdW corrections etc. All phases that would border the host material on the phase diagram, if their relative energy was downshifted by energy_above_hull, are included. Often energy_above_hull can be lowered (e.g. to 0) to reduce the number of calculations while retaining good accuracy relative to the typical error of defect calculations. (Default is 0.05 eV/atom).

  • extrinsic (str | Element | Iterable[str] | Iterable[Element] | None) – Extrinsic dopant/impurity species to consider, to generate the relevant competing phases to additionally determine their chemical potential limits within the host. Can be a single element as a string (e.g. “Mg”) or an iterable of element strings (list, set, tuple, dict) (e.g. [“Mg”, “Na”]). All entries are taken from a single MP query over the full (host + extrinsic) chemical system, so intrinsic and extrinsic entries share one common energy scale; as the MP mixing-scheme energy frame is chemical-system-dependent, the intrinsic entries (and their energies above hull, and so which low-energy polymorphs fall within energy_above_hull) can then differ from those of an intrinsic-only query in some cases.

  • full_phase_diagram (bool) – If True, include all phases on the MP phase diagram (with energy above hull < energy_above_hull eV/atom) for the chemical system of the input composition and any extrinsic species. Typically not recommended. If False (default), only includes phases that would border the host material on the phase diagram (and thus set the chemical potential limits), if their relative energy was downshifted by energy_above_hull eV/atom. (Default is False).

  • single_extrinsic_phase_limits (bool) – If True, and extrinsic is not None, only consider chemical potential limits where the host composition borders a maximum of 1 extrinsic phase (composition with extrinsic element(s)). This is an approximation that can reduce the number of extrinsic phases to consider (to reduce computational costs, e.g. when considering many possible extrinsic dopants / impurities), while often (but not always) being reasonably accurate for dilute extrinsic concentrations. Default is False.

  • codoping (bool) – Whether to consider extrinsic competing phases containing multiple extrinsic species (e.g. KInO2 as a potential competing phase for BaSnO3 with K and In extrinsic species). Usually only relevant under high (non-dilute) co-doping concentrations. Ignored if extrinsic is a single element. If set to True (and multiple extrinsic species present), then single_extrinsic_phase_limits is forced to be False. Default is False.

  • expected_polymorphs (bool) – If True, prune competing phase entries to expected ground- state / room-temperature polymorphs for compositions listed in doped/utils/known_MP_ground_states.yaml (common elements and oxides with many low-energy polymorphs on the MP database, and known ground-state phases). For each listed composition, only the lowest MP energy-above-hull entry plus any entries whose Materials Project ID is in the listed set are retained. See docs/known_MP_ground_states.md for the rationale and citations behind each composition’s curated set. See the Chemical Systems with Many Polymorphs section of the competing phases tutorial for discussion and examples. Default is False.

  • MP_doc_dicts (bool) – If True, also queries the Materials Project (MP) for summary doc dicts with MPRester.summary_search() for the competing phase entries, and stores them in CompetingPhases.MP_doc_dicts. Default is False.

  • api_key (str) – Materials Project (MP) API key, needed to access the MP database for competing phase generation. If not supplied, will attempt to read from ~/.pmgrc.yaml or ~/.config/.pmgrc.yaml (under PMG_MAPI_KEY) or from the MP_API_KEY environment variable – see the doped Installation docs.

  • **kwargs – Additional keyword arguments to pass to the Materials Project API get_entries_in_chemsys() query used to pull competing phase entries – e.g. additional_criteria={"thermo_types": ["GGA_GGA+U"]} to query only GGA/GGA+U data, rather than the default mixed GGA/GGA+U/r2SCAN phase diagrams ("GGA_GGA+U_R2SCAN"). Under the mixed default, any further additional_criteria (e.g. {"is_stable": True}) are applied by mp-api as a post-hoc filter on the (common energy scale) chemical system entries (see get_entries_in_chemsys()).

entries

Final list of competing phase entries (intrinsic and, if requested, extrinsic) to consider for chemical potential analysis.

Type:

list[ComputedEntry]

intrinsic_entries

Subset of entries corresponding to phases in the host (intrinsic) chemical system only (no extrinsic species).

Type:

list[ComputedEntry]

extrinsic_entries

Subset of entries corresponding to phases containing one or more extrinsic species. Empty if extrinsic is None.

Type:

list[ComputedEntry]

metallic_entries / nonmetallic_entries / molecular_entries

Properties returning the subsets of entries that are metallic, non-metallic (according to the Materials Project band gap values), or diatomic molecules (generated by doped), respectively (used to set smearing parameters, k-point convergence ranges etc. when writing calculation input files).

Type:

list[ComputedEntry]

composition

pymatgen Composition of the host material.

Type:

Composition

bulk_structure

Primitive pymatgen Structure of the host (if a Structure was supplied as composition), else None.

Type:

Structure | None

intrinsic_elements

Element symbols of the host composition.

Type:

list[str]

extrinsic_elements

Element symbols of the extrinsic species (empty when extrinsic is None).

Type:

list[str]

MP_full_pd_entries

All Materials Project entries in the (intrinsic + extrinsic) chemical system with energy above hull < energy_above_hull (including any multi-extrinsic “codoping” phases, which are excluded from the calculation entries unless codoping=True), used to build MP_full_pd. All entries come from a single MP query over the full chemical system, sharing one common, self-consistent energy scale.

Type:

list[ComputedStructureEntry]

MP_full_pd

pymatgen PhaseDiagram built from MP_full_pd_entries.

Type:

PhaseDiagram

MP_intrinsic_full_pd_entries

MP_full_pd_entries restricted to the intrinsic chemical system (only set when extrinsic is None).

Type:

list[ComputedStructureEntry]

MP_bulk_computed_entry

Materials Project ComputedStructureEntry for the host composition (downshifted to the convex hull if MP-unstable, or a hull-energy placeholder if not present on MP).

Type:

ComputedStructureEntry

MP_doc_dicts

Materials Project summary dictionaries for self.entries, keyed by entry name (empty unless MP_doc_dicts=True).

Type:

dict[str, dict]

intrinsic_MP_doc_dicts

Materials Project summary dictionaries for self.intrinsic_entries only (set when MP_doc_dicts=True and extrinsic species are present).

Type:

dict[str, dict]

X

Stored constructor (initialisation) arguments, for reference. e.g. CompetingPhases.energy_above_hull. See Args.

Type:

Any

_get_entries_kwargs

**kwargs passed to the MP get_entries_in_chemsys() query; see Args.

Type:

dict

as_dict() dict[source]
Returns:

JSON-serializable dict representation of CompetingPhases.

convergence_setup(**kwargs) dict[str, DopedDictSet][source]

Deprecated alias for write_kpoint_convergence_files().

Deprecated since version 4.0: Use write_kpoint_convergence_files() instead; this name will be removed in v4.1.

property entries_dict: dict[str, ComputedEntry]

Mapping of doped competing phase names to entries.

classmethod from_dict(d: dict) CompetingPhases[source]

Reconstitute a CompetingPhases object from a dict representation created using as_dict().

Parameters:

d (dict) – dict representation of CompetingPhases.

Returns:

CompetingPhases object

get_kpoint_convergence_sets(kpoints_metals: tuple[float, float, float] = (40.0, 1000.0, 5.0), kpoints_nonmetals: tuple[float, float, float] = (5.0, 120.0, 5.0), user_incar_settings: dict | None = None, user_potcar_functional: str = 'PBE', user_potcar_settings: dict | None = None, extrinsic_only: bool = False, output_path: str | Path = 'CompetingPhases') dict[str, DopedDictSet][source]

Generates a dictionary of DopedDictSets (subclasses of VaspInputSet) for k-point convergence testing of competing phases, using PBEsol (GGA) DFT by default.

Automatically sets the ISMEAR INCAR tag to 2 (if metallic) or 0 if not.

Parameters:
  • kpoints_metals (tuple[float, float, float]) – Kpoint density per inverse volume (kpoints/Å⁻³) to be tested for metallic entries (those with zero band gap), as a (min, max, step) tuple. Note that only unique kpoint combinations are generated, so small step sizes (as default) just results in each k-points choice between min and max being included.

  • kpoints_nonmetals (tuple[float, float, float]) – Kpoint density per inverse volume (kpoints/Å⁻³) to be tested for non-metallic entries (those with a non-zero band gap), as a (min, max, step) tuple. Note that only unique kpoint combinations are generated, so small step sizes (as default) just results in each k-points choice between min and max being included.

  • user_incar_settings (dict) – Override the default INCAR settings e.g. {"EDIFF": 1e-5, "LDAU": False, "ALGO": "All"}. Note that any non-numerical or non-True/False flags need to be input as strings with quotation marks. See doped/VASP_sets/PBEsol_ConvergenceSet.yaml for the default settings.

  • user_potcar_functional (str) – POTCAR functional to use. Default is “PBE” and if this fails, tries “PBE_52”, then “PBE_54”.

  • user_potcar_settings (dict) – Override the default POTCARs, e.g. {“Li”: “Li_sv”}. See doped/VASP_sets/PotcarSet.yaml for the default POTCAR set.

  • extrinsic_only (bool) – If True, only generate inputs for self.extrinsic_entries (useful when adding dopants to an existing intrinsic competing-phases set). Default is False (generate inputs for all entries).

  • output_path (PathLike) – Top-level output directory name (used as a key prefix). Default is "CompetingPhases".

Returns:

Mapping of output folder paths to generated DopedDictSets (subclasses of VaspInputSet).

Return type:

dict[str, DopedDictSet]

get_relaxation_sets(kpoints_metals: float = 200.0, kpoints_nonmetals: float = 64.0, user_incar_settings: dict | None = None, user_potcar_functional: str = 'PBE', user_potcar_settings: dict | None = None, extrinsic_only: bool = False, output_path: str | Path = 'CompetingPhases', subfolder: str | Path = 'Relax') dict[str, DopedDictSet][source]

Generates DopedDictSets for relaxations of the competing phases, using HSE06 (hybrid DFT) by default (consistent with the default input settings for defect calculations in doped.vasp).

Automatically sets the ISMEAR INCAR tag to 2 (if metallic) or 0 if not. Note that any changes to the default INCAR/POTCAR settings should be consistent with those used for the defect supercell calculations.

Note that this function uses a single kpoint density setting each for metals (kpoints_metals), non-metals (kpoints_nonmetals) and molecules (Gamma-only), while one will often want to specify custom k-point settings for each material individually based on convergence testing (e.g. using get_kpoint_convergence_sets()) to minimise cost.

Note that, because these relaxations usually involve volume relaxation, one should successively repeat the relaxation from the previous relaxed geometry until convergence (no more significant volume changes), or use a higher plane-wave cutoff energy (ENCUT in VASP) for the volume relaxations (but using an energy cutoff consistent with any defect calculations for a final single-point energy calculation), to avoid spurious Pulay stress effects.

See the Competing Phases & Chemical Potentials tips section for tips on boosting the efficiency of competing phases calculations.

Parameters:
  • kpoints_metals (float) – Kpoint density per inverse volume (kpoints/Å⁻³) for metallic entries (those with zero band gap). Default is 200 kpoints/Å⁻³. Note that you may want to specify custom k-point settings for each material individually based on convergence testing to minimise cost.

  • kpoints_nonmetals (float) – Kpoint density per inverse volume (kpoints/Å⁻³) for non-metallic entries (those with non-zero band gap). Default is 64 kpoints/Å⁻³, matching the MPRelaxSet default). Note that you may want to specify custom k-point settings for each material individually based on convergence testing to minimise cost.

  • user_incar_settings (dict) – Override the default INCAR settings e.g. {"EDIFF": 1e-5, "LDAU": False, "ALGO": "All"}. Note that any non-numerical or non-True/False flags need to be input as strings with quotation marks. See doped/VASP_sets/RelaxSet.yaml and HSESet.yaml for the default settings.

  • user_potcar_functional (str) – POTCAR functional to use. Default is “PBE” and if this fails, tries “PBE_52”, then “PBE_54”.

  • user_potcar_settings (dict) – Override the default POTCARs, e.g. {“Li”: “Li_sv”}. See doped/VASP_sets/PotcarSet.yaml for the default POTCAR set.

  • extrinsic_only (bool) – If True, only generate inputs for self.extrinsic_entries (useful when adding dopants to an existing intrinsic competing-phases set). Default is False (generate inputs for all entries).

  • output_path (PathLike) – Top-level output directory name (used as a key prefix). Default is "CompetingPhases".

  • subfolder (PathLike) – Output folder structure is <output_path>/<competing_phase_dir>/<subfolder>. Default is "Relax". Set to "." to write input files directly to <output_path>/<competing_phase_dir>, with no subfolders created.

Returns:

Mapping of output folder paths to generated DopedDictSets (subclasses of VaspInputSet).

Return type:

dict[str, DopedDictSet]

get_singlepoint_sets(kpoints_metals: float = 200.0, kpoints_nonmetals: float = 64.0, soc: bool | None = None, user_incar_settings: dict | None = None, user_potcar_functional: str = 'PBE', user_potcar_settings: dict | None = None, extrinsic_only: bool = False, output_path: str | Path = 'CompetingPhases', subfolder: str | Path | None = None) dict[str, DopedDictSet][source]

Generates DopedDictSets for single-point (static) energy calculations of the competing phases (i.e. NSW = 0, IBRION = -1 in VASP), using HSE06 (hybrid DFT) by default (consistent with the default input settings for defect calculations in doped.vasp).

These are expected to be used as the final energy calculation after geometry relaxation (from write_relaxation_files()), to obtain accurate total energies with tight convergence settings.

If soc=True, spin-orbit coupling (SOC) is included (by setting LSORBIT = True for VASP) and the output subfolder name will default to "vasp_ncl" (if not set otherwise). If soc is not explicitly set (i.e. is None), it defaults to True for systems where the max atomic number across all species (host and extrinsic) is Z >= 31 (heavier than Zn), matching the convention in doped.vasp.

Inclusion of SOC is crucial for accurate formation energies and chemical potentials in heavy-element systems, as discussed in Guidelines for robust and reproducible point defect simulations in crystals. However, non-SOC energies can generally be reliably used to determine relative energies of polymorphs, of the same composition/oxidation states, to good accuracy, which can be useful for pre-screening (e.g. then only performing more expensive SOC calculations on the ground-state polymorph of each potential competing phase). Moreover, one typically turns off symmetry for SOC calculations (i.e. ISYM set to -1 or 0 in VASP), as SOC can break crystal symmetries due to spin-space coupling. However, one generally finds that total energies from SOC calculations with (VASP) symmetry routines turned on give energies consistent with no-symmetry calculations, and can be much faster. Thus by default we do not turn off symmetry for SOC calculations here – note that the electronic band structure from these calculations is thus unreliable.

Automatically sets the ISMEAR INCAR tag to 2 (if metallic) or 0 if not. Note that any changes to the default INCAR/POTCAR settings should be consistent with those used for the defect supercell calculations.

For metals, while Methfessel-Paxton smearing (ISMEAR = 2; the default here) is well-suited to the geometry relaxations, tetrahedron smearing (ISMEAR = -5) typically gives more accurate total energies for these final single-point calculations with modest k-point densities, and can be set via user_incar_settings={"ISMEAR": -5}. Often this requires a lower k-point density than Methfessel-Paxton smearing, and so it can be worth re-running k-point convergence testing (with get_kpoint_convergence_sets()) using ISMEAR = -5 to check for cheaper converged k-point densities for these final single-point calculations – particularly useful if e.g. performing hybrid DFT SOC calculations. See the Competing Phases & Chemical Potentials tips section for further tips on boosting the efficiency of competing phases calculations.

Note that this function uses a single kpoint density setting each for metals (kpoints_metals), non-metals (kpoints_nonmetals) and molecules (Gamma-only), while one will often want to specify custom k-point settings for each material individually based on convergence testing (e.g. using get_kpoint_convergence_sets()) to minimise cost.

Parameters:
  • kpoints_metals (float) – Kpoint density per inverse volume (kpoints/Å⁻³) for metallic entries (those with zero band gap). Default is 200 kpoints/Å⁻³. Note that you may want to specify custom k-point settings for each material individually based on convergence testing to minimise cost.

  • kpoints_nonmetals (float) – Kpoint density per inverse volume (kpoints/Å⁻³) for non-metallic entries (those with non-zero band gap). Default is 64 kpoints/Å⁻³, matching the MPRelaxSet default). Note that you may want to specify custom k-point settings for each material individually based on convergence testing to minimise cost.

  • soc (bool) – Whether to include spin-orbit coupling (SOC), by setting LSORBIT = True in VASP INCAR files. If not set (when soc = None; default), SOC is enabled when the max atomic number across all species (host and extrinsic) is Z >= 31. The vasp_ncl executable is required to run VASP SOC calculations, and the default subfolder name is set to "vasp_ncl" when soc is True.

  • user_incar_settings (dict) – Override the default INCAR settings e.g. {"EDIFF": 1e-5, "LDAU": False, "ALGO": "All"}. Note that any non-numerical or non-True/False flags need to be input as strings with quotation marks. See doped/VASP_sets/RelaxSet.yaml and HSESet.yaml for the default settings.

  • user_potcar_functional (str) – POTCAR functional to use. Default is “PBE” and if this fails, tries “PBE_52”, then “PBE_54”.

  • user_potcar_settings (dict) – Override the default POTCARs, e.g. {“Li”: “Li_sv”}. See doped/VASP_sets/PotcarSet.yaml for the default POTCAR set.

  • extrinsic_only (bool) – If True, only generate inputs for self.extrinsic_entries (useful when adding dopants to an existing intrinsic competing-phases set). Default is False (generate inputs for all entries).

  • output_path (PathLike) – Top-level output directory name (used as a key prefix). Default is "CompetingPhases".

  • subfolder (PathLike) – Output folder structure is <output_path>/<competing_phase_dir>/<subfolder> where subfolder = ‘SinglePoint’ by default if soc is False, or ‘vasp_ncl’ if soc is True. Set to '.' to write input files directly to <output_path>/<competing_phase_dir>, with no subfolders created.

Returns:

Mapping of output folder paths to generated DopedDictSets (subclasses of VaspInputSet).

Return type:

dict[str, DopedDictSet]

property metallic_entries: list[ComputedEntry]

Returns a list of entries in self.entries which are metallic (i.e. have a band gap = 0) according to the Materials Project database.

property molecular_entries: list[ComputedEntry]

Returns a list of entries in self.entries which are diatomic molecules generated by doped (i.e. O2, N2, H2, F2, or Cl2).

property nonmetallic_entries: list[ComputedEntry]

Returns a list of entries in self.entries which are non-metallic (i.e. have a band gap > 0, or no recorded band gap) according to the Materials Project database.

Note that the doped-generated diatomic molecule phases, which are insulators, are not included here.

vasp_std_setup(**kwargs) dict[str, DopedDictSet][source]

Deprecated alias for write_relaxation_files().

Deprecated since version 4.0: Use write_relaxation_files() instead; this name will be removed in v4.1.

write_kpoint_convergence_files(kpoints_metals: tuple[float, float, float] = (40.0, 1000.0, 5.0), kpoints_nonmetals: tuple[float, float, float] = (5.0, 120.0, 5.0), user_incar_settings: dict | None = None, user_potcar_functional: str = 'PBE', user_potcar_settings: dict | None = None, extrinsic_only: bool = False, output_path: str | Path = 'CompetingPhases', **kwargs) dict[str, DopedDictSet][source]

Generates and writes VASP input files for k-point convergence testing of competing phases, using PBEsol (GGA) DFT by default.

Automatically sets the ISMEAR INCAR tag to 2 (if metallic) or 0 if not. Recommended to use with https://github.com/kavanase/vaspup2.0. Returns the corresponding dictionary of DopedDictSet objects (subclasses of VaspInputSet) which contain the input file settings.

Parameters:
  • kpoints_metals (tuple[float, float, float]) – Kpoint density per inverse volume (kpoints/Å⁻³) to be tested for metallic entries (those with zero band gap), as a (min, max, step) tuple. Note that only unique kpoint combinations are generated, so small step sizes (as default) just results in each k-points choice between min and max being included.

  • kpoints_nonmetals (tuple[float, float, float]) – Kpoint density per inverse volume (kpoints/Å⁻³) to be tested for non-metallic entries (those with a non-zero band gap), as a (min, max, step) tuple. Note that only unique kpoint combinations are generated, so small step sizes (as default) just results in each k-points choice between min and max being included.

  • user_incar_settings (dict) – Override the default INCAR settings e.g. {"EDIFF": 1e-5, "LDAU": False, "ALGO": "All"}. Note that any non-numerical or non-True/False flags need to be input as strings with quotation marks. See doped/VASP_sets/PBEsol_ConvergenceSet.yaml for the default settings.

  • user_potcar_functional (str) – POTCAR functional to use. Default is “PBE” and if this fails, tries “PBE_52”, then “PBE_54”.

  • user_potcar_settings (dict) – Override the default POTCARs, e.g. {“Li”: “Li_sv”}. See doped/VASP_sets/PotcarSet.yaml for the default POTCAR set.

  • extrinsic_only (bool) – If True, only generate inputs for self.extrinsic_entries (useful when adding dopants to an existing intrinsic competing-phases set). Default is False (generate inputs for all entries).

  • output_path (PathLike) – Top-level output directory name. Default is "CompetingPhases".

  • **kwargs – Additional kwargs to pass to DictSet.write_input()

Returns:

Mapping of output folder paths to generated DopedDictSets (subclasses of VaspInputSet).

Return type:

dict[str, DopedDictSet]

write_relaxation_files(kpoints_metals: float = 200.0, kpoints_nonmetals: float = 64.0, user_incar_settings: dict | None = None, user_potcar_functional: str = 'PBE', user_potcar_settings: dict | None = None, extrinsic_only: bool = False, output_path: str | Path = 'CompetingPhases', subfolder: str | Path = 'Relax', **kwargs) dict[str, DopedDictSet][source]

Generates and writes VASP input files for relaxations of the competing phases, using HSE06 (hybrid DFT) by default (consistent with the default input settings for defect calculations in doped.vasp).

Automatically sets the ISMEAR INCAR tag to 2 (if metallic) or 0 if not. Note that any changes to the default INCAR/POTCAR settings should be consistent with those used for the defect supercell calculations.

Note that this function uses a single kpoint density setting each for metals (kpoints_metals), non-metals (kpoints_nonmetals) and molecules (Gamma-only), while one will often want to specify custom k-point settings for each material individually based on convergence testing (e.g. using get_kpoint_convergence_sets()) to minimise cost.

Returns the corresponding dictionary of DopedDictSet objects (subclasses of VaspInputSet) which contain the input file settings.

Note that, because these relaxations usually involve volume relaxation, one should successively repeat the relaxation from the previous relaxed geometry until convergence (no more significant volume changes), or use a higher plane-wave cutoff energy (ENCUT in VASP) for the volume relaxations (but using an energy cutoff consistent with any defect calculations for a final single-point energy calculation), to avoid spurious Pulay stress effects.

See the Competing Phases & Chemical Potentials tips section for tips on boosting the efficiency of competing phases calculations.

Parameters:
  • kpoints_metals (float) – Kpoint density per inverse volume (kpoints/Å⁻³) for metallic entries (those with zero band gap). Default is 200 kpoints/Å⁻³. Note that you may want to specify custom k-point settings for each material individually based on convergence testing to minimise cost.

  • kpoints_nonmetals (float) – Kpoint density per inverse volume (kpoints/Å⁻³) for non-metallic entries (those with non-zero band gap). Default is 64 kpoints/Å⁻³, matching the MPRelaxSet default). Note that you may want to specify custom k-point settings for each material individually based on convergence testing to minimise cost.

  • user_incar_settings (dict) – Override the default INCAR settings e.g. {"EDIFF": 1e-5, "LDAU": False, "ALGO": "All"}. Note that any non-numerical or non-True/False flags need to be input as strings with quotation marks. See doped/VASP_sets/RelaxSet.yaml and HSESet.yaml for the default settings.

  • user_potcar_functional (str) – POTCAR functional to use. Default is “PBE” and if this fails, tries “PBE_52”, then “PBE_54”.

  • user_potcar_settings (dict) – Override the default POTCARs, e.g. {“Li”: “Li_sv”}. See doped/VASP_sets/PotcarSet.yaml for the default POTCAR set.

  • extrinsic_only (bool) – If True, only generate inputs for self.extrinsic_entries (useful when adding dopants to an existing intrinsic competing-phases set). Default is False (generate/write inputs for all entries).

  • output_path (PathLike) – Top-level output directory name. Default is "CompetingPhases".

  • subfolder (PathLike) – Output folder structure is <output_path>/<competing_phase_dir>/<subfolder>. Default is "Relax". Set to "." to write input files directly to <output_path>/<competing_phase_dir>, with no subfolders created.

  • **kwargs – Additional kwargs to pass to DictSet.write_input()

Returns:

Mapping of output folder paths to generated DopedDictSets (subclasses of VaspInputSet).

Return type:

dict[str, DopedDictSet]

write_singlepoint_files(kpoints_metals: float = 200.0, kpoints_nonmetals: float = 64.0, soc: bool | None = None, user_incar_settings: dict | None = None, user_potcar_functional: str = 'PBE', user_potcar_settings: dict | None = None, extrinsic_only: bool = False, output_path: str | Path = 'CompetingPhases', subfolder: str | Path | None = None, poscar: bool = False, **kwargs) dict[str, DopedDictSet][source]

Generates and writes DopedDictSets for single-point (static) energy calculations of the competing phases (i.e. NSW = 0, IBRION = -1 in VASP), using HSE06 (hybrid DFT) by default (consistent with the default input settings for defect calculations in doped.vasp).

These are expected to be used as the final energy calculation after geometry relaxation (from write_relaxation_files()), to obtain accurate total energies with tight convergence settings.

If soc=True, spin-orbit coupling (SOC) is included (by setting LSORBIT = True for VASP) and the output subfolder name will default to "vasp_ncl" (if not set otherwise). If soc is not explicitly set (i.e. is None), it defaults to True for systems where the max atomic number across all species (host and extrinsic) is Z >= 31 (heavier than Zn), matching the convention in doped.vasp.

Inclusion of SOC is crucial for accurate formation energies and chemical potentials in heavy-element systems, as discussed in Guidelines for robust and reproducible point defect simulations in crystals. However, non-SOC energies can generally be reliably used to determine relative energies of polymorphs, of the same composition/oxidation states, to good accuracy, which can be useful for pre-screening (e.g. then only performing more expensive SOC calculations on the ground-state polymorph of each potential competing phase). Moreover, one typically turns off symmetry for SOC calculations (i.e. ISYM set to -1 or 0 in VASP), as SOC can break crystal symmetries due to spin-space coupling. However, one generally finds that total energies from SOC calculations with (VASP) symmetry routines turned on give energies consistent with no-symmetry calculations, and can be much faster. Thus by default we do not turn off symmetry for SOC calculations here – note that the electronic band structure from these calculations is thus unreliable.

Automatically sets the ISMEAR INCAR tag to 2 (if metallic) or 0 if not. Note that any changes to the default INCAR/POTCAR settings should be consistent with those used for the defect supercell calculations.

For metals, while Methfessel-Paxton smearing (ISMEAR = 2; the default here) is well-suited to the geometry relaxations, tetrahedron smearing (ISMEAR = -5) typically gives more accurate total energies for these final single-point calculations with modest k-point densities, and can be set via user_incar_settings={"ISMEAR": -5}. Often this requires a lower k-point density than Methfessel-Paxton smearing, and so it can be worth re-running k-point convergence testing (with get_kpoint_convergence_sets()) using ISMEAR = -5 to check for cheaper converged k-point densities for these final single-point calculations – particularly useful if e.g. performing hybrid DFT SOC calculations. See the Competing Phases & Chemical Potentials tips section for further tips on boosting the efficiency of competing phases calculations.

Note that this function uses a single kpoint density setting each for metals (kpoints_metals), non-metals (kpoints_nonmetals) and molecules (Gamma-only), while one will often want to specify custom k-point settings for each material individually based on convergence testing (e.g. using get_kpoint_convergence_sets()) to minimise cost.

Parameters:
  • kpoints_metals (float) – Kpoint density per inverse volume (kpoints/Å⁻³) for metallic entries (those with zero band gap). Default is 200 kpoints/Å⁻³. Note that you may want to specify custom k-point settings for each material individually based on convergence testing to minimise cost.

  • kpoints_nonmetals (float) – Kpoint density per inverse volume (kpoints/Å⁻³) for non-metallic entries (those with non-zero band gap). Default is 64 kpoints/Å⁻³, matching the MPRelaxSet default). Note that you may want to specify custom k-point settings for each material individually based on convergence testing to minimise cost.

  • soc (bool) – Whether to include spin-orbit coupling (SOC), by setting LSORBIT = True in VASP INCAR files. If not set (when soc = None; default), SOC is enabled when the max atomic number across all species (host and extrinsic) is Z >= 31. The vasp_ncl executable is required to run VASP SOC calculations, and the default subfolder name is set to "vasp_ncl" when soc is True.

  • user_incar_settings (dict) – Override the default INCAR settings e.g. {"EDIFF": 1e-5, "LDAU": False, "ALGO": "All"}. Note that any non-numerical or non-True/False flags need to be input as strings with quotation marks. See doped/VASP_sets/RelaxSet.yaml and HSESet.yaml for the default settings.

  • user_potcar_functional (str) – POTCAR functional to use. Default is “PBE” and if this fails, tries “PBE_52”, then “PBE_54”.

  • user_potcar_settings (dict) – Override the default POTCARs, e.g. {“Li”: “Li_sv”}. See doped/VASP_sets/PotcarSet.yaml for the default POTCAR set.

  • extrinsic_only (bool) – If True, only generate inputs for self.extrinsic_entries (useful when adding dopants to an existing intrinsic competing-phases set). Default is False (generate inputs for all entries).

  • output_path (PathLike) – Top-level output directory name (used as a key prefix). Default is "CompetingPhases".

  • subfolder (PathLike) – Output folder structure is <output_path>/<competing_phase_dir>/<subfolder> where subfolder = ‘SinglePoint’ by default if soc is False, or ‘vasp_ncl’ if soc is True. Set to '.' to write input files directly to <output_path>/<competing_phase_dir>, with no subfolders created.

  • poscar (bool) – Whether to write POSCAR files. Defaults to False, as single-point (static) calculations are intended to be run on relaxed structures (e.g. from relaxations with write_relaxation_files()), so using the (unrelaxed) Materials Project structure is typically undesirable.

  • **kwargs – Additional kwargs to pass to DictSet.write_input()

Returns:

Mapping of output folder paths to generated DopedDictSets (subclasses of VaspInputSet).

Return type:

dict[str, DopedDictSet]

class doped.chemical_potentials.CompetingPhasesAnalyzer(composition: str | Composition, entries: str | Path | list[str | Path] | list[ComputedEntry] | list[ComputedStructureEntry] = 'CompetingPhases', subfolder: str | Path | None = None, single_extrinsic_phase_limits: bool = False, verbose: bool = True, processes: int | None = None, check_compatibility: bool = True)[source]

Bases: _EntriesMixin, MSONable

Class for post-processing competing phases calculations, to determine the corresponding chemical potentials for the host composition.

This class can be initialised from VASP outputs (vasprun.xmls) by specifying the path to the directory containing the outputs (e.g. "CompetingPhases") or a list of directories, or from a list of of ComputedEntrys / ComputedStructureEntrys (e.g. for use with high-throughput computing architectures such as atomate2 or AiiDA).

Multiprocessing is used by default to speed up parsing of VASP outputs, which can be controlled with processes. If parsing hangs, this may be due to memory issues, in which case you should reduce processes (e.g. 4 or less).

If extrinsic (dopant/impurity) elements are present, their chemical potential limits will also be calculated, where every facet (limit) jointly determines μ_host and μ_extrinsic.

Parameters:
  • composition (str, Composition) – Composition of the host material (e.g. 'LiFePO4', or Composition('LiFePO4'), or Composition({"Li":1, "Fe":1, "P":1, "O":4})).

  • entries (PathLike, list[PathLike], list[ComputedEntry], list[ComputedStructureEntry]) – Either a path to the base folder containing the VASP outputs (e.g. "CompetingPhases"; default), which is searched recursively for vasprun.xml(.gz) files, or a list of paths to vasprun.xml(.gz) files / directories. Alternatively, can be a list of ComputedEntrys / ComputedStructureEntrys.

  • subfolder (PathLike) – Restrict parsing to vasprun.xml(.gz) files inside directories with this name (e.g. "vasp_std"; default) – i.e. with a file-structure like: {Formula}_{spg}_EaH_{EaH}/{subfolder}/vasprun.xml(.gz)) If None (default), then auto-detects the subfolder: the highest-priority name (case-insensitive) among _SUBFOLDER_PRIORITY (vasp_ncl, singlepoint, final, relax, vasp_std, vasp_nkred_std, vasp_gam), with calculation outputs (vasprun.xml(.gz) files) and present in the discovered paths, is used. If none match, all found vaspruns are parsed. Set subfolder = "." to parse calculation files from the competing phase directory with no subfolder.

  • single_extrinsic_phase_limits (bool) – If True, pin μ_host at the intrinsic chemical potential limits, with the corresponding μ_extrinsic then determined at these points – equivalent to only considering the chemical potential limits with a single extrinsic competing phase (as with single_extrinsic_phase_limits in CompetingPhases initialisation). This typically returns fewer limits, which can simplify analysis when considering multiple extrinsic species at once, but can result in substantial portions of the chemical stability region being overlooked, and so is rarely recommended. Setting single_extrinsic_phase_limits=True in CompetingPhases initialisation (to reduce the number of extrinsic phases to calculate), but keeping it as False in parsing here is a significantly improved (though still imperfect) approximation, compared to True for parsing. Default is False (recommended; parse as normal with no restriction on the number of extrinsic phases in equilibrium at each facet (limit)).

  • verbose (bool) – Whether to print out information about directories that were skipped (due to no vasprun.xml(.gz) files being found), when parsing VASP outputs. Default is True.

  • processes (int) – Number of processes to use for multiprocessing for expedited parsing of VASP outputs. If None (default), then the parsing time with multiprocessing is estimated based on vasprun.xml(.gz) file sizes, and used if predicted to be faster than serial processing. Set to 1 to prevent multiprocessing.

  • check_compatibility (bool) – Whether to check the compatibility of the parsed entries, by comparing their INCAR and POTCAR settings (if available). Default is True.

composition

The bulk (host) composition.

Type:

str

chempots

Dictionary of the chemical potential limits for the host material, in the doped format (i.e. {"limits": [{'limit': [chempot_dict]}], ...}). This can be directly used with the DefectThermodynamics plotting & analysis methods, and saved to file with dumpfn from monty.serialization.

Type:

dict

chempots_df

DataFrame of the chemical potential limits for the host.

Type:

DataFrame

intrinsic_chempots

Dictionary of the chemical potential limits for the host material considering only intrinsic competing phases (i.e. ignoring extrinsic species), in the doped format. Equal to chempots when no extrinsic species are present.

Type:

dict

intrinsic_chempots_df

DataFrame of the intrinsic chemical potential limits for the host (i.e. ignoring extrinsic species).

Type:

DataFrame

elements

List of all elements in the chemical system (host + extrinsic), from all parsed calculations.

Type:

list

extrinsic_elements

List of extrinsic elements in the chemical system (not present in composition).

Type:

list[str]

intrinsic_elements

List of intrinsic elements (i.e. those in composition).

Type:

list[str]

bulk_entry

The lowest energy computed entry for the host material.

Type:

ComputedStructureEntry

unstable_host

Whether the host material is unstable with respect to competing phases (i.e. has an energy above hull > 0).

Type:

bool

entries

List of all parsed ComputedEntrys / ComputedStructureEntrys.

Type:

list[ComputedEntry, ComputedStructureEntry]

extrinsic_entries

Subset of entries containing one or more extrinsic species. Empty if no extrinsic species are present.

Type:

list[ComputedEntry, ComputedStructureEntry]

phase_diagram

A pymatgen phase diagram generated from the parsed entries. Note that this phase diagram is likely not a full phase diagram for this chemical space, as we typically only generate the nearby competing phases for the host material to reduce the number of calculations.

Type:

PhaseDiagram

intrinsic_phase_diagram

A pymatgen phase diagram containing only entries with elements from the host material (i.e. no extrinsic elements).

Type:

PhaseDiagram

elemental_energies

Dictionary of the lowest energy elemental phases for each element in the chemical system.

Type:

dict

vasprun_paths

List of paths to the vasprun.xml(.gz) files that were parsed (empty if initialised directly from entries).

Type:

list[str]

parsed_folders

List of folders from which VASP calculation outputs were parsed, if entries was given as a path / paths to directories.

Type:

list

single_extrinsic_phase_limits

Stored input parameter (see Args above).

Type:

bool

as_dict() dict[source]
Returns:

JSON-serializable dict representation of CompetingPhasesAnalyzer.

calculate_chempots(extrinsic: str | Element | Iterable[str] | Iterable[Element] | None = None, single_extrinsic_phase_limits: bool = False, sort_by: str | None = None, verbose: bool = True) DataFrame[source]

Calculates the chemical potential limits for the host composition (self.composition) and any extrinsic elements (which defaults to self.extrinsic_elements – i.e. all extrinsic elements present in self.entries).

If extrinsic (dopant/impurity) elements are present, their chemical potential limits will also be calculated, where every facet (limit) jointly determines μ_host and μ_extrinsic.

Parameters:
  • extrinsic (str | Element | Iterable[str] | Iterable[Element] | None) – If set, will calculate the chemical potential limits for these extrinsic elements (and all intrinsic elements) only. Can be a single element (str or Element), or a list of elements. If None (default), uses self.extrinsic_elements (all extrinsic elements present).

  • single_extrinsic_phase_limits (bool) – If True, pin μ_host at the intrinsic chemical potential limits, with the corresponding μ_extrinsic then determined at these points – equivalent to only considering the chemical potential limits with a single extrinsic competing phase (as with single_extrinsic_phase_limits in CompetingPhases initialisation). This typically returns fewer limits, which can simplify analysis when considering multiple extrinsic species at once, but can result in substantial portions of the chemical stability region being overlooked, and so is rarely recommended. Setting single_extrinsic_phase_limits=True in CompetingPhases initialisation (to reduce the number of extrinsic phases to calculate), but keeping it as False in parsing here is a significantly improved (though still imperfect) approximation, compared to True for parsing. Default is False (recommended; parse as normal with no restriction on the number of extrinsic phases in equilibrium at each facet (limit)).

  • sort_by (str) – If set, will sort the chemical potential limits in self.(intrinsic_)chempots and the output DataFrame according to the chemical potential of the specified element (from element-rich to element-poor conditions).

  • verbose (bool) – If True (default), will print the parsed chemical potential limits.

Returns:

pandas DataFrame, optionally saved to csv.

property chempot_grid: ChemicalPotentialGrid

ChemicalPotentialGrid object for the chemical potential limits of the host composition.

This object can be used for plotting and numerical analyses of chemical stability regions. See the ChemicalPotentialGrid class for more details.

property entries_dict: dict[str, ComputedEntry]

Mapping of doped competing phase names to entries.

classmethod from_dict(d: dict) CompetingPhasesAnalyzer[source]

Reconstitute a CompetingPhasesAnalyzer object from a dict representation created using as_dict().

Parameters:

d (dict) – dict representation of CompetingPhasesAnalyzer.

Returns:

CompetingPhasesAnalyzer object

get_formation_energy_df(prune_polymorphs: bool = False, include_raw_energies: bool = False, skip_rounding: bool = False) DataFrame[source]

Generate a DataFrame of the formation energies of parsed competing phases calculations.

Useful for quick summary and analysis of results, e.g. to include in the SI of journal articles or a thesis – to aid open-science and reproducibility, or for quick data sharing, or for use with other codes. Can be saved to file with formation_energy_df.to_csv() etc.

Rows are sorted according to CompetingPhasesAnalyzer.entries, which by default is sorted by energy above hull (with the host composition first), then by the number of elements in the formula, then by the position of elements in the periodic table (main group elements, then transition metals, sorted by row), then alphabetically.

Parameters:
  • prune_polymorphs (bool) – Whether to only write the lowest energy polymorphs for each composition. Doesn’t affect chemical potential limits (only the ground-state polymorphs matter for this). Default is False.

  • include_raw_energies (bool) – Whether to include the raw (QM/DFT) energies in the output DataFrame. Default is False.

  • skip_rounding (bool) – Whether to skip rounding the energies to 3 decimal places (1 meV/atom or meV/fu) for cleanliness. Default is False.

plot_chempot_heatmap(dependent_element: str | Element | None = None, fixed_elements: dict[str, float] | None = None, bordering_phases: bool = True, xlim: tuple[float, float] | None = None, ylim: tuple[float, float] | None = None, cbar_range: tuple[float, float] | None = None, colormap: str | Colormap | None = None, padding: float | None = None, title: str | bool = False, label_positions: bool | dict[str, tuple[float, float]] | list[tuple[float, float]] = True, filename: str | Path | None = None, style_file: str | Path | None = None, **kwargs) Figure[source]

Plot a heatmap of the chemical potentials for a multinary system, showing bordering secondary phases.

In this plot, the dependent_element chemical potential is plotted as a heatmap over the stability region of the host composition, as a function of two other elemental chemical potentials on the x and y axes.

3-D data is required to plot a 2-D heatmap, and so this function can be applied as-is for ternary systems (or binary systems with an extrinsic element), but for higher-dimensional systems a set of chemical potential constraints must be provided (as fixed_elements) to project the chemical stability region to 3-D; see the competing phases tutorial section on Analysing and visualising the chemical potential limits.

Extrinsic chemical potentials are also supported; added as additional dimensions to the chemical potential diagram and can be used as plot axes (see dependent_element / fixed_elements).

Note that due to an issue with matplotlib Stroke path effects, sometimes there can be odd holes in the whitespace around the chemical formula labels (see: https://github.com/matplotlib/matplotlib/issues/25669). This is only the case for png output, so saving to e.g. svg or pdf instead will avoid this issue.

If the heatmap interpolation looks odd (e.g. striation effects), generally this can be easily solved by setting n_points (via **kwargs) to a higher value (default = 1000).

If using the default colour map (batlow) in publications, please consider citing: https://zenodo.org/records/8409685

Tip: https://github.com/frssp/cplapy can be used to generate 3D plots of chemical stability regions, to show the bordering competing phases in quaternary systems.

Parameters:
  • dependent_element (str or Element) – The element for which the chemical potential is plotted as a heatmap. If None (default), the last element in the bulk composition formula is used (which corresponds to the most electronegative element present).

  • fixed_elements (dict) – A dictionary of chemical potentials to fix (in the format: {element: value}; e.g. {"Li": -2}) if the chemical system is >3-D. Constraining chemical potentials is required for multinary systems, in order to reduce the dimensionality to 3-D for plotting a 2-D heatmap. For a system with N elements, N-3 fixed chemical potentials should be specified. If None (default), the chemical potentials of the first N-3 elements in the bulk composition are fixed to their mean values in the stability region (i.e. the centroid of the stability region).

  • bordering_phases (bool) – Whether to plot the competing/secondary phases which border the host composition in the chemical potential diagram. Default is True.

  • xlim (tuple) – The x-axis limits for the plot. If None (default), the limits are set to the minimum and maximum values of the x-axis data, with padding equal to padding (default = 10% of the range).

  • ylim (tuple) – The y-axis limits for the plot. If None (default), the limits are set to the minimum and maximum values of the y-axis data, with padding equal to padding (default = 10% of the range).

  • cbar_range (tuple) – The range for the colourbar. If None (default), the range is set to the minimum and maximum values of the data.

  • colormap (str, matplotlib.colors.Colormap) –

    Colormap to use for the heatmap, either as a string (which can be a colormap name from https://www.fabiocrameri.ch/colourmaps / https://matplotlib.org/stable/users/explain/colors/colormaps) or a Colormap / ListedColormap object. If None (default), uses batlow from https://www.fabiocrameri.ch/colourmaps.

    Append “S” to the colormap name if using a sequential colormap from https://www.fabiocrameri.ch/colourmaps.

  • padding (float) – The padding to add to the x and y axis limits. If None (default), the padding is set to 10% of the range.

  • title (str or bool) – The title for the plot. If False (default), no title is added. If True, the title is set to the bulk composition formula, or if str, the title is set to the provided string.

  • label_positions (bool, dict or list) – The positions for the chemical formula line labels. If True (default), the labels are placed using a custom doped algorithm which attempts to find the best possible positions (minimising overlap). If False, no labels are added. Alternatively a dictionary can be provided, where the keys are the chemical formulae and the values are tuples of (x_coord, y-offset) at which to place the line labels (where y-offset is the offset from the line at x=x_coord). A list of tuples can also be provided, where the order is assumed to match the competing phase lines.

  • filename (PathLike) – The filename to save the plot to. If None (default), the plot is not saved.

  • style_file (PathLike) – Path to a mplstyle file to use for the plot. If None (default), uses the default doped style (from doped/utils/doped.mplstyle).

  • **kwargs – Additional keyword arguments to pass to ChemicalPotentialGrid.get_grid(), such as n_points (default = 1000) and cartesian (default = True for heatmap plotting, to ensure smooth interpolation).

Returns:

The matplotlib Figure object.

Return type:

plt.Figure

to_LaTeX_table(splits: int = 1, prune_polymorphs: bool = True) str[source]

A very simple function to print out the competing phase formation energies in a LaTeX table format, showing the formula, space group, energy above hull, kpoints (if present in the parsed data) and formation energy.

Needs the mhchem package to work and does not use the booktabs package; change hline to toprule, midrule and bottomrule if you want to use booktabs style.

Parameters:
  • splits (int) – Number of splits for the table; either 1 (default) or 2 (with two large columns, each with the formula, kpoints (if present) and formation energy (sub-)columns).

  • prune_polymorphs (bool) – Whether to only print out the lowest energy polymorphs for each composition. Default is True.

Returns:

LaTeX table string

Return type:

str

doped.chemical_potentials.entries_from_chempot_limits(chempots_dict: dict[str, dict]) list[ComputedEntry][source]

Generate a list of ComputedEntry objects from a doped dictionary of chemical potential limits.

These entries will correspond to the ground-state phase for each chemically-stable composition in the chemical system, and can be used to generate a ChemicalPotentialDiagram object (used in chemical potential heatmap plotting).

Parameters:

chempots_dict (dict[str, dict]) –

doped chemical potential limits dictionary, as output by CompetingPhasesAnalyzer.chempots, having the keys:

  • ”limits”: {“phaseA-phaseB-phaseC”:

    {“Li”: mu_Li, “P”: mu_P, …}, … }

  • ”elemental_refs”:

    {“Li”: mu_Li_ref, “P”: mu_P_ref, …}

Returns:

List of ComputedEntry objects, with energies per formula unit.

Return type:

list[ComputedEntry]

doped.chemical_potentials.get_MP_summary_dicts(entries: list[ComputedEntry] | None = None, chemsys: str | list[str] | None = None, api_key: str | None = None, **kwargs: Any) dict[str, dict][source]

Get the corresponding Materials Project (MP) summary dictionaries for computed entries in the input entries list or chemsys chemical system.

If entries is provided (which should be a list of ComputedEntrys from the Materials Project), then only summary dictionaries in this chemical system which match one of these entries (based on the MPIDs given in ComputedEntry.data["material_id"] / summary_dict["material_id"]) are returned.

Parameters:
  • entries (list[ComputedEntry]) – Optional input; list of ComputedEntry objects for the input chemical system. If provided, only summary dictionaries which match one of these entries (based on the MPIDs given in ComputedEntry.data["material_id"] and summary_dict["material_id"]) are returned.

  • chemsys (str, list[str]) – Optional input; chemical system to get entries for, in the format "A-B-C" or ["A", "B", "C"]. E.g. "Li-Fe-O" or ["Li", "Fe", "O"]. Either entries or chemsys must be provided!

  • api_key (str) – Materials Project (MP) API key, needed to access the MP database to obtain the corresponding summary dictionaries. If not supplied, will attempt to read from ~/.pmgrc.yaml or ~/.config/.pmgrc.yaml (under PMG_MAPI_KEY) or from the MP_API_KEY environment variable – see the doped Installation docs.

  • **kwargs – Additional keyword arguments to pass to the Materials Project API query, e.g. MPRester.materials.summary.search().

Returns:

Dictionary of summary dictionaries for the input chemical system. The keys are the MPIDs (e.g. "mp-1234") and the values are the corresponding summary dictionaries.

Return type:

dict[str, dict]

doped.chemical_potentials.get_X_poor_limit(X: str, chempots: dict, **kwargs) str[source]

Deprecated alias for get_X_rich_poor_limit(..., rich=False).

Will be removed in doped 4.1; use get_X_rich_poor_limit() (with rich=False) instead.

doped.chemical_potentials.get_X_rich_limit(X: str, chempots: dict, **kwargs) str[source]

Deprecated alias for get_X_rich_poor_limit(..., rich=True).

Will be removed in doped 4.1; use get_X_rich_poor_limit() (with rich=True) instead.

doped.chemical_potentials.get_X_rich_poor_limit(X: str, chempots: dict, rich: bool = True, warn_if_multiple: bool = True, tol: float = 0.01, bulk_composition: str | Composition | None = None) str[source]

Determine the chemical potential limit of the input chempots dict with extremal μ_X – maximum μ_X for X-rich (rich = True; default) or minimum μ_X for X-poor (rich = False).

If there are multiple chemical potential limits with the same extremal μ_X within an energy tolerance tol in eV (0.01 eV by default), a warning is thrown (if warn_if_multiple is True, default) and the tie is broken by firstly sorting the other elements by:

  • Whether or not they are in the bulk composition, prioritising elements in the bulk composition (this aids determinism in this function output).

  • Electronegativity similarity to the extremal element X, with more electronegatively-similar elements prioritised (such that in e.g. a multi-cation composition (A,B)Z, ‘A-rich’ here will resolve to the A-rich limit with the most B-rich chemical potential – i.e. the most ‘cation-rich’ limit).

Then, for each element Y in the sorted list, the max / min (for rich / poor respectively) of the μ_Y values among the still-tied limits is taken as μ_Y*, and only limits with |μ_Y - μ_Y*| < tol are kept. The process repeats until one limit remains, which is then returned. This is mostly equivalent to choosing the lexicographic max / min (μ_Y, …) tuple for X-rich/poor respectively, with a numerical tolerance tol.

This implementation is similar to that of FormationEnergyDiagram.get_chempots() in pymatgen.analysis.defects, but using electronegativity instead of electron affinity.

Parameters:
  • X (str) – Element symbol for the extremum species (e.g. “Te”), or a string as "X-rich" or "X-poor" where X is the extremum element – rich will be set automatically in this latter case (e.g. rich will be set to False for "Te-poor").

  • chempots (dict) – The chemical potential limits dict, as returned by CompetingPhasesAnalyzer.chempots (i.e. containing "limits" mapping limit names to {element: absolute μ}).

  • rich (bool) – Whether to use the maximum μ_X (X-rich; True) or minimum μ_X (X-poor; False). Default is True. Note that this setting will be overwritten if the X input is given as a "X-rich" / "X-poor" string (e.g. rich will be set to False for X = "Te-poor").

  • warn_if_multiple (bool) – Whether to warn if there are multiple chemical potential limits with the same extremal μ_X within an energy tolerance tol in eV. Default is True.

  • tol (float) – Energy tolerance in eV. Limits whose μ_X satisfies |μ_X - μ_X*| < tol, with μ_X* being the extremal value, are treated as tied. Default is 0.01 eV.

  • bulk_composition (str | Composition | None) – Host composition for intrinsic-vs-extrinsic ordering in ties. If None (default), auto-determines the bulk composition from the chempots dict (i.e. the composition which is present for each limit).

Returns:

The key in chempots["limits"] for the chosen limit.

Return type:

str

doped.chemical_potentials.get_and_set_competing_phase_name(entry: ComputedStructureEntry | ComputedEntry, regenerate: bool = False, ndigits: int = 3) str[source]

Get the doped name for a competing phase entry from the Materials Project (MP) database.

The default naming convention in doped for competing phases is: "{Chemical Formula}_{Space Group}_EaH_{MP Energy above Hull}". This is stored in the entry.data["doped_name"] key-value pair. If this value is already set, then this function just returns the previously-generated doped name, unless regenerate=True.

Parameters:
  • entry (ComputedStructureEntry, ComputedEntry) – pymatgen ComputedStructureEntry object for the competing phase.

  • regenerate (bool) – Whether to regenerate the doped name for the competing phase, if entry.data["doped_name"] already set. Default is False.

  • ndigits (int) – Number of digits to round the energy above hull value (in eV/atom) to. Default is 3.

Returns:

The doped name for the competing phase.

Return type:

doped_name (str)

doped.chemical_potentials.get_chempots_from_phase_diagram(bulk_computed_entry: ComputedEntry, phase_diagram: PhaseDiagram) dict[str, dict[Element, float]][source]

Get the chemical potential limits for the bulk computed entry in the supplied phase diagram.

Parameters:
Returns:

Dictionary of the chemical potential limits for the bulk computed entry in the phase diagram.

Return type:

dict

doped.chemical_potentials.get_doped_chempots_from_entries(entries: Sequence[ComputedEntry | ComputedStructureEntry | PDEntry], composition: str | Composition | ComputedEntry, single_chempot_limit: bool = False) dict[source]

Given a list of ComputedEntrys / ComputedStructureEntrys / PDEntrys and the bulk composition, returns the chemical potential limits dictionary in the doped format (i.e. {"limits": [{'limit': [chempot_dict]}], ...}) for the host material.

Parameters:
  • entries (list[ComputedEntry]) – List of ComputedEntrys / ComputedStructureEntrys / PDEntrys for the chemical system, from which to determine the chemical potential limits for the host material (composition).

  • composition (str, Composition, ComputedEntry) – Composition of the host material either as a string (e.g. ‘LiFePO4’) a pymatgen Composition object (e.g. Composition('LiFePO4')), or a ComputedEntry object.

  • single_chempot_limit (bool) – If set to True, only returns the first chemical potential limit in the calculated chemical potentials dictionary. Mainly intended for internal doped usage when the host material is calculated to be unstable with respect to the competing phases.

Returns:

Dictionary of chemical potential limits in the doped format.

Return type:

dict

doped.chemical_potentials.get_entries(chemsys_formula_id_criteria: str | dict[str, Any], api_key: str | None = None, bulk_composition: str | Composition | None = None, **kwargs: Any) list[ComputedStructureEntry][source]

Convenience function to get a list of ComputedStructureEntrys for an input single composition/formula, chemical system, MPID or full criteria, using MPRester.get_entries().

The output entries list is sorted by energy above hull, then by the number of elements in the formula, then by the position of elements in the periodic table (main group elements, then transition metals, sorted by row).

Parameters:
  • chemsys_formula_id_criteria (str/dict) – A formula (e.g., Fe2O3), chemical system (e.g., Li-Fe-O) or MPID (e.g., mp-1234) or full Mongo-style dict criteria.

  • api_key (str) – Materials Project (MP) API key, needed to access the MP database to obtain the corresponding ComputedStructureEntrys. If not supplied, will attempt to read from ~/.pmgrc.yaml or ~/.config/.pmgrc.yaml (under PMG_MAPI_KEY) or from the MP_API_KEY environment variable – see the doped Installation docs.

  • bulk_composition (str/Composition) – Optional input; formula of the bulk host material, to use for sorting the output entries (with all those matching the bulk composition first). Default is None.

  • **kwargs – Additional keyword arguments to pass to the Materials Project API get_entries() query – e.g. additional_criteria={"thermo_types": ["GGA_GGA+U"]} to query only GGA/GGA+U data, rather than the default mixed GGA/GGA+U/r2SCAN phase diagrams ("GGA_GGA+U_R2SCAN").

Returns:

List of ComputedStructureEntry objects for the input chemical system.

Return type:

list[ComputedStructureEntry]

doped.chemical_potentials.get_entries_in_chemsys(chemsys: str | list[str], api_key: str | None = None, energy_above_hull: float | None = None, bulk_composition: str | Composition | None = None, **kwargs: Any) list[ComputedStructureEntry][source]

Convenience function to get a list of ComputedStructureEntrys for an input chemical system, using MPRester.get_entries_in_chemsys().

Automatically uses the appropriate format and syntax required for the (new) Materials Project (MP) API. chemsys = ["Li", "Fe", "O"] will return a list of all entries in the Li-Fe-O chemical system, i.e., all LixOy, FexOy, LixFey, LixFeyOz, Li, Fe and O phases. Extremely useful for creating phase diagrams of entire chemical systems.

If energy_above_hull is supplied, then only entries with energies above hull (according to the MP-computed phase diagram) less than this value (in eV/atom) will be returned.

By default, entries are taken from the Materials Project mixed GGA/GGA+U/r2SCAN thermodynamic data (thermo_type = "GGA_GGA+U_R2SCAN"; the MP default since mp-api 0.46.5), where the MP mixing scheme gives one corrected energy per material on a single mixed phase diagram (hull). See **kwargs below for querying other thermo types.

The output entries list is sorted by energy above hull, then by the number of elements in the formula, then by the position of elements in the periodic table (main group elements, then transition metals, sorted by row).

Parameters:
  • chemsys (str, list[str]) – Chemical system to get entries for, in the format “A-B-C” or [“A”, “B”, “C”]. E.g. “Li-Fe-O” or [“Li”, “Fe”, “O”].

  • api_key (str) – Materials Project (MP) API key, needed to access the MP database to obtain the corresponding ComputedStructureEntrys. If not supplied, will attempt to read from ~/.pmgrc.yaml or ~/.config/.pmgrc.yaml (under PMG_MAPI_KEY) or from the MP_API_KEY environment variable – see the doped Installation docs.

  • energy_above_hull (float) – If supplied, only entries with energies above hull (according to the MP-computed phase diagram) less than this value (in eV/atom) will be returned. Set to 0 to only return phases on the MP convex hull. Default is None (i.e. all entries are returned).

  • bulk_composition (str/Composition) – Optional input; formula of the bulk host material, to use for sorting the output entries (with all those matching the bulk composition first). Default is None.

  • **kwargs – Additional keyword arguments to pass to the Materials Project API get_entries_in_chemsys() query – e.g. additional_criteria={"thermo_types": ["GGA_GGA+U"]} to query only GGA/GGA+U data, rather than the default mixed GGA/GGA+U/r2SCAN phase diagrams ("GGA_GGA+U_R2SCAN"; the MP default since mp-api 0.46.5, where the MP mixing scheme gives one corrected energy per material on a single mixed hull). Under the mixed default, any further additional_criteria (e.g. {"is_stable": True}) are applied by mp-api as a post-hoc filter on the (common energy scale) chemical system entries, with MP’s own per-material semantics; i.e. is_stable / energy_above_hull refer to each material’s own chemical-system mixing frame, so for multi-element systems they can differ slightly from hull distances on the returned (full chemical system) phase diagram – use the energy_above_hull argument here to filter on the latter.

Returns:

List of ComputedStructureEntry objects for the input chemical system.

Return type:

list[ComputedStructureEntry]

doped.chemical_potentials.make_molecular_entry(computed_entry: ComputedEntry) ComputedStructureEntry[source]

Generate a ComputedStructureEntry for a diatomic ‘molecule-in-a-box’ (X2) structure (e.g. O2, H2, Cl2, etc.), with composition and energy-per-atom set to match the input elemental ComputedEntry.

The magnetization of the output molecular entry (as in entry.data["summary"]["total_magnetization"]) is set to 0 for all X2 except O2, which has a triplet ground state (S = 1) – this is then used to set spin polarisation input settings (ISPIN and NUPDOWN in VASP) appropriately, with _set_spin_polarisation().

Parameters:

computed_entry (ComputedEntry) – ComputedEntry object for a single-element entry, for which to generate a corresponding diatomic ‘molecule-in-a-box’ entry (with matching composition and energy-per-atom).

Returns:

ComputedStructureEntry for the diatomic (X2) ‘molecule-in-a-box’.

Return type:

ComputedStructureEntry

doped.chemical_potentials.make_molecule_in_a_box(element: str) Structure[source]

Generate an X2 ‘molecule-in-a-box’ structure for the input element X, (i.e. a 30 Å cuboid supercell with a single X2 molecule in the centre).

This is the natural state of several elemental competing phases, such as O2, N2, H2, F2 and Cl2. Initial bond lengths are set to the experimental bond lengths of these gaseous molecules.

Parameters:

element (str) – Element symbol of the molecule to generate.

Returns:

pymatgen Structure of the molecule in a box.

Return type:

Structure

doped.chemical_potentials.plot_chempot_heatmap(chempots: dict, composition: str | Composition | ComputedEntry, dependent_element: str | Element | None = None, fixed_elements: dict[str, float] | None = None, bordering_phases: bool = True, xlim: tuple[float, float] | None = None, ylim: tuple[float, float] | None = None, cbar_range: tuple[float, float] | None = None, colormap: str | Colormap | None = None, padding: float | None = None, title: str | bool = False, label_positions: bool | dict[str, tuple[float, float]] | list[tuple[float, float]] = True, filename: str | Path | None = None, style_file: str | Path | None = None, **kwargs) Figure[source]

Plot a heatmap of the chemical potentials (chempots) for a multinary system (composition), showing bordering secondary phases.

In this plot, the dependent_element chemical potential is plotted as a heatmap over the stability region of the host composition, as a function of two other elemental chemical potentials on the x and y axes.

3-D data is required to plot a 2-D heatmap, and so this function can be applied as-is for ternary systems (or binary systems with an extrinsic element), but for higher-dimensional systems a set of chemical potential constraints must be provided (as fixed_elements) to project the chemical stability region to 3-D; see the competing phases tutorial section on Analysing and visualising the chemical potential limits.

Extrinsic chemical potentials are also supported; added as additional dimensions to the chemical potential diagram and can be used as plot axes (see dependent_element / fixed_elements). Note that extrinsic chemical potentials are unbounded at the poor (low) chemical potential limit, and so by default the lower limit is set equal to 3 eV lower than the lowest chemical potential bound, rounded down to the nearest integer. This behavior can be controlled by setting xlim, ylim and/or cbar_range.

Note that due to an issue with matplotlib Stroke path effects, sometimes there can be odd holes in the whitespace around the chemical formula labels (see: https://github.com/matplotlib/matplotlib/issues/25669). This is only the case for png output, so saving to e.g. svg or pdf instead will avoid this issue.

If the heatmap interpolation looks odd (e.g. striation effects), generally this can be easily solved by setting n_points (via **kwargs) to a higher value (default = 10,000 for heatmap plotting).

If using the default colour map (batlow) in publications, please consider citing: https://zenodo.org/records/8409685

Tip: https://github.com/frssp/cplapy can be used to generate 3D plots of chemical stability regions, to show the bordering competing phases in quaternary systems.

Parameters:
  • chempots (dict) – Chemical potential limits dictionary in the doped format (i.e. {"limits": [{'limit': [chempot_dict]}], ...}) for the host material (composition).

  • composition (str or Composition or ComputedEntry) – Host material composition as a string, Composition object or ComputedEntry, for which to plot the chemical stability region (and for which chempots corresponds to).

  • dependent_element (str or Element) – The element for which the chemical potential is plotted as a heatmap. If None (default), the last element in the bulk composition formula is used (which corresponds to the most electronegative element present).

  • fixed_elements (dict) – A dictionary of chemical potentials to fix (in the format: {element: value}; e.g. {"Li": -2}) if the chemical system is >3-D. Constraining chemical potentials is required for multinary systems, in order to reduce the dimensionality to 3-D for plotting a 2-D heatmap. For a system with N elements, N-3 fixed chemical potentials should be specified. If None (default), the chemical potentials of the first N-3 elements in the bulk composition are fixed to their mean values in the stability region (i.e. the centroid of the stability region).

  • bordering_phases (bool) – Whether to plot the competing/secondary phases which border the host composition in the chemical potential diagram. Default is True.

  • xlim (tuple) – The x-axis limits for the plot. If None (default), the limits are set to the minimum and maximum values of the x-axis data, with padding equal to padding (default = 10% of the range).

  • ylim (tuple) – The y-axis limits for the plot. If None (default), the limits are set to the minimum and maximum values of the y-axis data, with padding equal to padding (default = 10% of the range).

  • cbar_range (tuple) – The range for the colourbar. If None (default), the range is set to the minimum and maximum values of the data.

  • colormap (str, matplotlib.colors.Colormap) –

    Colormap to use for the heatmap, either as a string (which can be a colormap name from https://www.fabiocrameri.ch/colourmaps / https://matplotlib.org/stable/users/explain/colors/colormaps) or a Colormap / ListedColormap object. If None (default), uses batlow from https://www.fabiocrameri.ch/colourmaps.

    Append “S” to the colormap name if using a sequential colormap from https://www.fabiocrameri.ch/colourmaps.

  • padding (float) – The padding to add to the x and y axis limits. If None (default), the padding is set to 10% of the range.

  • title (str or bool) – The title for the plot. If False (default), no title is added. If True, the title is set to the bulk composition formula, or if str, the title is set to the provided string.

  • label_positions (bool, dict or list) – The positions for the chemical formula line labels. If True (default), the labels are placed using a custom doped algorithm which attempts to find the best possible positions (minimising overlap). If False, no labels are added. Alternatively a dictionary can be provided, where the keys are the chemical formulae and the values are tuples of (x_coord, y-offset) at which to place the line labels (where y-offset is the offset from the line at x=x_coord). A list of tuples can also be provided, where the order is assumed to match the competing phase lines.

  • filename (PathLike) – The filename to save the plot to. If None (default), the plot is not saved.

  • style_file (PathLike) – Path to a mplstyle file to use for the plot. If None (default), uses the default doped style (from doped/utils/doped.mplstyle).

  • **kwargs – Additional keyword arguments to pass to ChemicalPotentialGrid.get_grid(), such as n_points (default = 10,000 for heatmap plotting, rather than the get_grid() default of 1000) and cartesian (default = True for heatmap plotting, to ensure smooth interpolation).

Returns:

The matplotlib Figure object.

Return type:

plt.Figure

doped.chemical_potentials.prune_entries_to_border_candidates(entries: list[ComputedEntry], bulk_computed_entry: ComputedEntry, phase_diagram: PhaseDiagram | None = None, energy_above_hull: float = 0.05) list[ComputedEntry][source]

Given an input list of ComputedEntry/ComputedStructureEntrys (entries) and a single entry for the host material (bulk_computed_entry), returns the subset of entries which could border the host on the phase diagram (and therefore be a competing phase which determines the host chemical potential limits), allowing for an error tolerance (i.e. for the semi-local (mixed GGA/GGA+U/r2SCAN) DFT database energies (energy_above_hull, set to self.energy_above_hull – 0.05 eV/atom by default)).

If phase_diagram is provided then this is used as the reference phase diagram, otherwise it is generated from entries and bulk_computed_entry.

Parameters:
  • entries (list[ComputedEntry]) – List of ComputedEntry objects to prune down to potential host border candidates on the phase diagram.

  • bulk_computed_entry (ComputedEntry) – ComputedEntry object for the host material.

  • phase_diagram (PhaseDiagram) – Optional input; PhaseDiagram object for the system of interest. If provided, this is used as the reference phase diagram from which to determine the (potential) chemical potential limits, otherwise it is generated from entries and bulk_computed_entry.

  • energy_above_hull (float) – Maximum energy above hull (in eV/atom) of Materials Project entries to be considered as competing phases. This is an uncertainty range for the MP-calculated formation energies (mixed GGA/GGA+U/r2SCAN data by default), which may not be accurate due to functional choice (semi-local DFT vs hybrid DFT / RPA etc.), lack of vdW corrections etc. All phases that would border the host material on the phase diagram, if their relative energy was downshifted by energy_above_hull, are included. (Default is 0.05 eV/atom).

Returns:

List of all ComputedEntry objects in entries which could border the host material on the phase diagram (and thus set the chemical potential limits), if their relative energy was downshifted by energy_above_hull eV/atom.

Return type:

list[ComputedEntry]

doped.chemical_potentials.prune_to_expected_polymorphs(entries: list[ComputedEntry]) list[ComputedEntry][source]

For each composition listed in doped/utils/known_MP_ground_states.yaml, retain only the lowest energy-above-hull entry plus any entries whose Materials Project ID is included in the listed set; entries for compositions not listed in the data file are returned unchanged.

Parameters:

entries (list[ComputedEntry]) – Input list of ComputedEntry objects to prune.

Returns:

Pruned list of entries.

Return type:

list[ComputedEntry]