Ejemplo n.º 1
0
 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)
Ejemplo n.º 2
0
def get_competing_phases():
    """
    Collect the species to which the material might decompose to.

    Returns:
        A list of phases as tuples formatted as
        [(formula_1, Materials_Project_ID_1),
        (formula_2, Materials_Project_ID_2), ...]
    """

    composition = Structure.from_file('POSCAR').composition
    try:
        energy = Vasprun('vasprun.xml').final_energy
    except:
        energy = 100  # The function can work without a vasprun.xml
    entries = MPR.get_entries_in_chemsys([elt.symbol for elt in composition])
    my_entry = ComputedEntry(composition, energy)
    entries.append(my_entry)

    pda = PDAnalyzer(PhaseDiagram(entries))
    decomp = pda.get_decomp_and_e_above_hull(my_entry, allow_negative=True)
    competing_phases = [(entry.composition.reduced_formula, entry.entry_id)
                        for entry in decomp[0]]

    return competing_phases
Ejemplo n.º 3
0
def get_competing_phases_new(structure):
    """
    Collect the species to which the 2D materials might decompose to.
    Since a lot of 2D materials with similar compositions will have the
    same competing phases, duplicates aren't counted.
    """

    total_competing_phases = []
    composition = structure.composition
    energy = 100
    my_entry = ComputedEntry(composition, energy)  # 2D material
    entries = MPR.get_entries_in_chemsys(
        elements=[elt.symbol for elt in composition])

    entries.append(my_entry)  # 2D material

    pda = PDAnalyzer(PhaseDiagram(entries))
    decomp = pda.get_decomp_and_e_above_hull(my_entry, allow_negative=True)
    competing_phases = [(entry.composition.reduced_formula, entry.entry_id)
                        for entry in decomp[0]]

    # Keep a running list of all unique competing phases, since in
    # high throughput 2D searches there is usually some overlap in
    # competing phases for different materials.
    for specie in competing_phases:
        if specie not in total_competing_phases:
            total_competing_phases.append(specie)

    return total_competing_phases
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
def get_hull_distance(competing_phase_directory='../competing_phases'):
    """
    Calculate the material's distance to the thermodynamic hull,
    based on species in the Materials Project database.

    Args:
        competing_phase_directory (str): absolute or relative path
            to the location where your competing phases have been
            relaxed. The default expectation is that they are stored
            in a directory named 'competing_phases' at the same level
            as your material's relaxation directory.
    Returns:
        float. distance (eV/atom) between the material and the
            hull.
    """

    finished_competitors = {}
    original_directory = os.getcwd()
    # Determine which competing phases have been relaxed in the current
    # framework and store them in a dictionary ({formula: entry}).
    if os.path.isdir(competing_phase_directory):
        os.chdir(competing_phase_directory)
        for comp_dir in [
            dir for dir in os.listdir(os.getcwd()) if os.path.isdir(dir) and
            is_converged(dir)
                ]:
            vasprun = Vasprun('{}/vasprun.xml'.format(comp_dir))
            composition = vasprun.final_structure.composition
            energy = vasprun.final_energy
            finished_competitors[comp_dir] = ComputedEntry(composition, energy)
        os.chdir(original_directory)
    else:
        raise ValueError('Competing phase directory does not exist.')

    composition = Structure.from_file('POSCAR').composition
    try:
        energy = Vasprun('vasprun.xml').final_energy
    except:
        raise ValueError('This directory does not have a converged vasprun.xml')
    my_entry = ComputedEntry(composition, energy)  # 2D material
    entries = MPR.get_entries_in_chemsys(
        [elt.symbol for elt in composition]
        )

    # If the energies of competing phases have been calculated in
    # the current framework, put them in the phase diagram instead
    # of the MP energies.
    for i in range(len(entries)):
        formula = entries[i].composition.reduced_formula
        if formula in finished_competitors:
            entries[i] = finished_competitors[formula]
        else:
            entries[i] = ComputedEntry(entries[i].composition, 100)

    entries.append(my_entry)  # 2D material

    pda = PDAnalyzer(PhaseDiagram(entries))
    decomp = pda.get_decomp_and_e_above_hull(my_entry, allow_negative=True)

    return decomp[1]
Ejemplo n.º 6
0
def get_competing_phases():
    """
    Collect the species to which the material might decompose to.

    Returns:
        A list of phases as tuples formatted as
        [(formula_1, Materials_Project_ID_1),
        (formula_2, Materials_Project_ID_2), ...]
    """

    total_competing_phases = []

    composition = Structure.from_file('POSCAR').composition
    try:
        energy = Vasprun('vasprun.xml').final_energy
    except:
        energy = 100  # The function can work without a vasprun.xml
    entries = MPR.get_entries_in_chemsys(
        [elt.symbol for elt in composition]
        )
    my_entry = ComputedEntry(composition, energy)
    entries.append(my_entry)

    pda = PDAnalyzer(PhaseDiagram(entries))
    decomp = pda.get_decomp_and_e_above_hull(my_entry, allow_negative=True)
    competing_phases = [
        (entry.composition.reduced_formula,
         entry.entry_id) for entry in decomp[0]
        ]

    return competing_phases
Ejemplo n.º 7
0
def get_hull_distance(competing_phase_directory='../competing_phases'):
    """
    Calculate the material's distance to the thermodynamic hull,
    based on species in the Materials Project database.

    Args:
        competing_phase_directory (str): absolute or relative path
            to the location where your competing phases have been
            relaxed. The default expectation is that they are stored
            in a directory named 'competing_phases' at the same level
            as your material's relaxation directory.
    Returns:
        float. distance (eV/atom) between the material and the
            hull.
    """

    finished_competitors = {}
    original_directory = os.getcwd()
    # Determine which competing phases have been relaxed in the current
    # framework and store them in a dictionary ({formula: entry}).
    if os.path.isdir(competing_phase_directory):
        os.chdir(competing_phase_directory)
        for comp_dir in [
                dir for dir in os.listdir(os.getcwd())
                if os.path.isdir(dir) and is_converged(dir)
        ]:
            vasprun = Vasprun('{}/vasprun.xml'.format(comp_dir))
            composition = vasprun.final_structure.composition
            energy = vasprun.final_energy
            finished_competitors[comp_dir] = ComputedEntry(composition, energy)
        os.chdir(original_directory)
    else:
        raise ValueError('Competing phase directory does not exist.')

    composition = Structure.from_file('POSCAR').composition
    try:
        energy = Vasprun('vasprun.xml').final_energy
    except:
        raise ValueError(
            'This directory does not have a converged vasprun.xml')
    my_entry = ComputedEntry(composition, energy)  # 2D material
    entries = MPR.get_entries_in_chemsys([elt.symbol for elt in composition])

    # If the energies of competing phases have been calculated in
    # the current framework, put them in the phase diagram instead
    # of the MP energies.
    for i in range(len(entries)):
        formula = entries[i].composition.reduced_formula
        if formula in finished_competitors:
            entries[i] = finished_competitors[formula]
        else:
            entries[i] = ComputedEntry(entries[i].composition, 100)

    entries.append(my_entry)  # 2D material

    pda = PDAnalyzer(PhaseDiagram(entries))
    decomp = pda.get_decomp_and_e_above_hull(my_entry, allow_negative=True)

    return decomp[1]
Ejemplo n.º 8
0
    def get_e_above_hull(self):
        """ 
        Get e_above_hull for this compound

        Args: 
            allow_negative: whether to calculate negative energy above hull for stable compound

        Returns:
            decomposition, energy above hull
        """
        pda = PDAnalyzer(self.pd)
        (decomp, hull) = pda.get_decomp_and_e_above_hull(self.entry)
        decomp = [compound.composition.reduced_formula for compound in decomp]
        return (decomp, hull)
Ejemplo n.º 9
0
    def test_dim1(self):
        #Ensure that dim 1 PDs can eb generated.
        for el in ["Li", "Fe", "O2"]:
            entries = [e for e in self.entries
                       if e.composition.reduced_formula == el]
            pd = PhaseDiagram(entries)
            self.assertEqual(len(pd.stable_entries), 1)

            a = PDAnalyzer(pd)
            for e in entries:
                decomp, ehull = a.get_decomp_and_e_above_hull(e)
                self.assertGreaterEqual(ehull, 0)
            plotter = PDPlotter(pd)
            lines, stable_entries, unstable_entries = plotter.pd_plot_data
            self.assertEqual(lines[0][1], [0, 0])
Ejemplo n.º 10
0
    def test_dim1(self):
        #Ensure that dim 1 PDs can eb generated.
        for el in ["Li", "Fe", "O2"]:
            entries = [
                e for e in self.entries if e.composition.reduced_formula == el
            ]
            pd = PhaseDiagram(entries)
            self.assertEqual(len(pd.stable_entries), 1)

            a = PDAnalyzer(pd)
            for e in entries:
                decomp, ehull = a.get_decomp_and_e_above_hull(e)
                self.assertGreaterEqual(ehull, 0)
            plotter = PDPlotter(pd)
            lines, stable_entries, unstable_entries = plotter.pd_plot_data
            self.assertEqual(lines[0][1], [0, 0])
Ejemplo n.º 11
0
def main():
    """
    Main function.
    """
    # Read the calculation results into a ComputedEntry.
    entl = VaspToComputedEntryDrone().assimilate(sys.argv[1])

    # Check if our local calculation is compatible with MP.
    if MaterialsProjectCompatibility().process_entry(entl) is None:
        print("Calculation not compatible with MP.")
        sys.exit(0)

    # Get other entries sharing a chemical system with the results.
    chemsys = [ele for ele in entl.composition.as_dict()]
    with MPRester() as mpr:
        chemsys_entries = mpr.get_entries_in_chemsys(chemsys)

    # Append our local calculation to the list of entries.
    chemsys_entries.append(entl)

    # Process the entries.
    p_e = MaterialsProjectCompatibility().process_entries(chemsys_entries)

    # Build a phase diagram and an analyzer for it.
    p_d = PhaseDiagram(p_e)
    pda = PDAnalyzer(p_d)

    # Scan stable entries for our calculation.
    for ent in p_d.stable_entries:
        if ent.entry_id is None:
            print(str(ent.composition.reduced_formula) + " 0.0")
            sys.exit(0)

    # Scan unstable entries for our calculation and print decomposition.
    for ent in p_d.unstable_entries:
        if ent.entry_id is None:
            dco, ehull = pda.get_decomp_and_e_above_hull(ent)
            pretty_dc = [("{}:{}".format(k.composition.reduced_formula,
                                         k.entry_id), round(v, 2))
                         for k, v in dco.items()]
            print(
                str(ent.composition.reduced_formula) + " %.3f" % ehull + " " +
                str(pretty_dc))
Ejemplo n.º 12
0
    def process_item(self, item):
        """
        Process the list of entries into a phase diagram

        Args:
            item (set(entry)): a list of entries to process into a phase diagram
            
        Returns:
            [dict]: a list of thermo dictionaries to update thermo with
        """
        entries = self.__compat.process_entries(item)
        try:
            pd = PhaseDiagram(entries)
            analyzer = PDAnalyzer(pd)

            docs = []

            for e in entries:
                (decomp, ehull) = \
                    analyzer.get_decomp_and_e_above_hull(e)

                d = {"material_id": e.entry_id}
                d["thermo"] = {}
                d["thermo"][
                    "formation_energy_per_atom"] = pd.get_form_energy_per_atom(
                        e)
                d["thermo"]["e_above_hull"] = ehull
                d["thermo"]["is_stable"] = e in stable_entries
                d["thermo"][
                    "eq_reaction_e"] = analyzer.get_equilibrium_reaction_energy(
                        e)
                d["thermo"]["decomposes_to"] = [{
                    "material_id": de.entry_id,
                    "formula": de.composition.formula,
                    "amount": amt
                } for de, amt in decomp.items()]
                docs.append(d)
        except PhaseDiagramError as p:
            self.__logger.warning("Phase diagram error: {}".format(p))
            return []

        return docs
Ejemplo n.º 13
0
    def get_equilibrium_reaction_energy(self):
        """
        Adapted from pymatgen. Only work if entry is stable(hull = 0)

        Provides the reaction energy of a stable entry from the neighboring
        equilibrium stable entries (also known as the inverse distance to
        hull).

        Returns:
            Equilibrium reaction energy of entry. Stable entries should have
            equilibrium reaction energy <= 0.
        """
        if self.entry not in self.pd.stable_entries:
            raise ValueError("Equilibrium reaction energy is available only "
                             "for stable entries.")
        entries = [e for e in self.pd.stable_entries if e != self.entry
                   ]  #all stable entries without this stable entry
        modpd = PhaseDiagram(entries, self.pd.elements)
        analyzer = PDAnalyzer(modpd)
        (decomp,
         hull) = analyzer.get_decomp_and_e_above_hull(self.entry,
                                                      allow_negative=True)
        decomp = [compound.composition.reduced_formula for compound in decomp]
        return (decomp, hull)
Ejemplo n.º 14
0
a_pbe = PDAnalyzer(pd_pbe)

# # visualize quaternary phase diagrams
# plotter_lda = PDPlotter(pd_lda,show_unstable = 200)
# plotter_lda.show()
# plotter_pbe = PDPlotter(pd_pbe,show_unstable = 200)
# plotter_pbe.show()
#

# printing results of the phase diagram
data_lda = collections.defaultdict(list)
data_pbe = collections.defaultdict(list)

print("LDA Phase diagram")
for e in entries_lda:
    decomp, ehull = a_lda.get_decomp_and_e_above_hull(e)
    formen = pd_lda.get_form_energy_per_atom(e)
    data_lda["Composition"].append(e.composition.reduced_formula)
    data_lda["Ehull (meV/atom)"].append(ehull * 13.605698066 * 1000)
    data_lda["Decomposition"].append(" + ".join(
        ["%.2f %s" % (v, k.composition.formula) for k, v in decomp.items()]))
    data_lda["Formation Energy (eV/atom)"].append(formen * 13.605698066)

df1 = DataFrame(data_lda,
                columns=[
                    "Composition", "Ehull (meV/atom)",
                    "Formation Energy (eV/atom)", "Decomposition"
                ])

print(df1)
print(" ")
Ejemplo n.º 15
0
# stable labels
labels_array = []
for a in phase.stable_entries:
    a_dict = dict()
    a_dict["materialid"] = a.entry_id
    a_dict["name"] = a.name
    a_dict["formation_energy_per_atom"] = phase.get_form_energy_per_atom(a)
    a_dict["is_element"] = True

    for coord, entry in stable.items():
        if a.name == entry.name:
            a_dict["x"] = coord[0]
            a_dict["y"] = coord[1]

    # decomp, e_above_hull 받기
    decomp, e_above_hull = pda.get_decomp_and_e_above_hull(a)
    #pretty_decomp = [("{}:{}".format(k.composition.reduced_formula, k.entry_id), round(v, 2)) for k, v in decomp.items()]
    a_dict["reduced_formula"] = a.composition.reduced_formula
    a_dict["e_above_hull"] = e_above_hull
    #a_dict["pretty_decomp"] = pretty_decomp

    labels_array.append(a_dict)
result["stable_labels"] = labels_array

# unstable labels
labels_array = []
for a in phase.unstable_entries:
    a_dict = dict()
    a_dict["materialid"] = a.entry_id
    a_dict["name"] = a.name
    a_dict["formation_energy_per_atom"] = phase.get_form_energy_per_atom(a)