Coverage for gpaw/test/xc/test_lb94.py: 100%
73 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
2from ase import Atoms
3from gpaw.mpi import world
4from gpaw import GPAW, FermiDirac, Mixer, MixerSum, Davidson
5from gpaw.atom.all_electron import AllElectron
6from gpaw.atom.generator import Generator
7from gpaw.atom.configurations import parameters
10@pytest.mark.slow
11def test_xc_lb94(in_tmp_dir, add_cwd_to_setup_paths):
12 ref1 = 'R. v. Leeuwen PhysRevA 49, 2421 (1994)'
13 ref2 = 'Gritsenko IntJQuanChem 76, 407 (2000)'
14 # HOMO energy in mHa for closed shell atoms
15 e_HOMO_cs = {'He': 851, 'Be': 321, 'Ne': 788,
16 'Ar': 577, 'Kr': 529, 'Xe': 474,
17 'Mg': 281 + 8}
19 txt = None
21 print('--- Comparing LB94 with', ref1)
22 print('and', ref2)
24 print('**** all electron calculations')
25 print('atom [refs] -e_homo diff all in mHa')
26 if world.rank == 0:
27 for atom in e_HOMO_cs.keys():
28 ae = AllElectron(atom, 'LB94', txt=txt)
29 ae.run()
30 e_homo = int(ae.e_j[-1] * 10000 + .5) / 10.
31 diff = e_HOMO_cs[atom] + e_homo
32 print('%2s %8g %6.1f %4.1g' %
33 (atom, e_HOMO_cs[atom], -e_homo, diff))
34 assert abs(diff) < 6
35 world.barrier()
37 setups = {}
39 print('**** 3D calculations')
40 print('atom [refs] -e_homo diff all in mHa')
42 for atom in sorted(e_HOMO_cs):
43 e_ref = e_HOMO_cs[atom]
44 # generate setup for the atom
45 if world.rank == 0 and atom not in setups:
46 g = Generator(atom, 'LB94', nofiles=True, txt=txt)
47 g.run(**parameters[atom])
48 setups[atom] = 1
49 world.barrier()
51 SS = Atoms(atom, cell=(7, 7, 7), pbc=False)
52 SS.center()
53 c = GPAW(mode='fd', h=.3, xc='LB94',
54 eigensolver=Davidson(3),
55 mixer=Mixer(0.5, 7, 50.0), nbands=-2, txt=txt)
56 c.calculate(SS)
57 # find HOMO energy
58 eps_n = c.get_eigenvalues(kpt=0, spin=0) / 27.211
59 f_n = c.get_occupation_numbers(kpt=0, spin=0)
60 for e, f in zip(eps_n, f_n):
61 if f < 0.99:
62 break
63 e_homo = e
64 e_homo = int(e_homo * 10000 + .5) / 10.
65 diff = e_ref + e_homo
66 print('%2s %8g %6.1f %4.1f' % (atom, e_ref, -e_homo, diff))
67 assert abs(diff) < 7
69 # HOMO energy in mHa and magn. mom. for open shell atoms
70 e_HOMO_os = {'He': [851, 0], # added for cross check
71 'H': [440, 1],
72 'N': [534 - 23, 3],
73 'Na': [189 + 17, 1],
74 'P': [385 - 16, 3]}
76 for atom in sorted(e_HOMO_os):
77 e_ref = e_HOMO_os[atom][0]
78 magmom = e_HOMO_os[atom][1]
79 # generate setup for the atom
80 if world.rank == 0 and atom not in setups:
81 g = Generator(atom, 'LB94', nofiles=True, txt=txt)
82 g.run(**parameters[atom])
83 setups[atom] = 1
84 world.barrier()
86 SS = Atoms(atom, magmoms=[magmom], cell=(7, 7, 7), pbc=False)
87 SS.center()
88 # fine grid needed for convergence!
89 c = GPAW(mode='fd',
90 h=0.2,
91 xc='LB94',
92 nbands=-2,
93 spinpol=True,
94 hund=True,
95 eigensolver=Davidson(3),
96 mixer=MixerSum(0.5, 7, 50.0),
97 occupations=FermiDirac(0.0, fixmagmom=True),
98 txt=txt)
99 c.calculate(SS)
100 # find HOMO energy
101 eps_n = c.get_eigenvalues(kpt=0, spin=0) / 27.211
102 f_n = c.get_occupation_numbers(kpt=0, spin=0)
103 for e, f in zip(eps_n, f_n):
104 if f < 0.99:
105 break
106 e_homo = e
107 e_homo = int(e_homo * 10000 + .5) / 10.
108 diff = e_ref + e_homo
109 print('%2s %8g %6.1f %4.1f' % (atom, e_ref, -e_homo, diff))
110 assert abs(diff) < 15