예제 #1
0
def material_load_binary(d, sep='-', p=prop):
    return_data = []

    d = d.split(sep)

    # Create a phase diagram object for the following system:
    entry = mp.get_entries_in_chemsys(
        [d[0], d[1]])  # gets the entries of the chemical system
    pd = PhaseDiagram(entry)  # creates a phasediagram object
    pd_analyse = PDAnalyzer(pd)  # creates a phase Diagram analysis object

    # Get the features for various proportions Using the get_hull_energy method;
    # (Need to add documentation)
    for i in range(0, len(p)):
        temp_data = {}
        prop_a = p[i]
        prop_b = p[-(i + 1)]
        try:
            temp_data['system'] = d[0] + '-' + d[1]
            temp_data['A'] = d[0]
            temp_data['B'] = d[1]
            temp_data[d[0] + '_prop'] = prop_a
            temp_data[d[1] + '_prop'] = prop_b
            temp_data['formation_energy'] = pd_analyse.get_hull_energy(
                Composition.from_dict({
                    d[0]: prop_a,
                    d[1]: prop_b
                }))

            # Element Property extraction

            temp_data['avg_atomic_mass'] = prop_a * elements.loc[
                d[0]].mass + prop_b * elements.loc[d[1]].mass
            temp_data['avg_row'] = prop_a * elements.loc[
                d[0]].period + prop_b * elements.loc[d[1]].period
            temp_data['avg_col'] = prop_a * elements.loc[
                d[0]].group + prop_b * elements.loc[d[1]].group
            temp_data['max_z_diff'] = abs(
                elements.loc[d[0]].z -
                elements.loc[d[1]].z)  # Max Difference in atomic number
            temp_data['avg_z'] = prop_a * elements.loc[
                d[0]].z + prop_b * elements.loc[d[1]].z
            temp_data['max_radius_diff'] = abs(
                elements.loc[d[0]].atomic_radii -
                elements.loc[d[1]].atomic_radii
            )  # Max Difference in atomic radius
            temp_data['avg_radius'] = prop_a * elements.loc[
                d[0]].atomic_radii + prop_b * elements.loc[d[1]].atomic_radii
            temp_data['max_en_diff'] = abs(
                elements.loc[d[0]].electronegativity -
                elements.loc[d[1]].electronegativity
            )  # Max Difference in electronegativity
            temp_data['avg_en'] = prop_a * elements.loc[
                d[0]].electronegativity + prop_b * elements.loc[d[
                    1]].electronegativity  # Avg Difference in electronegativity
            temp_data['avg_s_elec'] = prop_a * elements.loc[
                d[0]].s_elec + prop_b * elements.loc[d[1]].s_elec
            temp_data['avg_p_elec'] = prop_a * elements.loc[
                d[0]].p_elec + prop_b * elements.loc[d[1]].p_elec
            temp_data['avg_d_elec'] = prop_a * elements.loc[
                d[0]].d_elec + prop_b * elements.loc[d[1]].d_elec
            temp_data['avg_f_elec'] = prop_a * elements.loc[
                d[0]].f_elec + prop_b * elements.loc[d[1]].f_elec

            temp_sum = temp_data['avg_s_elec'] + temp_data[
                'avg_p_elec'] + temp_data['avg_d_elec'] + temp_data[
                    'avg_f_elec']

            temp_data['prop_s_elec'] = temp_data['avg_s_elec'] / temp_sum
            temp_data['prop_p_elec'] = temp_data['avg_p_elec'] / temp_sum
            temp_data['prop_d_elec'] = temp_data['avg_d_elec'] / temp_sum
            temp_data['prop_f_elec'] = temp_data['avg_f_elec'] / temp_sum

            return_data.append(temp_data)
        except:
            pass
    return return_data, temp_data['system']
예제 #2
0
class PDAnalyzerTest(unittest.TestCase):
    def setUp(self):
        module_dir = os.path.dirname(os.path.abspath(__file__))
        (elements, entries) = PDEntryIO.from_csv(
            os.path.join(module_dir, "pdentries_test.csv"))
        self.pd = PhaseDiagram(entries)
        self.analyzer = PDAnalyzer(self.pd)

    def test_get_e_above_hull(self):
        for entry in self.pd.stable_entries:
            self.assertLess(
                self.analyzer.get_e_above_hull(entry), 1e-11,
                "Stable entries should have e above hull of zero!")
        for entry in self.pd.all_entries:
            if entry not in self.pd.stable_entries:
                e_ah = self.analyzer.get_e_above_hull(entry)
                self.assertGreaterEqual(e_ah, 0)
                self.assertTrue(isinstance(e_ah, Number))

    def test_get_equilibrium_reaction_energy(self):
        for entry in self.pd.stable_entries:
            self.assertLessEqual(
                self.analyzer.get_equilibrium_reaction_energy(entry), 0,
                "Stable entries should have negative equilibrium reaction energy!"
            )

    def test_get_decomposition(self):
        for entry in self.pd.stable_entries:
            self.assertEqual(
                len(self.analyzer.get_decomposition(entry.composition)), 1,
                "Stable composition should have only 1 decomposition!")
        dim = len(self.pd.elements)
        for entry in self.pd.all_entries:
            ndecomp = len(self.analyzer.get_decomposition(entry.composition))
            self.assertTrue(
                ndecomp > 0 and ndecomp <= dim,
                "The number of decomposition phases can at most be equal to the number of components."
            )

        #Just to test decomp for a ficitious composition
        ansdict = {
            entry.composition.formula: amt
            for entry, amt in self.analyzer.get_decomposition(
                Composition("Li3Fe7O11")).items()
        }
        expected_ans = {
            "Fe2 O2": 0.0952380952380949,
            "Li1 Fe1 O2": 0.5714285714285714,
            "Fe6 O8": 0.33333333333333393
        }
        for k, v in expected_ans.items():
            self.assertAlmostEqual(ansdict[k], v)

    def test_get_transition_chempots(self):
        for el in self.pd.elements:
            self.assertLessEqual(
                len(self.analyzer.get_transition_chempots(el)),
                len(self.pd.facets))

    def test_get_element_profile(self):
        for el in self.pd.elements:
            for entry in self.pd.stable_entries:
                if not (entry.composition.is_element):
                    self.assertLessEqual(
                        len(
                            self.analyzer.get_element_profile(
                                el, entry.composition)), len(self.pd.facets))

    def test_get_get_chempot_range_map(self):
        elements = [el for el in self.pd.elements if el.symbol != "Fe"]
        self.assertEqual(len(self.analyzer.get_chempot_range_map(elements)),
                         10)

    def test_getmu_vertices_stability_phase(self):
        results = self.analyzer.getmu_vertices_stability_phase(
            Composition("LiFeO2"), Element("O"))
        self.assertAlmostEqual(len(results), 6)
        test_equality = False
        for c in results:
            if abs(c[Element("O")]+7.115) < 1e-2 and abs(c[Element("Fe")]+6.596) < 1e-2 and \
                    abs(c[Element("Li")]+3.931) < 1e-2:
                test_equality = True
        self.assertTrue(test_equality,
                        "there is an expected vertex missing in the list")

    def test_getmu_range_stability_phase(self):
        results = self.analyzer.get_chempot_range_stability_phase(
            Composition("LiFeO2"), Element("O"))
        self.assertAlmostEqual(results[Element("O")][1], -4.4501812249999997)
        self.assertAlmostEqual(results[Element("Fe")][0], -6.5961470999999996)
        self.assertAlmostEqual(results[Element("Li")][0], -3.6250022625000007)

    def test_get_hull_energy(self):
        for entry in self.pd.stable_entries:
            h_e = self.analyzer.get_hull_energy(entry.composition)
            self.assertAlmostEqual(h_e, entry.energy)
            n_h_e = self.analyzer.get_hull_energy(
                entry.composition.fractional_composition)
            self.assertAlmostEqual(n_h_e, entry.energy_per_atom)

    def test_1d_pd(self):
        entry = PDEntry('H', 0)
        pd = PhaseDiagram([entry])
        pda = PDAnalyzer(pd)
        decomp, e = pda.get_decomp_and_e_above_hull(PDEntry('H', 1))
        self.assertAlmostEqual(e, 1)
        self.assertAlmostEqual(decomp[entry], 1.0)
예제 #3
0
class PDAnalyzerTest(unittest.TestCase):
    def setUp(self):
        module_dir = os.path.dirname(os.path.abspath(__file__))
        (elements, entries) = PDEntryIO.from_csv(os.path.join(module_dir, "pdentries_test.csv"))
        self.pd = PhaseDiagram(entries)
        self.analyzer = PDAnalyzer(self.pd)

    def test_get_e_above_hull(self):
        for entry in self.pd.stable_entries:
            self.assertLess(
                self.analyzer.get_e_above_hull(entry), 1e-11, "Stable entries should have e above hull of zero!"
            )
        for entry in self.pd.all_entries:
            if entry not in self.pd.stable_entries:
                e_ah = self.analyzer.get_e_above_hull(entry)
                self.assertGreaterEqual(e_ah, 0)
                self.assertTrue(isinstance(e_ah, Number))

    def test_get_equilibrium_reaction_energy(self):
        for entry in self.pd.stable_entries:
            self.assertLessEqual(
                self.analyzer.get_equilibrium_reaction_energy(entry),
                0,
                "Stable entries should have negative equilibrium reaction energy!",
            )

    def test_get_decomposition(self):
        for entry in self.pd.stable_entries:
            self.assertEqual(
                len(self.analyzer.get_decomposition(entry.composition)),
                1,
                "Stable composition should have only 1 decomposition!",
            )
        dim = len(self.pd.elements)
        for entry in self.pd.all_entries:
            ndecomp = len(self.analyzer.get_decomposition(entry.composition))
            self.assertTrue(
                ndecomp > 0 and ndecomp <= dim,
                "The number of decomposition phases can at most be equal to the number of components.",
            )

        # Just to test decomp for a ficitious composition
        ansdict = {
            entry.composition.formula: amt
            for entry, amt in self.analyzer.get_decomposition(Composition("Li3Fe7O11")).items()
        }
        expected_ans = {"Fe2 O2": 0.0952380952380949, "Li1 Fe1 O2": 0.5714285714285714, "Fe6 O8": 0.33333333333333393}
        for k, v in expected_ans.items():
            self.assertAlmostEqual(ansdict[k], v)

    def test_get_transition_chempots(self):
        for el in self.pd.elements:
            self.assertLessEqual(len(self.analyzer.get_transition_chempots(el)), len(self.pd.facets))

    def test_get_element_profile(self):
        for el in self.pd.elements:
            for entry in self.pd.stable_entries:
                if not (entry.composition.is_element):
                    self.assertLessEqual(
                        len(self.analyzer.get_element_profile(el, entry.composition)), len(self.pd.facets)
                    )

    def test_get_get_chempot_range_map(self):
        elements = [el for el in self.pd.elements if el.symbol != "Fe"]
        self.assertEqual(len(self.analyzer.get_chempot_range_map(elements)), 10)

    def test_getmu_vertices_stability_phase(self):
        results = self.analyzer.getmu_vertices_stability_phase(Composition("LiFeO2"), Element("O"))
        self.assertAlmostEqual(len(results), 6)
        test_equality = False
        for c in results:
            if (
                abs(c[Element("O")] + 7.115) < 1e-2
                and abs(c[Element("Fe")] + 6.596) < 1e-2
                and abs(c[Element("Li")] + 3.931) < 1e-2
            ):
                test_equality = True
        self.assertTrue(test_equality, "there is an expected vertex missing in the list")

    def test_getmu_range_stability_phase(self):
        results = self.analyzer.get_chempot_range_stability_phase(Composition("LiFeO2"), Element("O"))
        self.assertAlmostEqual(results[Element("O")][1], -4.4501812249999997)
        self.assertAlmostEqual(results[Element("Fe")][0], -6.5961470999999996)
        self.assertAlmostEqual(results[Element("Li")][0], -3.6250022625000007)

    def test_get_hull_energy(self):
        for entry in self.pd.stable_entries:
            h_e = self.analyzer.get_hull_energy(entry.composition)
            self.assertAlmostEqual(h_e, entry.energy)
            n_h_e = self.analyzer.get_hull_energy(entry.composition.fractional_composition)
            self.assertAlmostEqual(n_h_e, entry.energy_per_atom)

    def test_1d_pd(self):
        entry = PDEntry("H", 0)
        pd = PhaseDiagram([entry])
        pda = PDAnalyzer(pd)
        decomp, e = pda.get_decomp_and_e_above_hull(PDEntry("H", 1))
        self.assertAlmostEqual(e, 1)
        self.assertAlmostEqual(decomp[entry], 1.0)