Skip to content

Commit 300a33e

Browse files
Fix DOS parsing for SOC calculations (#4239)
* Add informative error message to SymmetryUndeterminedError * Add debug message for DOS parsing * Fix `vasprun.xml` DOS parsing for SOC calculations * Add test for `vasprun.xml` DOS parsing for SOC calculations * pre-commit auto-fixes * Typing fix --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent da607e8 commit 300a33e

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

src/pymatgen/io/vasp/outputs.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,10 +1631,13 @@ def _parse_dos(elem: XML_Element) -> tuple[Dos, Dos, list[dict]]:
16311631
tdensities = {}
16321632
idensities = {}
16331633

1634+
soc_run = len(elem.find("total").find("array").find("set").findall("set")) > 2 # type: ignore[union-attr]
16341635
for s in elem.find("total").find("array").find("set").findall("set"): # type: ignore[union-attr]
16351636
data = np.array(_parse_vasp_array(s))
16361637
energies = data[:, 0]
16371638
spin = Spin.up if s.attrib["comment"] == "spin 1" else Spin.down
1639+
if spin != Spin.up and soc_run: # other 'spins' are x,y,z SOC projections
1640+
continue
16381641
tdensities[spin] = data[:, 1]
16391642
idensities[spin] = data[:, 2]
16401643

@@ -1649,6 +1652,8 @@ def _parse_dos(elem: XML_Element) -> tuple[Dos, Dos, list[dict]]:
16491652

16501653
for ss in s.findall("set"):
16511654
spin = Spin.up if ss.attrib["comment"] == "spin 1" else Spin.down
1655+
if spin != Spin.up and soc_run: # other 'spins' are x,y,z SOC projections
1656+
continue
16521657
data = np.array(_parse_vasp_array(ss))
16531658
_n_row, n_col = data.shape
16541659
for col_idx in range(1, n_col):

tests/io/vasp/test_outputs.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@
5454

5555

5656
class TestVasprun(PymatgenTest):
57+
def test_vasprun_soc(self):
58+
# Test that SOC vaspruns are parsed appropriately, giving just Spin.Up tdos, idos and pdos
59+
vasp_run = Vasprun(f"{VASP_OUT_DIR}/vasprun.int_Te_SOC.xml.gz")
60+
dos_density_dicts_to_check = [vasp_run.complete_dos.densities, vasp_run.tdos.densities, vasp_run.idos.densities]
61+
dos_density_dicts_to_check += [
62+
densities for orbital_dict in vasp_run.complete_dos.pdos.values() for densities in orbital_dict.values()
63+
]
64+
for i, dos_density_dict in enumerate(dos_density_dicts_to_check):
65+
assert set(dos_density_dict.keys()) == {Spin.up}, f"Failed spin keys check for {i}th dos obj!"
66+
67+
assert vasp_run.complete_dos.spin_polarization is None
68+
5769
def test_vasprun_ml(self):
5870
# Test for ML MD simulation
5971
# The trajectory data is stored in md_data
@@ -79,7 +91,6 @@ def test_vasprun_md(self):
7991
def test_vasprun_ediffg_set_to_0(self):
8092
# Test for case where EDIFFG is set to 0. This should pass if all ionic steps
8193
# complete and are electronically converged.
82-
print(list(os.walk(VASP_OUT_DIR)))
8394
vasp_run = Vasprun(f"{VASP_OUT_DIR}/vasprun.ediffg_set_to_0.xml.gz")
8495
assert len(vasp_run.ionic_steps) == 3
8596
assert vasp_run.final_energy == approx(-34.60164204)

0 commit comments

Comments
 (0)