Coverage for gpaw/test/response/test_tetra_point_smoothing.py: 100%
44 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
1from ase import Atoms
2from scipy.ndimage import gaussian_filter1d
3import numpy as np
4import pytest
6from gpaw import GPAW, FermiDirac
7from gpaw import PW
8from gpaw.bztools import find_high_symmetry_monkhorst_pack
9from gpaw.response.df import DielectricFunction
10from gpaw.test import findpeak
13@pytest.mark.tetrahedron
14@pytest.mark.dielectricfunction
15@pytest.mark.response
16def test_point_tetra_match(in_tmp_dir):
18 gs_file = 'gs.gpw'
19 response_file = 'gsresponse.gpw'
21 # Create graphene lattice
22 a = 2.5
23 atoms = Atoms(
24 symbols='C2', positions=[(0.5 * a, -np.sqrt(3) / 6 * a, 0.0),
25 (0.5 * a, np.sqrt(3) / 6 * a, 0.0)],
26 cell=[(0.5 * a, -0.5 * 3**0.5 * a, 0),
27 (0.5 * a, 0.5 * 3**0.5 * a, 0),
28 (0.0, 0.0, 3.2)],
29 pbc=[True, True, False])
31 atoms.center(axis=2)
33 calc = GPAW(mode=PW(400),
34 kpts={'density': 10.0, 'gamma': True},
35 occupations=FermiDirac(0.1))
37 atoms.calc = calc
38 atoms.get_potential_energy()
39 calc.write(gs_file)
41 density = 15
42 kpts = find_high_symmetry_monkhorst_pack(gs_file, density=density)
43 responseGS = GPAW(gs_file).fixed_density(
44 kpts=kpts,
45 parallel={'band': 1},
46 nbands=20,
47 occupations=FermiDirac(0.001),
48 convergence={'bands': 10})
49 responseGS.write(response_file, 'all')
51 # DF with tetra integration
52 df = DielectricFunction(response_file,
53 eta=25e-3,
54 rate='eta',
55 frequencies={'type': 'nonlinear',
56 'domega0': 0.1},
57 integrationmode='tetrahedron integration')
58 df1_tetra, df2_tetra = df.get_dielectric_function(q_c=[0, 0, 0])
60 # DF with point integration
61 df = DielectricFunction(response_file,
62 frequencies={'type': 'nonlinear',
63 'domega0': 0.1},
64 eta=25e-3,
65 rate='eta')
66 df1_point, df2_point = df.get_dielectric_function(q_c=[0, 0, 0])
68 omega = df.get_frequencies()
69 df2_tetra = np.imag(df2_tetra)
70 df2_point = np.imag(df2_point)
72 # Do not use frequencies near the w=0 singularity
73 slicer = [(freq >= 1.5) and (freq <= 20) for freq in omega]
74 # Convolve with Gaussian to smoothen the curve
75 sigma = 1.9
76 df2_gauss = gaussian_filter1d(df2_point[slicer], sigma)
78 rms_diff_tetra_point = np.sqrt(np.sum((df2_tetra[slicer]
79 - df2_point[slicer])**2) / np.sum(slicer))
80 rms_diff_tetra_gauss = np.sqrt(np.sum((df2_tetra[slicer]
81 - df2_gauss)**2) / np.sum(slicer))
83 assert rms_diff_tetra_point < 1.35
84 assert rms_diff_tetra_gauss < 1.10
85 assert rms_diff_tetra_point * 0.80 > rms_diff_tetra_gauss
87 freq1, amp1 = findpeak(omega[slicer], df2_tetra[slicer])
88 freq2, amp2 = findpeak(omega[slicer], df2_gauss)
90 assert freq1 - freq2 < 0.1
92 # # Plot the figures
93 # import matplotlib.pyplot as plt
94 # plt.figure(figsize=(6, 6))
95 # plt.plot(omega[slicer], df2_tetra[slicer], label='Tetrahedron')
96 # plt.plot(omega[slicer], df2_point[slicer], label='Point sampling')
97 # plt.plot(omega[slicer], df2_gauss, label='Gaussian convolution')
98 # plt.xlabel('Frequency (eV)')
99 # plt.ylabel('$\\mathrm{Im}\\varepsilon$')
100 # plt.xlim(0, 6)
101 # plt.ylim(0, 20)
102 # plt.legend()
103 # plt.tight_layout()
104 # plt.savefig('graphene_eps.png', dpi=300)