Coverage for gpaw/test/elph/test_gradient.py: 97%

35 statements  

« prev     ^ index     » next       coverage.py v7.7.1, created at 2025-07-12 00:18 +0000

1"""Basic test of elph/supercell/calculate_gradient 

2 

3Check that calculate_gradient is capable of reading stuff properly. 

4""" 

5import ase.units as units 

6import numpy as np 

7import pytest 

8from ase.build import bulk 

9from gpaw import GPAW 

10from gpaw.elph import DisplacementRunner, Supercell 

11from gpaw.mpi import world 

12 

13 

14@pytest.mark.elph 

15def test_gradient(in_tmp_dir): 

16 # 2 atoms with one 1 valence electron each 

17 atoms = bulk('Li', crystalstructure='bcc', a=3.51, cubic=True) 

18 assert len(atoms) == 2 

19 # Note: usually we need to disable point group symmetry for displacements, 

20 # but we won't run actual displacements, so it saves time not to bother. 

21 calc = GPAW(mode='lcao', 

22 basis='sz(dzp)', 

23 kpts={'size': (2, 2, 2), 'gamma': False}, 

24 # symmetry={'point_group': False}, 

25 txt='elph_displacements.txt') 

26 atoms.calc = calc 

27 

28 elph = DisplacementRunner(atoms=atoms, calc=atoms.calc, 

29 supercell=(1, 1, 1), name='elph', 

30 calculate_forces=False) 

31 elph.indices = [] 

32 elph.run() 

33 

34 # Barrier will be included in elph.run() in the future: 

35 # https://gitlab.com/ase/ase/-/merge_requests/2903 

36 world.barrier() 

37 

38 Vt_sG = elph.cache['eq']['Vt_sG'] 

39 dH_all_asp = elph.cache['eq']['dH_all_asp'] 

40 

41 # create displaced entries without calculation to save time 

42 V1expected = [] 

43 for a in (0, 1): 

44 for i in range(3): 

45 V1expected.append(2 * 0.1 * (a + 1) * (i + 1) / 

46 (2 * 0.01 / units.Bohr)) 

47 for sign in [-1, 1]: 

48 disp = elph._disp(a, i, sign) 

49 with elph.cache.lock(disp.name) as handle: 

50 if handle is None: 

51 continue 

52 try: 

53 Vfake = Vt_sG + sign * 0.1 * (a + 1) * (i + 1) 

54 # dHfake = {} 

55 # for atom in dH_all_asp.keys(): 

56 # dHfake[atom] = dH_all_asp[atom] + (sign * 0.2 * 

57 # (a+1) * (i+1)) 

58 result = {'Vt_sG': Vfake, 'dH_all_asp': dH_all_asp} 

59 handle.save(result) 

60 finally: 

61 pass 

62 

63 # calculate gradient 

64 V1t_xsG, dH1_xasp = Supercell.calculate_gradient('elph') 

65 assert np.array(V1expected) == pytest.approx(V1t_xsG[:, 0, 0, 0, 0]) 

66 # should probably add something about dH as well, but the principle is the 

67 # same