Skip to content

Commit

Permalink
Fix DOS parsing for SOC calculations (#4239)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
kavanase and pre-commit-ci[bot] authored Dec 31, 2024
1 parent da607e8 commit 300a33e
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/pymatgen/io/vasp/outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1631,10 +1631,13 @@ def _parse_dos(elem: XML_Element) -> tuple[Dos, Dos, list[dict]]:
tdensities = {}
idensities = {}

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

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

for ss in s.findall("set"):
spin = Spin.up if ss.attrib["comment"] == "spin 1" else Spin.down
if spin != Spin.up and soc_run: # other 'spins' are x,y,z SOC projections
continue
data = np.array(_parse_vasp_array(ss))
_n_row, n_col = data.shape
for col_idx in range(1, n_col):
Expand Down
13 changes: 12 additions & 1 deletion tests/io/vasp/test_outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@


class TestVasprun(PymatgenTest):
def test_vasprun_soc(self):
# Test that SOC vaspruns are parsed appropriately, giving just Spin.Up tdos, idos and pdos
vasp_run = Vasprun(f"{VASP_OUT_DIR}/vasprun.int_Te_SOC.xml.gz")
dos_density_dicts_to_check = [vasp_run.complete_dos.densities, vasp_run.tdos.densities, vasp_run.idos.densities]
dos_density_dicts_to_check += [
densities for orbital_dict in vasp_run.complete_dos.pdos.values() for densities in orbital_dict.values()
]
for i, dos_density_dict in enumerate(dos_density_dicts_to_check):
assert set(dos_density_dict.keys()) == {Spin.up}, f"Failed spin keys check for {i}th dos obj!"

assert vasp_run.complete_dos.spin_polarization is None

def test_vasprun_ml(self):
# Test for ML MD simulation
# The trajectory data is stored in md_data
Expand All @@ -79,7 +91,6 @@ def test_vasprun_md(self):
def test_vasprun_ediffg_set_to_0(self):
# Test for case where EDIFFG is set to 0. This should pass if all ionic steps
# complete and are electronically converged.
print(list(os.walk(VASP_OUT_DIR)))
vasp_run = Vasprun(f"{VASP_OUT_DIR}/vasprun.ediffg_set_to_0.xml.gz")
assert len(vasp_run.ionic_steps) == 3
assert vasp_run.final_energy == approx(-34.60164204)
Expand Down

0 comments on commit 300a33e

Please sign in to comment.