Coverage for gpaw/test/lcao/test_largecellforce.py: 71%
38 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-08 00:17 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-08 00:17 +0000
1# This test calculates the force on the atoms in a hydrogen chain, comparing
2# the results to finite-difference values.
3#
4# The reference result is obtained from an FD calculation, which can be rerun
5# by setting the fd boolean below.
6#
7# The purpose is to test domain decomposition with large cells. The basis
8# functions of one atom are defined to not overlap the rightmost domain
9# for z-decompositions of two or more slices. This will change the set
10# of atomic indices stored in BasisFunctions objects and other things
11#
12# This test also ensures that lcao forces are tested with non-pbc.
13import numpy as np
14from numpy import array
15from ase import Atoms
16from gpaw import GPAW
17from gpaw.atom.basis import BasisMaker
20def test_lcao_largecellforce(gpaw_new):
21 hbasis = BasisMaker.from_symbol('H').generate(1, 0, energysplit=1.8,
22 tailnorm=0.03**.5)
23 basis = {'H': hbasis}
25 atom = Atoms('H')
26 atom.center(vacuum=.8)
27 system = atom.repeat((1, 1, 4))
29 system.center(vacuum=2.5)
31 calc = GPAW(h=0.23,
32 mode='lcao',
33 basis=basis,
34 convergence={'density': 1e-4, 'energy': 1e-7})
36 system.calc = calc
38 F_ac = system.get_forces()
40 # Check that rightmost domain is in fact outside range of basis functions
41 from gpaw.mpi import rank, size
42 if rank == 0 and size > 1:
43 if gpaw_new:
44 basis = calc.dft.scf_loop.hamiltonian.basis
45 else:
46 basis = calc.wfs.basis_functions
47 assert len(basis.atom_indices) < len(system)
49 fd = 0
51 # Values taken from FD calculation below
52 # (Symmetry means only z-component may be nonzero)
53 ref = array([[0, 0, 4.616841597363752],
54 [0, 0, -2.7315136482540803],
55 [0, 0, 2.7315116638237935],
56 [0, 0, -4.616840606709416]])
58 if fd:
59 from gpaw.test import calculate_numerical_forces
60 ref = calculate_numerical_forces(system, 0.002, icarts=[2])
61 print('Calced')
62 print(F_ac)
63 print('FD')
64 print(ref)
65 print(repr(ref))
67 err = np.abs(F_ac - ref).max()
68 print('Ref')
69 print(ref)
70 print('Calculated')
71 print(F_ac)
72 print('Max error', err)
73 assert err < 6e-4