Coverage for gpaw/test/lcao/test_bsse.py: 100%

37 statements  

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

1import pytest 

2from ase.build import molecule 

3 

4from gpaw import GPAW 

5from gpaw.atom.basis import BasisMaker 

6from gpaw.poisson import FDPoissonSolver as PoissonSolver 

7 

8 

9@pytest.mark.old_gpaw_only 

10def test_lcao_bsse(): 

11 """Tests basis set super position error correction. 

12 

13 Compares a single hydrogen atom to a system of one hydrogen atom 

14 and one ghost hydrogen atom. The systems should have identical properties, 

15 i.e. the ghost orbital should have a coefficient of 0. 

16 """ 

17 

18 b = BasisMaker.from_symbol('H').generate(1, 0, energysplit=0.005) 

19 

20 system = molecule('H2') 

21 system.center(vacuum=6.0) 

22 

23 def prepare(setups): 

24 calc = GPAW(basis={'H': b}, mode='lcao', 

25 setups=setups, h=0.2, 

26 poissonsolver=PoissonSolver(nn='M', relax='GS', eps=1e-5), 

27 spinpol=False, 

28 nbands=1) 

29 system.calc = calc 

30 return calc 

31 

32 calc = prepare({0: 'paw', 1: 'ghost'}) 

33 system.calc = calc 

34 e_bsse = system.get_potential_energy() 

35 niter_bsse = calc.get_number_of_iterations() 

36 

37 c_nM = calc.wfs.kpt_u[0].C_nM 

38 print('coefs') 

39 print(c_nM) 

40 print('energy', e_bsse) 

41 

42 # Reference system which is just a hydrogen 

43 sys0 = system[0:1].copy() 

44 calc = prepare('paw') 

45 sys0.calc = calc 

46 e0 = sys0.get_potential_energy() 

47 niter0 = calc.get_number_of_iterations() 

48 print('e0, e_bsse = ', e0, e_bsse) 

49 

50 # One coefficient should be very small (0.012), the other very large (0.99) 

51 assert abs(1.0 - abs(c_nM[0, 0])) < 0.02 

52 assert abs(c_nM[0, 1]) < 0.02 

53 assert abs(e_bsse - e0) < 2e-3 

54 

55 energy_tolerance = 0.002 

56 niter_tolerance = 3 

57 assert e_bsse == pytest.approx(0.02914, abs=energy_tolerance) 

58 assert niter_bsse == pytest.approx(7, abs=niter_tolerance) 

59 assert e0 == pytest.approx(0.03038, abs=energy_tolerance) 

60 assert niter0 == pytest.approx(6, abs=niter_tolerance)