Пример #1
0
    def get_decomposition_in_gppd(self,
                                  chempot,
                                  entries=None,
                                  exclusions=None,
                                  trypreload=False):
        gppd_entries = entries if entries \
            else self.get_gppd_entries(chempot, exclusions=exclusions, trypreload=trypreload)
        pd = PhaseDiagram(gppd_entries)
        gppd_entries = pd.stable_entries
        open_el_entries = [
            _ for _ in gppd_entries if _.is_element
            and _.composition.elements[0].symbol in chempot.keys()
        ]
        el_ref = {
            _.composition.elements[0].symbol: _.energy_per_atom
            for _ in open_el_entries
        }
        chempot_vaspref = {_: chempot[_] + el_ref[_] for _ in chempot}
        for open_entry in open_el_entries:
            open_entry.correction += chempot_vaspref[
                open_entry.composition.elements[0].symbol]

        GPPD = GrandPotentialPhaseDiagram(gppd_entries, chempot_vaspref)
        GPComp = self.GPComp(chempot)
        decomp_GP_entries = GPPD.get_decomposition(GPComp)
        decomp_entries = [gpe.original_entry for gpe in decomp_GP_entries]
        rxn = ComputedReaction([self] + open_el_entries, decomp_entries)
        rxn.normalize_to(self.composition)
        return decomp_entries, rxn
Пример #2
0
    def test_get_critical_compositions(self):
        c1 = Composition("Fe2O3")
        c2 = Composition("Li3FeO4")
        c3 = Composition("Li2O")

        comps = self.pd.get_critical_compositions(c1, c2)
        expected = [
            Composition("Fe2O3"),
            Composition("Li0.3243244Fe0.1621621O0.51351349") * 7.4,
            Composition("Li3FeO4"),
        ]
        for crit, exp in zip(comps, expected):
            self.assertTrue(crit.almost_equals(exp, rtol=0, atol=1e-5))

        comps = self.pd.get_critical_compositions(c1, c3)
        expected = [
            Composition("Fe2O3"),
            Composition("LiFeO2"),
            Composition("Li5FeO4") / 3,
            Composition("Li2O"),
        ]
        for crit, exp in zip(comps, expected):
            self.assertTrue(crit.almost_equals(exp, rtol=0, atol=1e-5))

        # Don't fail silently if input compositions aren't in phase diagram
        # Can be very confusing if you're working with a GrandPotentialPD
        self.assertRaises(
            ValueError,
            self.pd.get_critical_compositions,
            Composition("Xe"),
            Composition("Mn"),
        )

        # For the moment, should also fail even if compositions are in the gppd
        # because it isn't handled properly
        gppd = GrandPotentialPhaseDiagram(self.pd.all_entries, {"Xe": 1},
                                          self.pd.elements + [Element("Xe")])
        self.assertRaises(
            ValueError,
            gppd.get_critical_compositions,
            Composition("Fe2O3"),
            Composition("Li3FeO4Xe"),
        )

        # check that the function still works though
        comps = gppd.get_critical_compositions(c1, c2)
        expected = [
            Composition("Fe2O3"),
            Composition("Li0.3243244Fe0.1621621O0.51351349") * 7.4,
            Composition("Li3FeO4"),
        ]
        for crit, exp in zip(comps, expected):
            self.assertTrue(crit.almost_equals(exp, rtol=0, atol=1e-5))

        # case where the endpoints are identical
        self.assertEqual(self.pd.get_critical_compositions(c1, c1 * 2),
                         [c1, c1 * 2])
    def get_phase_diagram_data(self):
        """
        Returns grand potential phase diagram data to external plot
        Assumes openelement specific element equals None
        :return: Data to external plot
        """
        open_elements_specific = None
        open_element_all = Element(self.open_element)
        mpr = MPRester("settings")

        # Get data to make phase diagram
        entries = mpr.get_entries_in_chemsys(self.system, compatible_only=True)
        #print(entries)

        if open_elements_specific:
            gcpd = GrandPotentialPhaseDiagram(entries, open_elements_specific)
            self.plot_phase_diagram(gcpd, False)
            self.analyze_phase_diagram(gcpd)

        if open_element_all:
            pd = PhaseDiagram(entries)
            chempots = pd.get_transition_chempots(open_element_all)
            #print(chempots)
            #all_gcpds = list()
            toplot = []
            # dic = {}
            for idx in range(len(chempots)):
                if idx == len(chempots) - 1:
                    avgchempot = chempots[idx] - 0.1
                else:
                    avgchempot = 0.5 * (chempots[idx] + chempots[idx + 1])
                gcpd = GrandPotentialPhaseDiagram(
                    entries, {open_element_all: avgchempot}, pd.elements)
                # toplot.append(self.get_grand_potential_phase_diagram(gcpd))

                min_chempot = None if idx == len(chempots) - 1 else chempots[
                    idx + 1]
                max_chempot = chempots[idx]
                #gcpd = GrandPotentialPhaseDiagram(entries, {open_element_all: max_chempot}, pd.elements)

                toplot.append(self.get_grand_potential_phase_diagram(gcpd))
                #toplot.append(max_chempot)

                #self.plot_phase_diagram(gcpd, False)
                #print({open_element_all: max_chempot})

            # Data to plot phase diagram
            return toplot
Пример #4
0
def FullChemicalPotentialWindow(target_phase, key_element):
    chemsys = key_element + '-' + Composition(target_phase).chemical_system
    with MPRester(api_key='') as mpr:
        entries = mpr.get_entries_in_chemsys(chemsys)

    pd_closed = PhaseDiagram(entries)
    transition_chempots = pd_closed.get_transition_chempots(
        Element(key_element))
    # The exact mu value used to construct the plot for each range is
    # the average of the endpoints of the range, with the exception of the last range,
    # which is plotted at the value of the last endpoint minus 0.1.
    # https://matsci.org/t/question-on-phase-diagram-app-chemical-potential/511
    average_chempots = []
    if len(transition_chempots) > 1:
        for i in range(len(transition_chempots) - 1):
            ave = (transition_chempots[i] + transition_chempots[i + 1]) / 2
            average_chempots.append(ave)
        average_chempots.append(transition_chempots[-1] - 0.1)
    elif len(transition_chempots) == 1:
        # prepare for binary systems, of which two endnodes tielined directly, like Li-Zr
        average_chempots.append(transition_chempots[0])
    average_chempots = np.round(average_chempots, 3)

    boolean_list = []
    for chempot in average_chempots:
        # GrandPotentialPhaseDiagram works good even for binary systems to find stable phases
        pd_open = GrandPotentialPhaseDiagram(entries,
                                             {Element(key_element): chempot})
        stable_phases = [entry.name for entry in pd_open.stable_entries]
        boolean_list.append(target_phase in stable_phases)
    return (False not in boolean_list)
Пример #5
0
class GrandPotentialPhaseDiagramTest(unittest.TestCase):
    def setUp(self):
        self.entries = EntrySet.from_csv(str(module_dir / "pdentries_test.csv"))
        self.pd = GrandPotentialPhaseDiagram(self.entries, {Element("O"): -5})
        self.pd6 = GrandPotentialPhaseDiagram(self.entries, {Element("O"): -6})

    def test_stable_entries(self):
        stable_formulas = [ent.original_entry.composition.reduced_formula for ent in self.pd.stable_entries]
        expected_stable = ["Li5FeO4", "Li2FeO3", "LiFeO2", "Fe2O3", "Li2O2"]
        for formula in expected_stable:
            self.assertTrue(formula in stable_formulas, f"{formula} not in stable entries!")
        self.assertEqual(len(self.pd6.stable_entries), 4)

    def test_get_formation_energy(self):
        stable_formation_energies = {
            ent.original_entry.composition.reduced_formula: self.pd.get_form_energy(ent)
            for ent in self.pd.stable_entries
        }
        expected_formation_energies = {
            "Fe2O3": 0.0,
            "Li5FeO4": -5.305515040000046,
            "Li2FeO3": -2.3424741500000152,
            "LiFeO2": -0.43026396250000154,
            "Li2O2": 0.0,
        }
        for formula, energy in expected_formation_energies.items():
            self.assertAlmostEqual(
                energy,
                stable_formation_energies[formula],
                7,
                f"Calculated formation for {formula} is not correct!",
            )

    def test_str(self):
        self.assertIsNotNone(str(self.pd))
Пример #6
0
    def get_composition_boundaries(self, comp, fixed_chempot_delta):
        """
        Get compositions of phases in boundary of stability with a target composition given a fixed chemical potential 
        on one component. Currently only works for 3-component PD (to check). 
        Used Pymatgen GrandPotentialPhaseDiagram class. The fixed chemical potential is the referenced value that is
        converted in the global value for the analysis with the GrandPotentialPhaseDiagram class.

        Parameters
        ----------
        comp : (Pymatgen Composition object)
            Target composition for which you want to get the bounday phases.
        fixed_chempots_delta : (Dict)
            Dictionary with fixed Element as key and respective chemical potential as value ({Element:chempot}).
            The chemical potential is the referenced value

        Returns
        -------
        comp1,comp2 : (Pymatgen Composition object)
            Compositions of the boundary phases given a fixed chemical potential for one element.
        """

        fixed_chempot = self.get_chempots_abs(fixed_chempot_delta)

        entries = self.pd.all_entries
        gpd = GrandPotentialPhaseDiagram(entries, fixed_chempot)
        stable_entries = gpd.stable_entries
        comp_in_stable_entries = False
        for e in stable_entries:
            if e.original_comp.reduced_composition == comp:
                comp_in_stable_entries = True
        if comp_in_stable_entries == False:
            raise ValueError(
                'Target composition %s is not a stable entry for fixed chemical potential: %s'
                % (comp.reduced_formula, fixed_chempot))

        el = comp.elements[0]
        x_target = comp.get_wt_fraction(el)
        x_max_left = 0
        x_min_right = 1
        for e in stable_entries:
            c = e.original_comp
            if c != comp:
                x = c.get_wt_fraction(el)
                if x < x_target and x >= x_max_left:
                    x_max_left = x
                    comp1 = c
                if x > x_target and x <= x_min_right:
                    x_min_right = x
                    comp2 = c
        return comp1.reduced_composition, comp2.reduced_composition
Пример #7
0
    def get_stable_range(self, open_el):
        """
    	Given a open element, return the chemical potential range within which this entry is stable

    	Args:
    		open_el: the open element, a pymaten Element object

    	Returns: 
    		min_chempot, max_chempot
    	"""
        pd, entry, entries = self.get_pd()
        working_chempot = []
        for chempot in np.arange(-10, 0, 0.01):
            gcpd = GrandPotentialPhaseDiagram(entries, {open_el: chempot},
                                              pd.elements)
            mp_ids = [e.entry_id for e in gcpd.stable_entries]
            if None in mp_ids:
                working_chempot.append(chempot)
        return working_chempot[0], working_chempot[-1]
Пример #8
0
    def get_pd_with_open_element(self, open_el):
        """
        The Materials Project website method

        Return a list of grand canonical phase diagrams with one open element

        Args:
            open_el: the open element, a pymaten Element object

        Returns:
            a list of grand canonical phase diagrams, 
            a list of corresponding min_chempots, 
            a list of corresponding avg_chempots, 
            a list of corresponding max_chempots, 
        """
        pd, entry, entries = self.get_pd()
        chempots = pd.get_transition_chempots(open_el)

        gcpds = []
        min_chempots = []
        max_chempots = []
        avg_chempots = []

        for i in range(len(chempots)):
            if i == len(chempots) - 1:
                avg_chempot = chempots[i] - 0.1
                min_chempot = None
            else:
                avg_chempot = 0.5 * (chempots[i] + chempots[i + 1])
                min_chempot = chempots[i + 1]

            gcpds.append(
                GrandPotentialPhaseDiagram(entries, {open_el: avg_chempot},
                                           pd.elements))
            min_chempots.append(min_chempot)
            max_chempots.append(chempots[i])
            avg_chempots.append(avg_chempot)

        return gcpds, min_chempots, avg_chempots, max_chempots
 def gppd_mixing(self, chempots, gppd_entries=None):
     """
     This function give the phase equilibria of a pseudo-binary in a open system (GPPD).
     It will give a complete evolution profile for mixing ratio x change from 0 to 1.
     x is the ratio (both entry norm. to 1 atom/fu(w/o open element) ) or each entry
     """
     open_el = list(chempots.keys())[0]
     el_ref = VirtualEntry.get_mp_entry(open_el)
     chempots[open_el] = chempots[open_el] + el_ref.energy_per_atom
     gppd_entry1 = GrandPotPDEntry(
         self.entry1, {Element[_]: chempots[_]
                       for _ in chempots})
     gppd_entry2 = GrandPotPDEntry(
         self.entry2, {Element[_]: chempots[_]
                       for _ in chempots})
     if not gppd_entries:
         gppd_entries = self.get_gppd_entries(open_el)
     gppd = GrandPotentialPhaseDiagram(gppd_entries, chempots)
     profile = get_full_evolution_profile(gppd, gppd_entry1, gppd_entry2, 0,
                                          1)
     cleaned = clean_profile(profile)
     return cleaned
    def get_phase_diagram_data(self):
        """
        Returns grand potential phase diagram data to external plot
        Assumes openelement specific element equals None
        :return: Data to external plot
        """
        open_elements_specific = None
        open_element_all = Element(self.open_element)
        mpr = MPRester("key")

        # import do dados dos arquivos tipo vasp
        drone = VaspToComputedEntryDrone()
        queen = BorgQueen(drone, rootpath=".")
        entries = queen.get_data()

        # Get data to make phase diagram
        mp_entries = mpr.get_entries_in_chemsys(self.system,
                                                compatible_only=True)

        entries.extend(mp_entries)

        compat = MaterialsProjectCompatibility()
        entries = compat.process_entries(entries)
        #explanation_output = open("explain.txt",'w')
        entries_output = open("entries.txt", 'w')
        compat.explain(entries[0])
        print(entries, file=entries_output)
        #print(entries)

        if open_elements_specific:
            gcpd = GrandPotentialPhaseDiagram(entries, open_elements_specific)
            self.plot_phase_diagram(gcpd, False)
            self.analyze_phase_diagram(gcpd)

        if open_element_all:
            pd = PhaseDiagram(entries)
            chempots = pd.get_transition_chempots(open_element_all)
            #print(chempots)
            #all_gcpds = list()
            toplot = []
            # dic = {}
            for idx in range(len(chempots)):
                if idx == len(chempots) - 1:
                    avgchempot = chempots[idx] - 0.1
                else:
                    avgchempot = 0.5 * (chempots[idx] + chempots[idx + 1])
                gcpd = GrandPotentialPhaseDiagram(
                    entries, {open_element_all: avgchempot}, pd.elements)
                # toplot.append(self.get_grand_potential_phase_diagram(gcpd))

                min_chempot = None if idx == len(chempots) - 1 else chempots[
                    idx + 1]
                max_chempot = chempots[idx]
                #gcpd = GrandPotentialPhaseDiagram(entries, {open_element_all: max_chempot}, pd.elements)

                toplot.append(self.get_grand_potential_phase_diagram(gcpd))
                #toplot.append(max_chempot)

                #self.plot_phase_diagram(gcpd, False)
                #print({open_element_all: max_chempot})

            # Data to plot phase diagram
            return toplot
Пример #11
0
    def setUp(self):
        self.entries = [ComputedEntry(Composition('Li'), 0),
                        ComputedEntry(Composition('Mn'), 0),
                        ComputedEntry(Composition('O2'), 0),
                        ComputedEntry(Composition('MnO2'), -10),
                        ComputedEntry(Composition('Mn2O4'), -60),
                        ComputedEntry(Composition('MnO3'), 20),
                        ComputedEntry(Composition('Li2O'), -10),
                        ComputedEntry(Composition('Li2O2'), -8),
                        ComputedEntry(Composition('LiMnO2'), -30)
                        ]
        self.pd = PhaseDiagram(self.entries)
        chempots = {'Li': -3}
        self.gpd = GrandPotentialPhaseDiagram(self.entries, chempots)
        self.ir = []
        self.ir.append(
            InterfacialReactivity(Composition('O2'), Composition('Mn'),
                                  self.pd, norm=0, include_no_mixing_energy=0,
                                  pd_non_grand=None, use_hull_energy=False))
        self.ir.append(
            InterfacialReactivity(Composition('MnO2'), Composition('Mn'),
                                  self.gpd, norm=0, include_no_mixing_energy=1,
                                  pd_non_grand=self.pd, use_hull_energy=False))
        self.ir.append(
            InterfacialReactivity(Composition('Mn'), Composition('O2'),
                                  self.gpd, norm=1, include_no_mixing_energy=1,
                                  pd_non_grand=self.pd, use_hull_energy=False))
        self.ir.append(
            InterfacialReactivity(Composition('Li2O'), Composition('Mn'),
                                  self.gpd, norm=0, include_no_mixing_energy=1,
                                  pd_non_grand=self.pd, use_hull_energy=False))
        self.ir.append(
            InterfacialReactivity(Composition('Mn'), Composition('O2'),
                                  self.gpd, norm=1, include_no_mixing_energy=0,
                                  pd_non_grand=self.pd, use_hull_energy=False))
        self.ir.append(
            InterfacialReactivity(Composition('Mn'), Composition('Li2O'),
                                  self.gpd, norm=1, include_no_mixing_energy=1,
                                  pd_non_grand=self.pd, use_hull_energy=False))
        self.ir.append(
            InterfacialReactivity(Composition('Li2O2'), Composition('Li'),
                                  self.pd, norm=0, include_no_mixing_energy=0,
                                  pd_non_grand=None, use_hull_energy=True))
        self.ir.append(
            InterfacialReactivity(Composition('Li2O2'), Composition('Li'),
                                  self.pd, norm=0, include_no_mixing_energy=0,
                                  pd_non_grand=None, use_hull_energy=False))

        self.ir.append(
            InterfacialReactivity(Composition('Li2O2'), Composition('MnO2'),
                                  self.gpd, norm=0, include_no_mixing_energy=0,
                                  pd_non_grand=self.pd, use_hull_energy=True))

        self.ir.append(
            InterfacialReactivity(Composition('Li2O2'), Composition('MnO2'),
                                  self.gpd, norm=0, include_no_mixing_energy=0,
                                  pd_non_grand=self.pd, use_hull_energy=False))

        self.ir.append(
            InterfacialReactivity(Composition('O2'), Composition('Mn'),
                                  self.pd, norm=1, include_no_mixing_energy=0,
                                  pd_non_grand=None, use_hull_energy=False))

        self.ir.append(
            InterfacialReactivity(Composition('Li2O2'), Composition('Li2O2'),
                                  self.gpd, norm=1, include_no_mixing_energy=1,
                                  pd_non_grand=self.pd, use_hull_energy=False))

        self.ir.append(
            InterfacialReactivity(Composition('Li2O2'), Composition('Li2O2'),
                                  self.pd, norm=1, include_no_mixing_energy=0,
                                  pd_non_grand=None, use_hull_energy=False))

        with self.assertRaises(Exception) as context1:
            self.ir.append(
                InterfacialReactivity(Composition('Li2O2'), Composition('Li'),
                                      self.pd, norm=1,
                                      include_no_mixing_energy=1,
                                      pd_non_grand=None))
        self.assertTrue(
            'Please provide grand phase diagram '
            'to compute no_mixing_energy!' == str(context1.exception))

        with self.assertRaises(Exception) as context2:
            self.ir.append(
                InterfacialReactivity(Composition('O2'), Composition('Mn'),
                                      self.gpd, norm=0,
                                      include_no_mixing_energy=1,
                                      pd_non_grand=None))
        self.assertTrue(
            'Please provide non-grand phase diagram '
            'to compute no_mixing_energy!' == str(context2.exception))
Пример #12
0
        "key"]  # You must change this to your Materials API key! (or set MAPI_KEY env variable)
    system = ["Li", "B", "O"]  # system we want to get open PD for
    # system = ["Li", "Fe", "P", "O"]  # alternate system example

    open_elements_specific = None  # e.g., {Element("O"): 0} where 0 is the specific chemical potential
    open_element_all = Element(
        "O"
    )  # plot a series of open phase diagrams at critical chem pots with this element open

    mpr = MPRester(MAPI_KEY)  # object for connecting to MP Rest interface

    # get data
    entries = mpr.get_entries_in_chemsys(system, compatible_only=True)

    if open_elements_specific:
        gcpd = GrandPotentialPhaseDiagram(entries, open_elements_specific)
        plot_pd(gcpd, False)
        analyze_pd(gcpd)

    if open_element_all:
        pd = PhaseDiagram(entries)
        chempots = pd.get_transition_chempots(open_element_all)
        all_gcpds = list()
        toplot = []
        arquivo = open("dados.txt", "w")
        for idx in range(len(chempots)):
            if idx == len(chempots) - 1:
                avgchempot = chempots[idx] - 0.1
            else:
                avgchempot = 0.5 * (chempots[idx] + chempots[idx + 1])
            gcpd = GrandPotentialPhaseDiagram(entries,
Пример #13
0
    def setUp(self):
        self.entries = [
            ComputedEntry(Composition("Li"), 0),
            ComputedEntry(Composition("Mn"), 0),
            ComputedEntry(Composition("O2"), 0),
            ComputedEntry(Composition("MnO2"), -10),
            ComputedEntry(Composition("Mn2O4"), -60),
            ComputedEntry(Composition("MnO3"), 20),
            ComputedEntry(Composition("Li2O"), -10),
            ComputedEntry(Composition("Li2O2"), -8),
            ComputedEntry(Composition("LiMnO2"), -30),
        ]
        self.pd = PhaseDiagram(self.entries)

        chempots = {Element("Li"): -3}
        self.gpd = GrandPotentialPhaseDiagram(self.entries, chempots)

        ir_0 = InterfacialReactivity(
            c1=Composition("O2"),
            c2=Composition("Mn"),
            pd=self.pd,
            norm=False,
            use_hull_energy=False,
        )
        ir_1 = GrandPotentialInterfacialReactivity(
            c1=Composition("MnO2"),
            c2=Composition("Mn"),
            grand_pd=self.gpd,
            pd_non_grand=self.pd,
            norm=False,
            include_no_mixing_energy=True,
            use_hull_energy=False,
        )
        ir_2 = GrandPotentialInterfacialReactivity(
            c1=Composition("Mn"),
            c2=Composition("O2"),
            grand_pd=self.gpd,
            pd_non_grand=self.pd,
            norm=True,
            include_no_mixing_energy=True,
            use_hull_energy=False,
        )
        ir_3 = GrandPotentialInterfacialReactivity(
            c1=Composition("Li2O"),
            c2=Composition("Mn"),
            grand_pd=self.gpd,
            norm=False,
            include_no_mixing_energy=True,
            pd_non_grand=self.pd,
            use_hull_energy=False,
        )
        ir_4 = GrandPotentialInterfacialReactivity(
            c1=Composition("Mn"),
            c2=Composition("O2"),
            grand_pd=self.gpd,
            norm=True,
            include_no_mixing_energy=False,
            pd_non_grand=self.pd,
            use_hull_energy=False,
        )
        ir_5 = GrandPotentialInterfacialReactivity(
            c1=Composition("Mn"),
            c2=Composition("Li2O"),
            grand_pd=self.gpd,
            pd_non_grand=self.pd,
            norm=True,
            include_no_mixing_energy=True,
            use_hull_energy=False,
        )
        ir_6 = InterfacialReactivity(
            c1=Composition("Li2O2"),
            c2=Composition("Li"),
            pd=self.pd,
            norm=False,
            use_hull_energy=True,
        )
        ir_7 = InterfacialReactivity(
            c1=Composition("Li2O2"),
            c2=Composition("Li"),
            pd=self.pd,
            norm=False,
            use_hull_energy=False,
        )
        ir_8 = GrandPotentialInterfacialReactivity(
            c1=Composition("Li2O2"),
            c2=Composition("MnO2"),
            grand_pd=self.gpd,
            pd_non_grand=self.pd,
            norm=False,
            include_no_mixing_energy=False,
            use_hull_energy=True,
        )
        ir_9 = GrandPotentialInterfacialReactivity(
            c1=Composition("Li2O2"),
            c2=Composition("MnO2"),
            grand_pd=self.gpd,
            pd_non_grand=self.pd,
            norm=False,
            include_no_mixing_energy=False,
            use_hull_energy=False,
        )
        ir_10 = InterfacialReactivity(
            Composition("O2"),
            Composition("Mn"),
            pd=self.pd,
            norm=True,
            use_hull_energy=False,
        )
        ir_11 = GrandPotentialInterfacialReactivity(
            Composition("Li2O2"),
            Composition("Li2O2"),
            grand_pd=self.gpd,
            norm=True,
            include_no_mixing_energy=True,
            pd_non_grand=self.pd,
            use_hull_energy=False,
        )
        ir_12 = InterfacialReactivity(
            Composition("Li2O2"),
            Composition("Li2O2"),
            pd=self.pd,
            norm=True,
            use_hull_energy=False,
        )
        with self.assertRaises(Exception) as context1:
            ir_13 = InterfacialReactivity(Composition("Li2O2"),
                                          Composition("Li"),
                                          pd=self.gpd,
                                          norm=True)
            self.assertTrue(
                "Please use the GrandPotentialInterfacialReactivity "
                "class for interfacial reactions with open elements!" == str(
                    context1.exception))
        with self.assertRaises(Exception) as context2:
            ir_14 = GrandPotentialInterfacialReactivity(
                Composition("O2"),
                Composition("Mn"),
                grand_pd=self.gpd,
                pd_non_grand=None,
                norm=False,
                include_no_mixing_energy=True,
            )
            self.assertTrue(
                "Please provide non-grand phase diagram to compute no_mixing_energy!"
                == str(context2.exception))

        self.ir = [
            ir_0, ir_1, ir_2, ir_3, ir_4, ir_5, ir_6, ir_7, ir_8, ir_9, ir_10,
            ir_11, ir_12
        ]
Пример #14
0
    def setUp(self):
        self.entries = [
            ComputedEntry(Composition("Li"), 0),
            ComputedEntry(Composition("Mn"), 0),
            ComputedEntry(Composition("O2"), 0),
            ComputedEntry(Composition("MnO2"), -10),
            ComputedEntry(Composition("Mn2O4"), -60),
            ComputedEntry(Composition("MnO3"), 20),
            ComputedEntry(Composition("Li2O"), -10),
            ComputedEntry(Composition("Li2O2"), -8),
            ComputedEntry(Composition("LiMnO2"), -30),
        ]
        self.pd = PhaseDiagram(self.entries)
        chempots = {"Li": -3}
        self.gpd = GrandPotentialPhaseDiagram(self.entries, chempots)
        self.ir = []
        # ir[0]
        self.ir.append(
            InterfacialReactivity(
                Composition("O2"),
                Composition("Mn"),
                self.pd,
                norm=0,
                include_no_mixing_energy=0,
                pd_non_grand=None,
                use_hull_energy=False,
            )
        )
        # ir[1]
        self.ir.append(
            InterfacialReactivity(
                Composition("MnO2"),
                Composition("Mn"),
                self.gpd,
                norm=0,
                include_no_mixing_energy=1,
                pd_non_grand=self.pd,
                use_hull_energy=False,
            )
        )
        # ir[2]
        self.ir.append(
            InterfacialReactivity(
                Composition("Mn"),
                Composition("O2"),
                self.gpd,
                norm=1,
                include_no_mixing_energy=1,
                pd_non_grand=self.pd,
                use_hull_energy=False,
            )
        )
        # ir[3]
        self.ir.append(
            InterfacialReactivity(
                Composition("Li2O"),
                Composition("Mn"),
                self.gpd,
                norm=0,
                include_no_mixing_energy=1,
                pd_non_grand=self.pd,
                use_hull_energy=False,
            )
        )
        # ir[4]
        self.ir.append(
            InterfacialReactivity(
                Composition("Mn"),
                Composition("O2"),
                self.gpd,
                norm=1,
                include_no_mixing_energy=0,
                pd_non_grand=self.pd,
                use_hull_energy=False,
            )
        )
        # ir[5]
        self.ir.append(
            InterfacialReactivity(
                Composition("Mn"),
                Composition("Li2O"),
                self.gpd,
                norm=1,
                include_no_mixing_energy=1,
                pd_non_grand=self.pd,
                use_hull_energy=False,
            )
        )
        # ir[6]
        self.ir.append(
            InterfacialReactivity(
                Composition("Li2O2"),
                Composition("Li"),
                self.pd,
                norm=0,
                include_no_mixing_energy=0,
                pd_non_grand=None,
                use_hull_energy=True,
            )
        )
        # ir[7]
        self.ir.append(
            InterfacialReactivity(
                Composition("Li2O2"),
                Composition("Li"),
                self.pd,
                norm=0,
                include_no_mixing_energy=0,
                pd_non_grand=None,
                use_hull_energy=False,
            )
        )
        # ir[8]
        self.ir.append(
            InterfacialReactivity(
                Composition("Li2O2"),
                Composition("MnO2"),
                self.gpd,
                norm=0,
                include_no_mixing_energy=0,
                pd_non_grand=self.pd,
                use_hull_energy=True,
            )
        )
        # ir[9]
        self.ir.append(
            InterfacialReactivity(
                Composition("Li2O2"),
                Composition("MnO2"),
                self.gpd,
                norm=0,
                include_no_mixing_energy=0,
                pd_non_grand=self.pd,
                use_hull_energy=False,
            )
        )
        # ir[10]
        self.ir.append(
            InterfacialReactivity(
                Composition("O2"),
                Composition("Mn"),
                self.pd,
                norm=1,
                include_no_mixing_energy=0,
                pd_non_grand=None,
                use_hull_energy=False,
            )
        )
        # ir[11]
        self.ir.append(
            InterfacialReactivity(
                Composition("Li2O2"),
                Composition("Li2O2"),
                self.gpd,
                norm=1,
                include_no_mixing_energy=1,
                pd_non_grand=self.pd,
                use_hull_energy=False,
            )
        )
        # ir[12]
        self.ir.append(
            InterfacialReactivity(
                Composition("Li2O2"),
                Composition("Li2O2"),
                self.pd,
                norm=1,
                include_no_mixing_energy=0,
                pd_non_grand=None,
                use_hull_energy=False,
            )
        )

        with self.assertRaises(Exception) as context1:
            self.ir.append(
                InterfacialReactivity(
                    Composition("Li2O2"),
                    Composition("Li"),
                    self.pd,
                    norm=1,
                    include_no_mixing_energy=1,
                    pd_non_grand=None,
                )
            )
        self.assertTrue("Please provide grand phase diagram to compute no_mixing_energy!" == str(context1.exception))

        with self.assertRaises(Exception) as context2:
            self.ir.append(
                InterfacialReactivity(
                    Composition("O2"),
                    Composition("Mn"),
                    self.gpd,
                    norm=0,
                    include_no_mixing_energy=1,
                    pd_non_grand=None,
                )
            )
        self.assertTrue(
            "Please provide non-grand phase diagram to compute no_mixing_energy!" == str(context2.exception)
        )
Пример #15
0
    def find_intermediate_rxns(self, intermediates, targets, chempots=None):
        """
        Identifies thermodynamically predicted reactions from intermediate to one or
        more targets using interfacial reaction method. This method has the unique benefit (
        compared to the find_crossover_rxns method) of identifying reactions open to a
        specfic element or producing 3 or more products.

        Args:
            intermediates ([ComputedEntry]): List of intermediate entries
            targets ([ComputedEntry]): List of target entries
            chempots ({Element: float}): Dictionary of chemical potentials used to
                create grand potential phase diagram by which interfacial reactions are
                predicted.

        Returns:
            [ComputedReaction]: List of intermediate reactions
        """
        all_rxns = set()
        combos = list(generate_all_combos(intermediates, 2))
        for entries in tqdm(combos):
            n = len(entries)
            r1 = entries[0].composition.reduced_composition
            chemsys = {
                str(el)
                for entry in entries for el in entry.composition.elements
            }
            elem = None
            if chempots:
                elem = str(list(chempots.keys())[0])
                chemsys.update(elem)
                if chemsys == {elem}:
                    continue

            if n == 1:
                r2 = entries[0].composition.reduced_composition
            elif n == 2:
                r2 = entries[1].composition.reduced_composition
            else:
                raise ValueError(
                    "Can't have an interface that is not 1 to 2 entries!")

            if chempots:
                elem_comp = Composition(elem).reduced_composition
                if r1 == elem_comp or r2 == elem_comp:
                    continue

            entry_subset = self.entry_set.get_subset_in_chemsys(list(chemsys))
            pd = PhaseDiagram(entry_subset)
            grand_pd = None
            if chempots:
                grand_pd = GrandPotentialPhaseDiagram(entry_subset, chempots)

            rxns = react_interface(r1, r2, pd, self.num_entries, grand_pd)
            rxns_filtered = {
                r
                for r in rxns if set(r._product_entries) & targets
            }
            if rxns_filtered:
                most_favorable_rxn = min(
                    rxns_filtered,
                    key=lambda x: (x.calculated_reaction_energy / sum(
                        [x.get_el_amount(elem) for elem in x.elements])),
                )
                all_rxns.add(most_favorable_rxn)

        return all_rxns
    def get_phase_diagram_data(self):
        """
        Returns grand potential phase diagram data to external plot
        Assumes openelement specific element equals None
        :return: Data to external plot
        """
        open_elements_specific = None
        open_element_all = Element(self.open_element)
        mpr = MPRester(settings.apiKey)

        drone = VaspToComputedEntryDrone()
        queen = BorgQueen(drone, rootpath=".")
        entries = queen.get_data()

        # Get data to make phase diagram
        mp_entries = mpr.get_entries_in_chemsys(self.system,
                                                compatible_only=True)

        entries.extend(mp_entries)

        compat = MaterialsProjectCompatibility()
        entries = compat.process_entries(entries)
        #explanation_output = open("explain.txt",'w')
        #entries_output = open("entries.txt", 'w')
        compat.explain(entries[0])
        #print(entries, file=entries_output)

        if open_elements_specific:
            gcpd = GrandPotentialPhaseDiagram(entries, open_elements_specific)
            self.plot_phase_diagram(gcpd, False)
            self.analyze_phase_diagram(gcpd)

        if open_element_all:
            pd = PhaseDiagram(entries)
            chempots = pd.get_transition_chempots(open_element_all)
            # print(chempots)
            #all_gcpds = list()
            toplot = []
            # dic = {}
            for idx in range(len(chempots)):
                if idx == len(chempots) - 1:
                    avgchempot = chempots[idx] - 0.1
                else:
                    avgchempot = 0.5 * (chempots[idx] + chempots[idx + 1])
                gcpd = GrandPotentialPhaseDiagram(
                    entries, {open_element_all: avgchempot}, pd.elements)

                # min_chempot = None if idx == len(
                #     chempots) - 1 else chempots[idx + 1]
                # max_chempot = chempots[idx]
                #gcpd = GrandPotentialPhaseDiagram(entries, {open_element_all: max_chempot}, pd.elements)

                toplot.append(self.get_grand_potential_phase_diagram(gcpd))
                # toplot.append(max_chempot)

                #self.plot_phase_diagram(gcpd, False)
                #print({open_element_all: max_chempot})

        all_phase_diagrams = toplot
        # print(all_phase_diagrams)

        number_of_phase_diagrams = len(all_phase_diagrams)

        #pd3 = PhaseDiagram(entries)

        chempot_list = pd.get_transition_chempots(open_element_all)
        pd_index = 0

        chempots_range_of_each_phase = {}
        for particular_phase_diagram in all_phase_diagrams:
            chempot = chempot_list[pd_index]

            if pd_index is not number_of_phase_diagrams - 1:
                next_chempot = chempot_list[pd_index + 1]
            else:
                next_chempot = chempot_list[pd_index] - 2.0
            chempot_range = [chempot, next_chempot]

            phases_list = particular_phase_diagram[0]

            for phase in phases_list:
                if phase in chempots_range_of_each_phase.keys():
                    chempots_range_of_each_phase[phase][1] = next_chempot.copy(
                    )
                else:
                    chempots_range_of_each_phase[phase] = chempot_range.copy()

            pd_index = pd_index + 1

        return chempots_range_of_each_phase
 def _gppd(self):
     chempots = {Element(self.wi): self.mu_wi}
     return GrandPotentialPhaseDiagram(self._pd.all_entries, chempots)
Пример #18
0
 def setUp(self):
     self.entries = EntrySet.from_csv(str(module_dir /
                                          "pdentries_test.csv"))
     self.pd = GrandPotentialPhaseDiagram(self.entries, {Element("O"): -5})
     self.pd6 = GrandPotentialPhaseDiagram(self.entries, {Element("O"): -6})
Пример #19
0
elements = list(set(elements))  # Remove duplicates

# Get all entries in the chemical system
entries = mpr.get_entries_in_chemsys(elements)

# Build a phase diagram using these entries.
pd = PhaseDiagram(entries)

# For an open system, include the grand potential phase diagram.
if grand:
    # Get the chemical potential of the pure subtance.
    mu = pd.get_transition_chempots(Element(open_el))[0]
    # Set the chemical potential in the elemental reservoir.
    chempots = {open_el: relative_mu + mu}
    # Build the grand potential phase diagram
    gpd = GrandPotentialPhaseDiagram(entries, chempots)
    # Create InterfacialReactivity object.
    interface = InterfacialReactivity(comp1,
                                      comp2,
                                      gpd,
                                      norm=True,
                                      include_no_mixing_energy=True,
                                      pd_non_grand=pd,
                                      use_hull_energy=False)
else:
    interface = InterfacialReactivity(comp1,
                                      comp2,
                                      pd,
                                      norm=True,
                                      include_no_mixing_energy=False,
                                      pd_non_grand=None,