def get_chempot_limits(self): """ Returns atomic chempots from bulk_composition based on data in the materials project database. This is abstractly handled in the ChemPotAnalyzer Note to user: If personal phase diagram desired, option exists in the pycdt.core.chemical_potentials to setup, run and parse personal phase diagrams for purposes of chemical potentials """ logger = logging.getLogger(__name__) if self._mpid: cpa = MPChemPotAnalyzer( mpid = self._mpid, sub_species = self._substitution_species, mapi_key = self._mapi_key) else: bulkvr = Vasprun(os.path.join( self._root_fldr, "bulk", "vasprun.xml"), parse_potcar_file=False) if not bulkvr: msg = "Could not fetch computed entry for atomic chempots!" logger.warning(msg) raise ValueError(msg) cpa = MPChemPotAnalyzer( bulk_ce=bulkvr.get_computed_entry(), sub_species = self._substitution_species, mapi_key = self._mapi_key) chem_lims = cpa.analyze_GGA_chempots() return chem_lims
class MPChemPotAnalyzerTest(PymatgenTest): def setUp(self): self.MPCPA = MPChemPotAnalyzer() def test_analyze_GGA_chempots(self): """ Test-cases to cover: (0) (stable + mpid given = tested in the CPA.test_get_chempots_from_pda unit test) (i) user's computed entry is stable w.r.t MP phase diagram; full_sub_approach = False (ii) user's computed entry is stable w.r.t MP phase diagram (and not currently in phase diagram); full_sub_approach = False (iii) not stable, composition exists in list of stable comps of PD; full_sub_approach = False (iv) not stable, composition DOESNT exists in list of stable comps of PD; full_sub_approach = False (v) one example of full_sub_approach = True... (just do for case with user's entry being stable) """ with MPRester() as mp: bulk_ce = mp.get_entry_by_material_id( 'mp-2534') #simulates an entry to play with for this unit test #test (i) user's computed entry is stable w.r.t MP phase diagram; full_sub_approach = False bce = copy.copy(bulk_ce) self.MPCPA = MPChemPotAnalyzer(bulk_ce=bce, sub_species=set(['Sb', 'In'])) cp_fsaf = self.MPCPA.analyze_GGA_chempots(full_sub_approach=False) self.assertEqual(set([u'Ga-GaAs-GaSb-In', u'As-GaAs-InAs-SbAs']), set(cp_fsaf.keys())) true_answer = [ cp_fsaf['Ga-GaAs-GaSb-In'][Element(elt)] for elt in ['Sb', 'As', 'Ga', 'In'] ] self.assertEqual([ -4.44626405, -5.352569090000001, -3.03723344, -2.7518583366666665 ], true_answer) # true_answer = [cp_fsaf['InAs-GaSb-In-GaAs'][Element(elt)] for elt in ['Sb', 'As', 'Ga', 'In']] # self.assertEqual([-4.243837989999999, -5.15014303, -3.239659500000001, -2.72488125], # true_answer) # true_answer = [cp_fsaf['InAs-GaSb-Sb-GaAs'][Element(elt)] for elt in ['Sb', 'As', 'Ga', 'In']] # self.assertEqual([-4.127761275, -5.0340663150000005, -3.3557362150000003, -2.8409579649999994], # true_answer) true_answer = [ cp_fsaf['As-GaAs-InAs-SbAs'][Element(elt)] for elt in ['Sb', 'As', 'Ga', 'In'] ] self.assertEqual([ -4.1687393749999995, -4.658070555, -3.7317319750000006, -3.2169537249999998 ], true_answer) #test (v) one example of full_sub_approach = True... (just doing for case with user's entry being stable) cp_fsat = self.MPCPA.analyze_GGA_chempots(full_sub_approach=True) self.assertEqual( set([ 'Ga-GaAs-GaSb-In', 'GaAs-InAs-InSb-Sb', 'GaAs-In-InAs-InSb', 'As-GaAs-InAs-SbAs', 'GaAs-GaSb-In-InSb', 'GaAs-InAs-Sb-SbAs', 'GaAs-GaSb-InSb-Sb' ]), set(cp_fsat.keys())) true_answer = [ cp_fsat["Ga-GaAs-GaSb-In"][Element(elt)] for elt in ['Sb', 'As', 'Ga', 'In'] ] self.assertEqual([ -4.44626405, -5.352569090000001, -3.03723344, -2.7518583366666665 ], true_answer) true_answer = [ cp_fsat["GaAs-InAs-InSb-Sb"][Element(elt)] for elt in ['Sb', 'As', 'Ga', 'In'] ] self.assertEqual([ -4.127761275, -4.895951335, -3.4938511950000004, -2.9790729449999995 ], true_answer) true_answer = [ cp_fsat["GaAs-In-InAs-InSb"][Element(elt)] for elt in ['Sb', 'As', 'Ga', 'In'] ] self.assertEqual([ -4.354975883333333, -5.123165943333333, -3.2666365866666673, -2.7518583366666665 ], true_answer) true_answer = [ cp_fsat["As-GaAs-InAs-SbAs"][Element(elt)] for elt in ['Sb', 'As', 'Ga', 'In'] ] self.assertEqual([ -4.1687393749999995, -4.658070555, -3.7317319750000006, -3.2169537249999998 ], true_answer) true_answer = [ cp_fsat["GaAs-GaSb-In-InSb"][Element(elt)] for elt in ['Sb', 'As', 'Ga', 'In'] ] self.assertEqual([ -4.354975883333333, -5.2612809233333335, -3.1285216066666672, -2.7518583366666665 ], true_answer) true_answer = [ cp_fsat["GaAs-InAs-Sb-SbAs"][Element(elt)] for elt in ['Sb', 'As', 'Ga', 'In'] ] self.assertEqual([ -4.127761275, -4.6990486549999995, -3.6907538750000013, -3.1759756250000004 ], true_answer) true_answer = [ cp_fsat["GaAs-GaSb-InSb-Sb"][Element(elt)] for elt in ['Sb', 'As', 'Ga', 'In'] ] self.assertEqual([ -4.127761275, -5.0340663150000005, -3.3557362150000003, -2.9790729449999995 ], true_answer) #test (iii) not stable, composition exists in list of stable comps of PD; full_sub_approach = False us_bce = ComputedEntry(Composition({'Ga': 1, 'As': 1}), -8) self.MPCPA = MPChemPotAnalyzer(bulk_ce=us_bce) cp_fsaf_us_ce = self.MPCPA.analyze_GGA_chempots( full_sub_approach=False) self.assertEqual(set(['As-GaAs', 'Ga-GaAs']), set(cp_fsaf_us_ce.keys())) self.assertEqual( [-4.6580705550000001, -3.7317319750000006], [cp_fsaf_us_ce['As-GaAs'][Element(elt)] for elt in ['As', 'Ga']]) self.assertEqual( [-5.352569090000001, -3.03723344], [cp_fsaf_us_ce['Ga-GaAs'][Element(elt)] for elt in ['As', 'Ga']]) #test (ii) user's computed entry is stable w.r.t MP phase diagram # AND composition DOESNT exists in list of stable comps of PD; full_sub_approach = False s_cdne_bce = ComputedEntry(Composition({'Ga': 2, 'As': 3}), -21.5) self.MPCPA = MPChemPotAnalyzer(bulk_ce=s_cdne_bce) cp_fsaf_s_cdne = self.MPCPA.analyze_GGA_chempots( full_sub_approach=False) self.assertEqual(set(['Ga2As3-GaAs', 'As-Ga2As3']), set(cp_fsaf_s_cdne.keys())) for tested, answer in zip([ cp_fsaf_s_cdne['Ga2As3-GaAs'][Element(elt)] for elt in ['As', 'Ga'] ], [-4.720394939999998, -3.669407590000002]): self.assertAlmostEqual(answer, tested) self.assertEqual([-4.6580705550000001, -3.7628941674999994], [ cp_fsaf_s_cdne['As-Ga2As3'][Element(elt)] for elt in ['As', 'Ga'] ]) #test (iv) not stable, composition DOESNT exists in list of stable comps of PD; full_sub_approach = False # case a) simple 2D phase diagram us_cdne_bce_a = ComputedEntry(Composition({'Ga': 2, 'As': 3}), -20.) self.MPCPA = MPChemPotAnalyzer(bulk_ce=us_cdne_bce_a) cp_fsaf_us_cdne_a = self.MPCPA.analyze_GGA_chempots( full_sub_approach=False) self.assertEqual(set(['As-GaAs']), set(cp_fsaf_us_cdne_a.keys())) self.assertEqual([-4.658070555, -3.7317319750000006], [ cp_fsaf_us_cdne_a['As-GaAs'][Element(elt)] for elt in ['As', 'Ga'] ]) # case b) larger phase diagram us_cdne_bce_b = ComputedEntry(Composition({ 'Ga': 2, 'As': 3, 'Sb': 2 }), -20.) self.MPCPA = MPChemPotAnalyzer(bulk_ce=us_cdne_bce_b) cp_fsaf_us_cdne_b = self.MPCPA.analyze_GGA_chempots( full_sub_approach=False) self.assertEqual(set(['GaAs-Sb-SbAs']), set(cp_fsaf_us_cdne_b.keys())) self.assertEqual( [-4.127761275, -4.6990486549999995, -3.6907538750000013], [ cp_fsaf_us_cdne_b['GaAs-Sb-SbAs'][Element(elt)] for elt in ['Sb', 'As', 'Ga'] ]) def test_get_chempots_from_composition(self): bulk_comp = Composition("Cr2O3") self.MPCPA = MPChemPotAnalyzer() #reinitalize cro_cp = self.MPCPA.get_chempots_from_composition(bulk_comp) self.assertEqual(set(['Cr2O3-CrO2', 'Cr-Cr2O3']), set(cro_cp.keys())) self.assertAlmostEqual(-14.635303979999982, cro_cp['Cr2O3-CrO2'][Element('Cr')]) self.assertAlmostEqual(-5.51908629500001, cro_cp['Cr2O3-CrO2'][Element('O')]) self.assertAlmostEqual(-9.63670386, cro_cp['Cr-Cr2O3'][Element('Cr')]) self.assertAlmostEqual(-8.851486374999999, cro_cp['Cr-Cr2O3'][Element('O')]) def test_get_mp_entries(self): #name mp-id of GaAs system and get mp-entries... self.MPCPA = MPChemPotAnalyzer(mpid='mp-2534') self.MPCPA.get_mp_entries() ents = self.MPCPA.entries self.assertEqual(set(['bulk_derived', 'subs_set']), set(ents.keys())) self.assertTrue(len(ents['bulk_derived']))