Skip to content

Commit b5e4536

Browse files
Added tests, made DOS splitting possible from QE out files as well
1 parent 3571c7b commit b5e4536

File tree

3 files changed

+133
-10
lines changed

3 files changed

+133
-10
lines changed

mala/targets/dos.py

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,15 @@ def feature_size(self):
206206
if isinstance(self.parameters.ldos_gridsize, int):
207207
return self.parameters.ldos_gridsize
208208
elif isinstance(self.parameters.ldos_gridsize, list):
209-
return np.sum(self.parameters.ldos_gridsize)
209+
# For splits, we sum up the individual grid sizes, BUT we
210+
# have to subtract one for each split, as the last energy
211+
# of each section gets discarded. So for three sections,
212+
# we have to subtract 2.
213+
return (
214+
np.sum(self.parameters.ldos_gridsize)
215+
- len(self.parameters.ldos_gridsize)
216+
+ 1
217+
)
210218

211219
@property
212220
def data_name(self):
@@ -514,17 +522,40 @@ def read_from_qe_out(self, path=None, smearing_factor=2):
514522
"Rerun calculation with verbosity set to 'high'."
515523
)
516524

525+
if isinstance(self.parameters.ldos_gridspacing_ev, list):
526+
grid_spacings = self.parameters.ldos_gridspacing_ev
527+
grid_sizes = self.parameters.ldos_gridsize
528+
else:
529+
grid_spacings = [self.parameters.ldos_gridspacing_ev]
530+
grid_sizes = [self.parameters.ldos_gridsize]
531+
517532
# Get the gaussians for all energy values and calculate the DOS per
518533
# band.
519-
dos_per_band = gaussians(
520-
self.energy_grid,
521-
atoms_object.get_calculator().band_structure().energies[0, :, :],
522-
smearing_factor * self.parameters.ldos_gridspacing_ev,
523-
)
524-
dos_per_band = kweights[:, np.newaxis, np.newaxis] * dos_per_band
534+
dos_data = None
535+
previous_beginning = 0
536+
for spacing_idx, grid_spacing in enumerate(grid_spacings):
537+
size_for_spacing = grid_sizes[spacing_idx] + previous_beginning
538+
if spacing_idx != len(grid_spacings) - 1:
539+
size_for_spacing -= 1
540+
541+
dos_per_band = gaussians(
542+
self.energy_grid[previous_beginning:size_for_spacing],
543+
atoms_object.get_calculator()
544+
.band_structure()
545+
.energies[0, :, :],
546+
smearing_factor * grid_spacing,
547+
)
548+
dos_per_band = kweights[:, np.newaxis, np.newaxis] * dos_per_band
525549

526-
# QE gives the band energies in eV, so no conversion necessary here.
527-
dos_data = np.sum(dos_per_band, axis=(0, 1))
550+
# QE gives the band energies in eV, so no conversion necessary
551+
# here.
552+
if spacing_idx == 0:
553+
dos_data = np.sum(dos_per_band, axis=(0, 1))
554+
else:
555+
dos_data = np.concatenate(
556+
(dos_data, np.sum(dos_per_band, axis=(0, 1)))
557+
)
558+
previous_beginning = size_for_spacing
528559
self.density_of_states = dos_data
529560
return dos_data
530561

mala/targets/ldos.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,15 @@ def feature_size(self):
198198
if isinstance(self.parameters.ldos_gridsize, int):
199199
return self.parameters.ldos_gridsize
200200
elif isinstance(self.parameters.ldos_gridsize, list):
201-
return np.sum(self.parameters.ldos_gridsize)
201+
# For splits, we sum up the individual grid sizes, BUT we
202+
# have to subtract one for each split, as the last energy
203+
# of each section gets discarded. So for three sections,
204+
# we have to subtract 2.
205+
return (
206+
np.sum(self.parameters.ldos_gridsize)
207+
- len(self.parameters.ldos_gridsize)
208+
+ 1
209+
)
202210

203211
@property
204212
def data_name(self):

test/splitting_test.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import os
2+
3+
import numpy as np
4+
5+
import mala
6+
from mala.datahandling.data_repo import data_path
7+
8+
9+
class TestSplitting:
10+
"""
11+
Class that tests that splitted (L)DOS data can be processed
12+
13+
Splitted means along the energy domain.
14+
"""
15+
16+
def test_ldos_splitting(self):
17+
parameters3 = mala.Parameters()
18+
parameters3.targets.ldos_gridsize = [
19+
3,
20+
3,
21+
7,
22+
]
23+
parameters3.targets.ldos_gridoffset_ev = [-5, 0, 5]
24+
parameters3.targets.ldos_gridspacing_ev = [2.5, 2.5, 2.5]
25+
cubes_path = os.path.join(data_path, "cubes")
26+
ldos_calculator3 = mala.LDOS(parameters3)
27+
ldos_calculator3.read_from_cube(
28+
[
29+
os.path.join(cubes_path, "tmp.pp0*Be_part1_ldos.cube"),
30+
os.path.join(cubes_path, "tmp.pp0*Be_part2_ldos.cube"),
31+
os.path.join(cubes_path, "tmp.pp0*Be_part3_ldos.cube"),
32+
]
33+
)
34+
35+
parameters = mala.Parameters()
36+
parameters.targets.ldos_gridsize = 11
37+
parameters.targets.ldos_gridspacing_ev = 2.5
38+
parameters.targets.ldos_gridoffset_ev = -5
39+
ldos_calculator = mala.LDOS(parameters)
40+
ldos_calculator.read_from_cube(
41+
os.path.join(cubes_path, "tmp.pp*Be_ldos.cube")
42+
)
43+
44+
print(
45+
np.mean(
46+
np.abs(
47+
ldos_calculator3.local_density_of_states
48+
- ldos_calculator.local_density_of_states
49+
)
50+
)
51+
)
52+
53+
def test_dos_splitting(self):
54+
parameters3 = mala.Parameters()
55+
parameters3.targets.ldos_gridsize = [
56+
3,
57+
3,
58+
7,
59+
]
60+
parameters3.targets.ldos_gridoffset_ev = [-5, 0, 5]
61+
parameters3.targets.ldos_gridspacing_ev = [2.5, 2.5, 2.5]
62+
cubes_path = os.path.join(data_path, "cubes")
63+
dos_calculator3 = mala.DOS(parameters3)
64+
dos_calculator3.read_from_qe_out(
65+
os.path.join(data_path, "Be_snapshot1.out")
66+
)
67+
68+
parameters = mala.Parameters()
69+
parameters.targets.ldos_gridsize = 11
70+
parameters.targets.ldos_gridspacing_ev = 2.5
71+
parameters.targets.ldos_gridoffset_ev = -5
72+
dos_calculator = mala.DOS(parameters)
73+
dos_calculator.read_from_qe_out(
74+
os.path.join(data_path, "Be_snapshot1.out")
75+
)
76+
77+
print(
78+
np.mean(
79+
np.abs(
80+
dos_calculator3.density_of_states
81+
- dos_calculator.density_of_states
82+
)
83+
)
84+
)

0 commit comments

Comments
 (0)