Coverage for gpaw/test/mom/test_mom_lcao_forces.py: 100%
41 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 numpy as np
2import pytest
3from ase import Atoms
5from gpaw import GPAW, restart
6from gpaw.mom import prepare_mom_calculation
9@pytest.mark.mom
10def test_mom_lcao_forces(in_tmp_dir):
11 force_ref = 11.52
13 f_sn = [[1., 1., 1., 1., 0., 1., 0.],
14 [1., 1., 1., 1., 1., 0., 0.]]
15 L = 4.0
16 d = 1.13
17 delta = 0.01
19 atoms = Atoms('CO',
20 [[0.5 * L, 0.5 * L, 0.5 * L - 0.5 * d],
21 [0.5 * L, 0.5 * L, 0.5 * L + 0.5 * d]])
22 atoms.set_cell([L, L, L])
23 atoms.rotate(1, 'x', center=[0.5 * L, 0.5 * L, 0.5 * L])
25 calc = GPAW(mode='lcao',
26 basis='dzp',
27 nbands=7,
28 h=0.24,
29 xc='PBE',
30 spinpol=True,
31 symmetry='off',
32 convergence={'energy': 100,
33 'density': 1e-4})
35 atoms.calc = calc
36 # Ground-state calculation
37 atoms.get_potential_energy()
38 calc.write('co_lcao_gs.gpw', 'all')
40 for mom in [False, True]:
41 atoms, calc = restart('co_lcao_gs.gpw', txt='-')
43 occ = prepare_mom_calculation(calc, atoms, f_sn, use_projections=mom)
44 F = atoms.get_forces()
46 # Test overlaps
47 occ.initialize_reference_orbitals()
48 for kpt in calc.wfs.kpt_u:
49 f_n = calc.get_occupation_numbers(spin=kpt.s)
50 P = occ.calculate_weights(kpt, 1.0)
51 assert (np.allclose(P, f_n))
53 E = []
54 p = atoms.positions.copy()
55 for i in [-1, 1]:
56 pnew = p.copy()
57 pnew[0, 2] -= delta / 2. * i
58 pnew[1, 2] += delta / 2. * i
59 atoms.set_positions(pnew)
61 E.append(atoms.get_potential_energy())
63 f = np.sqrt(((F[1, :] - F[0, :])**2).sum()) * 0.5
64 fnum = (E[0] - E[1]) / (2. * delta) # central difference
66 print(fnum, f)
67 assert fnum == pytest.approx(force_ref, abs=0.016)
68 assert f == pytest.approx(fnum, abs=0.1)