Coverage for gpaw/test/utilities/test_ldos.py: 100%
66 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-20 00:19 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-20 00:19 +0000
1import numpy as np
2from ase import Atom, Atoms
4import gpaw.mpi as mpi
5from gpaw import GPAW, FermiDirac, PoissonSolver
6import pytest
7from gpaw.utilities.dos import RawLDOS, raw_orbital_LDOS, raw_wignerseitz_LDOS
10def test_utilities_ldos(in_tmp_dir, gpaw_new):
11 comms = [mpi.world.new_communicator(np.array([r]))
12 for r in range(mpi.size)]
13 comm = comms[mpi.rank]
15 Hnospin = Atoms([Atom('H')], cell=[5, 5, 5], pbc=False)
16 Hspin = Atoms([Atom('H', magmom=1)], cell=[5, 5, 5], pbc=False)
17 LiH = Atoms([Atom('Li', [.0, .0, .41]),
18 Atom('H', [.0, .0, -1.23])])
19 Hnospin.center()
20 Hspin.center()
21 LiH.center(vacuum=3.0)
23 # This is needed for the Wigner-Seitz test to give
24 # architecture-independent results:
25 LiH.translate(0.003234)
27 calc = GPAW(mode='fd', gpts=(24, 24, 24), communicator=comm)
28 Hnospin.calc = calc
29 e_Hnospin = Hnospin.get_potential_energy()
30 energies, sweight = raw_orbital_LDOS(calc, a=0, spin=0, angular='s')
31 energies, pdfweight = raw_orbital_LDOS(calc, a=0, spin=0, angular='pdf')
33 calc = GPAW(mode='fd',
34 gpts=(24, 24, 24),
35 occupations=FermiDirac(width=0, fixmagmom=True),
36 poissonsolver=PoissonSolver('fd'),
37 hund=True,
38 communicator=comm)
39 Hspin.calc = calc
40 e_Hspin = Hspin.get_potential_energy()
41 energies, sweight_spin = raw_orbital_LDOS(calc, a=0, spin=0, angular='s')
43 calc = GPAW(mode='fd', gpts=(32, 32, 40), nbands=2,
44 poissonsolver=PoissonSolver('fd'),
45 communicator=comm)
46 LiH.calc = calc
47 e_LiH = LiH.get_potential_energy()
48 energies, Li_orbitalweight = raw_orbital_LDOS(calc, a=0, spin=0,
49 angular=None)
50 energies, H_orbitalweight = raw_orbital_LDOS(calc, a=1, spin=0,
51 angular=None)
52 energies, Li_wzweight = raw_wignerseitz_LDOS(calc, a=0, spin=0)
53 energies, H_wzweight = raw_wignerseitz_LDOS(calc, a=1, spin=0)
55 if not gpaw_new:
56 n_a = calc.get_wigner_seitz_densities(spin=0)
57 print(n_a)
58 assert n_a.sum() == pytest.approx(0.0, abs=1e-5)
59 assert n_a[1] == pytest.approx(0.737, abs=0.001)
61 print(sweight, pdfweight)
62 print(sweight_spin)
63 print(Li_wzweight)
64 print(H_wzweight)
66 assert sweight[0] == pytest.approx(1.0, abs=0.06)
67 assert pdfweight[0] == pytest.approx(0.0, abs=0.0001)
68 assert sweight_spin[0] == pytest.approx(1.14, abs=0.06)
69 assert ((Li_wzweight - [.13, 0.93]).round(2) == 0).all()
70 assert ((H_wzweight - [0.87, 0.07]).round(2) == 0).all()
71 assert ((Li_wzweight + H_wzweight).round(5) == 1).all()
73 print(Li_orbitalweight)
74 print(H_orbitalweight)
75 # HOMO s py pz px *s
76 Li_orbitalweight[0] -= [.5, .0, .6, .0, .0]
77 H_orbitalweight[0] -= [.7, .0, .0, .0, .0]
79 # LUMO s py pz px *s
80 Li_orbitalweight[1] -= [1.0, .0, 0.9, .0, .0]
81 H_orbitalweight[1] -= [0.1, .0, 0.0, .0, .0]
83 assert not Li_orbitalweight.round(1).any()
84 assert not H_orbitalweight.round(1).any()
86 ldos = RawLDOS(calc)
87 fname = 'ldbe'
88 ldos.by_element_to_file(fname + '.dat', shift=False)
89 ldos.by_element_to_file(fname + '_2.0.dat', 2.0, shift=False)
90 ldos.by_element_to_file(fname + '_indx0.dat', indices=[0])
91 # the hydrogen entries are missing for index 0 only
92 if mpi.world.rank == 0:
93 assert (np.loadtxt(fname + '_indx0.dat').shape[1] + 3 ==
94 np.loadtxt(fname + '.dat').shape[1])
96 energy_tolerance = 0.001
97 assert e_Hnospin == pytest.approx(0.153991, abs=energy_tolerance)
98 assert e_Hspin == pytest.approx(-0.782309, abs=energy_tolerance)
99 assert e_LiH == pytest.approx(-3.74582, abs=energy_tolerance)