34
34
from typing import Any , Literal
35
35
36
36
import matplotlib .pyplot as plt
37
+ from numpy .typing import NDArray
37
38
from typing_extensions import Self
38
39
39
40
from pymatgen .core import DummySpecies , Species
@@ -526,15 +527,15 @@ def __init__(
526
527
527
528
self ._stable_domains , self ._stable_domain_vertices = self .get_pourbaix_domains (self ._processed_entries )
528
529
529
- def _convert_entries_to_points (self , pourbaix_entries ) :
530
+ def _convert_entries_to_points (self , pourbaix_entries : list [ PourbaixEntry ]) -> NDArray :
530
531
"""
531
532
Args:
532
- pourbaix_entries ([PourbaixEntry]): list of Pourbaix entries
533
+ pourbaix_entries (list [PourbaixEntry]): Pourbaix entries
533
534
to process into vectors in nph-nphi-composition space.
534
535
535
536
Returns:
536
- list of vectors, [[nph, nphi, e0, x1, x2, ..., xn-1]]
537
- corresponding to each entry in nph-nphi-composition space
537
+ NDAarray: vectors as [[nph, nphi, e0, x1, x2, ..., xn-1]]
538
+ corresponding to each entry in nph-nphi-composition space
538
539
"""
539
540
vecs = [
540
541
[entry .npH , entry .nPhi , entry .energy ] + [entry .composition .get (elt ) for elt in self .pbx_elts [:- 1 ]]
@@ -545,15 +546,18 @@ def _convert_entries_to_points(self, pourbaix_entries):
545
546
vecs *= norms
546
547
return vecs
547
548
548
- def _get_hull_in_nph_nphi_space (self , entries ) -> tuple [list [PourbaixEntry ], list [Simplex ]]:
549
+ def _get_hull_in_nph_nphi_space (
550
+ self ,
551
+ entries : list [PourbaixEntry ],
552
+ ) -> tuple [list [PourbaixEntry ], list [Simplex ]]:
549
553
"""Generate convex hull of Pourbaix diagram entries in composition,
550
554
npH, and nphi space. This enables filtering of multi-entries
551
555
such that only compositionally stable combinations of entries
552
556
are included.
553
557
554
558
Args:
555
- entries ([PourbaixEntry]): list of PourbaixEntries to construct
556
- the convex hull
559
+ entries (list [PourbaixEntry]): PourbaixEntries to construct
560
+ the convex hull.
557
561
558
562
Returns:
559
563
tuple[list[PourbaixEntry], list[Simplex]]: PourbaixEntry list and stable
@@ -602,11 +606,15 @@ def _get_hull_in_nph_nphi_space(self, entries) -> tuple[list[PourbaixEntry], lis
602
606
603
607
return min_entries , valid_facets
604
608
605
- def _preprocess_pourbaix_entries (self , entries , nproc = None ):
609
+ def _preprocess_pourbaix_entries (
610
+ self ,
611
+ entries : list [PourbaixEntry ],
612
+ nproc : int | None = None ,
613
+ ) -> list [MultiEntry ]:
606
614
"""Generate multi-entries for Pourbaix diagram.
607
615
608
616
Args:
609
- entries ([PourbaixEntry]): list of PourbaixEntries to preprocess
617
+ entries (list [PourbaixEntry]): PourbaixEntries to preprocess
610
618
into MultiEntries
611
619
nproc (int): number of processes to be used in parallel
612
620
treatment of entry combos
@@ -651,7 +659,11 @@ def _preprocess_pourbaix_entries(self, entries, nproc=None):
651
659
652
660
return multi_entries
653
661
654
- def _generate_multielement_entries (self , entries , nproc = None ):
662
+ def _generate_multielement_entries (
663
+ self ,
664
+ entries : list [PourbaixEntry ],
665
+ nproc : int | None = None ,
666
+ ) -> list [MultiEntry ]:
655
667
"""
656
668
Create entries for multi-element Pourbaix construction.
657
669
@@ -698,7 +710,9 @@ def _generate_multielement_entries(self, entries, nproc=None):
698
710
return processed_entries
699
711
700
712
@staticmethod
701
- def process_multientry (entry_list , prod_comp , coeff_threshold = 1e-4 ):
713
+ def process_multientry (
714
+ entry_list : list , prod_comp : Composition , coeff_threshold : float = 1e-4
715
+ ) -> MultiEntry | None :
702
716
"""Static method for finding a multientry based on
703
717
a list of entries and a product composition.
704
718
Essentially checks to see if a valid aqueous
@@ -736,7 +750,10 @@ def process_multientry(entry_list, prod_comp, coeff_threshold=1e-4):
736
750
return None
737
751
738
752
@staticmethod
739
- def get_pourbaix_domains (pourbaix_entries , limits = None ):
753
+ def get_pourbaix_domains (
754
+ pourbaix_entries : list [PourbaixEntry ],
755
+ limits : list [list [float ]] | None = None ,
756
+ ) -> tuple [dict , dict ]:
740
757
"""Get a set of Pourbaix stable domains (i.e. polygons) in
741
758
pH-V space from a list of pourbaix_entries.
742
759
@@ -750,12 +767,12 @@ def get_pourbaix_domains(pourbaix_entries, limits=None):
750
767
points.
751
768
752
769
Args:
753
- pourbaix_entries ([PourbaixEntry]): Pourbaix entries
770
+ pourbaix_entries (list [PourbaixEntry]): Pourbaix entries
754
771
with which to construct stable Pourbaix domains
755
- limits ([ [float]]): limits in which to do the pourbaix
772
+ limits (list[list [float]]): limits in which to do the pourbaix
756
773
analysis
757
774
758
- Returns:
775
+ Returns: # TODO: incorrect return type doc
759
776
Returns a dict of the form {entry: [boundary_points]}.
760
777
The list of boundary points are the sides of the N-1
761
778
dim polytope bounding the allowable ph-V range of each entry.
@@ -817,7 +834,7 @@ def get_pourbaix_domains(pourbaix_entries, limits=None):
817
834
818
835
return pourbaix_domains , pourbaix_domain_vertices
819
836
820
- def find_stable_entry (self , pH , V ) :
837
+ def find_stable_entry (self , pH : float , V : float ) -> PourbaixEntry :
821
838
"""Find stable entry at a pH,V condition.
822
839
823
840
Args:
@@ -830,7 +847,12 @@ def find_stable_entry(self, pH, V):
830
847
energies_at_conditions = [entry .normalized_energy_at_conditions (pH , V ) for entry in self .stable_entries ]
831
848
return self .stable_entries [np .argmin (energies_at_conditions )]
832
849
833
- def get_decomposition_energy (self , entry , pH , V ):
850
+ def get_decomposition_energy (
851
+ self ,
852
+ entry : PourbaixEntry ,
853
+ pH : float | list [float ],
854
+ V : float | list [float ],
855
+ ) -> NDArray :
834
856
"""Find decomposition to most stable entries in eV/atom,
835
857
supports vectorized inputs for pH and V.
836
858
@@ -860,7 +882,7 @@ def get_decomposition_energy(self, entry, pH, V):
860
882
decomposition_energy /= entry .composition .num_atoms
861
883
return decomposition_energy
862
884
863
- def get_hull_energy (self , pH : float | list [float ], V : float | list [float ]) -> np . ndarray :
885
+ def get_hull_energy (self , pH : float | list [float ], V : float | list [float ]) -> NDArray :
864
886
"""Get the minimum energy of the Pourbaix "basin" that is formed
865
887
from the stable Pourbaix planes. Vectorized.
866
888
@@ -874,7 +896,7 @@ def get_hull_energy(self, pH: float | list[float], V: float | list[float]) -> np
874
896
all_gs = np .array ([entry .normalized_energy_at_conditions (pH , V ) for entry in self .stable_entries ])
875
897
return np .min (all_gs , axis = 0 )
876
898
877
- def get_stable_entry (self , pH , V ) :
899
+ def get_stable_entry (self , pH : float , V : float ) -> PourbaixEntry | MultiEntry :
878
900
"""Get the stable entry at a given pH, V condition.
879
901
880
902
Args:
@@ -889,26 +911,26 @@ def get_stable_entry(self, pH, V):
889
911
return self .stable_entries [np .argmin (all_gs )]
890
912
891
913
@property
892
- def stable_entries (self ):
914
+ def stable_entries (self ) -> list :
893
915
"""The stable entries in the Pourbaix diagram."""
894
916
return list (self ._stable_domains )
895
917
896
918
@property
897
- def unstable_entries (self ):
919
+ def unstable_entries (self ) -> list :
898
920
"""All unstable entries in the Pourbaix diagram."""
899
921
return [entry for entry in self .all_entries if entry not in self .stable_entries ]
900
922
901
923
@property
902
- def all_entries (self ):
924
+ def all_entries (self ) -> list :
903
925
"""All entries used to generate the Pourbaix diagram."""
904
926
return self ._processed_entries
905
927
906
928
@property
907
- def unprocessed_entries (self ):
929
+ def unprocessed_entries (self ) -> list :
908
930
"""Unprocessed entries."""
909
931
return self ._unprocessed_entries
910
932
911
- def as_dict (self ):
933
+ def as_dict (self ) -> dict [ str , Any ] :
912
934
"""Get MSONable dict."""
913
935
return {
914
936
"@module" : type (self ).__module__ ,
@@ -940,7 +962,7 @@ def from_dict(cls, dct: dict) -> Self:
940
962
class PourbaixPlotter :
941
963
"""A plotter class for phase diagrams."""
942
964
943
- def __init__ (self , pourbaix_diagram ) :
965
+ def __init__ (self , pourbaix_diagram : PourbaixDiagram ) -> None :
944
966
"""
945
967
Args:
946
968
pourbaix_diagram (PourbaixDiagram): A PourbaixDiagram object.
@@ -1046,12 +1068,12 @@ def plot_entry_stability(
1046
1068
1047
1069
Args:
1048
1070
entry (Any): The entry to plot stability for.
1049
- pH_range (tuple[float, float], optional ): pH range for the plot. Defaults to (-2, 16).
1050
- pH_resolution (int, optional ): pH resolution. Defaults to 100.
1051
- V_range (tuple[float, float], optional ): Voltage range for the plot. Defaults to (-3, 3).
1052
- V_resolution (int, optional ): Voltage resolution. Defaults to 100.
1053
- e_hull_max (float, optional ): Maximum energy above the hull. Defaults to 1.
1054
- cmap (str, optional ): Colormap for the plot. Defaults to "RdYlBu_r".
1071
+ pH_range (tuple[float, float]): pH range for the plot. Defaults to (-2, 16).
1072
+ pH_resolution (int): pH resolution. Defaults to 100.
1073
+ V_range (tuple[float, float]): Voltage range for the plot. Defaults to (-3, 3).
1074
+ V_resolution (int): Voltage resolution. Defaults to 100.
1075
+ e_hull_max (float): Maximum energy above the hull. Defaults to 1.
1076
+ cmap (str): Colormap for the plot. Defaults to "RdYlBu_r".
1055
1077
ax (Axes, optional): Existing matplotlib Axes object for plotting. Defaults to None.
1056
1078
**kwargs (Any): Additional keyword arguments passed to `get_pourbaix_plot`.
1057
1079
@@ -1079,7 +1101,7 @@ def plot_entry_stability(
1079
1101
1080
1102
return ax
1081
1103
1082
- def domain_vertices (self , entry ):
1104
+ def domain_vertices (self , entry ) -> list :
1083
1105
"""Get the vertices of the Pourbaix domain.
1084
1106
1085
1107
Args:
@@ -1091,7 +1113,7 @@ def domain_vertices(self, entry):
1091
1113
return self ._pbx ._stable_domain_vertices [entry ]
1092
1114
1093
1115
1094
- def generate_entry_label (entry ) :
1116
+ def generate_entry_label (entry : PourbaixEntry | MultiEntry ) -> str :
1095
1117
"""
1096
1118
Generates a label for the Pourbaix plotter.
1097
1119
0 commit comments