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
« 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
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
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):
30 if not symm and world.size < 2:
31 pytest.skip('Skip nosymm test in serial')
33 if symm:
34 gpwfile = gpw_files['gaas_pw']
35 else:
36 gpwfile = gpw_files['gaas_pw_nosym']
38 calc = GPAW(gpwfile, communicator=serial_comm)
39 seed = 'GaAs'
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)
56 world.barrier()
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)
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)
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