Branch data Line data Source code
1 : : !****m* ABINIT/m_oscillators
2 : : !! NAME
3 : : !! m_oscillators
4 : : !!
5 : : !! FUNCTION
6 : : !! This module contains procedures to calculate the oscillator matrix elements used in the GW code.
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2008-2026 ABINIT group (MG)
10 : : !! This file is distributed under the terms of the
11 : : !! GNU General Public License, see ~abinit/COPYING
12 : : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : : !!
14 : : !! SOURCE
15 : :
16 : : #if defined HAVE_CONFIG_H
17 : : #include "config.h"
18 : : #endif
19 : :
20 : : #include "abi_common.h"
21 : :
22 : : module m_oscillators
23 : :
24 : : use defs_basis
25 : : use m_errors
26 : : use m_abicore
27 : : use m_fft
28 : :
29 : : use m_gwdefs, only : czero_gw
30 : : use m_fstrings, only : toupper, itoa, sjoin
31 : : use m_geometry, only : spinrot_cmat
32 : : use m_hide_blas, only : xcopy
33 : : use m_gsphere, only : gsphere_t
34 : :
35 : : implicit none
36 : :
37 : : private
38 : : !!***
39 : :
40 : : !----------------------------------------------------------------------
41 : :
42 : : public :: rho_tw_g ! Calculate rhotwg(G) = <wfn1| exp(-i(q+G).r) |wfn2>
43 : : public :: calc_wfwfg ! Calculate the Fourier transform of the product u_{bk}^*(r).u_{b"k}(r) at an arbitrary k in the BZ.
44 : : public :: sym_rhotwgq0 ! Symmetrize the oscillator matrix elements in the BZ in the special case of q = 0.
45 : : !!***
46 : :
47 : : !----------------------------------------------------------------------
48 : :
49 : : CONTAINS
50 : :
51 : : !!****f* m_oscillators/rho_tw_g
52 : : !! NAME
53 : : !! rho_tw_g
54 : : !!
55 : : !! FUNCTION
56 : : !! Calculate rhotwg(G) = <wfn1| exp(-i(q+G).r) |wfn2>
57 : : !!
58 : : !! INPUTS
59 : : !! dim_rtwg=Define the size of the output array rhotwg
60 : : !! === for nspinor==1 ===
61 : : !! dim_rtwg=1
62 : : !! === for nspinor==2 ===
63 : : !! dim_rtwg=1 if the sum of the matrix elements is wanted.
64 : : !! dim_rtwg=2 if <up|up>, <dwn|dwn> matrix elements are required
65 : : !! map2sphere= 1 to retrieve Fourier components indexed according to igfftg0.
66 : : !! 0 to retrieve Fourier components indexed according to the FFT box.
67 : : !! NOTE: If map2sphere==0 npwvec must be equal to nr
68 : : !! use_padfft= Only compatible with map2sphere 1.
69 : : !! 1 if matrix elements are calculated via zero-padded FFT.
70 : : !! 0 R-->G Transform in done on the full FFT box.
71 : : !! igfftg0(npwvec*map2sphere)=index of G-G_o in the FFT array for each G in the sphere.
72 : : !! i1=1 if kbz1 = Sk1, 2 if kbz1 = -Sk_1 (k_1 is in the IBZ)
73 : : !! i2=1 if kbz2 = Sk2, 2 if kbz2 = -Sk_2 (k_2 is in the IBZ)
74 : : !! ktabr1(nr),ktabr2(nr)= tables R^-1(r-t) for the two k-points
75 : : !! ktabp1,ktabp2 = phase factors for non-simmorphic symmetries e^{-i 2\pi kbz.\tau}
76 : : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
77 : : !! npwvec=number of plane waves (in the sphere if map2sphere==1, in the FFT box if map2sphere==1)
78 : : !! nr=number of FFT grid points
79 : : !! ndat=Number of wavefunctions to transform.
80 : : !! nspinor=number of spinorial components.
81 : : !! spinrot1(4),spinrot2(4)=components of the spinor rotation matrix. See getspinrot
82 : : !! wfn1(nr*nspinor*ndat),wfn2(nr*nspinor*ndat)=the two wavefunctions (periodic part)
83 : : !! [nhat12(2,nr,nspinor**2*ndat)]=Compensation charge in real space to be added to \Psi_1^*\Psi_2 -- Only for PAW.
84 : : !!
85 : : !! OUTPUT
86 : : !! rhotwg(npwvec)=density of a pair of states, in reciprocal space
87 : : !!
88 : : !! SOURCE
89 : :
90 [ - + ]: 5694935 : subroutine rho_tw_g(nspinor, npwvec, nr, ndat, ngfft, map2sphere, use_padfft, igfftg0, gbound, &
91 : 5694935 : wfn1, i1, ktabr1, ktabp1, spinrot1, &
92 : 5694935 : wfn2, i2, ktabr2, ktabp2, spinrot2, &
93 : 5694935 : dim_rtwg, rhotwg) !& nhat12)
94 : :
95 : : !Arguments ------------------------------------
96 : : !scalars
97 : : integer,intent(in) :: i1,i2,npwvec,nr,nspinor,dim_rtwg,map2sphere,use_padfft,ndat
98 : : complex(dp),intent(in) :: ktabp1, ktabp2
99 : : !arrays
100 : : integer,intent(in) :: gbound(:,:) !gbound(2*mgfft+8,2)
101 : : integer,intent(in) :: igfftg0(npwvec*map2sphere),ngfft(18)
102 : : integer,intent(in) :: ktabr1(nr),ktabr2(nr)
103 : : real(dp),intent(in) :: spinrot1(4),spinrot2(4)
104 : : complex(gwp),intent(in) :: wfn1(nr*nspinor*ndat),wfn2(nr*nspinor*ndat)
105 : : complex(gwp),intent(out) :: rhotwg(npwvec*dim_rtwg*ndat)
106 : : ! real(dp),optional,intent(in) :: nhat12(2,nr,nspinor**2*ndat)
107 : :
108 : : !Local variables-------------------------------
109 : : !scalars
110 : : integer :: fftcache0 = 0, gpu_option_0 = 0
111 : : integer :: ig,igfft,iab,spad1,spad2,spad0,nx,ny,nz,ldx,ldy,ldz,mgfft
112 : : type(fftbox_plan3_t) :: plan
113 : : !arrays
114 : : integer :: spinor_pad(2,4)
115 : 5694935 : complex(gwp),allocatable :: u12prod(:),cwavef1(:),cwavef2(:),cwork(:)
116 : : ! *************************************************************************
117 : :
118 : 5643847 : SELECT CASE (nspinor)
119 : : CASE (1)
120 : : ! Collinear case.
121 : : call ts_usug_kkp_bz(npwvec,nr,ndat,ngfft,map2sphere,use_padfft,igfftg0,gbound,&
122 : : wfn1,i1,ktabr1,ktabp1,&
123 : 5643847 : wfn2,i2,ktabr2,ktabp2,rhotwg)
124 : :
125 : : CASE (2)
126 : : ! Spinorial case.
127 [ - + ]: 51088 : ABI_CHECK(ndat==1,"ndat != 1 not coded")
128 [ - + + - : 153264 : ABI_MALLOC(cwavef1, (nr * nspinor * ndat))
+ - + - -
+ - + ]
129 [ - + + - : 102176 : ABI_MALLOC(cwavef2, (nr * nspinor * ndat))
- + - + ]
130 [ - + + - : 102176 : ABI_MALLOC(cwork, (nr * nspinor * ndat))
- + - + ]
131 : :
132 : 51088 : call rotate_spinor(i1, ktabr1, ktabp1, spinrot1, nr, nspinor, ndat, wfn1, cwork, cwavef1)
133 : 51088 : call rotate_spinor(i2, ktabr2, ktabp2, spinrot2, nr, nspinor, ndat, wfn2, cwork, cwavef2)
134 : :
135 [ - + ]: 51088 : ABI_FREE(cwork)
136 [ - + + - : 153264 : ABI_MALLOC(u12prod, (nr))
+ - + - -
+ - + ]
137 : :
138 [ + + ]: 459792 : spinor_pad = reshape([0, 0, nr, nr, 0, nr, nr, 0], [2, 4])
139 [ + + ]: 17654704 : rhotwg = czero_gw
140 [ + + ]: 153264 : do iab=1,2
141 : 102176 : spad1 = spinor_pad(1,iab); spad2=spinor_pad(2,iab)
142 : :
143 [ - + + + ]: 817612352 : u12prod = GWPC_CONJG(cwavef1(spad1+1:spad1+nr)) * cwavef2(spad2+1:spad2+nr)
144 : : ! Add compensation charge.
145 : : !if (PRESENT(nhat12)) u12prod = u12prod + CMPLX(nhat12(1,:,iab),nhat12(2,:,iab))
146 : :
147 : 102176 : spad0 = (iab-1)*npwvec
148 : 51088 : SELECT CASE (map2sphere)
149 : : CASE (0)
150 : : ! Need results on the full FFT box thus cannot use zero-padded FFT.
151 : 0 : call plan%init(ndat, ngfft(1:3), ngfft(1:3), ngfft(7), fftcache0, gpu_option_0)
152 : 0 : call plan%execute(u12prod, -1, ndat)
153 : 0 : call plan%free()
154 [ # # ]: 0 : if (dim_rtwg == 1) then
155 [ # # ]: 0 : rhotwg(1:npwvec) = rhotwg(1:npwvec) + u12prod
156 : : else
157 [ # # ]: 0 : rhotwg(spad0+1:spad0+npwvec) = u12prod
158 : : end if
159 : :
160 : : CASE (1)
161 : : ! Need results on the G-sphere. Call zero-padded FFT routines if required.
162 [ + - ]: 102176 : if (use_padfft == 1) then
163 [ + + ]: 408704 : nx = ngfft(1); ny = ngfft(2); nz = ngfft(3); mgfft = maxval(ngfft(1:3))
164 : 102176 : ldx = nx; ldy = ny; ldz = nz
165 [ - + - - : 102176 : call fftpad(u12prod, ngfft, nx, ny, nz, ldx, ldy, ldz, ndat, mgfft, -1, gbound)
- - - - -
+ ]
166 : : else
167 : 0 : call plan%init(ndat, ngfft(1:3), ngfft(1:3), ngfft(7), fftcache0, gpu_option_0)
168 : 0 : call plan%execute(u12prod, -1, ndat)
169 : 0 : call plan%free()
170 : : end if
171 : :
172 : : ! Have to map FFT to G-sphere.
173 [ + + ]: 102176 : if (dim_rtwg == 1) then
174 [ + + ]: 354816 : do ig=1,npwvec
175 : 342144 : igfft = igfftg0(ig)
176 : : ! G-G0 belong to the FFT mesh.
177 [ + - ]: 354816 : if (igfft /= 0) rhotwg(ig) = rhotwg(ig) + u12prod(igfft)
178 : : end do
179 : : else
180 [ + + ]: 17522048 : do ig=1,npwvec
181 : 17432544 : igfft = igfftg0(ig)
182 : : ! G-G0 belong to the FFT mesh.
183 [ + - ]: 17522048 : if (igfft /= 0) rhotwg(ig+spad0) = u12prod(igfft)
184 : : end do
185 : : end if
186 : :
187 : : CASE DEFAULT
188 [ - + - ]: 102176 : ABI_BUG("Wrong map2sphere")
189 : : END SELECT
190 : : end do !iab
191 : :
192 [ - + ]: 51088 : ABI_FREE(u12prod)
193 [ - + ]: 51088 : ABI_FREE(cwavef1)
194 [ - + ]: 51088 : ABI_FREE(cwavef2)
195 : :
196 : : CASE DEFAULT
197 : 0 : ABI_BUG('Wrong nspinor')
198 : : END SELECT
199 : :
200 [ + + + + : 45559480 : end subroutine rho_tw_g
+ + - ]
201 : : !!***
202 : :
203 : : !----------------------------------------------------------------------
204 : :
205 : : !!****f* m_oscillators/ts_usug_kkp_bz
206 : : !! NAME
207 : : !! ts_usug_kkp_bz
208 : : !!
209 : : !! FUNCTION
210 : : !! Calculate usug(G) = <u1|exp(-i(q+G).r)|u2> for ndat pair of wavefunctions
211 : : !! TODO: The routine is thread-safe hence it can be called within an OMP parallel region.
212 : : !!
213 : : !! INPUTS
214 : : !! map2sphere= 1 to retrieve Fourier components indexed according to igfftg0.
215 : : !! 0 to retrieve Fourier components indexed according to the FFT box.
216 : : !! NOTE: If map2sphere==0 npw must be equal to nr
217 : : !! use_padfft= Only compatible with map2sphere 1.
218 : : !! 1 if matrix elements are calculated via zero-padded FFT.
219 : : !! 0 R-->G Transform in done on the full FFT box.
220 : : !! igfftg0(npw*map2sphere)=index of G-G_o in the FFT array for each G in the sphere.
221 : : !! time1=1 if kbz1 = Sk1, 2 if kbz1 = -Sk_1 (k_1 is in the IBZ)
222 : : !! time2=1 if kbz2 = Sk2, 2 if kbz2 = -Sk_2 (k_2 is in the IBZ)
223 : : !! ktabr1(nr),ktabr2(nr)= tables R^-1(r-t) for the two k-points
224 : : !! ktabp1,ktabp2 = phase factors for non-simmorphic symmetries e^{-i 2\pi kbz.\tau}
225 : : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
226 : : !! npw=number of plane waves (in the sphere if map2sphere==1, in the FFT box if map2sphere==1)
227 : : !! nr=number of FFT grid points
228 : : !! ndat=Number of wavefunctions to transform.
229 : : !! u1(nr*ndat),u2(nr*ndat)=the two wavefunctions (periodic part)
230 : : !!
231 : : !! OUTPUT
232 : : !! usug(npw*ndat)=density of a pair of states, in reciprocal space
233 : : !!
234 : : !! SOURCE
235 : :
236 : 5643847 : subroutine ts_usug_kkp_bz(npw, nr, ndat, ngfft, map2sphere, use_padfft, igfftg0, gbound, &
237 : 5643847 : u1, time1, ktabr1, ktabp1, &
238 [ - + ]: 5643847 : u2, time2, ktabr2, ktabp2, usug) !& nhat12)
239 : :
240 : : !Arguments ------------------------------------
241 : : !scalars
242 : : integer,intent(in) :: time1,time2,npw,nr,map2sphere,use_padfft,ndat
243 : : complex(dp),intent(in) :: ktabp1,ktabp2
244 : : !arrays
245 : : integer,intent(in) :: gbound(:,:) !gbound(2*mgfft+8,2)
246 : : integer,intent(in) :: igfftg0(npw*map2sphere),ngfft(18)
247 : : integer,intent(in) :: ktabr1(nr),ktabr2(nr)
248 : : complex(gwp),intent(in) :: u1(nr*ndat),u2(nr*ndat)
249 : : complex(gwp),intent(out) :: usug(npw*ndat)
250 : :
251 : : !Local variables-------------------------------
252 : : !scalars
253 : : integer :: fftcache0 = 0, gpu_option_0 = 0
254 : : integer :: nx,ny,nz,ldx,ldy,ldz,mgfft
255 : : type(fftbox_plan3_t) :: plan
256 : : !arrays
257 : 5643847 : complex(gwp),allocatable :: u12prod(:)
258 : : ! *************************************************************************
259 : :
260 : : ! Form rho-twiddle(r) = u_1^*(r,b1,kbz1) u_2(r,b2,kbz2), to account for symmetries:
261 : : !
262 : : ! u(r,b,kbz) = e^{-2i\pi kibz.(R^{-1}t} u (R{^-1}(r-t), b, kibz)
263 : : ! = e^{+2i\pi kibz.(R^{-1}t} u*({R^-1}(r-t), b, kibz) for time-reversal symmetry.
264 : : !
265 [ + - + - : 16931541 : ABI_MALLOC(u12prod,(nr*ndat))
+ - - + -
+ ]
266 : 5643847 : call usur_kkp_bz(nr,ndat,time1,ktabr1,ktabp1,u1,time2,ktabr2,ktabp2,u2,u12prod)
267 : :
268 : : ! Add compensation charge.
269 : : !if (PRESENT(nhat12)) u12prod = u1prod + CMPLX(nhat12(1,:,1),nhat12(2,:,1))
270 : :
271 : 0 : SELECT CASE (map2sphere)
272 : : CASE (0)
273 : : ! Need results on the full FFT box thus cannot use zero-padded FFT.
274 : 0 : call plan%init(ndat, ngfft(1:3), ngfft(1:3), ngfft(7), fftcache0, gpu_option_0)
275 : 0 : call plan%execute(u12prod, -1, ndat)
276 : 0 : call plan%free()
277 : 0 : call xcopy(nr*ndat,u12prod,1,usug,1)
278 : :
279 : : CASE (1)
280 : : ! Need results on the G-sphere. Call zero-padded FFT routines if required.
281 [ + + ]: 5643847 : if (use_padfft==1) then
282 [ + + ]: 22526960 : nx = ngfft(1); ny = ngfft(2); nz = ngfft(3); mgfft = MAXVAL(ngfft(1:3))
283 : 5631740 : ldx=nx; ldy=ny; ldz=nz
284 [ - + - - : 5631740 : call fftpad(u12prod,ngfft,nx,ny,nz,ldx,ldy,ldz,ndat,mgfft,-1,gbound)
- - - - -
+ ]
285 : : else
286 : 12107 : call plan%init(ndat, ngfft(1:3), ngfft(1:3), ngfft(7), fftcache0, gpu_option_0)
287 : 12107 : call plan%execute(u12prod, -1, ndat)
288 : 12107 : call plan%free()
289 : : end if
290 : :
291 : : ! From the FFT to the G-sphere.
292 : 5643847 : call gw_box2gsph(nr,ndat,npw,igfftg0,u12prod,usug)
293 : :
294 : : CASE DEFAULT
295 [ - + - ]: 5643847 : ABI_BUG("Wrong map2sphere")
296 : : END SELECT
297 : :
298 [ - + ]: 5643847 : ABI_FREE(u12prod)
299 : :
300 [ + + + + : 45150776 : end subroutine ts_usug_kkp_bz
- + ]
301 : : !!***
302 : :
303 : : !----------------------------------------------------------------------
304 : :
305 : : !!****f* m_oscillators/usur_kkp_bz
306 : : !! NAME
307 : : !! usur_kkp_bz
308 : : !!
309 : : !! FUNCTION
310 : : !! Calculate u1_kbz^*(r) u2_kbz(r) in real space from the symmetric images in the IBZ.
311 : : !! Does not support spinor wavefunctions.
312 : : !!
313 : : !! INPUTS
314 : : !! nr=number of FFT grid points
315 : : !! ndat=Number of wavefunctions to transform.
316 : : !! u1(nr*ndat),u2(nr*ndat)=the two wavefunctions in the IBZ (periodic part)
317 : : !! time1=1 if kbz1 = Sk1, 2 if kbz1 = -Sk_1 (k_1 is in the IBZ)
318 : : !! time2=1 if kbz2 = Sk2, 2 if kbz2 = -Sk_2 (k_2 is in the IBZ)
319 : : !! ktabr1(nr),ktabr2(nr)= tables R^-1(r-t) for the two k-points
320 : : !! ktabp1,ktabp2 = phase factors for non-simmorphic symmetries e^{-i 2\pi kbz.\tau}
321 : : !!
322 : : !! OUTPUT
323 : : !! u12prod(nr*dat) = u1_kbz^*(r) u2_kbz(r) for the ndat pairs.
324 : : !!
325 : : !! SOURCE
326 : :
327 : 5643847 : subroutine usur_kkp_bz(nr, ndat, time1, ktabr1, ktabp1, u1, time2, ktabr2, ktabp2, u2, u12prod)
328 : :
329 : : !Arguments ------------------------------------
330 : : !scalars
331 : : integer,intent(in) :: nr,ndat,time1,time2
332 : : complex(dp),intent(in) :: ktabp1,ktabp2
333 : : !arrays
334 : : integer,intent(in) :: ktabr1(nr),ktabr2(nr)
335 : : complex(gwp),intent(in) :: u1(nr*ndat),u2(nr*ndat)
336 : : complex(gwp),intent(out) :: u12prod(nr*ndat)
337 : :
338 : : !Local variables-------------------------------
339 : : !scalars
340 : : integer :: ir,dat,padat
341 : : complex(gwp) :: my_ktabp1,my_ktabp2
342 : : !arrays
343 : 5643847 : complex(gwp),allocatable :: u1_bz(:),u2_bz(:)
344 : : ! *************************************************************************
345 : :
346 : : ! Form rho-twiddle(r)=u_1^*(r,b1,kbz1) u_2(r,b2,kbz2), to account for symmetries:
347 : : ! u(r,b,kbz)=e^{-2i\pi kibz.(R^{-1}t} u (R{^-1}(r-t),b,kibz)
348 : : ! =e^{+2i\pi kibz.(R^{-1}t} u*({R^-1}(r-t),b,kibz) for time-reversal
349 : : !
350 [ - + + - : 16931541 : ABI_MALLOC(u1_bz,(nr*ndat))
+ - + - -
+ - + ]
351 [ - + + - : 11287694 : ABI_MALLOC(u2_bz,(nr*ndat))
- + - + ]
352 : :
353 : 5643847 : my_ktabp1 = ktabp1
354 : 5643847 : my_ktabp2 = ktabp2
355 : :
356 [ - + ]: 5643847 : if (ndat==1) then
357 [ + + ]: 33854934128 : do ir=1,nr
358 : 33854934128 : u1_bz(ir) = u1(ktabr1(ir))*my_ktabp1
359 : : end do
360 [ + + ]: 33854934128 : do ir=1,nr
361 : 33854934128 : u2_bz(ir) = u2(ktabr2(ir))*my_ktabp2
362 : : end do
363 : : else
364 : : !$OMP PARALLEL PRIVATE(padat)
365 : : !$OMP DO
366 [ # # ]: 0 : do dat=1,ndat
367 : 0 : padat = (dat-1)*nr
368 [ # # ]: 0 : do ir=1,nr
369 : 0 : u1_bz(ir+padat) = u1(ktabr1(ir)+padat)*my_ktabp1
370 : : end do
371 : : end do
372 : : !$OMP END DO NOWAIT
373 : : !$OMP DO
374 [ # # ]: 0 : do dat=1,ndat
375 : 0 : padat = (dat-1)*nr
376 [ # # ]: 0 : do ir=1,nr
377 : 0 : u2_bz(ir+padat) = u2(ktabr2(ir)+padat)*my_ktabp2
378 : : end do
379 : : end do
380 : : !$OMP END DO NOWAIT
381 : : !$OMP END PARALLEL
382 : : end if
383 : :
384 : : ! Treat time-reversal.
385 : 10920594 : SELECT CASE (time1)
386 : : CASE (1)
387 [ + - ]: 5276747 : if (ndat==1) then
388 [ + + ]: 5276747 : if (time2==1) then
389 [ + + ]: 32558152608 : do ir=1,nr
390 : 32558152608 : u12prod(ir) = GWPC_CONJG(u1_bz(ir)) * u2_bz(ir)
391 : : end do
392 [ + - ]: 70980 : else if (time2==2) then
393 [ + + ]: 191450328 : do ir=1,nr
394 : 191450328 : u12prod(ir) = GWPC_CONJG(u1_bz(ir)) * GWPC_CONJG(u2_bz(ir))
395 : : end do
396 : : else
397 : 0 : ABI_ERROR("Wrong time2")
398 : : end if
399 : : else
400 [ # # ]: 0 : if (time2==1) then
401 : : !$OMP PARALLEL DO PRIVATE(padat)
402 [ # # ]: 0 : do dat=1,ndat
403 : 0 : padat = (dat-1)*nr
404 [ # # ]: 0 : do ir=1,nr
405 : 0 : u12prod(ir+padat) = GWPC_CONJG(u1_bz(ir+padat)) * u2_bz(ir+padat)
406 : : end do
407 : : end do
408 [ # # ]: 0 : else if (time2==2) then
409 : : !$OMP PARALLEL DO PRIVATE(padat)
410 [ # # ]: 0 : do dat=1,ndat
411 : 0 : padat = (dat-1)*nr
412 [ # # ]: 0 : do ir=1,nr
413 : 0 : u12prod(ir+padat) = GWPC_CONJG(u1_bz(ir+padat)) * GWPC_CONJG(u2_bz(ir+padat))
414 : : end do
415 : : end do
416 : : else
417 : 0 : ABI_ERROR("Wrong time2")
418 : : end if
419 : : end if
420 : :
421 : : CASE (2)
422 [ + - ]: 367100 : if (ndat==1) then
423 [ + + ]: 367100 : if (time2==1) then
424 [ + + ]: 805808192 : do ir=1,nr
425 : 805808192 : u12prod(ir) = u1_bz(ir) * u2_bz(ir)
426 : : end do
427 [ + - ]: 96672 : else if (time2==2) then
428 [ + + ]: 299523000 : do ir=1,nr
429 : 299523000 : u12prod(ir) = u1_bz(ir) * GWPC_CONJG(u2_bz(ir))
430 : : end do
431 : : else
432 : 0 : ABI_ERROR("Wrong time2")
433 : : end if
434 : : else
435 [ # # ]: 0 : if (time2==1) then
436 : : !$OMP PARALLEL DO PRIVATE(padat)
437 [ # # ]: 0 : do dat=1,ndat
438 : 0 : padat = (dat-1)*nr
439 [ # # ]: 0 : do ir=1,nr
440 : 0 : u12prod(ir+padat) = u1_bz(ir+padat) * u2_bz(ir+padat)
441 : : end do
442 : : end do
443 [ # # ]: 0 : else if (time2==2) then
444 : : !$OMP PARALLEL DO PRIVATE(padat)
445 [ # # ]: 0 : do dat=1,ndat
446 : 0 : padat = (dat-1)*nr
447 [ # # ]: 0 : do ir=1,nr
448 : 0 : u12prod(ir+padat) = u1_bz(ir+padat) * GWPC_CONJG(u2_bz(ir+padat))
449 : : end do
450 : : end do
451 : : else
452 : 0 : ABI_ERROR("Wrong time2")
453 : : end if
454 : : end if
455 : : CASE DEFAULT
456 [ + + - ]: 5643847 : ABI_ERROR("Wrong time1")
457 : : END SELECT
458 : :
459 [ - + ]: 5643847 : ABI_FREE(u1_bz)
460 [ - + ]: 5643847 : ABI_FREE(u2_bz)
461 : :
462 : 5643847 : end subroutine usur_kkp_bz
463 : : !!***
464 : :
465 : : !----------------------------------------------------------------------
466 : :
467 : : !!****f* m_oscillators/gw_box2gsph
468 : : !! NAME
469 : : !! gw_box2gsph
470 : : !!
471 : : !! FUNCTION
472 : : !! Trasnfer data from the FFT box to the G-sphere.
473 : : !!
474 : : !! INPUTS
475 : : !! nr=number of FFT grid points
476 : : !! ndat=Number of wavefunctions to transform.
477 : : !! npw=number of plane waves in the sphere
478 : : !! igfftg0(npw)=index of G-G_o in the FFT array for each G in the sphere.
479 : : !! iarrbox(nr*ndat)=Input array on the FFT mesh
480 : : !!
481 : : !! OUTPUT
482 : : !! oarrsph(npw*ndat)=output array on the sphere.
483 : : !!
484 : : !! SOURCE
485 : :
486 : 5643847 : subroutine gw_box2gsph(nr, ndat, npw, igfftg0, iarrbox, oarrsph)
487 : :
488 : : !Arguments ------------------------------------
489 : : !scalars
490 : : integer,intent(in) :: nr,ndat,npw
491 : : !arrays
492 : : integer,intent(in) :: igfftg0(npw)
493 : : complex(gwp),intent(in) :: iarrbox(nr*ndat)
494 : : complex(gwp),intent(out) :: oarrsph(npw*ndat)
495 : :
496 : : !Local variables-------------------------------
497 : : !scalars
498 : : integer :: ig,igfft,dat,pgsp,pfft
499 : : ! *************************************************************************
500 : :
501 [ - + ]: 5643847 : if (ndat==1) then
502 [ + + ]: 327180366 : do ig=1,npw
503 : 321536519 : igfft=igfftg0(ig)
504 [ + - ]: 327180366 : if (igfft/=0) then
505 : : ! G-G0 belongs to the FFT mesh.
506 : 321536519 : oarrsph(ig) = iarrbox(igfft)
507 : : else
508 : : ! Set this component to zero.
509 : 0 : oarrsph(ig) = czero_gw
510 : : end if
511 : : end do
512 : : else
513 : : !$OMP PARALLEL DO PRIVATE(pgsp,pfft,igfft)
514 [ # # ]: 0 : do dat=1,ndat
515 : 0 : pgsp = (dat-1)*npw
516 : 0 : pfft = (dat-1)*nr
517 [ # # ]: 0 : do ig=1,npw
518 : 0 : igfft=igfftg0(ig)
519 [ # # ]: 0 : if (igfft/=0) then
520 : : ! G-G0 belongs to the FFT mesh.
521 : 0 : oarrsph(ig+pgsp) = iarrbox(igfft+pfft)
522 : : else
523 : : ! Set this component to zero.
524 : 0 : oarrsph(ig+pgsp) = czero_gw
525 : : end if
526 : : end do
527 : : end do
528 : : end if
529 : :
530 : 5643847 : end subroutine gw_box2gsph
531 : : !!***
532 : :
533 : : !----------------------------------------------------------------------
534 : :
535 : : !!****f* m_oscillators/calc_wfwfg
536 : : !! NAME
537 : : !! calc_wfwfg
538 : : !!
539 : : !! FUNCTION
540 : : !! Calculate the Fourier transform of the product u_{bk}^*(r) u_{b"k}(r)
541 : : !! Return values on the FFT box.
542 : : !!
543 : : !! INPUTS
544 : : !! nspinor=number of spinorial components.
545 : : !! spinrot(4)=components of the spinor rotation matrix
546 : : !!
547 : : !! OUTPUT
548 : : !!
549 : : !! SOURCE
550 : :
551 : 2842 : subroutine calc_wfwfg(ktabr_k, ktabi_k, spinrot, nr, nspinor, ngfft_gw, wfr_jb, wfr_kb, wfg2_jk)
552 : :
553 : : !Arguments ------------------------------------
554 : : !scalars
555 : : integer,intent(in) :: ktabi_k,nr,nspinor
556 : : !arrays
557 : : integer,intent(in) :: ktabr_k(nr),ngfft_gw(18)
558 : : real(dp),intent(in) :: spinrot(4)
559 : : complex(gwp),intent(in) :: wfr_jb(nr*nspinor),wfr_kb(nr*nspinor)
560 : : complex(gwp),intent(out) :: wfg2_jk(nr*nspinor)
561 : :
562 : : !Local variables-------------------------------
563 : : integer,parameter :: ndat1 = 1, fftcache0 = 0, gpu_option_0 = 0
564 : : type(fftbox_plan3_t) :: plan
565 : : !arrays
566 : 2842 : complex(gwp),allocatable :: wfr2_dpcplx(:),ujb_bz(:),ukb_bz(:)
567 : : ! *************************************************************************
568 : :
569 : : ! There is no need to take into account phases arising from non-symmorphic
570 : : ! operations since the wavefunctions are evaluated at the same k-point.
571 [ + - + - : 8526 : ABI_MALLOC(wfr2_dpcplx, (nr * nspinor * ndat1))
+ - - + -
+ ]
572 : :
573 [ + + ]: 2842 : if (nspinor == 1) then
574 : 5300 : select case (ktabi_k)
575 : : case (1)
576 [ + - - + : 15955530 : wfr2_dpcplx = GWPC_CONJG(wfr_jb(ktabr_k)) * wfr_kb(ktabr_k)
- - + + ]
577 : : case (2)
578 : : ! Conjugate the product if time-reversal is used to reconstruct this k-point
579 [ + - - + : 540320 : wfr2_dpcplx = wfr_jb(ktabr_k) * GWPC_CONJG(wfr_kb(ktabr_k))
- - + + ]
580 : : case default
581 [ + + - ]: 2730 : ABI_ERROR(sjoin("Wrong ktabi_k:", itoa(ktabi_k)))
582 : : end select
583 : :
584 [ + - ]: 112 : else if (nspinor == 2) then
585 [ - + + - : 224 : ABI_MALLOC(ujb_bz, (nr * nspinor * ndat1))
- + - + ]
586 [ - + + - : 224 : ABI_MALLOC(ukb_bz, (nr * nspinor * ndat1))
- + - + ]
587 : : ! Use wfr2_dpcplx as workspace array
588 : 112 : call rotate_spinor(ktabi_k, ktabr_k, cone, spinrot, nr, nspinor, ndat1, wfr_jb, wfr2_dpcplx, ujb_bz)
589 : 112 : call rotate_spinor(ktabi_k, ktabr_k, cone, spinrot, nr, nspinor, ndat1, wfr_kb, wfr2_dpcplx, ukb_bz)
590 [ - + + + ]: 1792224 : wfr2_dpcplx = GWPC_CONJG(ujb_bz) * ukb_bz
591 [ - + ]: 112 : ABI_FREE(ujb_bz)
592 [ - + ]: 112 : ABI_FREE(ukb_bz)
593 : :
594 : : else
595 : 0 : ABI_ERROR(sjoin("Wrong nspinor:", itoa(nspinor)))
596 : : end if
597 : :
598 : : ! Transform to Fourier space (result in wfg2_jk)
599 : 2842 : call plan%init(nspinor, ngfft_gw(1:3), ngfft_gw(1:3), ngfft_gw(7), fftcache0, gpu_option_0)
600 : 2842 : call plan%execute(wfr2_dpcplx, wfg2_jk, -1, nspinor)
601 : 2842 : call plan%free()
602 [ - + ]: 2842 : ABI_FREE(wfr2_dpcplx)
603 : :
604 [ + + + + : 19894 : end subroutine calc_wfwfg
- + ]
605 : : !!***
606 : :
607 : : !----------------------------------------------------------------------
608 : :
609 : : !!****f* m_oscillators/sym_rhotwgq0
610 : : !! NAME
611 : : !! sym_rhotwgq0
612 : : !!
613 : : !! FUNCTION
614 : : !! Symmetrization of the oscillator matrix elements <k-q,b1|exp(-i(q+G).r)|k,b2> in the special case of q=0.
615 : : !! The matrix elements in the full BZ is obtained from the matrix elements in the IBZ by
616 : : !! rotating the wavefunctions and taking into account time reversal symmetry.
617 : : !! strictly speaking the symmetrization can be performed only for non-degenerate states.
618 : : !!
619 : : !! INPUTS
620 : : !! Gsph<gsphere_t>=Info on the G-sphere used to describe wavefunctions and W (the largest one is actually stored).
621 : : !! npw=Number of G-vectors
622 : : !! dim_rtwg=Number of spin-spin combinations, 1 for collinear spin, 4 is nspinor==2 (TODO NOT CODED)
623 : : !! itim_k=2 if time reversal is used to reconstruct the k in the BZ, 1 otherwise.
624 : : !! isym_k=The index of the symmetry symrec rotains k_IBZ onto k_BZ.
625 : : !! rhxtwg_in(dim_rtwg*npw)=The input matrix elements in the IBZ.
626 : : !!
627 : : !! OUTPUT
628 : : !! rhxtwg_sym(dim_rtwg*npw)=The symmetrized matrix elements in the BZ.
629 : : !!
630 : : !! NOTES
631 : : !! Let M_{G}(k,q) =<k-q,b1|exp(-i(q+G).r)|k,b2>
632 : : !! At q ==0, supposing non-degenerate bands, one obtains:
633 : : !!
634 : : !! 1) M_{ SG}( Sk) = e^{-iSG.t} M_{G} (k)
635 : : !! 2) M_{-SG}(-Sk) = e^{+iSG.t} M_{G}^* (k)
636 : : !!
637 : : !! SOURCE
638 : :
639 [ - + ]: 2084436 : function sym_rhotwgq0(itim_k, isym_k, dim_rtwg, npw, rhxtwg_in, Gsph) result(rhxtwg_sym)
640 : :
641 : : !Arguments ------------------------------------
642 : : !scalars
643 : : integer,intent(in) :: npw,dim_rtwg,itim_k,isym_k
644 : : type(gsphere_t),intent(in) :: Gsph
645 : : !arrays
646 : : complex(gwp),intent(in) :: rhxtwg_in(dim_rtwg*npw)
647 : : complex(gwp) :: rhxtwg_sym(dim_rtwg*npw)
648 : :
649 : : !Local variables ------------------------------
650 : : !scalars
651 : : integer :: ig
652 : : !************************************************************************
653 : :
654 [ - + ]: 2084436 : ABI_CHECK(dim_rtwg == 1, "dim_rtwg/=1 not coded")
655 : :
656 : 3537388 : SELECT CASE (isym_k)
657 : : CASE (1)
658 : : ! Fractional translation associated to E is assumed to be (zero,zero,zero).
659 : 2084436 : SELECT CASE (itim_k)
660 : : CASE (1)
661 : : ! Identity, no time-reversal. No symmetrization is needed.
662 [ + + ]: 62072096 : rhxtwg_sym(:) = rhxtwg_in(:)
663 : : CASE (2)
664 : : ! Identity + Time-reversal.
665 [ + + ]: 735072 : do ig=1,npw
666 : 735072 : rhxtwg_sym( Gsph%rottb(ig,itim_k,isym_k) ) = GWPC_CONJG(rhxtwg_in(ig))
667 : : end do
668 : : CASE DEFAULT
669 [ + + - ]: 1452952 : ABI_ERROR(sjoin("Wrong value of itim_k:", itoa(itim_k)))
670 : : END SELECT
671 : :
672 : : CASE DEFAULT
673 : : ! Rotate wavefunctions.
674 [ + + ]: 2084436 : SELECT CASE (itim_k)
675 : : CASE (1)
676 : : ! no time-reversal, only rotation.
677 [ + + ]: 28247440 : do ig=1,npw
678 : 28247440 : rhxtwg_sym( Gsph%rottb(ig,itim_k,isym_k) ) = rhxtwg_in(ig) * Gsph%phmSGt(ig,isym_k)
679 : : end do
680 : : CASE (2)
681 : : ! time-reversal + spatial rotation.
682 [ + + ]: 4905888 : do ig=1,npw
683 : 4905888 : rhxtwg_sym( Gsph%rottb(ig,itim_k,isym_k) ) = GWPC_CONJG( rhxtwg_in(ig) * Gsph%phmSGt(ig,isym_k) )
684 : : end do
685 : : CASE DEFAULT
686 [ + + - ]: 631484 : ABI_ERROR(sjoin("Wrong value of itim_k:", itoa(itim_k)))
687 : : END SELECT
688 : : END SELECT
689 : :
690 : 2084436 : end function sym_rhotwgq0
691 : : !!***
692 : :
693 : : !----------------------------------------------------------------------
694 : :
695 : : !!****f* m_oscillators/rotate_spinor
696 : : !! NAME
697 : : !! rotate_spinor
698 : : !!
699 : : !! FUNCTION
700 : : !! Return a spinor in the full BZ from its symmetrical image in the IBZ.
701 : : !!
702 : : !! INPUTS
703 : : !!
704 : : !! OUTPUT
705 : : !!
706 : : !! SOURCE
707 : :
708 : 102400 : subroutine rotate_spinor(itim_kbz, ktabr_kbz, ktabp_kbz, spinrot, nr, nspinor, ndat, ug_ibz, cwork, oug_bz)
709 : :
710 : : !Arguments ------------------------------------
711 : : !scalars
712 : : integer,intent(in) :: itim_kbz, nr, nspinor, ndat
713 : : complex(dp),intent(in) :: ktabp_kbz
714 : : !arrays
715 : : integer,intent(in) :: ktabr_kbz(nr)
716 : : real(dp),intent(in) :: spinrot(4)
717 : : complex(gwp),intent(in) :: ug_ibz(nr*nspinor*ndat)
718 : : complex(gwp),intent(out) :: cwork(nr*nspinor*ndat), oug_bz(nr*nspinor*ndat)
719 : :
720 : : !Local variables ------------------------------
721 : : !scalars
722 : : integer :: ir,ir1,spad0,ispinor
723 : : complex(gwp) :: u1a,u1b
724 : : !arrays
725 : : complex(dp) :: spinrot_cmat1(2,2)
726 : : !************************************************************************
727 : :
728 [ - + ]: 102400 : ABI_CHECK(ndat == 1, "ndat > 1 not coded")
729 [ - + ]: 102400 : ABI_CHECK(nspinor == 2, "nspinor should be 1")
730 : :
731 : : ! Step 1: Real-space rotation per spinor component (apply ktabr + phase).
732 : : ! This is done BEFORE time-reversal, consistent with cgtk_rotate in m_cgtk.F90:
733 : : ! u_{Sk}(r) = e^{-2i\pi k_ibz.(R^{-1}\tau)} u_{k_ibz}(R^{-1}(r-\tau))
734 [ + + ]: 307200 : do ispinor=1,nspinor
735 : 204800 : spad0 = (ispinor-1) * nr
736 [ + + ]: 1638707200 : do ir=1,nr
737 : 1638400000 : ir1 = ktabr_kbz(ir)
738 : 1638604800 : oug_bz(ir+spad0) = ug_ibz(ir1+spad0) * ktabp_kbz
739 : : end do
740 : : end do
741 : :
742 : : ! Step 2: Apply time-reversal AFTER spatial rotation (consistent with cgtk_rotate).
743 : : ! \psi_{-k}^1 = (\psi_k^2)^*
744 : : ! \psi_{-k}^2 = -(\psi_k^1)^*
745 [ - + ]: 102400 : if (itim_kbz == 2) then
746 [ # # ]: 0 : cwork(1:nr) = GWPC_CONJG(oug_bz(nr+1:2*nr))
747 [ # # ]: 0 : cwork(nr+1:2*nr) = -GWPC_CONJG(oug_bz(1:nr))
748 [ # # ]: 0 : oug_bz(:) = cwork(:)
749 : : end if
750 : :
751 : : ! Step 3: Rotation in spinor space using the INVERSE spinor rotation matrix (S^\dagger)
752 : : ! since the mapping from IBZ to BZ uses the inverse symmetry operation in real space.
753 : 102400 : spinrot_cmat1(1,1) = spinrot(1) - j_dpc*spinrot(4)
754 : 102400 : spinrot_cmat1(1,2) =-spinrot(3) - j_dpc*spinrot(2)
755 : 102400 : spinrot_cmat1(2,1) = spinrot(3) - j_dpc*spinrot(2)
756 : 102400 : spinrot_cmat1(2,2) = spinrot(1) + j_dpc*spinrot(4)
757 [ + + ]: 1638502400 : cwork = oug_bz
758 [ + + ]: 819302400 : do ir=1,nr
759 : 819200000 : u1a = cwork(ir); u1b = cwork(ir+nr)
760 : 819200000 : oug_bz(ir) = spinrot_cmat1(1, 1) * u1a + spinrot_cmat1(1, 2) * u1b
761 : 819302400 : oug_bz(ir+nr) = spinrot_cmat1(2, 1) * u1a + spinrot_cmat1(2, 2) * u1b
762 : : end do
763 : :
764 : 102400 : end subroutine rotate_spinor
765 : : !!***
766 : :
767 : : end module m_oscillators
768 : : !!***
|