Skip to content

Commit 4e40e57

Browse files
authored
PhononDos.get_smeared_densities return density unchanged for sigma=0 (#3524)
* PhononDos.get_smeared_densities add special case for 0 Gaussian smearing * remove unnecessary assignment in test_dos.py * test sigma=0 in TestPhononDos.test_get_smeared_densities
1 parent 0caa466 commit 4e40e57

File tree

3 files changed

+52
-44
lines changed

3 files changed

+52
-44
lines changed

pymatgen/phonon/dos.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,14 @@ def get_smeared_densities(self, sigma: float) -> np.ndarray:
3737
std dev sigma applied.
3838
3939
Args:
40-
sigma: Std dev of Gaussian smearing function.
40+
sigma: Std dev of Gaussian smearing function. In units of
41+
THz. Common values are 0.01 - 0.1 THz.
4142
4243
Returns:
43-
Gaussian-smeared densities.
44+
np.array: Gaussian-smeared DOS densities.
4445
"""
46+
if sigma == 0:
47+
return self.densities
4548
diff = [self.frequencies[idx + 1] - self.frequencies[idx] for idx in range(len(self.frequencies) - 1)]
4649
avg_diff = sum(diff) / len(diff)
4750

tests/electronic_structure/test_dos.py

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,21 @@ def setUp(self):
2222
self.dos = CompleteDos.from_dict(json.load(f))
2323

2424
def test_get_gap(self):
25-
dos = self.dos
26-
assert dos.get_gap() == approx(2.0589, abs=1e-4)
27-
assert len(dos.energies) == 301
28-
assert dos.get_interpolated_gap(tol=0.001, abs_tol=False, spin=None)[0] == approx(2.16815942458015, abs=1e-7)
29-
assert dos.get_cbm_vbm() == approx((3.8729, 1.8140000000000001))
30-
31-
assert dos.get_interpolated_value(9.9)[Spin.up] == approx(1.744588888888891, abs=1e-7)
32-
assert dos.get_interpolated_value(9.9)[Spin.down] == approx(1.756888888888886, abs=1e-7)
25+
assert self.dos.get_gap() == approx(2.0589, abs=1e-4)
26+
assert len(self.dos.energies) == 301
27+
assert self.dos.get_interpolated_gap(tol=0.001, abs_tol=False, spin=None)[0] == approx(
28+
2.16815942458015, abs=1e-7
29+
)
30+
assert self.dos.get_cbm_vbm() == approx((3.8729, 1.8140000000000001))
31+
32+
assert self.dos.get_interpolated_value(9.9)[Spin.up] == approx(1.744588888888891, abs=1e-7)
33+
assert self.dos.get_interpolated_value(9.9)[Spin.down] == approx(1.756888888888886, abs=1e-7)
3334
with pytest.raises(ValueError, match="x is out of range of provided x_values"):
34-
dos.get_interpolated_value(1000)
35+
self.dos.get_interpolated_value(1000)
3536

3637
def test_get_smeared_densities(self):
37-
dos = self.dos
38-
smeared = dos.get_smeared_densities(0.2)
39-
dens = dos.densities
38+
smeared = self.dos.get_smeared_densities(0.2)
39+
dens = self.dos.densities
4040
for spin in Spin:
4141
assert sum(dens[spin]) == approx(sum(smeared[spin]))
4242

@@ -106,13 +106,14 @@ def setUp(self):
106106
self.dos_pdag3 = CompleteDos.from_dict(json.load(f))
107107

108108
def test_get_gap(self):
109-
dos = self.dos
110-
assert dos.get_gap() == approx(2.0589, abs=1e-4), "Wrong gap from dos!"
111-
assert len(dos.energies) == 301
112-
assert dos.get_interpolated_gap(tol=0.001, abs_tol=False, spin=None)[0] == approx(2.16815942458015, abs=1e-7)
113-
spd_dos = dos.get_spd_dos()
109+
assert self.dos.get_gap() == approx(2.0589, abs=1e-4), "Wrong gap from dos!"
110+
assert len(self.dos.energies) == 301
111+
assert self.dos.get_interpolated_gap(tol=0.001, abs_tol=False, spin=None)[0] == approx(
112+
2.16815942458015, abs=1e-7
113+
)
114+
spd_dos = self.dos.get_spd_dos()
114115
assert len(spd_dos) == 3
115-
el_dos = dos.get_element_dos()
116+
el_dos = self.dos.get_element_dos()
116117
assert len(el_dos) == 4
117118
sum_spd = spd_dos[OrbitalType.s] + spd_dos[OrbitalType.p] + spd_dos[OrbitalType.d]
118119
sum_element = None
@@ -127,23 +128,23 @@ def test_get_gap(self):
127128
assert (abs(sum_spd.densities[Spin.up] - sum_element.densities[Spin.up]) < 0.0001).all()
128129
assert (abs(sum_spd.densities[Spin.down] - sum_element.densities[Spin.down]) < 0.0001).all()
129130

130-
site = dos.structure[0]
131-
assert dos.get_site_dos(site) is not None
132-
assert sum(dos.get_site_dos(site).get_densities(Spin.up)) == approx(2.0391)
133-
assert sum(dos.get_site_dos(site).get_densities(Spin.down)) == approx(2.0331999999999995)
134-
assert dos.get_site_orbital_dos(site, Orbital.s) is not None
135-
egt2g = dos.get_site_t2g_eg_resolved_dos(site)
131+
site = self.dos.structure[0]
132+
assert self.dos.get_site_dos(site) is not None
133+
assert sum(self.dos.get_site_dos(site).get_densities(Spin.up)) == approx(2.0391)
134+
assert sum(self.dos.get_site_dos(site).get_densities(Spin.down)) == approx(2.0331999999999995)
135+
assert self.dos.get_site_orbital_dos(site, Orbital.s) is not None
136+
egt2g = self.dos.get_site_t2g_eg_resolved_dos(site)
136137
assert sum(egt2g["e_g"].get_densities(Spin.up)) == approx(0.0)
137138
assert sum(egt2g["t2g"].get_densities(Spin.up)) == approx(0.0)
138-
egt2g = dos.get_site_t2g_eg_resolved_dos(dos.structure[4])
139+
egt2g = self.dos.get_site_t2g_eg_resolved_dos(self.dos.structure[4])
139140
assert sum(egt2g["e_g"].get_densities(Spin.up)) == approx(15.004399999999997)
140141
assert sum(egt2g["t2g"].get_densities(Spin.up)) == approx(22.910399999999999)
141-
assert dos.get_cbm_vbm() == approx((3.8729, 1.8140000000000001))
142+
assert self.dos.get_cbm_vbm() == approx((3.8729, 1.8140000000000001))
142143

143-
assert dos.get_interpolated_value(9.9)[Spin.up] == approx(1.744588888888891, abs=1e-7)
144-
assert dos.get_interpolated_value(9.9)[Spin.down] == approx(1.756888888888886, abs=1e-7)
144+
assert self.dos.get_interpolated_value(9.9)[Spin.up] == approx(1.744588888888891, abs=1e-7)
145+
assert self.dos.get_interpolated_value(9.9)[Spin.down] == approx(1.756888888888886, abs=1e-7)
145146
with pytest.raises(ValueError, match="x is out of range of provided x_values"):
146-
dos.get_interpolated_value(1000)
147+
self.dos.get_interpolated_value(1000)
147148

148149
def test_as_from_dict(self):
149150
d = self.dos.as_dict()
@@ -296,24 +297,25 @@ class TestDOS(PymatgenTest):
296297
def setUp(self):
297298
with open(f"{TEST_FILES_DIR}/complete_dos.json") as file:
298299
dct = json.load(file)
299-
y = list(zip(dct["densities"]["1"], dct["densities"]["-1"]))
300-
self.dos = DOS(dct["energies"], y, dct["efermi"])
300+
ys = list(zip(dct["densities"]["1"], dct["densities"]["-1"]))
301+
self.dos = DOS(dct["energies"], ys, dct["efermi"])
301302

302303
def test_get_gap(self):
303-
dos = self.dos
304-
assert dos.get_gap() == approx(2.0589, abs=1e-4)
305-
assert len(dos.x) == 301
306-
assert dos.get_interpolated_gap(tol=0.001, abs_tol=False, spin=None)[0] == approx(2.16815942458015, abs=1e-7)
307-
assert_allclose(dos.get_cbm_vbm(), (3.8729, 1.8140000000000001))
308-
309-
assert dos.get_interpolated_value(9.9)[0] == approx(1.744588888888891, abs=1e-7)
310-
assert dos.get_interpolated_value(9.9)[1] == approx(1.756888888888886, abs=1e-7)
304+
assert self.dos.get_gap() == approx(2.0589, abs=1e-4)
305+
assert len(self.dos.x) == 301
306+
assert self.dos.get_interpolated_gap(tol=0.001, abs_tol=False, spin=None)[0] == approx(
307+
2.16815942458015, abs=1e-7
308+
)
309+
assert_allclose(self.dos.get_cbm_vbm(), (3.8729, 1.8140000000000001))
310+
311+
assert self.dos.get_interpolated_value(9.9)[0] == approx(1.744588888888891, abs=1e-7)
312+
assert self.dos.get_interpolated_value(9.9)[1] == approx(1.756888888888886, abs=1e-7)
311313
with pytest.raises(ValueError, match="x is out of range of provided x_values"):
312-
dos.get_interpolated_value(1000)
314+
self.dos.get_interpolated_value(1000)
313315

314-
assert_allclose(dos.get_cbm_vbm(spin=Spin.up), (3.8729, 1.2992999999999999))
316+
assert_allclose(self.dos.get_cbm_vbm(spin=Spin.up), (3.8729, 1.2992999999999999))
315317

316-
assert_allclose(dos.get_cbm_vbm(spin=Spin.down), (4.645, 1.8140000000000001))
318+
assert_allclose(self.dos.get_cbm_vbm(spin=Spin.down), (4.645, 1.8140000000000001))
317319

318320

319321
class TestSpinPolarization(unittest.TestCase):

tests/phonon/test_dos.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ def test_get_smeared_densities(self):
3939
dens = self.dos.densities
4040
assert sum(dens) == approx(sum(smeared))
4141

42+
# test 0 smearing returns original DOS
43+
assert self.dos.get_smeared_densities(0) is self.dos.densities
44+
4245
def test_dict_methods(self):
4346
json_str = json.dumps(self.dos.as_dict())
4447
assert json_str is not None

0 commit comments

Comments
 (0)