Coverage for gpaw/test/directopt/test_grad_numerically_pw.py: 100%
33 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
1import pytest
2import numpy as np
4from gpaw import GPAW
5from gpaw.directmin.etdm_fdpw import FDPWETDM
6from gpaw.directmin.derivatives import Derivatives
7from gpaw.mom import prepare_mom_calculation
10@pytest.mark.do
11def test_gradient_numerically_pw(in_tmp_dir, gpw_files):
12 """
13 Test analytical vs. numerical gradients exponential
14 transformation in pw
15 :param in_tmp_dir:
16 :return:
17 """
19 tol_between_methods = dict(abs=1.0e-4)
20 tol_between_rngs = dict(abs=1.0e-4)
22 for calc in [
23 GPAW(gpw_files["h3_do_num_pw_complex"]),
24 GPAW(gpw_files["h3_do_num_pw"]),
25 ]:
26 atoms = calc.atoms
27 atoms.calc = calc
28 # Repeated for False
29 atoms.get_potential_energy()
31 calc.set(eigensolver=FDPWETDM(excited_state=True))
32 f_sn = [calc.get_occupation_numbers(spin=s).copy() / 2
33 for s in range(calc.wfs.nspins)]
34 prepare_mom_calculation(calc, atoms, f_sn, use_fixed_occupations=True)
35 atoms.get_potential_energy()
37 ham = calc.hamiltonian
38 wfs = calc.wfs
39 dens = calc.density
41 rngs = [np.random.default_rng(8),
42 np.random.default_rng(123456)]
43 ders = [Derivatives(wfs.eigensolver.outer_iloop,
44 wfs,
45 random_amat=rng,
46 update_c_ref=True)
47 for rng in rngs]
49 iut = np.triu_indices(ders[0].a[0].shape[0], 1)
50 analytical_results = [
51 der.get_analytical_derivatives(
52 wfs.eigensolver.outer_iloop, ham, wfs, dens)[0][iut]
53 for der in ders]
54 numerical_results = [
55 der.get_numerical_derivatives(
56 wfs.eigensolver.outer_iloop, ham, wfs, dens)[0]
57 for der in ders]
59 # Test 1: consistency between methods (numerical v. analytic)
60 for an, num in zip(analytical_results, numerical_results):
61 assert num.real == pytest.approx(an.real, **tol_between_methods)
62 assert num.imag == pytest.approx(an.imag, **tol_between_methods)
64 # Test 2: consistency between results obtained from different random
65 # RNGs
66 x, *ys = analytical_results
67 for y in ys:
68 assert y.real == pytest.approx(x.real, **tol_between_rngs)
69 assert y.imag == pytest.approx(x.imag, **tol_between_rngs)