Coverage for gpaw/test/exx/test_coarse.py: 100%

41 statements  

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

1import sys 

2 

3from ase import Atoms 

4from ase.utils.timing import Timer 

5import pytest 

6 

7from gpaw import GPAW 

8from gpaw.xc.hybrid import HybridXC 

9 

10 

11@pytest.mark.slow 

12@pytest.mark.libxc 

13@pytest.mark.hybrids 

14def test_exx_coarse(in_tmp_dir): 

15 timer = Timer() 

16 

17 loa = Atoms('Be2', 

18 [(0, 0, 0), (2.45, 0, 0)], 

19 magmoms=[0.5, 0.5], 

20 cell=[5.9, 4.8, 5.0]) 

21 loa.center() 

22 

23 fgl = [False, True] 

24 # fgl = [True, False] 

25 

26 E = {} 

27 niter = {} 

28 for fg in fgl: 

29 if fg: 

30 tstr = 'Exx on fine grid' 

31 else: 

32 tstr = 'Exx on coarse grid' 

33 timer.start(tstr) 

34 loa.calc = GPAW(mode='fd', 

35 h=0.3, 

36 eigensolver='rmm-diis', 

37 xc=dict(name='PBE', stencil=1), 

38 poissonsolver={'name': 'fd'}, 

39 nbands=4, 

40 convergence={'eigenstates': 1e-4}, 

41 charge=-1) 

42 E[fg] = loa.get_potential_energy() 

43 loa.calc = loa.calc.new(xc=HybridXC('PBE0', stencil=1, finegrid=fg)) 

44 E[fg] = loa.get_potential_energy() 

45 niter[fg] = loa.calc.get_number_of_iterations() 

46 timer.stop(tstr) 

47 if not fg: 

48 fname = 'exx_load.gpw' 

49 loa.calc.write(fname) 

50 calcl = GPAW(fname) 

51 func = calcl.parameters.xc 

52 

53 assert func['name'] == 'PBE0', 'wrong name for functional' 

54 assert func['hybrid'] == 0.25, 'wrong factor for functional' 

55 

56 timer.write(sys.stdout) 

57 

58 print('Total energy on the fine grid =', E[True]) 

59 print('Total energy on the coarse grid =', E[False]) 

60 assert E[True] == pytest.approx(E[False], abs=0.01) 

61 

62 energy_tolerance = 0.003 

63 assert E[False] == pytest.approx(6.97818, abs=energy_tolerance) 

64 assert E[True] == pytest.approx(6.97153, abs=energy_tolerance)