Exemplo n.º 1
0
    def perform_bandfilling(defect_entry):
        """
        Perform bandfilling correction.

        Args:
            defect_entry (DefectEntry): Defect to correct.

        Returns:
            Corrected DefectEntry
        """
        BFC = BandFillingCorrection()
        bfc_dict = BFC.get_correction(defect_entry)

        bandfilling_meta = defect_entry.parameters["bandfilling_meta"].copy()
        bandfilling_meta.update(
            {"bandfilling_correction": bfc_dict["bandfilling_correction"]})
        defect_entry.parameters.update({
            "bandfilling_meta":
            bandfilling_meta,
            # also update free holes and electrons for shallow level shifting correction...
            "num_hole_vbm":
            bandfilling_meta["num_hole_vbm"],
            "num_elec_cbm":
            bandfilling_meta["num_elec_cbm"],
        })
        return defect_entry
Exemplo n.º 2
0
    def perform_bandfilling(self, defect_entry):
        """
        Perform bandfilling correction.

        Args:
            defect_entry (DefectEntry): Defect to correct.

        Returns:
            Corrected DefectEntry
        """
        BFC = BandFillingCorrection()
        bfc_dict = BFC.get_correction(defect_entry)

        bandfilling_meta = defect_entry.parameters['bandfilling_meta'].copy()
        bandfilling_meta.update(
            {'bandfilling_correction': bfc_dict['bandfilling_correction']})
        defect_entry.parameters.update({
            'bandfilling_meta':
            bandfilling_meta,
            # also update free holes and electrons for shallow level shifting correction...
            'num_hole_vbm':
            bandfilling_meta['num_hole_vbm'],
            'num_elec_cbm':
            bandfilling_meta['num_elec_cbm']
        })
        return defect_entry
Exemplo n.º 3
0
    def perform_bandfilling(self, defect_entry):
        BFC = BandFillingCorrection()
        bfc_dict = BFC.get_correction(defect_entry)

        bandfilling_meta = defect_entry.parameters['bandfilling_meta'].copy()
        bandfilling_meta.update( {'bandfilling_correction': bfc_dict['bandfilling']})
        defect_entry.parameters.update({'bandfilling_meta': bandfilling_meta,
                                        # also update free holes and electrons for band edge shifting correction...
                                        'num_hole_vbm': bandfilling_meta['num_hole_vbm'],
                                        'num_elec_cbm': bandfilling_meta['num_elec_cbm']})
        return defect_entry
Exemplo n.º 4
0
    def perform_bandfilling(self, defect_entry):
        BFC = BandFillingCorrection()
        bfc_dict = BFC.get_correction(defect_entry)

        bandfilling_meta = defect_entry.parameters['bandfilling_meta'].copy()
        bandfilling_meta.update(
            {'bandfilling_correction': bfc_dict['bandfilling']})
        defect_entry.parameters.update({
            'bandfilling_meta':
            bandfilling_meta,
            # also update free holes and electrons for band edge shifting correction...
            'num_hole_vbm':
            bandfilling_meta['num_hole_vbm'],
            'num_elec_cbm':
            bandfilling_meta['num_elec_cbm']
        })
        return defect_entry
Exemplo n.º 5
0
    def test_bandfilling(self):
        v = Vasprun(os.path.join(PymatgenTest.TEST_FILES_DIR, "vasprun.xml"))
        eigenvalues = v.eigenvalues.copy()
        kptweights = v.actual_kpoints_weights
        potalign = 0.0
        vbm = v.eigenvalue_band_properties[2]
        cbm = v.eigenvalue_band_properties[1]
        params = {
            "eigenvalues": eigenvalues,
            "kpoint_weights": kptweights,
            "potalign": potalign,
            "vbm": vbm,
            "cbm": cbm,
        }
        bfc = BandFillingCorrection()
        struc = PymatgenTest.get_structure("VO2")
        struc.make_supercell(3)
        vac = Vacancy(struc, struc.sites[0], charge=-3)

        # test trivial performing bandfilling correction
        bf_corr = bfc.perform_bandfill_corr(eigenvalues, kptweights, potalign, vbm, cbm)
        self.assertAlmostEqual(bf_corr, 0.0)
        self.assertFalse(bfc.metadata["num_elec_cbm"])
        self.assertFalse(bfc.metadata["num_hole_vbm"])
        self.assertFalse(bfc.metadata["potalign"])

        # test trivial full entry bandfill evaluation
        de = DefectEntry(vac, 0.0, corrections={}, parameters=params, entry_id=None)

        corr = bfc.get_correction(de)
        self.assertAlmostEqual(corr["bandfilling_correction"], 0.0)

        # modify the eigenvalue list to have free holes
        hole_eigenvalues = {}
        for spinkey, spinset in eigenvalues.items():
            hole_eigenvalues[spinkey] = []
            for kptset in spinset:
                hole_eigenvalues[spinkey].append([])
                for eig in kptset:
                    if (eig[0] < vbm) and (eig[0] > vbm - 0.8):
                        hole_eigenvalues[spinkey][-1].append([eig[0], 0.5])
                    else:
                        hole_eigenvalues[spinkey][-1].append(eig)

        hole_bf_corr = bfc.perform_bandfill_corr(
            hole_eigenvalues, kptweights, potalign, vbm, cbm
        )
        self.assertAlmostEqual(hole_bf_corr, -0.41138336)
        self.assertAlmostEqual(bfc.metadata["num_hole_vbm"], 0.8125000649)
        self.assertFalse(bfc.metadata["num_elec_cbm"])

        # test case with only one spin and eigen-occupations are 1.
        one_spin_eigen = hole_eigenvalues.copy()
        del one_spin_eigen[list(eigenvalues.keys())[0]]
        bf_corr = bfc.perform_bandfill_corr(
            one_spin_eigen, kptweights, potalign, vbm, cbm
        )
        self.assertAlmostEqual(bf_corr, -0.14487501159000005)

        # test case with only one spin and eigen-occupations are 2.
        one_spin_eigen_twooccu = one_spin_eigen.copy()
        for kptset in one_spin_eigen_twooccu.values():
            for bandset in kptset:
                for occuset in bandset:
                    if occuset[1] == 1.0:
                        occuset[1] = 2.0
                    elif occuset[1] == 0.5:
                        occuset[1] = 1.0
        bf_corr = bfc.perform_bandfill_corr(
            one_spin_eigen_twooccu, kptweights, potalign, vbm, cbm
        )
        self.assertAlmostEqual(bf_corr, -0.14487501159000005)
Exemplo n.º 6
0
    def test_bandfilling(self):
        v = Vasprun(os.path.join(test_dir, 'vasprun.xml'))
        eigenvalues = v.eigenvalues.copy()
        kptweights = v.actual_kpoints_weights
        potalign = 0.
        vbm = v.eigenvalue_band_properties[2]
        cbm = v.eigenvalue_band_properties[1]
        params = {
            'eigenvalues': eigenvalues,
            'kpoint_weights': kptweights,
            'potalign': potalign,
            'vbm': vbm,
            'cbm': cbm
        }
        bfc = BandFillingCorrection()
        struc = PymatgenTest.get_structure("VO2")
        struc.make_supercell(3)
        vac = Vacancy(struc, struc.sites[0], charge=-3)

        #test trivial performing bandfilling correction
        bf_corr = bfc.perform_bandfill_corr(eigenvalues, kptweights, potalign, vbm, cbm)
        self.assertAlmostEqual(bf_corr, 0.)
        self.assertFalse(bfc.metadata['occupied_def_levels'])
        self.assertFalse(bfc.metadata['unoccupied_def_levels'])
        self.assertFalse(bfc.metadata['total_occupation_defect_levels'])
        self.assertFalse(bfc.metadata['num_elec_cbm'])
        self.assertFalse(bfc.metadata['num_hole_vbm'])
        self.assertFalse(bfc.metadata['potalign'])

        #test trivial full entry bandfill evaluation
        de = DefectEntry(vac, 0., corrections={}, parameters=params, entry_id=None)

        corr = bfc.get_correction(de)
        self.assertAlmostEqual(corr['bandfilling'], 0.)

        #modify the eigenvalue list to have free holes
        hole_eigenvalues = {}
        for spinkey, spinset in eigenvalues.items():
            hole_eigenvalues[spinkey] = []
            for kptset in spinset:
                hole_eigenvalues[spinkey].append([])
                for eig in kptset:
                    if (eig[0] < vbm) and (eig[0] > vbm - .8):
                        hole_eigenvalues[spinkey][-1].append([eig[0], 0.5])
                    else:
                        hole_eigenvalues[spinkey][-1].append(eig)

        hole_bf_corr = bfc.perform_bandfill_corr(hole_eigenvalues, kptweights, potalign, vbm, cbm)
        self.assertAlmostEqual(hole_bf_corr, -0.41138336)
        self.assertAlmostEqual(bfc.metadata['num_hole_vbm'], 0.8125000649)
        self.assertFalse(bfc.metadata['num_elec_cbm'])

        #modify the eigenvalue list to have free electrons
        elec_eigenvalues = {}
        for spinkey, spinset in eigenvalues.items():
            elec_eigenvalues[spinkey] = []
            for kptset in spinset:
                elec_eigenvalues[spinkey].append([])
                for eig in kptset:
                    if (eig[0] > cbm) and (eig[0] < cbm + .2):
                        elec_eigenvalues[spinkey][-1].append([eig[0], 0.5])
                    else:
                        elec_eigenvalues[spinkey][-1].append(eig)

        elec_bf_corr = bfc.perform_bandfill_corr(elec_eigenvalues, kptweights, potalign, vbm, cbm)
        self.assertAlmostEqual(elec_bf_corr, -0.0903187572254)
        self.assertAlmostEqual(bfc.metadata['num_elec_cbm'], 0.8541667349)
        self.assertFalse(bfc.metadata['num_hole_vbm'])

        #modify the potalignment and introduce new occupied defect levels from vbm states
        potalign = -0.1

        bf_corr = bfc.perform_bandfill_corr(eigenvalues, kptweights, potalign, vbm, cbm)
        self.assertAlmostEqual(bfc.metadata['num_hole_vbm'], 0.)
        self.assertAlmostEqual(bf_corr, 0.)
        occu = [[1.457,  0.0833333], [1.5204, 0.0833333], [1.53465, 0.0833333], [1.5498, 0.0416667]]
        self.assertArrayAlmostEqual(
            list(sorted(bfc.metadata['occupied_def_levels'], key=lambda x: x[0])), list(
                sorted(occu, key=lambda x: x[0])))
        self.assertAlmostEqual(bfc.metadata['total_occupation_defect_levels'], 0.29166669)
        self.assertFalse(bfc.metadata['unoccupied_def_levels'])
Exemplo n.º 7
0
    def test_bandfilling(self):
        v = Vasprun(os.path.join(test_dir, 'vasprun.xml'))
        eigenvalues = v.eigenvalues.copy()
        kptweights = v.actual_kpoints_weights
        potalign = 0.
        vbm = v.eigenvalue_band_properties[2]
        cbm = v.eigenvalue_band_properties[1]
        params = {
            'eigenvalues': eigenvalues,
            'kpoint_weights': kptweights,
            'potalign': potalign,
            'vbm': vbm,
            'cbm': cbm
        }
        bfc = BandFillingCorrection()
        struc = PymatgenTest.get_structure("VO2")
        struc.make_supercell(3)
        vac = Vacancy(struc, struc.sites[0], charge=-3)

        #test trivial performing bandfilling correction
        bf_corr = bfc.perform_bandfill_corr(eigenvalues, kptweights, potalign,
                                            vbm, cbm)
        self.assertAlmostEqual(bf_corr, 0.)
        self.assertFalse(bfc.metadata['occupied_def_levels'])
        self.assertFalse(bfc.metadata['unoccupied_def_levels'])
        self.assertFalse(bfc.metadata['total_occupation_defect_levels'])
        self.assertFalse(bfc.metadata['num_elec_cbm'])
        self.assertFalse(bfc.metadata['num_hole_vbm'])
        self.assertFalse(bfc.metadata['potalign'])

        #test trivial full entry bandfill evaluation
        de = DefectEntry(vac,
                         0.,
                         corrections={},
                         parameters=params,
                         entry_id=None)

        corr = bfc.get_correction(de)
        self.assertAlmostEqual(corr['bandfilling'], 0.)

        #modify the eigenvalue list to have free holes
        hole_eigenvalues = {}
        for spinkey, spinset in eigenvalues.items():
            hole_eigenvalues[spinkey] = []
            for kptset in spinset:
                hole_eigenvalues[spinkey].append([])
                for eig in kptset:
                    if (eig[0] < vbm) and (eig[0] > vbm - .8):
                        hole_eigenvalues[spinkey][-1].append([eig[0], 0.5])
                    else:
                        hole_eigenvalues[spinkey][-1].append(eig)

        hole_bf_corr = bfc.perform_bandfill_corr(hole_eigenvalues, kptweights,
                                                 potalign, vbm, cbm)
        self.assertAlmostEqual(hole_bf_corr, -0.41138336)
        self.assertAlmostEqual(bfc.metadata['num_hole_vbm'], 0.8125000649)
        self.assertFalse(bfc.metadata['num_elec_cbm'])

        #modify the eigenvalue list to have free electrons
        elec_eigenvalues = {}
        for spinkey, spinset in eigenvalues.items():
            elec_eigenvalues[spinkey] = []
            for kptset in spinset:
                elec_eigenvalues[spinkey].append([])
                for eig in kptset:
                    if (eig[0] > cbm) and (eig[0] < cbm + .2):
                        elec_eigenvalues[spinkey][-1].append([eig[0], 0.5])
                    else:
                        elec_eigenvalues[spinkey][-1].append(eig)

        elec_bf_corr = bfc.perform_bandfill_corr(elec_eigenvalues, kptweights,
                                                 potalign, vbm, cbm)
        self.assertAlmostEqual(elec_bf_corr, -0.0903187572254)
        self.assertAlmostEqual(bfc.metadata['num_elec_cbm'], 0.8541667349)
        self.assertFalse(bfc.metadata['num_hole_vbm'])

        #modify the potalignment and introduce new occupied defect levels from vbm states
        potalign = -0.1

        bf_corr = bfc.perform_bandfill_corr(eigenvalues, kptweights, potalign,
                                            vbm, cbm)
        self.assertAlmostEqual(bfc.metadata['num_hole_vbm'], 0.)
        self.assertAlmostEqual(bf_corr, 0.)
        occu = [[1.457, 0.0833333], [1.5204, 0.0833333], [1.53465, 0.0833333],
                [1.5498, 0.0416667]]
        self.assertArrayAlmostEqual(
            list(
                sorted(bfc.metadata['occupied_def_levels'],
                       key=lambda x: x[0])),
            list(sorted(occu, key=lambda x: x[0])))
        self.assertAlmostEqual(bfc.metadata['total_occupation_defect_levels'],
                               0.29166669)
        self.assertFalse(bfc.metadata['unoccupied_def_levels'])
Exemplo n.º 8
0
    def test_bandfilling(self):
        v = Vasprun(os.path.join(test_dir, 'vasprun.xml'))
        eigenvalues = v.eigenvalues.copy()
        kptweights = v.actual_kpoints_weights
        potalign = 0.
        vbm = v.eigenvalue_band_properties[2]
        cbm = v.eigenvalue_band_properties[1]
        params = {
            'eigenvalues': eigenvalues,
            'kpoint_weights': kptweights,
            'potalign': potalign,
            'vbm': vbm,
            'cbm': cbm
        }
        bfc = BandFillingCorrection()
        struc = PymatgenTest.get_structure("VO2")
        struc.make_supercell(3)
        vac = Vacancy(struc, struc.sites[0], charge=-3)

        #test trivial performing bandfilling correction
        bf_corr = bfc.perform_bandfill_corr(eigenvalues, kptweights, potalign, vbm, cbm)
        self.assertAlmostEqual(bf_corr, 0.)
        self.assertFalse(bfc.metadata['num_elec_cbm'])
        self.assertFalse(bfc.metadata['num_hole_vbm'])
        self.assertFalse(bfc.metadata['potalign'])

        #test trivial full entry bandfill evaluation
        de = DefectEntry(vac, 0., corrections={}, parameters=params, entry_id=None)

        corr = bfc.get_correction(de)
        self.assertAlmostEqual(corr['bandfilling_correction'], 0.)

        #modify the eigenvalue list to have free holes
        hole_eigenvalues = {}
        for spinkey, spinset in eigenvalues.items():
            hole_eigenvalues[spinkey] = []
            for kptset in spinset:
                hole_eigenvalues[spinkey].append([])
                for eig in kptset:
                    if (eig[0] < vbm) and (eig[0] > vbm - .8):
                        hole_eigenvalues[spinkey][-1].append([eig[0], 0.5])
                    else:
                        hole_eigenvalues[spinkey][-1].append(eig)

        hole_bf_corr = bfc.perform_bandfill_corr(hole_eigenvalues, kptweights, potalign, vbm, cbm)
        self.assertAlmostEqual(hole_bf_corr, -0.41138336)
        self.assertAlmostEqual(bfc.metadata['num_hole_vbm'], 0.8125000649)
        self.assertFalse(bfc.metadata['num_elec_cbm'])

        #test case with only one spin and eigen-occupations are 1.
        one_spin_eigen = hole_eigenvalues.copy()
        del one_spin_eigen[list(eigenvalues.keys())[0]]
        bf_corr = bfc.perform_bandfill_corr(one_spin_eigen, kptweights, potalign, vbm, cbm)
        self.assertAlmostEqual(bf_corr, -0.14487501159000005)

        #test case with only one spin and eigen-occupations are 2.
        one_spin_eigen_twooccu = one_spin_eigen.copy()
        for kptset in one_spin_eigen_twooccu.values():
            for bandset in kptset:
                for occuset in bandset:
                    if occuset[1] == 1.:
                        occuset[1] = 2.
                    elif occuset[1] == .5:
                        occuset[1] = 1.
        bf_corr = bfc.perform_bandfill_corr(one_spin_eigen_twooccu, kptweights, potalign, vbm, cbm)
        self.assertAlmostEqual(bf_corr, -0.14487501159000005)