Coverage for gpaw/test/response/test_symmetry.py: 97%

29 statements  

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

1import numpy as np 

2import pytest 

3 

4from gpaw.response import ResponseContext, ResponseGroundStateAdapter 

5from gpaw.response.symmetry import QSymmetryAnalyzer 

6from gpaw.test.gpwfile import response_band_cutoff 

7 

8 

9@pytest.mark.response 

10@pytest.mark.parametrize('identifier', list(response_band_cutoff)) 

11def test_qsymmetries(gpw_files, identifier, gpaw_new): 

12 if gpaw_new and identifier == 'v2br4_pw': 

13 pytest.skip('New-GPAW does not support interpolate=3') 

14 # Set up basic response code objects 

15 gs = ResponseGroundStateAdapter.from_gpw_file(gpw_files[identifier]) 

16 context = ResponseContext() 

17 qsymmetry = QSymmetryAnalyzer() 

18 

19 # Count all symmetries: 

20 symmetry = gs.kd.symmetry 

21 ndirect = len(symmetry.op_scc) 

22 nindirect = ndirect * (1 - symmetry.has_inversion) 

23 nsymmetries = ndirect + nindirect 

24 

25 # Test symmetry analysis 

26 rng = np.random.default_rng(42) 

27 if np.linalg.norm(gs.kd.ibzk_kc, axis=1).min() < 1e-10: 

28 # If the ground state is Γ-centered, all IBZ k-points are valid 

29 # q-points as well (autocommensurate) and we check that the q-point 

30 # symmetry analyzer reproduces the symmetries of the ground state. 

31 for k, k_c in enumerate(gs.kd.ibzk_kc): 

32 # Add a bit of numerical noise: 

33 q_c = k_c + (rng.random(3) - 0.5) * 1e-15 

34 qsymmetries, _ = qsymmetry.analyze(q_c, gs.kpoints, context) 

35 # The number of q -> G + q symmetries is reduced by the 

36 # multiplicity of the corresponding k-point 

37 bzk_K = np.where(gs.kd.bz2ibz_k == k)[0] 

38 assert nsymmetries % len(bzk_K) == 0 

39 assert len(qsymmetries) == nsymmetries // len(bzk_K) 

40 else: 

41 # If the ground state isn't Γ-centered, we simply check that a "noisy" 

42 # Γ-point q vector recovers all symmetries of the system 

43 q_c = (rng.random(3) - 0.5) * 1e-15 # "Noisy" Γ-point 

44 qsymmetries, _ = qsymmetry.analyze(q_c, gs.kpoints, context) 

45 assert qsymmetries.ndirect == ndirect, f'{q_c}' 

46 assert qsymmetries.nindirect == nindirect, f'{q_c}'