From d94537d70377e6d7719ec01e18e9ff96f3af578b Mon Sep 17 00:00:00 2001 From: esoteric-ephemera Date: Fri, 27 Jun 2025 14:17:17 -0700 Subject: [PATCH] add feature to place user entries on pourbaix --- mp_api/client/mprester.py | 40 +++++++++++++++++++++--- mp_api/client/routes/materials/phonon.py | 4 +-- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/mp_api/client/mprester.py b/mp_api/client/mprester.py index 6a000c4e0..4e15ec32d 100644 --- a/mp_api/client/mprester.py +++ b/mp_api/client/mprester.py @@ -783,7 +783,7 @@ def get_entries( def get_pourbaix_entries( self, - chemsys: str | list, + chemsys: str | list[str] | list[ComputedEntry | ComputedStructureEntry], solid_compat="MaterialsProject2020Compatibility", use_gibbs: Literal[300] | None = None, ): @@ -791,9 +791,14 @@ def get_pourbaix_entries( a Pourbaix diagram from the rest interface. Args: - chemsys (str or [str]): Chemical system string comprising element + chemsys (str or [str] or Computed(Structure)Entry): + Chemical system string comprising element symbols separated by dashes, e.g., "Li-Fe-O" or List of element symbols, e.g., ["Li", "Fe", "O"]. + + Can also be a list of Computed(Structure)Entry objects to allow + for adding extra calculation data to the Pourbaix Diagram. + If this is set, the chemsys will be inferred from the entries. solid_compat: Compatibility scheme used to pre-process solid DFT energies prior to applying aqueous energy adjustments. May be passed as a class (e.g. MaterialsProject2020Compatibility) or an instance @@ -816,6 +821,27 @@ def get_pourbaix_entries( ) from pymatgen.entries.computed_entries import ComputedEntry + thermo_types = ["GGA_GGA+U"] + user_entries: list[ComputedEntry | ComputedStructureEntry] = [] + if isinstance(chemsys, list) and all( + isinstance(v, ComputedEntry | ComputedStructureEntry) for v in chemsys + ): + user_entries = [ce.copy() for ce in chemsys] + + elements = set() + for entry in user_entries: + elements.update(entry.elements) + chemsys = [ele.name for ele in elements] + + user_run_types = set( + [ + entry.parameters.get("run_type", "unknown").lower() + for entry in user_entries + ] + ) + if any("r2scan" in rt for rt in user_run_types): + thermo_types = ["GGA_GGA+U_R2SCAN"] + if solid_compat == "MaterialsProjectCompatibility": solid_compat = MaterialsProjectCompatibility() elif solid_compat == "MaterialsProject2020Compatibility": @@ -851,9 +877,13 @@ def get_pourbaix_entries( # TODO - would be great if the commented line below would work # However for some reason you cannot process GibbsComputedStructureEntry with # MaterialsProjectAqueousCompatibility - ion_ref_entries = self.get_entries_in_chemsys( - list([str(e) for e in ion_ref_elts] + ["O", "H"]), - # use_gibbs=use_gibbs + ion_ref_entries = ( + self.get_entries_in_chemsys( + list([str(e) for e in ion_ref_elts] + ["O", "H"]), + additional_criteria={"thermo_types": thermo_types} + # use_gibbs=use_gibbs + ) + + user_entries ) # suppress the warning about supplying the required energies; they will be calculated from the diff --git a/mp_api/client/routes/materials/phonon.py b/mp_api/client/routes/materials/phonon.py index f9d9ac9a5..4ce52950e 100644 --- a/mp_api/client/routes/materials/phonon.py +++ b/mp_api/client/routes/materials/phonon.py @@ -1,11 +1,11 @@ from __future__ import annotations import json -import numpy as np from collections import defaultdict +import numpy as np +from emmet.core.phonon import PhononBS, PhononBSDOSDoc, PhononDOS from monty.json import MontyDecoder -from emmet.core.phonon import PhononBSDOSDoc, PhononBS, PhononDOS from mp_api.client.core import BaseRester, MPRestError from mp_api.client.core.utils import validate_ids