Coverage for gpaw/test/response/test_nicl2_sf_gssALDA.py: 28%
65 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 gpaw.mpi import world
5from gpaw.test import findpeak
7from gpaw.response import ResponseGroundStateAdapter
8from gpaw.response.frequencies import ComplexFrequencyDescriptor
9from gpaw.response.chiks import ChiKSCalculator
10from gpaw.response.fxc_kernels import AdiabaticFXCCalculator
11from gpaw.response.dyson import HXCKernel
12from gpaw.response.goldstone import FMGoldstoneScaling
13from gpaw.response.susceptibility import ChiFactory
14from gpaw.response.pair_functions import read_pair_function
17pytestmark = pytest.mark.skipif(world.size < 4,
18 reason='too slow for world.size < 4')
21@pytest.mark.kspair
22@pytest.mark.response
23@pytest.mark.old_gpaw_only
24def test_nicl2_magnetic_response(in_tmp_dir, gpw_files):
25 # ---------- Inputs ---------- #
27 q_qc = [[0., 0., 0.],
28 [1. / 3., 1. / 3., 0.]]
29 fxc = 'ALDA'
30 rshelmax = 0
31 rshewmin = None
32 bg_density = 0.004
33 ecut = 200
34 frq_w = np.linspace(-0.15, 0.075, 16)
35 eta = 0.12
36 zd = ComplexFrequencyDescriptor.from_array(frq_w + 1.j * eta)
37 nblocks = 4
39 # ---------- Script ---------- #
41 # Magnetic response calculation
42 gs = ResponseGroundStateAdapter.from_gpw_file(gpw_files['nicl2_pw'])
43 chiks_calc = ChiKSCalculator(gs,
44 ecut=ecut,
45 gammacentered=True,
46 nblocks=nblocks)
48 # Calculate the magnetic response with and without a background density
49 hxc_scaling = FMGoldstoneScaling()
50 fxc_calculator = AdiabaticFXCCalculator.from_rshe_parameters(
51 gs, chiks_calc.context,
52 rshelmax=rshelmax,
53 rshewmin=rshewmin)
54 chi_factory = ChiFactory(chiks_calc, fxc_calculator)
55 bgd_hxc_scaling = FMGoldstoneScaling()
56 bgd_fxc_calculator = AdiabaticFXCCalculator.from_rshe_parameters(
57 gs, chiks_calc.context,
58 bg_density=bg_density,
59 rshelmax=rshelmax,
60 rshewmin=rshewmin)
62 # Check that the pseudo-density is nonnegative
63 nt_sr, gd = gs.get_pseudo_density(gridrefinement=2)
64 assert np.all(nt_sr >= 0.)
66 # Plot pseudo spin-density to check exponential localization into vacuum
67 # if world.rank == 0:
68 # import matplotlib.pyplot as plt
69 # N_c = gd.N_c
70 # # Plot the spin-densities above one of the Cl atoms
71 # plt.plot(range(N_c[2]), nt_sr[0, 2 * N_c[0] // 3, N_c[1] // 3])
72 # plt.plot(range(N_c[2]), nt_sr[1, 2 * N_c[0] // 3, N_c[1] // 3])
73 # plt.yscale('log')
74 # plt.show()
76 filestr = 'nicl2_macro_tms'
77 bgd_filestr = 'nicl2_macro_tms_bgd'
78 for q, q_c in enumerate(q_qc):
79 chiks, chi = chi_factory('+-', q_c, zd,
80 fxc=fxc,
81 hxc_scaling=hxc_scaling,
82 txt=filestr + '_q%d.txt' % q)
83 chi.write_macroscopic_component(filestr + '_q%d.csv' % q)
84 if q == 0:
85 # Calculate kernel with background charge
86 bgd_hxc_kernel = HXCKernel(
87 hartree_kernel=chi_factory.get_hartree_kernel(
88 '+-', chiks.qpd),
89 xc_kernel=bgd_fxc_calculator(fxc, '+-', chiks.qpd))
90 bgd_chi = chi_factory.dyson_solver(
91 chiks, bgd_hxc_kernel, bgd_hxc_scaling)
92 bgd_chi.write_macroscopic_component(bgd_filestr + '_q%d.csv' % q)
94 chiks_calc.context.write_timer()
95 world.barrier()
97 # Compare new results to test values
98 check_magnons(filestr, hxc_scaling,
99 test_fxcs=0.7130,
100 test_mw0=-10.3, # meV
101 test_mw1=-40.9, # meV
102 test_Ipeak0=0.2306, # a.u.
103 test_Ipeak1=0.0956, # a.u.
104 )
105 check_magnons(bgd_filestr, bgd_hxc_scaling,
106 test_fxcs=1.0826,
107 test_mw0=-10.2, # meV
108 test_mw1=-48.0, # meV
109 test_Ipeak0=0.2321, # a.u.
110 test_Ipeak1=0.0956, # a.u.
111 )
114def check_magnons(filestr, hxc_scaling, *,
115 test_fxcs, test_mw0, test_mw1, test_Ipeak0, test_Ipeak1):
116 # Identify magnon peaks and extract kernel scaling
117 w0_w, chi0_w = read_pair_function(filestr + '_q0.csv')
118 w1_w, chi1_w = read_pair_function(filestr + '_q1.csv')
120 wpeak0, Ipeak0 = findpeak(w0_w, -chi0_w.imag / np.pi)
121 wpeak1, Ipeak1 = findpeak(w1_w, -chi1_w.imag / np.pi)
122 mw0 = wpeak0 * 1e3 # meV
123 mw1 = wpeak1 * 1e3 # meV
125 assert hxc_scaling.lambd is not None
126 fxcs = hxc_scaling.lambd
128 if world.rank == 0:
129 # import matplotlib.pyplot as plt
130 # plt.plot(w0_w, -chi0_w.imag / np.pi)
131 # plt.plot(w1_w, -chi1_w.imag / np.pi)
132 # plt.show()
134 print(fxcs, mw0, mw1, Ipeak0, Ipeak1)
136 # Test fxc scaling
137 assert fxcs == pytest.approx(test_fxcs, abs=0.005)
139 # Test magnon peaks
140 assert mw0 == pytest.approx(test_mw0, abs=5.0)
141 assert mw1 == pytest.approx(test_mw1, abs=10.0)
143 # Test peak intensities
144 assert Ipeak0 == pytest.approx(test_Ipeak0, abs=0.01)
145 assert Ipeak1 == pytest.approx(test_Ipeak1, abs=0.01)