Coverage for gpaw/test/elph/test_ramancalculator.py: 100%
58 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-20 00:19 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-20 00:19 +0000
1import numpy as np
2import pytest
4from ase.utils.filecache import MultiFileJSONCache
5from gpaw import GPAW
6from gpaw.lcao.dipoletransition import get_momentum_transitions
7from gpaw.elph import ResonantRamanCalculator
8from gpaw.mpi import world
11def get_random_g(nk, nb):
12 g_sqklnn = np.zeros((1, 1, 4, 3, 4, 4), dtype=complex)
13 rng = np.random.default_rng()
14 tmp = rng.random((4, 4)) + 1j * rng.random((4, 4))
15 # make hermitian
16 for i in range(4):
17 for j in range(i + 1, 4):
18 tmp[i, j] = tmp[j, i].conj()
19 g_sqklnn[0, 0, 0, 2] = tmp
20 return g_sqklnn
23@pytest.mark.old_gpaw_only # calc.initialize_positions(atoms) not implemented!
24@pytest.mark.serial
25def test_ramancalculator(gpw_files, in_tmp_dir):
26 """Test of ResonantRamanCalculator object"""
27 calc = GPAW(gpw_files['bcc_li_lcao'])
28 atoms = calc.atoms
29 # Initialize calculator if necessary
30 if not hasattr(calc.wfs, 'C_nM'):
31 calc.initialize_positions(atoms)
32 # need to fiddle with some occupation numnbers as this exampe is
33 # not properly converged
34 for kpt in calc.wfs.kpt_u:
35 kpt.f_n[0] = kpt.weight
37 # prepare some required data
38 wph_w = np.array([0., 0., 0.1])
39 get_momentum_transitions(calc.wfs)
40 if world.rank == 0:
41 g_sqklnn = get_random_g(4, 4)
42 np.save("gsqklnn.npy", g_sqklnn)
44 rrc = ResonantRamanCalculator(calc, wph_w)
45 assert rrc.mom_skvnm == pytest.approx(np.transpose(rrc.mom_skvnm,
46 (0, 1, 2, 4, 3)).conj())
47 # Force momentum matrix elements to be the same in all directions
48 # else R^ab won't be R^{ba*}
49 # This is a bit of a dirty hack I guess. Ideally we need a test systm with
50 # equivalent axes but no degenerate bands... so yeah
51 rrc.mom_skvnm[0, :, 1] = rrc.mom_skvnm[0, :, 0]
52 rrc.mom_skvnm[0, :, 2] = rrc.mom_skvnm[0, :, 0]
54 # check reading of file cache
55 check_cache = MultiFileJSONCache("Rlab")
56 assert check_cache["phonon_frequencies"] == pytest.approx(wph_w)
57 assert check_cache["frequency_grid"] is None
59 rrc.calculate_raman_tensor(1.0)
60 for i in range(3):
61 for j in range(3):
62 R_l = check_cache[f"{'xyz'[i]}{'xyz'[j]}"]
63 assert R_l is not None
64 assert R_l[0] == pytest.approx(0.0 + 1j * 0.)
65 assert R_l[1] == pytest.approx(0.0 + 1j * 0.)
67 if j > i:
68 # need to make sure momentum matrix is perfectly hermitian too
69 Rother_l = check_cache[f"{'xyz'[j]}{'xyz'[i]}"]
70 print(i, j, R_l[2], Rother_l[2])
71 assert R_l[2].real == pytest.approx(Rother_l[2].real)
72 assert R_l[2].imag == pytest.approx(Rother_l[2].imag)
74 # check proper kpt dependence. If we half all the weights,
75 # the total intensity should be half as well
76 for kpt in calc.wfs.kpt_u:
77 kpt.weight /= 2
78 kpt.f_n /= 2 # because f_n = kpt.f_n / kpt.weight
80 for i in range(3):
81 for j in range(3):
82 R_l = check_cache[f"{'xyz'[i]}{'xyz'[j]}"]
83 R_l_half = rrc.calculate(1.0, i, j)
84 assert 2. * R_l_half[2].real == pytest.approx(R_l[2].real)
85 assert 2. * R_l_half[2].imag == pytest.approx(R_l[2].imag)