Example #1
0
    def setUpClass(cls):
        cls.vbm_val = 2.6682
        cls.gap = 1.5
        cls.entries = list(loadfn(os.path.join(os.path.dirname(__file__), "GaAs_test_defentries.json")).values())
        for entry in cls.entries:
            entry.parameters.update({"vbm": cls.vbm_val})
        cls.pd = DefectPhaseDiagram(cls.entries, cls.vbm_val, cls.gap)
        cls.mu_elts = {Element("As"): -4.658070555, Element("Ga"): -3.7317319750000006}

        # make Vac_As (q= -2) only defect test single-stable-charge exceptions
        cls.extra_entry = DefectEntry(cls.entries[5].defect.copy(), 100.0)
        sep_entries = [
            ent for ent in cls.entries if not (ent.name == "Vac_As_mult4" and ent.charge in [-2, -1, 0, 1, 2])
        ]
        sep_entries.append(cls.extra_entry.copy())
        cls.sep_pd = DefectPhaseDiagram(sep_entries, cls.vbm_val, cls.gap)

        # make Vac_As (q= -2) is incompatible for larger supercell
        ls_entries = cls.entries[:]
        for entry in ls_entries:
            if entry.name == "Vac_As_mult4" and entry.charge == -2.0:
                entry.parameters["is_compatible"] = False
        cls.pd_ls_fcTrue = DefectPhaseDiagram(ls_entries, cls.vbm_val, cls.gap, filter_compatible=True)
        cls.pd_ls_fcFalse = DefectPhaseDiagram(ls_entries, cls.vbm_val, cls.gap, filter_compatible=False)

        # load complete dos for fermi energy solving
        with open(os.path.join(PymatgenTest.TEST_FILES_DIR, "complete_dos.json")) as f:
            dos_dict = json.load(f)
        cls.dos = CompleteDos.from_dict(dos_dict)
Example #2
0
    def setUp(self):
        self.vbm_val = 2.6682
        self.gap = 1.5
        self.entries = list(loadfn(os.path.join(os.path.dirname(__file__), "GaAs_test_defentries.json")).values())
        for entry in self.entries:
            entry.parameters.update( {'vbm': self.vbm_val})
        self.pd = DefectPhaseDiagram(self.entries, self.vbm_val, self.gap)
        self.mu_elts = {Element("As"): -4.658070555, Element("Ga"): -3.7317319750000006}

        # make Vac_As (q= -2) only defect test single-stable-charge exceptions
        self.extra_entry = DefectEntry(self.entries[5].defect.copy(), 100.)
        sep_entries = [ent for ent in self.entries if not (ent.name == 'Vac_As_mult4' and
                                                           ent.charge in [-2,-1,0,1,2])]
        sep_entries.append( self.extra_entry.copy())
        self.sep_pd = DefectPhaseDiagram( sep_entries, self.vbm_val, self.gap)

        # make Vac_As (q= -2) is incompatible for larger supercell
        ls_entries = self.entries[:]
        for entry in ls_entries:
            if entry.name == 'Vac_As_mult4' and entry.charge == -2.:
                entry.parameters['is_compatible'] = False
        self.pd_ls_fcTrue = DefectPhaseDiagram(ls_entries, self.vbm_val, self.gap, filter_compatible=True)
        self.pd_ls_fcFalse = DefectPhaseDiagram(ls_entries, self.vbm_val, self.gap, filter_compatible=False)

        # load complete dos for fermi energy solving
        with open(os.path.join(test_dir, "complete_dos.json"), "r") as f:
            dos_dict = json.load(f)
        self.dos = CompleteDos.from_dict(dos_dict)
    def test_suggest_charges(self):
        suggested_charges = self.pd.suggest_charges()
        for k in [
                "Vac_As_mult4@0-1-2-3-4-5", "Sub_Ga_on_As_mult4@6-7-8-9-10-11",
                "Vac_Ga_mult4@12-13-14-15",
                "Sub_As_on_Ga_mult4@16-17-18-19-20-21",
                "Int_Ga_mult1@22-23-24-25",
                "Int_As_mult1@26-27-28-29-30-31-32-33-34",
                "Int_As_mult1@35-36-37-38-39-40-41-42-43",
                "Int_Ga_mult1@44-45-46-47"
        ]:
            self.assertTrue(
                len(suggested_charges[k]) > 0,
                "Could not find any suggested charges for {} with band_gap of {}"
                .format(k, self.pd.band_gap))

        pd = DefectPhaseDiagram(self.entries, 2.6682, 1.0)
        suggested_charges = self.pd.suggest_charges()
        for k in ["Vac_As_mult4@0-1-2-3-4-5", "Vac_Ga_mult4@12-13-14-15"]:
            self.assertTrue(
                len(suggested_charges[k]) > 0,
                "Could not find any suggested charges for {} with band_gap of {}"
                .format(k, pd.band_gap))

        # test again but with only one charge state stable for Vac_As
        suggested_charges = self.sep_pd.suggest_charges()
        self.assertEqual(set(suggested_charges['Vac_As_mult4@0-43']),
                         set([-4]))
Example #4
0
    def test_suggest_charges(self):
        pd = DefectPhaseDiagram(self.entries, 2.6682, 2.0)
        suggested_charges = pd.suggest_charges()
        for k in [
                "Int_As_mult1", "Int_Ga_mult1", "Sub_As_on_Ga_mult4", "Sub_Ga_on_As_mult4", "Vac_As_mult4",
                "Vac_Ga_mult4"
        ]:
            self.assertTrue(
                len(suggested_charges[k]) > 0, "Could not find any suggested charges for {} with band_gap of {}".format(
                    k, pd.band_gap))

        pd = DefectPhaseDiagram(self.entries, 2.6682, 1.0)
        suggested_charges = pd.suggest_charges()
        for k in ["Vac_As_mult4", "Vac_Ga_mult4"]:
            self.assertTrue(
                len(suggested_charges[k]) > 0, "Could not find any suggested charges for {} with band_gap of {}".format(
                    k, pd.band_gap))
Example #5
0
    def test_entries(self):
        pd = DefectPhaseDiagram(self.entries, 2.6682, 2.0)

        all_stable_entries = pd.all_stable_entries

        self.assertEqual(len(pd.defect_types), 6)
        self.assertEqual(len(all_stable_entries),
                         sum([len(v) for v in pd.stable_charges.values()]))
    def setUp(self):
        dpd_path = os.path.split(inspect.getfile(DefectPhaseDiagram))[0]
        pymatgen_test_files = os.path.abspath(os.path.join(dpd_path, 'tests'))
        vbm_val = 2.6682
        gap = 1.5
        entries = list(
            loadfn(
                os.path.join(pymatgen_test_files,
                             "GaAs_test_defentries.json")).values())
        for entry in entries:
            entry.parameters.update({'vbm': vbm_val})

        self.dpd = DefectPhaseDiagram(entries, vbm_val, gap)
Example #7
0
    def setUp(self):
        l = Lattice([[3.52,0.0,2.033], [1.174,3.32,2.033], \
                [0.0,0.0,4.066]])
        s_bulk = Structure(l, ['Ga', 'As'], \
                [[0.0000, 0.0000, 0.0000], \
                [0.2500, 0.2500, 0.2500]])
        defect_site = PeriodicSite('As', [0.25, 0.25, 0.25], l)
        defect = Vacancy(s_bulk, defect_site, charge=1.)
        defect_entry = DefectEntry(defect, 0.)

        entries = [defect_entry]
        vbm = 0.2
        band_gap = 1.
        dpd = DefectPhaseDiagram(entries, vbm, band_gap)
        self.dp = DefectPlotter(dpd)
    def setUp(self):
        self.vbm_val = 2.6682
        self.gap = 1.5
        self.entries = list(
            loadfn(
                os.path.join(os.path.dirname(__file__),
                             "GaAs_test_defentries.json")).values())
        for entry in self.entries:
            entry.parameters.update({'vbm': self.vbm_val})
        self.pd = DefectPhaseDiagram(self.entries, self.vbm_val, self.gap)
        self.mu_elts = {
            Element("As"): -4.658070555,
            Element("Ga"): -3.7317319750000006
        }

        # make Vac_As (q= -2) only defect test single-stable-charge exceptions
        self.extra_entry = DefectEntry(self.entries[5].defect.copy(), 100.)
        sep_entries = [
            ent for ent in self.entries if not (
                ent.name == 'Vac_As_mult4' and ent.charge in [-2, -1, 0, 1, 2])
        ]
        sep_entries.append(self.extra_entry.copy())
        self.sep_pd = DefectPhaseDiagram(sep_entries, self.vbm_val, self.gap)

        # make Vac_As (q= -2) is incompatible for larger supercell
        ls_entries = self.entries[:]
        for entry in ls_entries:
            if entry.name == 'Vac_As_mult4' and entry.charge == -2.:
                entry.parameters['is_compatible'] = False
        self.pd_ls_fcTrue = DefectPhaseDiagram(ls_entries,
                                               self.vbm_val,
                                               self.gap,
                                               filter_compatible=True)
        self.pd_ls_fcFalse = DefectPhaseDiagram(ls_entries,
                                                self.vbm_val,
                                                self.gap,
                                                filter_compatible=False)

        # load complete dos for fermi energy solving
        with open(os.path.join(test_dir, "complete_dos.json"), "r") as f:
            dos_dict = json.load(f)
        self.dos = CompleteDos.from_dict(dos_dict)
Example #9
0
    def test_suggest_charges(self):
        pd = DefectPhaseDiagram(self.entries, 2.6682, 2.0)
        suggested_charges = pd.suggest_charges()
        for k in [
                "Int_As_mult1", "Int_Ga_mult1", "Sub_As_on_Ga_mult4",
                "Sub_Ga_on_As_mult4", "Vac_As_mult4", "Vac_Ga_mult4"
        ]:
            self.assertTrue(
                len(suggested_charges[k]) > 0,
                "Could not find any suggested charges for {} with band_gap of {}"
                .format(k, pd.band_gap))

        pd = DefectPhaseDiagram(self.entries, 2.6682, 1.0)
        suggested_charges = pd.suggest_charges()
        for k in ["Vac_As_mult4", "Vac_Ga_mult4"]:
            self.assertTrue(
                len(suggested_charges[k]) > 0,
                "Could not find any suggested charges for {} with band_gap of {}"
                .format(k, pd.band_gap))
class DefectsThermodynamicsTest(PymatgenTest):
    def setUp(self):
        self.vbm_val = 2.6682
        self.gap = 1.5
        self.entries = list(
            loadfn(
                os.path.join(os.path.dirname(__file__),
                             "GaAs_test_defentries.json")).values())
        for entry in self.entries:
            entry.parameters.update({'vbm': self.vbm_val})
        self.pd = DefectPhaseDiagram(self.entries, self.vbm_val, self.gap)
        self.mu_elts = {
            Element("As"): -4.658070555,
            Element("Ga"): -3.7317319750000006
        }

        # make Vac_As (q= -2) only defect test single-stable-charge exceptions
        self.extra_entry = DefectEntry(self.entries[5].defect.copy(), 100.)
        sep_entries = [
            ent for ent in self.entries if not (
                ent.name == 'Vac_As_mult4' and ent.charge in [-2, -1, 0, 1, 2])
        ]
        sep_entries.append(self.extra_entry.copy())
        self.sep_pd = DefectPhaseDiagram(sep_entries, self.vbm_val, self.gap)

        # make Vac_As (q= -2) is incompatible for larger supercell
        ls_entries = self.entries[:]
        for entry in ls_entries:
            if entry.name == 'Vac_As_mult4' and entry.charge == -2.:
                entry.parameters['is_compatible'] = False
        self.pd_ls_fcTrue = DefectPhaseDiagram(ls_entries,
                                               self.vbm_val,
                                               self.gap,
                                               filter_compatible=True)
        self.pd_ls_fcFalse = DefectPhaseDiagram(ls_entries,
                                                self.vbm_val,
                                                self.gap,
                                                filter_compatible=False)

        # load complete dos for fermi energy solving
        with open(os.path.join(test_dir, "complete_dos.json"), "r") as f:
            dos_dict = json.load(f)
        self.dos = CompleteDos.from_dict(dos_dict)

    def test_good_test_data(self):
        self.assertEqual(len(self.entries), 48)

    def test_suggest_charges(self):
        suggested_charges = self.pd.suggest_charges()
        for k in [
                "Vac_As_mult4@0-1-2-3-4-5", "Sub_Ga_on_As_mult4@6-7-8-9-10-11",
                "Vac_Ga_mult4@12-13-14-15",
                "Sub_As_on_Ga_mult4@16-17-18-19-20-21",
                "Int_Ga_mult1@22-23-24-25",
                "Int_As_mult1@26-27-28-29-30-31-32-33-34",
                "Int_As_mult1@35-36-37-38-39-40-41-42-43",
                "Int_Ga_mult1@44-45-46-47"
        ]:
            self.assertTrue(
                len(suggested_charges[k]) > 0,
                "Could not find any suggested charges for {} with band_gap of {}"
                .format(k, self.pd.band_gap))

        pd = DefectPhaseDiagram(self.entries, 2.6682, 1.0)
        suggested_charges = self.pd.suggest_charges()
        for k in ["Vac_As_mult4@0-1-2-3-4-5", "Vac_Ga_mult4@12-13-14-15"]:
            self.assertTrue(
                len(suggested_charges[k]) > 0,
                "Could not find any suggested charges for {} with band_gap of {}"
                .format(k, pd.band_gap))

        #test again but with only one charge state stable for Vac_As
        suggested_charges = self.sep_pd.suggest_charges()
        self.assertEqual(set(suggested_charges['Vac_As_mult4@0-43']),
                         set([-4]))

    def test_suggest_larger_supercells(self):
        suggested_larger_cells = self.pd_ls_fcFalse.suggest_larger_supercells()
        self.assertEqual(suggested_larger_cells['Vac_As_mult4@0-1-2-3-4-5'],
                         [-2])

        # raise error if filter_compatibile = True
        self.assertRaises(ValueError,
                          self.pd_ls_fcTrue.suggest_larger_supercells)

    def test_entries(self):
        all_stable_entries = self.pd.all_stable_entries

        self.assertEqual(len(self.pd.defect_types), 8)
        self.assertEqual(
            len(all_stable_entries),
            sum([len(v) for v in self.pd.stable_charges.values()]))

        #test again but with only one charge state stable for Vac_As
        self.assertEqual(
            len(self.sep_pd.transition_level_map['Vac_As_mult4@0-43']), 0)
        self.assertEqual(len(self.sep_pd.stable_entries['Vac_As_mult4@0-43']),
                         1)
        self.assertEqual(
            len(self.sep_pd.finished_charges['Vac_As_mult4@0-43']), 2)

    #
    def test_solve_for_fermi_energy(self):
        fermi_energy = self.pd.solve_for_fermi_energy(100., self.mu_elts,
                                                      self.dos)
        self.assertAlmostEqual(fermi_energy, 0.57387314)
        fermi_energy = self.pd.solve_for_fermi_energy(1000., self.mu_elts,
                                                      self.dos)
        self.assertAlmostEqual(fermi_energy, 0.74139553)

    def test_solve_for_non_equilibrium_fermi_energy(self):
        fermi_energy = self.pd.solve_for_non_equilibrium_fermi_energy(
            300., 1000., self.mu_elts, self.dos)
        self.assertAlmostEqual(fermi_energy, 0.29500637)
        fermi_energy = self.pd.solve_for_non_equilibrium_fermi_energy(
            1000., 1000., self.mu_elts, self.dos)
        self.assertAlmostEqual(fermi_energy, 0.74139553)

    def test_get_dopability_limits(self):
        lower_lim, upper_lim = self.pd.get_dopability_limits(self.mu_elts)
        self.assertAlmostEqual(lower_lim, -0.39996272)
        self.assertAlmostEqual(upper_lim, 1.064193047)
        # raise error if defects are negative across gap
        bad_mu_elts = self.mu_elts.copy()
        bad_mu_elts[Element("Ga")] += 10.
        lower_lim, upper_lim = self.pd.get_dopability_limits(bad_mu_elts)
        self.assertIsNone(lower_lim)
        self.assertIsNone(upper_lim)

    def test_plot(self):
        #simple test that plot is produced
        p = self.pd.plot(saved=False)
        self.assertTrue(p)
Example #11
0
class DefectsThermodynamicsTest(PymatgenTest):
    def setUp(self):
        self.vbm_val = 2.6682
        self.gap = 1.5
        self.entries = list(loadfn(os.path.join(os.path.dirname(__file__), "GaAs_test_defentries.json")).values())
        for entry in self.entries:
            entry.parameters.update( {'vbm': self.vbm_val})
        self.pd = DefectPhaseDiagram(self.entries, self.vbm_val, self.gap)
        self.mu_elts = {Element("As"): -4.658070555, Element("Ga"): -3.7317319750000006}

        # make Vac_As (q= -2) only defect test single-stable-charge exceptions
        self.extra_entry = DefectEntry(self.entries[5].defect.copy(), 100.)
        sep_entries = [ent for ent in self.entries if not (ent.name == 'Vac_As_mult4' and
                                                           ent.charge in [-2,-1,0,1,2])]
        sep_entries.append( self.extra_entry.copy())
        self.sep_pd = DefectPhaseDiagram( sep_entries, self.vbm_val, self.gap)

        # make Vac_As (q= -2) is incompatible for larger supercell
        ls_entries = self.entries[:]
        for entry in ls_entries:
            if entry.name == 'Vac_As_mult4' and entry.charge == -2.:
                entry.parameters['is_compatible'] = False
        self.pd_ls_fcTrue = DefectPhaseDiagram(ls_entries, self.vbm_val, self.gap, filter_compatible=True)
        self.pd_ls_fcFalse = DefectPhaseDiagram(ls_entries, self.vbm_val, self.gap, filter_compatible=False)

        # load complete dos for fermi energy solving
        with open(os.path.join(test_dir, "complete_dos.json"), "r") as f:
            dos_dict = json.load(f)
        self.dos = CompleteDos.from_dict(dos_dict)


    def test_good_test_data(self):
        self.assertEqual(len(self.entries), 48)

    def test_suggest_charges(self):
        suggested_charges = self.pd.suggest_charges()
        for k in [
                    "Vac_As_mult4@0-1-2-3-4-5", "Sub_Ga_on_As_mult4@6-7-8-9-10-11", "Vac_Ga_mult4@12-13-14-15",
                    "Sub_As_on_Ga_mult4@16-17-18-19-20-21", "Int_Ga_mult1@22-23-24-25",
                    "Int_As_mult1@26-27-28-29-30-31-32-33-34", "Int_As_mult1@35-36-37-38-39-40-41-42-43",
                    "Int_Ga_mult1@44-45-46-47"
        ]:
            self.assertTrue(
                len(suggested_charges[k]) > 0, "Could not find any suggested charges for {} with band_gap of {}".format(
                    k, self.pd.band_gap))

        pd = DefectPhaseDiagram(self.entries, 2.6682, 1.0)
        suggested_charges = self.pd.suggest_charges()
        for k in ["Vac_As_mult4@0-1-2-3-4-5", "Vac_Ga_mult4@12-13-14-15"]:
            self.assertTrue(
                len(suggested_charges[k]) > 0, "Could not find any suggested charges for {} with band_gap of {}".format(
                    k, pd.band_gap))

        #test again but with only one charge state stable for Vac_As
        suggested_charges = self.sep_pd.suggest_charges()
        self.assertEqual( set(suggested_charges['Vac_As_mult4@0-43']), set([-4]))

    def test_suggest_larger_supercells(self):
        suggested_larger_cells = self.pd_ls_fcFalse.suggest_larger_supercells()
        self.assertEqual( suggested_larger_cells['Vac_As_mult4@0-1-2-3-4-5'], [-2])

        # raise error if filter_compatibile = True
        self.assertRaises( ValueError, self.pd_ls_fcTrue.suggest_larger_supercells)

    def test_entries(self):
        all_stable_entries = self.pd.all_stable_entries

        self.assertEqual(len(self.pd.defect_types), 8)
        self.assertEqual(len(all_stable_entries), sum([len(v) for v in self.pd.stable_charges.values()]))

        #test again but with only one charge state stable for Vac_As
        self.assertEqual( len(self.sep_pd.transition_level_map['Vac_As_mult4@0-43']), 0)
        self.assertEqual( len(self.sep_pd.stable_entries['Vac_As_mult4@0-43']), 1)
        self.assertEqual( len(self.sep_pd.finished_charges['Vac_As_mult4@0-43']), 2)
    #
    def test_solve_for_fermi_energy(self):
        fermi_energy = self.pd.solve_for_fermi_energy( 100., self.mu_elts, self.dos)
        self.assertAlmostEqual( fermi_energy, 0.57387314)
        fermi_energy = self.pd.solve_for_fermi_energy( 1000., self.mu_elts, self.dos)
        self.assertAlmostEqual( fermi_energy, 0.74139553)

    def test_solve_for_non_equilibrium_fermi_energy(self):
        fermi_energy = self.pd.solve_for_non_equilibrium_fermi_energy( 300., 1000., self.mu_elts, self.dos)
        self.assertAlmostEqual( fermi_energy, 0.29500637)
        fermi_energy = self.pd.solve_for_non_equilibrium_fermi_energy( 1000., 1000., self.mu_elts, self.dos)
        self.assertAlmostEqual( fermi_energy, 0.74139553)

    def test_get_dopability_limits(self):
        lower_lim, upper_lim = self.pd.get_dopability_limits( self.mu_elts)
        self.assertAlmostEqual( lower_lim, -0.39996272)
        self.assertAlmostEqual( upper_lim, 1.064193047)
        # raise error if defects are negative across gap
        bad_mu_elts = self.mu_elts.copy()
        bad_mu_elts[Element("Ga")] += 10.
        lower_lim, upper_lim = self.pd.get_dopability_limits( bad_mu_elts)
        self.assertIsNone( lower_lim)
        self.assertIsNone( upper_lim)

    def test_plot(self):
        #simple test that plot is produced
        p = self.pd.plot(saved=False)
        self.assertTrue( p)