Coverage for gpaw/test/pseudopotential/test_hgh_h2o.py: 74%
57 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-14 00:18 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-14 00:18 +0000
1"""Test of HGH pseudopotential implementation.
2This is the canonical makes-sure-nothing-breaks test, which checks that the
3numbers do not change from whatever they were before.
5The test runs an HGH calculation on a misconfigured H2O molecule, such that
6the forces are nonzero.
8Energy is compared to a previous calculation; if it differs significantly,
9that is considered an error.
11Forces are compared to a previous finite-difference result.
12"""
15import numpy as np
16from ase.build import molecule
18from gpaw import GPAW, PoissonSolver
19import pytest
22def test_pseudopotential_hgh_h2o():
23 mol = molecule('H2O')
24 mol.rattle(0.2)
25 mol.center(vacuum=2.0)
26 calc = GPAW(mode='fd',
27 nbands=6,
28 poissonsolver=PoissonSolver('fd'),
29 gpts=(32, 40, 40),
30 setups='hgh',
31 convergence=dict(eigenstates=1e-9,
32 density=1e-5,
33 energy=0.3e-5),
34 txt='-')
35 mol.calc = calc
36 e = mol.get_potential_energy()
37 F_ac = mol.get_forces()
39 F_ac_ref = np.array([[7.33077718, 3.81069249, -6.07405156],
40 [-0.9079617, -1.18203514, 3.43777589],
41 [-0.61642527, -0.41889306, 2.332415]])
43 eref = -468.527121304
45 eerr = abs(e - eref)
47 print('energy', e)
48 print('ref energy', eref)
49 print('energy error', eerr)
51 print('forces')
52 print(F_ac)
54 print('ref forces')
55 print(F_ac_ref)
57 ferr = np.abs(F_ac - F_ac_ref).max()
58 print('max force error', ferr)
60 fdcheck = False
62 if fdcheck:
63 from gpaw.test import calculate_numerical_forces
64 F_ac_fd = calculate_numerical_forces(mol)
66 print('Self-consistent forces')
67 print(F_ac)
68 print('FD forces')
69 print(F_ac_fd)
70 print()
71 print(repr(F_ac_fd))
72 print()
73 err = np.abs(F_ac - F_ac_fd).max()
74 print('max err', err)
76 wfs = calc.wfs
77 gd = wfs.gd
78 psit_nG = wfs.kpt_u[0].psit_nG
79 try:
80 dH_asp = calc.hamiltonian.dH_asp
81 except AttributeError:
82 from gpaw.utilities import pack_hermitian
83 dH_asii = calc.dft.potential.dH_asii
84 dH_asp = {a: pack_hermitian(dH_sii) for a, dH_sii in dH_asii.items()}
86 assert eerr < 1e-3, 'energy changed from reference'
87 assert ferr < 0.015, 'forces do not match FD check'
89 # Sanity check. In HGH, the atomic Hamiltonian is constant.
90 # Also the projectors should be normalized
91 for a, dH_sp in dH_asp.items():
92 dH_p = dH_sp[0]
93 K_p = wfs.setups[a].K_p
94 # B_ii = wfs.setups[a].B_ii
95 # assert np.abs(B_ii.diagonal() - 1).max() < 1e-3
96 # print 'B_ii'
97 # print wfs.setups[a].B_ii
98 # Actually, H2O might not be such a good test, since there'll only
99 # be one element in the atomic Hamiltonian for O and zero for H.
100 # print 'dH_p', dH_p
101 # print 'K_p', K_p
103 assert np.abs(dH_p - K_p).max() < 1e-10, 'atomic Hamiltonian changed'
105 # h_ii = setup.data.h_ii
106 # print 'h_ii', h_ii
107 # print 'dH_ii', dH_ii
109 # Sanity check: HGH is normconserving
110 for psit_G in psit_nG:
111 norm = gd.integrate(psit_G**2) # around 1e-15 ! Surprisingly good.
112 assert abs(1 - norm) < 1e-10, 'Not normconserving'
114 energy_tolerance = 0.0003
115 assert e == pytest.approx(eref, abs=energy_tolerance)