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)
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
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()
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)
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
#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()
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
# 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()
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
"--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)
# -*- 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)
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
""" # | - 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):
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