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
from pymatgen.analysis.phase_diagram import PhaseDiagram, PDPlotter, PDEntry
from pymatgen.core.periodic_table import Element
from pymatgen.core.composition import Composition
from pymatgen.io.vasp.outputs import Vasprun
import sys

print("Usage: get_phase_diagram_from_MP.py 'Element1,Element2,Element3,...'")

system = [el for el in sys.argv[1].split(',')]  # system we want to get PD for

MAPI_KEY = 'DSR45TfHVuyuB1WvP1'  # You must change this to your Materials API key! (or set MAPI_KEY env variable)
system_name = '-'.join(system)

mpr = MPRester(MAPI_KEY)  # object for connecting to MP Rest interface
compat = MaterialsProjectCompatibility(
)  # sets energy corrections and +U/pseudopotential choice

unprocessed_entries = mpr.get_entries_in_chemsys(system, inc_structure=True)
processed_entries = compat.process_entries(
    unprocessed_entries)  # filter and add energy corrections

pd = PhaseDiagram(processed_entries)
pd_dict = pd.as_dict()

filename = f'PD_{system_name}.json'

with open(filename, 'w') as f:
    json.dump(pd_dict, f)

print(f"PhaseDiagram object saved as dict in {filename}")
drone = VaspToComputedEntryDrone()
queen = BorgQueen(drone, rootpath=".")
entries = queen.get_data()

pd2 = PhaseDiagram(entries)

all_phase_diagrams = pd.get_phase_diagram_data()

number_of_phase_diagrams = len(all_phase_diagrams)

open_elements_specific = None
open_element_all = Element("O")
mpr = MPRester("######")

mp_entries = mpr.get_entries_in_chemsys(['Li', 'Ca', 'O'],
                                        compatible_only=True)

pd = PhaseDiagramOpenAnalyzer(mp_entries[0], open_element_all)

entries.extend(mp_entries)

# Process entries using the MaterialsProjectCompatibility
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)

# pd2 = PhaseDiagram(entries)
Exemplo n.º 4
0
import json
from pymatgen import MPRester
from pymatgen.entries.compatibility import MaterialsProjectCompatibility
from pymatgen.analysis.phase_diagram import PhaseDiagram, PDPlotter, PDEntry
from pymatgen.core.periodic_table import Element
from pymatgen.core.composition import Composition
from pymatgen.io.vasp.outputs import Vasprun

#if __name__ == "__main__":
MAPI_KEY = 'DSR45TfHVuyuB1WvP1'  # You must change this to your Materials API key! (or set MAPI_KEY env variable)
system = ['Na', 'C', 'O']  # system we want to get PD for
system_name = '-'.join(system)

mpr = MPRester(MAPI_KEY)  # object for connecting to MP Rest interface
compat = MaterialsProjectCompatibility(
)  # sets energy corrections and +U/pseudopotential choice

unprocessed_entries = mpr.get_entries_in_chemsys(system)
processed_entries = compat.process_entries(
    unprocessed_entries)  # filter and add energy corrections

# vasprun = Vasprun('vasprun.xml')
# comp = vasprun.initial_structure.composition
# energy = vasprun.final_energy
# NBTentry = PDEntry(comp, energy)
# processed_entries.append(NBTentry)

pd = PhaseDiagram(processed_entries)
    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
Exemplo n.º 6
0
from pymatgen import MPRester
from pymatgen.analysis.phase_diagram import PhaseDiagram, PDPlotter
import os

JINNYAPI = os.environ['materials_project']

a = MPRester(JINNYAPI)

#Entries are the basic unit for thermodynamic and other analyses in pymatgen.
#This gets all entries belonging to the Ca-C-O system.
entries = a.get_entries_in_chemsys(['Ca', 'C', 'O'])
print('entries', entries)

#With entries, you can do many sophisticated analyses,
#like creating phase diagrams.
pd = PhaseDiagram(entries)
plotter = PDPlotter(pd)
plotter.show()
Exemplo n.º 7
0
from httk.core import IoAdapterString
from httk.atomistic import Structure, StructurePhaseDiagram
from httk.analysis.matsci import PhaseDiagram
import httk.analysis.matsci.vis
from httk.external import pymatgen_glue

import pymatgen
# import pymatgen.phasediagram.plotter, pymatgen.phasediagram.pdmaker, pymatgen.phasediagram.pdanalyzer
from pymatgen.entries.computed_entries import ComputedEntry
from pymatgen import MPRester

# Fill in your materials project API key here
mp_key = 'xxxxxx'
a = MPRester(mp_key)
entries = a.get_entries_in_chemsys(
    ['Ca', 'Ti', 'F'],
    property_data=['material_id', 'pretty_formula', 'unit_cell_formula'])

# for i, entry in enumerate(entries):
# print(entry.data.keys())

structures = []
energies = []

# You can do it this way via structures, but it is quite slow
#
#for i, entry in enumerate(entries):
#    print("Entry",i+1,"/",len(entries))
#    cifstr = entry.data['cif']
#    energy = entry.energy
#    ioa = IoAdapterString(cifstr)
Exemplo n.º 8
0
if __name__ == "__main__":
    MAPI_KEY = config.KEY[
        "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
Exemplo n.º 9
0
#http://pymatgen.org/examples.html
from pymatgen.core import *
from pymatgen.io.vasp.sets import *
from pymatgen import Lattice, Structure, Molecule
from pymatgen.io.vasp.sets import MPRelaxSet

from pymatgen import MPRester, Composition, Element
from pymatgen.io.vasp import Vasprun
from pymatgen.analysis.phase_diagram import CompoundPhaseDiagram, GrandPotentialPhaseDiagram, PDPlotter, PhaseDiagram
import palettable
import matplotlib as mpl


rester = MPRester('5TxDLF4Iwa7rGcAl') #Generate your own key from materials project..
mp_entries = rester.get_entries_in_chemsys(["Li", "Fe", "O","S"])



pd = PhaseDiagram(mp_entries)
plotter = PDPlotter(pd)
plotter.show()
Exemplo n.º 10
0
class SurfaceEnergyAnalyzer(object):

    """
    A class used for analyzing the surface energies of a material of a given
        material_id. By default, this will use entries calculated from the
        Materials Project to obtain chemical potential and bulk energy. As a
        result, the difference in VASP parameters between the user's entry
        (vasprun_dict) and the parameters used by Materials Project, may lead
        to a rough estimate of the surface energy. For best results, it is
        recommend that the user calculates all decomposition components first,
        and insert the results into their own database as a pymatgen-db entry
        and use those entries instead (custom_entries). In addition, this code
        will only use one bulk entry to calculate surface energy. Ideally, to
        get the most accurate surface energy, the user should compare their
        slab energy to the energy of the oriented unit cell with both calculations
        containing consistent k-points to avoid converegence problems as the
        slab size is varied. See:
            Sun, W.; Ceder, G. Efficient creation and convergence of surface slabs,
                Surface Science, 2013, 617, 53–59, doi:10.1016/j.susc.2013.05.016.
        and
            Rogal, J., & Reuter, K. (2007). Ab Initio Atomistic Thermodynamics for
                Surfaces : A Primer. Experiment, Modeling and Simulation of Gas-Surface
                Interactions for Reactive Flows in Hypersonic Flights, 2–1 – 2–18.

    .. attribute:: ref_element

        All chemical potentials cna be written in terms of the range of chemical
            potential of this element which will be used to calculate surface energy.

    .. attribute:: mprester

        Materials project rester for querying entries from the materials project.
            Requires user MAPIKEY.

    .. attribute:: ucell_entry

        Materials Project entry of the material of the slab.

    .. attribute:: x

        Reduced amount composition of decomposed compound A in the bulk.

    .. attribute:: y

        Reduced amount composition of ref_element in the bulk.

    .. attribute:: gbulk

        Gibbs free energy of the bulk per formula unit

    .. attribute:: chempot_range

        List of the min and max chemical potential of ref_element.

    .. attribute:: e_of_element

        Energy per atom of ground state ref_element, eg. if ref_element=O,
            than e_of_element=1/2*E_O2.

    .. attribute:: vasprun_dict

        Dictionary containing a list of Vaspruns for slab calculations as
            items and the corresponding Miller index of the slab as the key

    """

    def __init__(self, material_id, vasprun_dict, ref_element,
                 exclude_ids=[], custom_entries=[], mapi_key=None):
        """
        Analyzes surface energies and Wulff shape of a particular
            material using the chemical potential.
        Args:
            material_id (str): Materials Project material_id (a string,
                e.g., mp-1234).
            vasprun_dict (dict): Dictionary containing a list of Vaspruns
                for slab calculations as items and the corresponding Miller
                index of the slab as the key.
                eg. vasprun_dict = {(1,1,1): [vasprun_111_1, vasprun_111_2,
                vasprun_111_3], (1,1,0): [vasprun_111_1, vasprun_111_2], ...}
            element: element to be considered as independent
                variables. E.g., if you want to show the stability
                ranges of all Li-Co-O phases wrt to uLi
            exclude_ids (list of material_ids): List of material_ids
                to exclude when obtaining the decomposition components
                to calculate the chemical potential
            custom_entries (list of pymatgen-db type entries): List of
                user specified pymatgen-db type entries to use in finding
                decomposition components for the chemical potential
            mapi_key (str): Materials Project API key for accessing the
                MP database via MPRester
        """

        self.ref_element = ref_element
        self.mprester = MPRester(mapi_key) if mapi_key else MPRester()
        self.ucell_entry = \
            self.mprester.get_entry_by_material_id(material_id,
                                                   inc_structure=True,
                                                   property_data=
                                                   ["formation_energy_per_atom"])
        ucell = self.ucell_entry.structure

        # Get x and y, the number of species in a formula unit of the bulk
        reduced_comp = ucell.composition.reduced_composition.as_dict()
        if len(reduced_comp.keys()) == 1:
            x = y = reduced_comp[ucell[0].species_string]
        else:
            for el in reduced_comp.keys():
                if self.ref_element == el:
                    y = reduced_comp[el]
                else:
                    x = reduced_comp[el]

        # Calculate Gibbs free energy of the bulk per unit formula
        gbulk = self.ucell_entry.energy /\
                (len([site for site in ucell
                      if site.species_string == self.ref_element]) / y)

        entries = [entry for entry in
                   self.mprester.get_entries_in_chemsys(list(reduced_comp.keys()),
                                                        property_data=["e_above_hull",
                                                                       "material_id"])
                   if entry.data["e_above_hull"] == 0 and
                   entry.data["material_id"] not in exclude_ids] \
            if not custom_entries else custom_entries

        pd = PhaseDiagram(entries)
        chempot_ranges = pd.get_chempot_range_map([Element(self.ref_element)])
        # If no chemical potential is found, we return u=0, eg.
        # for a elemental system, the relative u of Cu for Cu is 0
        chempot_range = [chempot_ranges[entry] for entry in chempot_ranges.keys()
                         if entry.composition ==
                         self.ucell_entry.composition][0][0]._coords if \
            chempot_ranges else [[0,0], [0,0]]

        e_of_element = [entry.energy_per_atom for entry in
                        entries if str(entry.composition.reduced_composition)
                        == self.ref_element + "1"][0]

        self.x = x
        self.y = y
        self.gbulk = gbulk
        chempot_range = list(chempot_range)
        self.chempot_range = sorted([chempot_range[0][0], chempot_range[1][0]])
        self.e_of_element = e_of_element
        self.vasprun_dict = vasprun_dict

    def calculate_gamma(self, vasprun):
        """
        Calculates the surface energy for a single slab.
        Args:
            vasprun (Vasprun): A Vasprun object

        Returns (list): The surface energy for the minimum/maximun
            chemical potential and the second list gives the range
            of the chemical potential
        """

        reduced_comp = self.ucell_entry.composition.reduced_composition.as_dict()
        # Get the composition in the slab
        slab = vasprun.final_structure
        comp = slab.composition.as_dict()
        if len(reduced_comp.keys()) == 1:
            Ny = comp[self.ucell_entry.structure[0].species_string]
            Nx = Ny
        else:
            for el in reduced_comp.keys():
                if self.ref_element == el:
                    Ny = comp[el]
                else:
                    Nx = comp[el]

        # Calculate surface area
        m = slab.lattice.matrix
        A = np.linalg.norm(np.cross(m[0], m[1]))

        # calculate the surface energy for the max and min chemical potential
        return [(1 / (2 * A)) * (vasprun.final_energy - (Nx / self.x)
                                 * self.gbulk - (Ny - (self.y / self.x) * Nx)
                                 * (delu + self.e_of_element))
                for delu in self.chempot_range]

    def wulff_shape_from_chempot(self, chempot, symprec=1e-5):
        """
        Method to get the Wulff shape at a specific chemical potential.
        Args:
            chempot (float): The chemical potential the Wulff Shape exist in.
        """

        # Check if the user provided chemical potential is within the
        # predetermine range of chemical potential. If not, raise a warning
        if not max(self.chempot_range) >= chempot >= min(self.chempot_range):
            warnings.warn("The provided chemical potential is outside the range "
                          "of chemical potential (%s to %s). The resulting Wulff "
                          "shape might not be reasonable." %(min(self.chempot_range),
                                                             max(self.chempot_range)))

        latt = SpacegroupAnalyzer(self.ucell_entry.structure).\
            get_conventional_standard_structure().lattice

        miller_list = self.vasprun_dict.keys()
        e_surf_list = []
        for hkl in miller_list:
            # At each possible configuration, we calculate surface energy as a
            # function of u and take the lowest surface energy (corresponds to
            # the most stable slab termination at that particular u)
            surf_e_range_list = [self.calculate_gamma(vasprun)
                                 for vasprun in self.vasprun_dict[hkl]]
            e_list = []
            for e_range in surf_e_range_list:
                slope, intercept = self.get_slope_and_intercept(e_range)
                e_list.append(slope * chempot + intercept)
            e_surf_list.append(min(e_list))

        return WulffShape(latt, miller_list, e_surf_list, symprec=symprec)

    def wulff_shape_dict(self, symprec=1e-5, at_intersections=False):
        """
        As the surface energy is a function of chemical potential, so too is the
            Wulff shape. This methods generates a dictionary of Wulff shapes at
            certain chemical potentials where a facet goes through a transition.
            Returns a dict, eg. {chempot1: WulffShape1, chempot2: WulffShape2}

        Args:
            symprec (float): for recp_operation, default is 1e-5.
            at_intersections (bool): Whether to generate a Wulff shape for each
                intersection of surface energy for a specific facet (eg. at the
                point where a (111) stoichiometric surface energy plot intersects
                with the (111) nonstoichiometric plot) or to just generate two
                Wulff shapes, one at the min and max chemical potential.
        """

        # First lets get the Wulff shape at the
        # minimum and maximum chemical potential
        wulff_dict = {self.chempot_range[0]: \
                          self.wulff_shape_from_chempot(self.chempot_range[0],
                                                        symprec=symprec),
                      self.chempot_range[1]: \
                          self.wulff_shape_from_chempot(self.chempot_range[1],
                                                        symprec=symprec)}

        # Now we get the Wulff shape each time a facet changes its configuration
        # (ie, adsorption coverage, stoichiometric to nonstoichiometric, etc)
        if at_intersections:
            # Get all values of chemical potential where an intersection occurs
            u_at_intersection = [self.get_intersections(hkl)[0] for hkl in
                                 self.vasprun_dict.keys()
                                 if self.get_intersections(hkl)]
            # Get a Wulff shape for each intersection. The change in the Wulff shape
            # will vary if the rate of change in surface energy for any facet changes
            for u in u_at_intersection:
                wulff_dict[u] = self.wulff_shape_from_chempot(u, symprec=symprec)

        return wulff_dict

    def get_slope_and_intercept(self, surf_e_pair):
        """
        Returns the slope and intercept of the surface
            energy vs chemical potential line
        Args:
            surf_e_pair ([e_at_min_u, e_at_max_u]): The surface energy at the
                minimum chemical potential and maximum chemical potential
        """

        slope, intercept, r_value, p_value, std_err = \
            linregress(self.chempot_range, surf_e_pair)
        slope = 0 if str(slope) == 'nan' else slope
        intercept = surf_e_pair[0] if str(intercept) == 'nan' else intercept
        return slope, intercept

    def get_intersections(self, miller_index):
        """
        Returns a all intersections for a specific facet. Useful for
            finding when the configuration of a particular facet changes.

        Args:
            miller_index ((h, k, l)): Miller index of the facet we
                are interested in
        """

        # First lets calculate the range of surface
        # energies for all terminations of a specific facet
        all_se_ranges = [self.calculate_gamma(vasprun) for vasprun
                         in self.vasprun_dict[miller_index]]

        if len(all_se_ranges) == 1:
            return []

        # Now get all possible intersection coordinates for each pair of lines
        intersections = []
        for pair_ranges in itertools.combinations(all_se_ranges, 2):
            slope1, intercept1 = self.get_slope_and_intercept(pair_ranges[0])
            slope2, intercept2 = self.get_slope_and_intercept(pair_ranges[1])
            # Calculate the intersection coordinates
            u = (intercept1-intercept2)/(slope2-slope1)
            # if the intersection is beyond the chemical potential
            # range or if the lines are parallel, we ignore it
            if slope1-slope2 == 0 or u < min(self.chempot_range) \
                    or u > max(self.chempot_range):
                continue
            intersections.append([u, slope1 * u + intercept1])

        return sorted(intersections, key=lambda ints: ints[0])

    def area_frac_vs_chempot_plot(self, cmap=cm.jet, at_intersections=False,
                                  increments=10):
        """
        Plots the change in the area contribution of
        each facet as a function of chemical potential.
        Args:
            cmap (cm): A matplotlib colormap object, defaults to jet.
            at_intersections (bool): Whether to generate a Wulff shape for each
                intersection of surface energy for a specific facet (eg. at the
                point where a (111) stoichiometric surface energy plot intersects
                with the (111) nonstoichiometric plot) or to just generate two
                Wulff shapes, one at the min and max chemical potential.
            increments (bool): Number of data points between min/max or point
                of intersection. Defaults to 5 points.
        """

        # Choose unique colors for each facet
        f = [int(i) for i in np.linspace(0, 255, len(self.vasprun_dict.keys()))]

        # Get all points of min/max chempot and intersections
        chempot_intersections = []
        chempot_intersections.extend(self.chempot_range)
        for hkl in self.vasprun_dict.keys():
            chempot_intersections.extend([ints[0] for ints in
                                          self.get_intersections(hkl)])
        chempot_intersections = sorted(chempot_intersections)

        # Get all chempots
        if at_intersections:
            all_chempots = []
            for i, intersection in enumerate(chempot_intersections):
                if i < len(chempot_intersections)-1:
                    all_chempots.extend(np.linspace(intersection,
                                                    chempot_intersections[i+1],
                                                    increments))
        else:
            all_chempots = np.linspace(min(self.chempot_range),
                                       max(self.chempot_range), increments)

        # initialize a dictionary of lists of fractional areas for each hkl
        hkl_area_dict = {}
        for hkl in self.vasprun_dict.keys():
            hkl_area_dict[hkl] = []

        # Get plot points for each Miller index
        for u in all_chempots:
            wulffshape = self.wulff_shape_from_chempot(u)
            for hkl in wulffshape.area_fraction_dict.keys():
                hkl_area_dict[hkl].append(wulffshape.area_fraction_dict[hkl])

        # Plot the area fraction vs chemical potential for each facet
        plt = pretty_plot()
        for i, hkl in enumerate(self.vasprun_dict.keys()):
            # Ignore any facets that never show up on the
            # Wulff shape regardless of chemical potential
            if all([a == 0 for a in hkl_area_dict[hkl]]):
                continue
            else:
                plt.plot(all_chempots, hkl_area_dict[hkl],
                         '--', color=cmap(f[i]), label=str(hkl))

        # Make the figure look nice
        plt.ylim([0,1])
        plt.xlim(self.chempot_range)
        plt.ylabel(r"Fractional area $A^{Wulff}_{hkl}/A^{Wulff}$")
        plt.xlabel(r"Chemical potential $\Delta\mu_{%s}$ (eV)" %(self.ref_element))
        plt.legend(bbox_to_anchor=(1.01, 1), loc=2, borderaxespad=0.)

        return plt

    def chempot_vs_gamma_plot(self, cmap=cm.jet, show_unstable_points=False):
        """
        Plots the surface energy of all facets as a function of chemical potential.
            Each facet will be associated with its own distinct colors. Dashed lines
            will represent stoichiometries different from that of the mpid's compound.

        Args:
            cmap (cm): A matplotlib colormap object, defaults to jet.
            show_unstable_points (bool): For each facet, there may be various
                terminations or stoichiometries and the relative stability of
                these different slabs may change with chemical potential. This
                option will only plot the most stable surface energy for a
                given chemical potential.
        """

        plt = pretty_plot()
        # Choose unique colors for each facet
        f = [int(i) for i in np.linspace(0, 255, sum([len(vaspruns) for vaspruns in
                                                      self.vasprun_dict.values()]))]
        i, already_labelled, colors = 0, [], []
        for hkl in self.vasprun_dict.keys():
            for vasprun in self.vasprun_dict[hkl]:
                slab = vasprun.final_structure
                # Generate a label for the type of slab
                label = str(hkl)
                # use dashed lines for slabs that are not stoichiometric
                # wrt bulk. Label with formula if nonstoichiometric
                if slab.composition.reduced_composition != \
                        self.ucell_entry.composition.reduced_composition:
                    mark = '--'
                    label += " %s" % (slab.composition.reduced_composition)
                else:
                    mark = '-'

                # label the chemical environment at the surface if different from the bulk.
                # First get the surface sites, then get the reduced composition at the surface
                # s = vasprun.final_structure
                # ucell = SpacegroupAnalyzer(self.ucell_entry.structure).\
                #     get_conventional_standard_structure()
                # slab = Slab(s.lattice, s.species, s.frac_coords, hkl, ucell, 0, None)
                # surf_comp = slab.surface_composition()
                #
                # if surf_comp.reduced_composition != ucell.composition.reduced_composition:
                #     label += " %s" %(surf_comp.reduced_composition)

                if label in already_labelled:
                    c = colors[already_labelled.index(label)]
                    label = None
                else:
                    already_labelled.append(label)
                    c = cmap(f[i])
                    colors.append(c)

                se_range = self.calculate_gamma(vasprun)
                plt.plot(self.chempot_range, se_range, mark, color=c, label=label)
                i += 1

        # Make the figure look nice
        axes = plt.gca()
        ylim = axes.get_ylim()
        plt.ylim(ylim)
        plt.xlim(self.chempot_range)
        plt.ylabel(r"Surface energy (eV/$\AA$)")
        plt.xlabel(r"Chemical potential $\Delta\mu_{%s}$ (eV)" %(self.ref_element))
        plt.legend(bbox_to_anchor=(1.01, 1), loc=2, borderaxespad=0.)

        return plt

    def broken_bond_vs_gamma(self):

        return
Exemplo n.º 11
0
# This initializes the REST adaptor. Put your own API key in.
from pymatgen import MPRester
from pymatgen.analysis.phase_diagram import PhaseDiagram, PDPlotter
from pymatgen.io.vasp import Poscar

a = MPRester("")

# Entries are the basic unit for thermodynamic and other analyses in pymatgen.
# This gets all entries belonging to the Ca-C-O system.
entries = a.get_entries_in_chemsys(
    ["Ca", "C", "O"],
    inc_structure=True,
    property_data=["material_id", "energy", "energy_per_atom", "volume"])

print(len(entries))

for entry in entries:
    #print(entry)
    print(entry.composition.formula)

#structure=entry.structure

#p=Poscar(structure)

#print(p)

# With entries, you can do many sophisticated analyses,
# like creating phase diagrams.
pd = PhaseDiagram(entries)
plotter = PDPlotter(pd)
plotter.show()
Exemplo n.º 12
0
from pymatgen import MPRester, Element
from pymatgen.analysis.phase_diagram import GrandPotentialPhaseDiagram, PhaseDiagram, PDPlotter

pd = PhaseDiagramOpenAnalyzer(system=["Mg", "P", "O"], open_element="O")
all_phase_diagrams = pd.get_phase_diagram_data()
# ler o tamanho da lista
number_of_phase_diagrams = len(all_phase_diagrams)

# cria uma lista só com os potenciais químicos
# chempot_list = [all_phase_diagrams[pd_index][1] for pd_index in range(number_of_phase_diagrams)]

open_elements_specific = None
open_element_all = Element("O")
mpr = MPRester("sMnWB7h8Lf4NKmzo")

entries = mpr.get_entries_in_chemsys(['Mg', 'P', 'O'], compatible_only=True)

pd2 = PhaseDiagram(entries)

chempot_list = pd2.get_transition_chempots(open_element_all)
pd_index = 0

# cria um dicionário
chempot_range_of_each_phase = {}
for particular_phase_diagram in all_phase_diagrams:
    # recebe o potencial químico
    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
Exemplo n.º 13
0
                      "--format",
                      dest="format",
                      default='poscar',
                      help="export structure in which format, poscar or cif",
                      metavar="format")

    (options, args) = parser.parse_args()

    mpr = MPRester('9RTlN5ZOXst6PAdS')
    strucs = []
    if options.id is None:
        system = parse_system(options.element)
        if type(system) is not list:
            mp_entries = mpr.get_entries(system)
        else:
            mp_entries = mpr.get_entries_in_chemsys(system)
            pd = PhaseDiagram(mp_entries)
            if options.dimension is None:
                options.dimension = len(system)
        for entry in mp_entries:
            accept = False
            if type(system) is list:
                if len(entry.composition) >= options.dimension:
                    eng = pd.get_e_above_hull(entry)
                    if eng <= options.cutoff:
                        accept = True
            else:
                eng = entry.energy_per_atom
                accept = True
            if accept:
                struc = output_struc(entry, eng, tol=1e-2)
Exemplo n.º 14
0
# -*- coding: utf-8 -*-
"""
Created on Thu Sep 20 18:09:50 2018

@author: Jeran
"""

from pymatgen import MPRester, Composition
from pymatgen.analysis.phase_diagram import PhaseDiagram
from pymatgen.entries.computed_entries import ComputedEntry
from pymatgen.apps.borg.hive import VaspToComputedEntryDrone
from pymatgen.entries.compatibility import MaterialsProjectCompatibility
from pymatgen.analysis.phase_diagram import ReactionDiagram, PDPlotter, PDEntry

mp = MPRester("6ycZ7v9nGu4TsKlA")
compat = MaterialsProjectCompatibility()
chemsys = ["H", "P", "V", "O", "C"]

all_entries = mp.get_entries_in_chemsys(chemsys)
Exemplo n.º 15
0
    for ix in x:
        for iy in y:
            for iz in z:
                formula.append([ix, iy, iz])
    return formula


comps = get_formula(M, A, X)
#comps=[['Sc', 'Al', 'N']]
#comps=[['N']]
mpr = MPRester("7UnVyVXyetJ5WK3r")

for comp in comps:
    print(comp)
    try:
        entries = mpr.get_entries_in_chemsys(comp)
    except:
        continue
    if len(entries) == 0:
        continue
#    pd = PhaseDiagram(entries)
#    data = collections.defaultdict(list)
    for e in entries:
        com = e.entry_id
        prop = mpr.query(criteria={"task_id": com}, properties=[\
        "formation_energy_per_atom", \
        "energy_per_atom", \
        "spacegroup", \
        "pretty_formula", \
        "cif"])
    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
Exemplo n.º 17
0
    """
    # | - contains_entry
    for e in entry_list:
        if e.entry_id == entry.entry_id or (
                abs(entry.energy_per_atom - e.energy_per_atom) < 1e-6
                and entry.composition.reduced_formula
                == e.composition.reduced_formula):
            return True
    #__|


#__|

# | - Main Code ****************************************************************
#Entries are the basic unit for thermodynamic and other analyses in pymatgen.
entries = mpr.get_entries_in_chemsys(['O', 'H'])

# | - Ion Reference Data
#Dictionary of reference state:experimental formation energy

# ion_dict_Co = mpr._make_request('/pourbaix_diagram/reference_data/Ru')
# ion_dict_S = mpr._make_request('/pourbaix_diagram/reference_data/Y')

ion_dict_Co = mpr._make_request('/pourbaix_diagram/reference_data/Ir')
ion_dict_S = mpr._make_request('/pourbaix_diagram/reference_data/Sr')

for i, dummy in enumerate(ion_dict_Co):
    print(ion_dict_Co[i])
    print('hi')

# for i,dummy in enumerate(ion_dict_S):
Exemplo n.º 18
0
def get_random_packed(composition,
                      add_specie=None,
                      target_atoms=100,
                      vol_per_atom=None,
                      vol_exp=1.0,
                      modify_species=None,
                      use_random_seed=True):
    mpr = MPRester()

    if type(composition) == str:
        composition = Composition(composition)
    if type(add_specie) == str:
        add_specie = Composition(add_specie)

    comp_entries = mpr.get_entries(composition.reduced_formula,
                                   inc_structure=True)
    if vol_per_atom is None:
        if len(comp_entries) > 0:
            vols = np.min([
                entry.structure.volume / entry.structure.num_sites
                for entry in comp_entries
            ])
        else:
            # Find all Materials project entries containing the elements in the
            # desired composition to estimate starting volume.
            _entries = mpr.get_entries_in_chemsys(
                [str(el) for el in composition.elements], inc_structure=True)
            entries = []
            for entry in _entries:
                if set(entry.structure.composition.elements) == set(
                        composition.elements):
                    entries.append(entry)
                if len(entry.structure.composition.elements) >= 2:
                    entries.append(entry)

            vols = [
                entry.structure.volume / entry.structure.num_sites
                for entry in entries
            ]
        vol_per_atom = np.mean(vols)

    # Find total composition of atoms in the unit cell
    formula, factor = composition.get_integer_formula_and_factor()
    composition = Composition(formula)
    comp = composition * np.ceil(target_atoms / composition.num_atoms)
    if add_specie is not None:
        comp += add_specie
        # comp = Composition(comp)

    # Generate dict of elements and amounts for AmorphousMaker
    structure = {}
    for el in comp:
        structure[str(el)] = int(comp.element_composition.get(el))

    if modify_species is not None:
        for i, v in modify_species.items():
            structure[i] += v
    # use packmol to get a random configured structure
    packmol_path = os.environ['PACKMOL_PATH']
    amorphous_maker_params = {
        'box_scale': (vol_per_atom * comp.num_atoms * vol_exp)**(1 / 3),
        'packmol_path': packmol_path,
        'xyz_paths': None,
        'time_seed': use_random_seed
    }

    glass = AmorphousMaker(structure, **amorphous_maker_params)
    structure = glass.random_packed_structure
    return structure