Coverage for gpaw/test/lcao/test_atomic_corrections.py: 89%

45 statements  

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

1# Test that the atomic corrections of LCAO work correctly, 

2# by verifying that the different implementations yield the same numbers. 

3# 

4# For example the corrections P^* dH P to the Hamiltonian. 

5# 

6# This is done by invoking GPAW once for each type of calculation. 

7 

8import pytest 

9from ase.build import molecule, bulk 

10 

11from gpaw import GPAW, LCAO 

12from gpaw.mpi import world 

13 

14 

15def system1(): 

16 system = molecule('CH3CH2OH') 

17 system.center(vacuum=3.0) 

18 system.pbc = (0, 1, 1) 

19 system = system.repeat((1, 1, 2)) 

20 system.rattle(stdev=0.05) 

21 return system 

22 

23 

24def system2(): 

25 return bulk('Cu', orthorhombic=True) * (2, 1, 2) 

26 

27 

28@pytest.mark.parametrize('atoms, kpts, eref', [ 

29 (system1(), [1, 1, 1], -58.845), 

30 (system2(), [2, 3, 4], -22.691)]) 

31def test_lcao_atomic_corrections(atoms, in_tmp_dir, scalapack, kpts, eref, 

32 gpaw_new): 

33 # Use a cell large enough that some overlaps are zero. 

34 # Thus the matrices will have at least some sparsity. 

35 

36 if gpaw_new: 

37 if world.size >= 4: 

38 pytest.skip('Not implemented') 

39 corrections = ['ignored for now'] 

40 else: 

41 corrections = ['dense', 'sparse'] 

42 

43 energies = [] 

44 for i, correction in enumerate(corrections): 

45 parallel = {} 

46 if world.size >= 4: 

47 parallel['band'] = 2 

48 # if correction.name != 'dense': 

49 parallel['sl_auto'] = True 

50 calc = GPAW(mode=LCAO(atomic_correction=correction), 

51 basis='sz(dzp)', 

52 # spinpol=True, 

53 parallel=parallel, 

54 txt=f'gpaw.{i}.txt', 

55 h=0.35, kpts=kpts, 

56 convergence={'maximum iterations': 2}) 

57 atoms.calc = calc 

58 energy = atoms.get_potential_energy() 

59 energies.append(energy) 

60 if calc.world.rank == 0: 

61 print('e', energy) 

62 

63 master = calc.wfs.world.rank == 0 

64 if master: 

65 print('energies', energies) 

66 

67 e0 = energies[0] 

68 errs = [] 

69 for energy, c in zip(energies, corrections): 

70 assert energy == pytest.approx(eref, abs=0.001) 

71 err = abs(energy - e0) 

72 errs.append(err) 

73 if master: 

74 print('err=%e :: name=%s' % (err, correction)) 

75 

76 maxerr = max(errs) 

77 assert maxerr < 1e-11, maxerr