diff --git a/pymatgen/analysis/defects/corrections.py b/pymatgen/analysis/defects/corrections.py index 8497490f7a7..08d8a1415fb 100644 --- a/pymatgen/analysis/defects/corrections.py +++ b/pymatgen/analysis/defects/corrections.py @@ -828,6 +828,11 @@ def get_correction(self, entry): VBM of bulk calculation (or band structure calculation of bulk); calculated on same level of theory as the defect (ex. GGA defects -> requires GGA vbm) + + run_metadata["defect_incar"] (dict) + Dictionary of INCAR settings for the defect calculation, + required to check if the calculation included spin-orbit coupling + (to determine the spin factor for occupancies of the electron bands) Returns: Bandfilling Correction value as a dictionary @@ -837,14 +842,15 @@ def get_correction(self, entry): potalign = entry.parameters["potalign"] vbm = entry.parameters["vbm"] cbm = entry.parameters["cbm"] + soc_calc = entry.parameters["run_metadata"]["defect_incar"].get("LSORBIT") - bf_corr = self.perform_bandfill_corr(eigenvalues, kpoint_weights, potalign, vbm, cbm) + bf_corr = self.perform_bandfill_corr(eigenvalues, kpoint_weights, potalign, vbm, cbm, soc_calc) entry.parameters["bandfilling_meta"] = dict(self.metadata) return {"bandfilling_correction": bf_corr} - def perform_bandfill_corr(self, eigenvalues, kpoint_weights, potalign, vbm, cbm): + def perform_bandfill_corr(self, eigenvalues, kpoint_weights, potalign, vbm, cbm, soc_calc=False): """ This calculates the band filling correction based on excess of electrons/holes in CB/VB... @@ -861,15 +867,15 @@ def perform_bandfill_corr(self, eigenvalues, kpoint_weights, potalign, vbm, cbm) core_occupation_value = list(eigenvalues.values())[0][0][0][1] # get occupation of a core eigenvalue if len(eigenvalues.keys()) == 1: # needed because occupation of non-spin calcs is sometimes still 1... should be 2 - spinfctr = 2.0 if core_occupation_value == 1.0 else 1.0 + spinfctr = 2.0 if core_occupation_value == 1.0 and not soc_calc else 1.0 elif len(eigenvalues.keys()) == 2: spinfctr = 1.0 else: raise ValueError("Eigenvalue keys greater than 2") # for tracking mid gap states... - shifted_cbm = potalign + cbm # shift cbm with potential alignment - shifted_vbm = potalign + vbm # shift vbm with potential alignment + shifted_cbm = cbm - potalign # shift cbm with potential alignment + shifted_vbm = vbm - potalign # shift vbm with potential alignment for spinset in eigenvalues.values(): for kptset, weight in zip(spinset, kpoint_weights): diff --git a/pymatgen/analysis/defects/defect_compatibility.py b/pymatgen/analysis/defects/defect_compatibility.py index 843966e5f60..f0e39988862 100644 --- a/pymatgen/analysis/defects/defect_compatibility.py +++ b/pymatgen/analysis/defects/defect_compatibility.py @@ -43,7 +43,7 @@ class DefectCompatibility(MSONable): "initial_defect_structure", "defect_frac_sc_coords"] kumagai: [ "dielectric", "bulk_atomic_site_averages", "defect_atomic_site_averages", "site_matching_indices", "initial_defect_structure", "defect_frac_sc_coords"] - bandfilling: ["eigenvalues", "kpoint_weights", "potalign", "vbm", "cbm"] + bandfilling: ["eigenvalues", "kpoint_weights", "potalign", "vbm", "cbm", "run_metadata"] bandshifting: ["hybrid_cbm", "hybrid_vbm", "vbm", "cbm"] defect relaxation/structure analysis: ["final_defect_structure", "initial_defect_structure", "sampling_radius", "defect_frac_sc_coords"] @@ -287,6 +287,7 @@ def perform_all_corrections(self, defect_entry): "potalign", "vbm", "cbm", + "run_metadata", ] run_bandfilling = len(set(defect_entry.parameters.keys()).intersection(required_bandfilling_params)) == len( required_bandfilling_params diff --git a/pymatgen/analysis/defects/tests/test_corrections.py b/pymatgen/analysis/defects/tests/test_corrections.py index 735319a4ede..ae7bd84594c 100644 --- a/pymatgen/analysis/defects/tests/test_corrections.py +++ b/pymatgen/analysis/defects/tests/test_corrections.py @@ -212,12 +212,14 @@ def test_bandfilling(self): potalign = 0.0 vbm = v.eigenvalue_band_properties[2] cbm = v.eigenvalue_band_properties[1] + defect_incar = v.incar params = { "eigenvalues": eigenvalues, "kpoint_weights": kptweights, "potalign": potalign, "vbm": vbm, "cbm": cbm, + "run_metadata": {"defect_incar": defect_incar}, } bfc = BandFillingCorrection() struc = PymatgenTest.get_structure("VO2") diff --git a/pymatgen/analysis/defects/tests/test_defect_compatibility.py b/pymatgen/analysis/defects/tests/test_defect_compatibility.py index 2b70a61a4fe..be8ffaab8d0 100644 --- a/pymatgen/analysis/defects/tests/test_defect_compatibility.py +++ b/pymatgen/analysis/defects/tests/test_defect_compatibility.py @@ -60,12 +60,14 @@ def setUp(self): potalign = -0.1 vbm = v.eigenvalue_band_properties[2] cbm = v.eigenvalue_band_properties[1] + defect_incar = v.incar self.bandfill_params = { "eigenvalues": eigenvalues, "kpoint_weights": kptweights, "potalign": potalign, "vbm": vbm, "cbm": cbm, + "run_metadata": {"defect_incar": defect_incar}, } self.band_edge_params = { @@ -108,6 +110,13 @@ def test_process_entry(self): self.assertAlmostEqual(dentry.corrections["charge_correction"], 5.44595036) # test over delocalized free carriers which forces skipping charge correction + params = self.bandfill_params.copy() # No Freysoldt metadata + params.update( + { + "hybrid_cbm": params["cbm"] + 0.2, + "hybrid_vbm": params["vbm"] - 0.4, + } + ) # modify the eigenvalue list to have free holes hole_eigenvalues = {} for spinkey, spinset in params["eigenvalues"].items(): @@ -125,7 +134,7 @@ def test_process_entry(self): dc = DefectCompatibility(free_chg_cutoff=0.8) dentry = dc.process_entry(dentry) self.assertAlmostEqual(dentry.corrections["bandedgeshifting_correction"], 1.19999999) - self.assertAlmostEqual(dentry.corrections["bandfilling_correction"], -1.62202400) + self.assertAlmostEqual(dentry.corrections["bandfilling_correction"], -0.492633372744) self.assertAlmostEqual(dentry.corrections["charge_correction"], 0.0) # turn off band filling and band edge shifting diff --git a/test_files/vasprun.xml.int_Te_SOC.gz b/test_files/vasprun.xml.int_Te_SOC.gz new file mode 100644 index 00000000000..313cb738441 Binary files /dev/null and b/test_files/vasprun.xml.int_Te_SOC.gz differ