Coverage for gpaw/test/response/test_model_interaction.py: 86%

63 statements  

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

1import numpy as np 

2import pytest 

3from gpaw import GPAW 

4from gpaw.response import ResponseContext, ResponseGroundStateAdapter 

5from gpaw.response.frequencies import FrequencyDescriptor 

6from gpaw.response.modelinteraction import initialize_w_model 

7from gpaw.response.chi0 import Chi0Calculator 

8from gpaw.wannier90 import Wannier90 

9import os 

10from gpaw.mpi import world, serial_comm 

11from subprocess import PIPE, run 

12 

13 

14def out(): 

15 result = run('wannier90.x --version', 

16 stdout=PIPE, 

17 stderr=PIPE, 

18 universal_newlines=True, 

19 shell=True) 

20 return result.stdout 

21 

22 

23@pytest.mark.old_gpaw_only 

24@pytest.mark.parametrize('symm', [True, False]) 

25@pytest.mark.response 

26@pytest.mark.skipif(': 3.' not in out(), 

27 reason="requires at least Wannier90 version 3.0") 

28def test_w(in_tmp_dir, gpw_files, symm): 

29 

30 if not symm and world.size < 2: 

31 pytest.skip('Skip nosymm test in serial') 

32 

33 if symm: 

34 gpwfile = gpw_files['gaas_pw'] 

35 else: 

36 gpwfile = gpw_files['gaas_pw_nosym'] 

37 

38 calc = GPAW(gpwfile, communicator=serial_comm) 

39 seed = 'GaAs' 

40 

41 # Wannier90 only works in serial 

42 if world.rank == 0: 

43 w90 = Wannier90(calc, orbitals_ai=[[], [0, 1, 2, 3]], 

44 bands=range(4), 

45 seed=seed) 

46 w90.write_input(num_iter=100, 

47 plot=False, 

48 write_u_matrices=True) 

49 w90.write_wavefunctions() 

50 os.system('wannier90.x -pp ' + seed) 

51 w90.write_projections() 

52 w90.write_eigenvalues() 

53 w90.write_overlaps() 

54 os.system('wannier90.x ' + seed) 

55 

56 world.barrier() 

57 

58 omega = np.array([0]) 

59 kwargs = dict(hilbert=False, ecut=30, intraband=False) 

60 gs = ResponseGroundStateAdapter.from_gpw_file(gpwfile) 

61 context = ResponseContext('test.log') 

62 wd = FrequencyDescriptor.from_array_or_dict(omega) 

63 chi0calc = Chi0Calculator(gs, context, wd=wd, **kwargs) 

64 Wm = initialize_w_model(chi0calc) 

65 w, Wwann = Wm.calc_in_Wannier(chi0calc, Uwan_mnk=seed, bandrange=[0, 4]) 

66 check_W(Wwann) 

67 assert np.allclose(w, omega) 

68 

69 # test block parallelization 

70 if world.size % 2 == 0 and symm: 

71 omega = np.array([0, 1]) 

72 wd = FrequencyDescriptor.from_array_or_dict(omega) 

73 chi0calc = Chi0Calculator(gs, context, wd=wd, nblocks=2, **kwargs) 

74 Wm = initialize_w_model(chi0calc) 

75 w, Wwann = Wm.calc_in_Wannier(chi0calc, Uwan_mnk=seed, 

76 bandrange=[0, 4]) 

77 check_W(Wwann) 

78 print(omega, w) 

79 assert np.allclose(w, omega) 

80 

81 

82def check_W(Wwann): 

83 assert Wwann[0, 0, 0, 0, 0] == pytest.approx(2.478, abs=0.003) 

84 assert Wwann[0, 1, 1, 1, 1] == pytest.approx(1.681, abs=0.003) 

85 assert Wwann[0, 2, 2, 2, 2] == pytest.approx(1.681, abs=0.003) 

86 assert Wwann[0, 3, 3, 3, 3] == pytest.approx(1.681, abs=0.003) 

87 assert Wwann[0, 3, 3, 0, 0] == pytest.approx(0.861, abs=0.003) 

88 assert Wwann[0, 3, 0, 3, 0].real == pytest.approx(1.757, abs=0.003) 

89 assert np.abs(Wwann[0, 3, 0, 3, 0].imag) < 0.005