Coverage for gpaw/test/pw/test_expert_diag.py: 98%
44 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-09 00:21 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-09 00:21 +0000
1import pytest
2import numpy as np
3from ase.build import bulk
5from gpaw import GPAW, PW
6from gpaw.mpi import world
8# This test is asserting that the expert diagonalization
9# routine gives the same result as the non-expert version
10# in terms of eigenvalues and wavefunctions
13def test_pw_expert_diag(in_tmp_dir, scalapack):
14 wfs_e = []
15 for i, nbands in enumerate([None, 48]):
16 si = bulk('Si')
17 name = f'si_{i}'
18 si.center()
19 calc = GPAW(mode=PW(120), kpts=(1, 1, 2),
20 eigensolver='rmm-diis',
21 parallel={'domain': 1},
22 symmetry='off', txt=name + '.txt')
23 si.calc = calc
24 si.get_potential_energy()
25 calc.diagonalize_full_hamiltonian(nbands=nbands)
26 string = name + '.gpw'
27 calc.write(string, 'all')
28 wfs_e.append(calc.wfs)
30 # Test against values from reference revision
31 epsn_n = np.array([-0.21072488, 0.05651796,
32 0.17629109, 0.17629122,
33 0.26459912])
34 wfsold_G = np.array([7.52087176, 54.64580691,
35 -3.813492786, -0.14781141,
36 -0.64662074])
38 kpt_u = wfs_e[0].kpt_u
39 for kpt in kpt_u:
40 if kpt.k == 0:
41 psit = kpt.psit_nG[1, 0:5].copy()
42 if wfsold_G[0] * psit[0] < 0:
43 psit *= -1.
44 if world.rank == 0:
45 assert np.allclose(epsn_n, kpt.eps_n[0:5], atol=1e-4), \
46 'Eigenvalues have changed'
47 assert np.allclose(wfsold_G, psit, atol=5e-3), \
48 'Wavefunctions have changed'
50 wfstmp, wfs = wfs_e
51 for kpt, kpttmp in zip(wfs.kpt_u, wfstmp.kpt_u):
52 if wfs.bd.comm.rank == 0:
53 for m, (psi_G, eps) in enumerate(zip(kpt.psit_nG, kpt.eps_n)):
54 # Have to do like this if bands are degenerate
55 booleanarray = np.abs(kpttmp.eps_n - eps) < 1e-10
56 inds = np.argwhere(booleanarray)
57 count = len(inds)
58 assert count > 0, 'Difference between eigenvalues!'
60 psitmp_nG = kpttmp.psit_nG[inds][:, 0, :]
61 fidelity = 0
62 for psitmp_G in psitmp_nG:
63 fidelity += (
64 np.abs(np.dot(psitmp_G.conj(), psi_G))**2 /
65 np.dot(psitmp_G.conj(), psitmp_G) /
66 np.dot(psi_G.conj(), psi_G))
68 assert fidelity == pytest.approx(1, abs=1e-10)
71if __name__ == '__main__':
72 test_pw_expert_diag(1, 1)