Coverage for gpaw/test/response/test_iron_sf_ALDA.py: 19%
77 statements
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-08 00:17 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2025-07-08 00:17 +0000
1"""
2Calculate the magnetic response in iron using ALDA.
4Tests whether the magnon energies and scattering intensities
5have changed for:
6 * Different kernel calculation strategies
7 * Different chi0 transitions summation strategies
8"""
10import numpy as np
11import pytest
13from gpaw import GPAW
14from gpaw.test import findpeak
15from gpaw.mpi import world
17from gpaw.response import ResponseGroundStateAdapter
18from gpaw.response.chiks import ChiKSCalculator
19from gpaw.response.susceptibility import ChiFactory
20from gpaw.response.fxc_kernels import AdiabaticFXCCalculator
21from gpaw.response.pair_functions import read_pair_function
22from gpaw.test.gpwfile import response_band_cutoff
24pytestmark = pytest.mark.skipif(world.size < 4, reason='world.size < 4')
27@pytest.mark.kspair
28@pytest.mark.response
29def test_response_iron_sf_ALDA(in_tmp_dir, gpw_files, scalapack):
30 # ---------- Inputs ---------- #
32 # Magnetic response calculation
33 q_c = [0.0, 0.0, 1 / 4.]
34 fxc = 'ALDA'
35 ecut = 300
36 eta = 0.1
38 # Test different kernel, summation and symmetry strategies
39 # rshelmax, rshewmin, bandsummation, qsymmetry
40 strat_sd = [(None, None, 'pairwise', True),
41 (-1, 0.001, 'pairwise', True),
42 (-1, 0.000001, 'pairwise', True),
43 (-1, 0.000001, 'double', True),
44 (-1, 0.000001, 'double', False),
45 (-1, None, 'pairwise', True),
46 (3, None, 'pairwise', True)]
47 frq_sw = [np.linspace(0.320, 0.480, 21),
48 np.linspace(0.420, 0.580, 21),
49 np.linspace(0.420, 0.580, 21),
50 np.linspace(0.420, 0.580, 21),
51 np.linspace(0.420, 0.580, 21),
52 np.linspace(0.420, 0.580, 21),
53 np.linspace(0.420, 0.580, 21),
54 np.linspace(0.420, 0.580, 21)]
56 # ---------- Script ---------- #
58 calc = GPAW(gpw_files['fe_pw'], parallel=dict(domain=1))
59 nbands = response_band_cutoff['fe_pw']
60 gs = ResponseGroundStateAdapter(calc)
62 for s, ((rshelmax, rshewmin, bandsummation, qsymmetry),
63 frq_w) in enumerate(zip(strat_sd, frq_sw)):
64 complex_frequencies = frq_w + 1.j * eta
65 chiks_calc = ChiKSCalculator(gs,
66 nbands=nbands,
67 ecut=ecut,
68 bandsummation=bandsummation,
69 qsymmetry=qsymmetry,
70 nblocks=2)
71 fxc_calculator = AdiabaticFXCCalculator.from_rshe_parameters(
72 gs, chiks_calc.context,
73 rshelmax=rshelmax,
74 rshewmin=rshewmin)
75 chi_factory = ChiFactory(chiks_calc, fxc_calculator)
76 _, chi = chi_factory('+-', q_c, complex_frequencies, fxc=fxc)
77 chi.write_macroscopic_component('iron_dsus' + '_G%d.csv' % (s + 1))
78 chi_factory.context.write_timer()
80 world.barrier()
82 # Identify magnon peak in scattering functions
83 w1_w, chi1_w = read_pair_function('iron_dsus_G1.csv')
84 w2_w, chi2_w = read_pair_function('iron_dsus_G2.csv')
85 w3_w, chi3_w = read_pair_function('iron_dsus_G3.csv')
86 w4_w, chi4_w = read_pair_function('iron_dsus_G4.csv')
87 w5_w, chi5_w = read_pair_function('iron_dsus_G5.csv')
88 w6_w, chi6_w = read_pair_function('iron_dsus_G6.csv')
89 w7_w, chi7_w = read_pair_function('iron_dsus_G7.csv')
90 print(-chi1_w.imag)
91 print(-chi2_w.imag)
93 wpeak1, Ipeak1 = findpeak(w1_w, -chi1_w.imag)
94 wpeak2, Ipeak2 = findpeak(w2_w, -chi2_w.imag)
95 wpeak3, Ipeak3 = findpeak(w3_w, -chi3_w.imag)
96 wpeak4, Ipeak4 = findpeak(w4_w, -chi4_w.imag)
97 wpeak5, Ipeak5 = findpeak(w5_w, -chi5_w.imag)
98 wpeak6, Ipeak6 = findpeak(w6_w, -chi6_w.imag)
99 wpeak7, Ipeak7 = findpeak(w7_w, -chi7_w.imag)
101 mw1 = wpeak1 * 1000
102 mw2 = wpeak2 * 1000
103 mw3 = wpeak3 * 1000
104 mw4 = wpeak4 * 1000
105 mw5 = wpeak5 * 1000
106 mw6 = wpeak6 * 1000
107 mw7 = wpeak7 * 1000
109 # Compare new results to test values
110 print(mw1, mw2, mw3, Ipeak1, Ipeak2, Ipeak3)
111 test_mw1 = 402. # meV
112 test_mw2 = 490. # meV
113 test_mw3 = 490. # meV
114 test_Ipeak1 = 4.10 # a.u.
115 test_Ipeak2 = 5.05 # a.u.
116 test_Ipeak3 = 5.04 # a.u.
118 # Different kernel strategies should remain the same
119 # Magnon peak:
120 assert mw1 == pytest.approx(test_mw1, abs=30.)
121 assert mw2 == pytest.approx(test_mw2, abs=30.)
122 assert mw3 == pytest.approx(test_mw3, abs=30.)
124 # Scattering function intensity:
125 assert Ipeak1 == pytest.approx(test_Ipeak1, abs=0.5)
126 assert Ipeak2 == pytest.approx(test_Ipeak2, abs=0.5)
127 assert Ipeak3 == pytest.approx(test_Ipeak3, abs=0.5)
129 # The two transitions summation strategies should give identical results
130 assert mw3 == pytest.approx(mw4, abs=35.)
131 assert Ipeak3 == pytest.approx(Ipeak4, abs=0.5)
133 # Toggling symmetry should preserve the result
134 assert mw5 == pytest.approx(mw4, abs=25.)
135 assert Ipeak5 == pytest.approx(Ipeak4, abs=0.5)
137 # Including vanishing coefficients should not matter for the result
138 assert mw6 == pytest.approx(mw3, abs=2.)
139 assert Ipeak6 == pytest.approx(Ipeak3, abs=0.1)
140 assert mw7 == pytest.approx(mw2, abs=2.)
141 assert Ipeak7 == pytest.approx(Ipeak2, abs=0.1)