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
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
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
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
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)
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'])
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'])
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)