def setUp(self): module_dir = os.path.dirname(os.path.abspath(__file__)) (self.elements, self.entries) = PDEntryIO.from_csv( os.path.join(module_dir, "pdentries_test.csv")) self.pd = GrandPotentialPhaseDiagram(self.entries, {Element("O"): -5}, self.elements) self.pd6 = GrandPotentialPhaseDiagram(self.entries, {Element("O"): -6})
class GrandPotentialPhaseDiagramTest(unittest.TestCase): def setUp(self): module_dir = os.path.dirname(os.path.abspath(__file__)) (self.elements, self.entries) = PDEntryIO.from_csv(os.path.join(module_dir, "pdentries_test.csv")) self.pd = GrandPotentialPhaseDiagram(self.entries, {Element("O"):-5}, self.elements) self.pd6 = GrandPotentialPhaseDiagram(self.entries, {Element("O"):-6}) def test_stable_entries(self): stable_formulas = [ent.original_entry.composition.reduced_formula for ent in self.pd.stable_entries] expected_stable = ['Li5FeO4', 'Li2FeO3', 'LiFeO2', 'Fe2O3', 'Li2O2'] for formula in expected_stable: self.assertTrue(formula in stable_formulas, formula + " not in stable entries!") self.assertEqual(len(self.pd6.stable_entries), 4) def test_get_formation_energy(self): stable_formation_energies = {ent.original_entry.composition.reduced_formula:self.pd.get_form_energy(ent) for ent in self.pd.stable_entries} expected_formation_energies = {'Fe2O3': 0.0, 'Li5FeO4':-5.305515040000046, 'Li2FeO3':-2.3424741500000152, 'LiFeO2':-0.43026396250000154, 'Li2O2': 0.0} for formula, energy in expected_formation_energies.items(): self.assertAlmostEqual(energy, stable_formation_energies[formula], 7, "Calculated formation for " + formula + " is not correct!") def test_str(self): self.assertIsNotNone(str(self.pd))
def get_decomp(o_chem_pot, mycomp, verbose=1): """Get decomposition from open phase diagram Args: o_chem_pot <float>: Oxygen chemical potential mycomp <pymatgen Composition>: Composition verbose <int>: 1 - verbose (default) 0 - silent Returns: decomposition string """ a = MPRester("<YOUR_MPREST_API_KEY_HERE>") elements = mycomp.elements ellist = map(str, elements) entries = a.get_entries_in_chemsys(ellist) #entries = a.get_entries_in_chemsys(['La', 'Mn', 'O', 'Fe']) pd = PhaseDiagram(entries) gppd = GrandPotentialPhaseDiagram(entries, {Element('O'): float(o_chem_pot)}) print gppd #plotter = PDPlotter(gppd) #plotter.show() gppda = PDAnalyzer(gppd) #mychempots = gppda.get_composition_chempots(mycomp) #print "My chem pots:" #print mychempots mydecompgppd = gppda.get_decomposition(mycomp) #pdentry = PDEntry(mycomp, 0) #print "Decomp and energy:" #decompandenergy = gppda.get_decomp_and_e_above_hull(pdentry) #print decompandenergy #mydecomppd = pda.get_decomposition(mycomp) #print "Mn profile:" #mnprof= gppda.get_element_profile(Element('Mn'),mycomp) #print mnprof if verbose: for (entry, amount) in mydecompgppd.iteritems(): print "%s: %3.3f" % (entry.name, amount) #mymurangegppd = gppda.getmu_range_stability_phase(Composition(entry.name),Element('O')) #print mymurangegppd #for (entry,amount) in mydecomppd.iteritems(): # print "%s: %3.3f" % (entry.name, amount) print "" return mydecompgppd
class GrandPotentialPhaseDiagramTest(unittest.TestCase): def setUp(self): module_dir = os.path.dirname(os.path.abspath(__file__)) (self.elements, self.entries) = PDEntryIO.from_csv( os.path.join(module_dir, "pdentries_test.csv")) self.pd = GrandPotentialPhaseDiagram(self.entries, {Element("O"): -5}, self.elements) self.pd6 = GrandPotentialPhaseDiagram(self.entries, {Element("O"): -6}) def test_stable_entries(self): stable_formulas = [ ent.original_entry.composition.reduced_formula for ent in self.pd.stable_entries ] expected_stable = ['Li5FeO4', 'Li2FeO3', 'LiFeO2', 'Fe2O3', 'Li2O2'] for formula in expected_stable: self.assertTrue(formula in stable_formulas, formula + " not in stable entries!") self.assertEqual(len(self.pd6.stable_entries), 4) def test_get_formation_energy(self): stable_formation_energies = { ent.original_entry.composition.reduced_formula: self.pd.get_form_energy(ent) for ent in self.pd.stable_entries } expected_formation_energies = { 'Fe2O3': 0.0, 'Li5FeO4': -5.305515040000046, 'Li2FeO3': -2.3424741500000152, 'LiFeO2': -0.43026396250000154, 'Li2O2': 0.0 } for formula, energy in expected_formation_energies.items(): self.assertAlmostEqual( energy, stable_formation_energies[formula], 7, "Calculated formation for " + formula + " is not correct!") def test_str(self): self.assertIsNotNone(str(self.pd))
def get_element_profile(self, element, comp, comp_tol=1e-5): """ Provides the element evolution data for a composition. For example, can be used to analyze Li conversion voltages by varying uLi and looking at the phases formed. Also can be used to analyze O2 evolution by varying uO2. Args: element: An element. Must be in the phase diagram. comp: A Composition comp_tol: The tolerance to use when calculating decompositions. Phases with amounts less than this tolerance are excluded. Defaults to 1e-5. Returns: Evolution data as a list of dictionaries of the following format: [ {'chempot': -10.487582010000001, 'evolution': -2.0, 'reaction': Reaction Object], ...] """ if element not in self._pd.elements: raise ValueError("get_transition_chempots can only be called with" " elements in the phase diagram.") chempots = self.get_transition_chempots(element) stable_entries = self._pd.stable_entries gccomp = Composition({el: amt for el, amt in comp.items() if el != element}) elref = self._pd.el_refs[element] elcomp = Composition(element.symbol) prev_decomp = [] evolution = [] def are_same_decomp(decomp1, decomp2): for comp in decomp2: if comp not in decomp1: return False return True for c in chempots: gcpd = GrandPotentialPhaseDiagram( stable_entries, {element: c - 1e-5}, self._pd.elements ) analyzer = PDAnalyzer(gcpd) gcdecomp = analyzer.get_decomposition(gccomp) decomp = [gcentry.original_entry.composition for gcentry, amt in gcdecomp.items() if amt > comp_tol] decomp_entries = [gcentry.original_entry for gcentry, amt in gcdecomp.items() if amt > comp_tol] if not are_same_decomp(prev_decomp, decomp): if elcomp not in decomp: decomp.insert(0, elcomp) rxn = Reaction([comp], decomp) rxn.normalize_to(comp) prev_decomp = decomp amt = -rxn.coeffs[rxn.all_comp.index(elcomp)] evolution.append({'chempot': c, 'evolution': amt, 'element_reference': elref, 'reaction': rxn, 'entries': decomp_entries}) return evolution
def main(comp="La0.5Sr0.5MnO3", energy=-43.3610, ostart="", oend="", ostep=""): """Get energy above hull for a composition Args: comp <str>: Composition in string form energy <float>: Energy PER FORMULA UNIT of composition given (Leave the following arguments blank for a non-grand potential phase diagram.) ostart <float>: Starting oxygen chemical potential. oend <float>: Ending oxygen chemical potential. ostep <float>: Step for oxygen chemical potential Returns: Prints to screen """ #a = MPRester("<YOUR_MPREST_API_KEY_HERE>") a = MPRester("wfmUu5VSsDCvIrhz") mycomp = Composition(comp) print "Composition: ", mycomp myenergy = energy print "Energy: ", myenergy myPDEntry = PDEntry(mycomp, myenergy) elements = mycomp.elements ellist = map(str, elements) chemsys_entries = a.get_entries_in_chemsys(ellist) #For reference: other ways of getting entries #entries = a.mpquery(criteria={'elements':{'$in':['La','Mn'],'$all':['O']},'nelements':3}) #entries = a.mpquery(criteria={'elements':{'$in':['La','Mn','O'],'$all':['O']}},properties=['pretty_formula']) #entries = a.get_entries_in_chemsys(['La', 'Mn', 'O', 'Sr']) if ostart == "": #Regular phase diagram entries = list(chemsys_entries) entries.append(myPDEntry) pd = PhaseDiagram(entries) #plotter = PDPlotter(gppd) #plotter.show() ppda = PDAnalyzer(pd) eabove = ppda.get_decomp_and_e_above_hull(myPDEntry) print "Energy above hull: ", eabove[1] print "Decomposition: ", eabove[0] return eabove else: #Grand potential phase diagram orange = np.arange( ostart, oend + ostep, ostep) #add ostep because otherwise the range ends before oend for o_chem_pot in orange: entries = list(chemsys_entries) myGrandPDEntry = GrandPotPDEntry( myPDEntry, {Element('O'): float(o_chem_pot) }) #need grand pot pd entry for GPPD entries.append(myGrandPDEntry) gppd = GrandPotentialPhaseDiagram( entries, {Element('O'): float(o_chem_pot)}) gppda = PDAnalyzer(gppd) geabove = gppda.get_decomp_and_e_above_hull(myGrandPDEntry, True) print "******** Decomposition for mu_O = %s eV ********" % o_chem_pot print "%30s%1.4f" % ("mu_O: ", o_chem_pot) print "%30s%1.4f" % ("Energy above hull (eV): ", geabove[1]) decomp = geabove[0] #print "Decomp: ", decomp print "%30s" % "Decomposition: " for dkey in decomp.keys(): print "%30s:%1.4f" % (dkey.composition, decomp[dkey]) return