Coverage for gpaw/test/response/test_response_band_cutoff.py: 96%

28 statements  

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

1import pytest 

2import numpy as np 

3 

4from ase.io.ulm import ulmopen 

5from gpaw.test.gpwfile import response_band_cutoff 

6 

7 

8@pytest.mark.response 

9@pytest.mark.parametrize('gs', list(response_band_cutoff)) 

10def test_response_band_cutoff(in_tmp_dir, gpw_files, gs, gpaw_new): 

11 if gpaw_new and gs == 'v2br4_pw': 

12 pytest.skip('interpolation=3 not implemented') 

13 nbands = response_band_cutoff[gs] 

14 with ulmopen(gpw_files[gs]) as reader: 

15 eps_skn = reader.wave_functions.eigenvalues 

16 nconv = reader.parameters.convergence['bands'] 

17 print(gs) 

18 assert nbands < nconv 

19 possible_cutoffs = get_nbands_cutoff_list(eps_skn, nconv) 

20 print(possible_cutoffs) 

21 assert nbands in possible_cutoffs 

22 

23 

24def get_nbands_cutoff_list(eps_skn, nconv, atol=1e-3): 

25 """ Possible cutoffs for response calc 

26 Returns the set all allowed band cutoffs in a response calculation. 

27 Assures that there are no degeneracies at the edge of the cutoff 

28 

29 >>> eps = np.array([[[0, 1, 2, 2, 3, 4, 5, 5]]]) 

30 >>> get_nbands_cutoff_list(eps, 7) 

31 {1, 2, 4, 5, 6} 

32 """ 

33 allset = set(range(nconv + 1)) 

34 # Loop over spins and k-points 

35 for eps_kn in eps_skn: 

36 for eps_n in eps_kn: 

37 # check degenerate eigenvalues 

38 cutlist = np.isclose(eps_n[:nconv - 1], eps_n[1:nconv], 

39 atol=atol) 

40 cutlist = np.argwhere(~cutlist) 

41 # cutoff is allowed index + 1 

42 cutlist += 1 

43 thisset = set(cutlist.flatten()) 

44 # find minimum cutoff that works for all k 

45 allset = thisset & allset 

46 

47 return {int(n) for n in allset}