Branch data Line data Source code
1 : : !!****m* ABINIT/m_bseinterp
2 : : !! NAME
3 : : !! m_bseinterp
4 : : !!
5 : : !! FUNCTION
6 : : !!
7 : : !! COPYRIGHT
8 : : !! Copyright (C) 2014-2026 ABINIT group (Y. Gillet, M.Giantomassi)
9 : : !! This file is distributed under the terms of the
10 : : !! GNU General Public License, see ~abinit/COPYING
11 : : !! or http://www.gnu.org/copyleft/gpl.txt .
12 : : !!
13 : : !! SOURCE
14 : :
15 : : #if defined HAVE_CONFIG_H
16 : : #include "config.h"
17 : : #endif
18 : :
19 : : #include "abi_common.h"
20 : :
21 : : MODULE m_bseinterp
22 : :
23 : : use defs_basis
24 : : use m_abicore
25 : : use m_bs_defs
26 : : use m_xmpi
27 : : use m_errors
28 : : use m_nctk
29 : : use m_haydock_io
30 : : use m_linalg_interfaces
31 : : use netcdf
32 : :
33 : : use m_fstrings, only : indent, strcat, sjoin, itoa
34 : : use defs_datatypes, only : pseudopotential_type
35 : : use m_hide_blas, only : xdotc
36 : : use m_fft_mesh, only : calc_ceigr
37 : : use m_crystal, only : crystal_t
38 : : use m_bz_mesh, only : kmesh_t
39 : : use m_double_grid, only : double_grid_t, get_kpt_from_indices_coarse
40 : : use m_wfd, only : wfdgw_t
41 : : use m_pawtab, only : pawtab_type
42 : :
43 : : implicit none
44 : :
45 : : private
46 : : !!***
47 : :
48 : : !----------------------------------------------------------------------
49 : :
50 : : !!****t* m_haydock/interpolator_t
51 : : !! NAME
52 : : !! interpolator_t
53 : : !!
54 : : !! FUNCTION
55 : : !! Store the overlap matrix elements needed for the interpolation of the BSE Hamiltonian
56 : : !!
57 : : !! TODO
58 : : !! Decide if we want to make the number of bands k-dependent.
59 : : !!
60 : : !! SOURCE
61 : :
62 : : type,public :: interpolator_t
63 : :
64 : : integer :: nvert=8
65 : : ! Number of vertices for interpolation
66 : :
67 : : integer :: method
68 : : ! Interpolation method (YG or Rohlfing & Louie or ...)
69 : :
70 : : integer :: mband_dense, mband_coarse
71 : : ! Max number of bands dense and coarse
72 : :
73 : : integer :: nsppol
74 : : ! Number of spin channels
75 : :
76 : : integer, allocatable :: corresp(:,:,:)
77 : : ! corresp(max_nreh,nvert,spin)
78 : : ! it_coarse, idiv -> it_coarse (idiv-th neighbour)
79 : :
80 : : real(dp),allocatable :: interp_factors(:,:)
81 : : ! interp_factors(nvert,ndiv)
82 : : ! index_in_fine_box -> k-point in Trans_interp
83 : :
84 : : complex(gwp),allocatable :: overlaps(:,:,:,:,:)
85 : : ! Overlaps between dense and coarse mesh
86 : : ! overlaps(mband_coarse,mband_dense,ivertex_coarse,double_grid%nkpt_dense,spin)
87 : :
88 : : complex(dp),allocatable :: btemp(:), ctemp(:)
89 : : ! Temporary arrays for work
90 : :
91 : : ! Pointers to datatypes that are already in memory
92 : : type(double_grid_t),pointer :: double_grid => null()
93 : : ! Mapping between coarse and dense mesh
94 : :
95 : : contains
96 : : procedure :: init => interpolator_init ! Construct the object
97 : : procedure :: free => interpolator_free ! Free memory
98 : : procedure :: normalize => interpolator_normalize ! Normalize the overlaps
99 : : procedure :: alloc_work => int_alloc_work ! Alloc temp memory
100 : : procedure :: int_free => int_free ! Free temp memory
101 : :
102 : : end type interpolator_t
103 : : !!***
104 : :
105 : : !----------------------------------------------------------------------
106 : :
107 : : CONTAINS !=======================================================================
108 : : !!***
109 : :
110 : : !!****f* m_bseinterp/interpolator_init
111 : : !! NAME
112 : : !! interpolator_init
113 : : !!
114 : : !! FUNCTION
115 : : !! Construct the interpolator object
116 : : !!
117 : : !! INPUTS
118 : : !!
119 : : !! OUTPUT
120 : : !!
121 : : !! SOURCE
122 : :
123 : 4 : subroutine interpolator_init(interpolator, double_grid, Wfd_dense, Wfd_coarse, &
124 : 4 : Kmesh_dense, Kmesh_coarse, BSp, Cryst, Psps, Pawtab, method)
125 : :
126 : : !Arguments ---------------------------
127 : : !scalars
128 : : class(interpolator_t),intent(inout) :: interpolator
129 : : integer,intent(in) :: method
130 : : type(double_grid_t),intent(in),target :: double_grid
131 : : type(wfdgw_t),intent(inout) :: Wfd_dense, Wfd_coarse
132 : : type(kmesh_t),intent(in) :: Kmesh_dense, Kmesh_coarse
133 : : type(excparam),intent(in) :: BSp
134 : : type(crystal_t),intent(in) :: Cryst
135 : : type(pseudopotential_type),intent(in) :: Psps
136 : : !arrays
137 : : type(pawtab_type),intent(in) :: Pawtab(Cryst%ntypat*Wfd_coarse%usepaw)
138 : :
139 : : !Local variables ---------------------
140 : : !scalars
141 : : integer :: nsppol, nvert
142 : : integer :: maxnreh, nreh1, nreh2
143 : : integer :: mbandc, mbandd, nbzd
144 : : real(dp),parameter :: threshold = 0.1_dp
145 : : !arrays
146 : : character(len=500) :: msg
147 : :
148 : : !*****************************************************************************
149 : :
150 [ - + ]: 4 : ABI_CHECK(Wfd_coarse%usepaw==0, "PAW not yet supported")
151 [ - + ]: 4 : ABI_CHECK(BSp%nsppol==1, "nsppol != 1 not yet implemented")
152 [ - + ]: 4 : ABI_CHECK(Wfd_coarse%nspinor==1, "nspinor != 1 not supported")
153 : :
154 : : ABI_UNUSED(Pawtab(1)%basis_size)
155 : : !paw_overlap(cprj1,cprj2,typat,pawtab,spinor_comm) result(onsite)
156 : :
157 : 4 : interpolator%double_grid => double_grid
158 : 4 : interpolator%mband_dense = Wfd_dense%mband
159 : 4 : interpolator%mband_coarse = Wfd_coarse%mband
160 : 4 : interpolator%method = method
161 [ + - ]: 4 : interpolator%nsppol = BSp%nsppol
162 : :
163 : : SELECT CASE(method)
164 : : CASE (BSE_INTERP_YG)
165 : : nvert = 8
166 : : CASE (BSE_INTERP_RL2)
167 : : nvert = 2
168 : : CASE (BSE_INTERP_RL)
169 : 0 : nvert = 1
170 : : CASE DEFAULT
171 : 0 : write(msg,'(a,i0)') "Wrong interpolation method: ",method
172 : 0 : ABI_ERROR(msg)
173 : : END SELECT
174 : :
175 : 4 : interpolator%nvert = nvert
176 : :
177 : 4 : mbandc = interpolator%mband_coarse
178 : 4 : mbandd = interpolator%mband_dense
179 : 4 : nbzd = double_grid%nbz_dense
180 : 4 : nsppol = interpolator%nsppol
181 [ - + + - : 28 : ABI_MALLOC(interpolator%overlaps,(mbandc,mbandd,nvert,nbzd,nsppol))
- + + - -
+ + - - +
+ - - + +
- + - + -
- + - + -
+ ]
182 : :
183 : : call int_compute_overlaps(interpolator,double_grid, Wfd_dense, Wfd_coarse, Kmesh_dense, &
184 : 4 : & Kmesh_coarse, BSp, Cryst, Psps, Pawtab)
185 : :
186 [ - + + - : 16 : ABI_MALLOC(interpolator%interp_factors,(nvert,double_grid%ndiv))
- + + - +
- + - - +
- + - + ]
187 : :
188 : 4 : call int_preprocess_tables(interpolator,double_grid)
189 : :
190 : 4 : nreh1 = BSp%nreh(1)
191 [ - + ]: 4 : nreh2 = nreh1; if(BSp%nsppol == 2) nreh2 = BSp%nreh(2)
192 : 4 : maxnreh = MAX(nreh1,nreh2)
193 : :
194 [ - + + - : 20 : ABI_MALLOC(interpolator%corresp,(maxnreh,interpolator%nvert,interpolator%nsppol))
- + + - -
+ + - + -
+ - - + -
+ - + ]
195 : :
196 : 4 : call int_compute_corresp(interpolator,BSp,double_grid)
197 : :
198 : 4 : end subroutine interpolator_init
199 : : !!***
200 : :
201 : : !-------------------------------------------------------------------
202 : :
203 : : !!****f* m_bseinterp/int_alloc_work
204 : : !! NAME
205 : : !! int_alloc_work
206 : : !!
207 : : !! FUNCTION
208 : : !! Allocate temporary arrays
209 : : !!
210 : : !! INPUTS
211 : : !!
212 : : !! SOURCE
213 : :
214 : 2 : subroutine int_alloc_work(interpolator, work_size)
215 : :
216 : : !Arguments ---------------------------
217 : : !scalars
218 : : class(interpolator_t),intent(inout) :: interpolator
219 : : integer,intent(in) :: work_size
220 : : !*****************************************************************************
221 : :
222 [ - + + - : 6 : ABI_MALLOC(interpolator%btemp,(work_size))
+ - + - -
+ - + -
+ ]
223 [ - + + - : 4 : ABI_MALLOC(interpolator%ctemp,(work_size))
- + - + -
+ ]
224 : :
225 : 2 : end subroutine int_alloc_work
226 : : !!***
227 : :
228 : : !-------------------------------------------------------------------
229 : :
230 : : !!****f* m_bseinterp/int_free
231 : : !! NAME
232 : : !! int_free
233 : : !!
234 : : !! FUNCTION
235 : : !! Deallocate temporary arrays
236 : : !!
237 : : !! SOURCE
238 : :
239 : 2 : subroutine int_free(interpolator)
240 : :
241 : : !Arguments ---------------------------
242 : : class(interpolator_t),intent(inout) :: interpolator
243 : : !*****************************************************************************
244 : :
245 [ + - ]: 2 : ABI_SFREE(interpolator%btemp)
246 [ + - ]: 2 : ABI_SFREE(interpolator%ctemp)
247 : :
248 : 2 : end subroutine int_free
249 : : !!***
250 : :
251 : : !-------------------------------------------------------------------
252 : :
253 : : !!****f* m_bseinterp/int_compute_overlaps
254 : : !! NAME
255 : : !! int_compute_overlaps
256 : : !!
257 : : !! FUNCTION
258 : : !! Compute the overlaps prefactors
259 : : !!
260 : : !! INPUTS
261 : : !!
262 : : !! OUTPUT
263 : : !!
264 : : !! SOURCE
265 : :
266 : 4 : subroutine int_compute_overlaps(interpolator, double_grid, Wfd_dense, Wfd_coarse, &
267 : 4 : Kmesh_dense, Kmesh_coarse, BSp, Cryst, Psps, Pawtab)
268 : :
269 : : !Arguments ---------------------------
270 : : !scalars
271 : : class(interpolator_t),intent(inout) :: interpolator
272 : : type(double_grid_t),intent(in),target :: double_grid
273 : : type(wfdgw_t),intent(inout) :: Wfd_dense, Wfd_coarse
274 : : type(kmesh_t),intent(in) :: Kmesh_dense, Kmesh_coarse
275 : : type(excparam),intent(in) :: BSp
276 : : type(crystal_t),intent(in) :: Cryst
277 : : type(pseudopotential_type),intent(in) :: Psps
278 : : !arrays
279 : : type(pawtab_type),intent(in) :: Pawtab(Cryst%ntypat*Wfd_coarse%usepaw)
280 : :
281 : : !Local variables ---------------------
282 : : !scalars
283 : : integer :: nprocs, my_rank, ierr
284 : : integer :: nfft, nspinor, nsppol, nvert
285 : : integer :: ib_coarse, ib_dense, ik_coarse, ik_dense
286 : : integer :: spin, iorder, ivertex, ix, iy, iz, bstart, bstop
287 : : real(dp),parameter :: threshold = 0.1_dp
288 : : complex(gwp) :: ovlp
289 : : !arrays
290 : : integer :: curindices_dense(6), curindices_coarse(3)
291 : : integer :: neighbour(3)
292 : : integer :: g0(3),g01(3),diffg0(3)
293 : 4 : complex(gwp),allocatable :: ur_coarse(:),ur_dense(:)
294 : 4 : complex(gwp),allocatable :: ceigr(:)
295 : : !*****************************************************************************
296 : :
297 : 4 : nprocs = xmpi_comm_size(Wfd_coarse%comm)
298 : 4 : my_rank = xmpi_comm_rank(Wfd_coarse%comm)
299 : :
300 : : ABI_UNUSED(Pawtab(1)%basis_size)
301 : :
302 : : ! Ensure Wfd and Wfd_coarse use the same FFT mesh.
303 : 4 : call wfd_dense%change_ngfft(Cryst,Psps,Wfd_coarse%ngfft)
304 : 4 : nfft = Wfd_coarse%nfft
305 : 4 : nspinor = Wfd_coarse%nspinor
306 : 4 : nsppol = Bsp%nsppol
307 : 4 : nvert = interpolator%nvert
308 : :
309 : : ! Allocate workspace for wavefunctions in real space.
310 [ - + + - : 12 : ABI_MALLOC(ur_coarse,(nfft*nspinor))
+ - + - -
+ - + ]
311 [ - + + - : 8 : ABI_MALLOC(ur_dense,(nfft*nspinor))
- + - + ]
312 [ - + + - : 8 : ABI_MALLOC(ceigr,(nfft*nspinor))
- + - + ]
313 : :
314 [ + + + + : 117064 : interpolator%overlaps = czero
+ + + + +
+ ]
315 : :
316 : : ! TODO
317 : : ! 1) Choose whether we want to compute only dvv, dcc or all dbb
318 : : ! 2) Check the ordering of the loops
319 : : ! 3) Improve vertex -> neighbour (in double_grid ?)
320 [ + + ]: 8 : do spin = 1,nsppol
321 [ + + ]: 264 : do ik_dense = 1,double_grid%nbz_dense
322 : :
323 : : ! MPI parallelization
324 : : ! We assume that each node owns in memory the full set of wavefunctions
325 : : ! both coarse and dense k-mesh and both spins.
326 [ + - ]: 256 : if (mod(ik_dense, nprocs) /= my_rank) cycle
327 : :
328 : : ! From ik_dense -> indices_dense
329 : 256 : iorder = double_grid%iktoint_dense(ik_dense)
330 [ + + ]: 1024 : g01 = double_grid%g0_dense(:,iorder)
331 [ + + ]: 1792 : curindices_dense = double_grid%indices_dense(:,iorder)
332 : :
333 [ + + ]: 1860 : do ivertex = 1,nvert
334 : :
335 : : ! From vertex to neighbour
336 : : ! TODO improve this part + permit to choose other neighbour (e.g. nearest neighbour for RL)
337 [ + + ]: 1600 : if(nvert > 1) then
338 : 1536 : ix = (ivertex-1)/4
339 : 1536 : iy = (ivertex-ix*4-1)/2
340 : 1536 : iz = (ivertex-ix*4-iy*2-1)
341 : : else
342 : 64 : ix = (BSp%rl_nb-1)/4
343 : 64 : iy = (BSp%rl_nb-ix*4-1)/2
344 : 64 : iz = (BSp%rl_nb-ix*4-iy*2-1)
345 : : end if
346 : :
347 [ + + ]: 6400 : neighbour = [ix,iy,iz]
348 : :
349 : : ! From indices_dense -> indices_coarse
350 [ + + ]: 6400 : curindices_coarse = curindices_dense(1:3) + neighbour(:)
351 : :
352 : : ! From indices_coarse -> ik_ibz in the coarse mesh
353 : : call get_kpt_from_indices_coarse(curindices_coarse,double_grid%maxcomp_coarse,&
354 : 1600 : & double_grid%inttoik_coarse,double_grid%g0_coarse,double_grid%nbz_closedcoarse,ik_coarse,g0)
355 : :
356 : : ! Take into account a possible umklapp between k_dense and k_coarse
357 [ + + ]: 6400 : diffg0 = g0 - g01
358 : :
359 [ + + + + : 4456 : if (ANY(diffg0/=0)) then
+ + ]
360 : : ! WARNING works only with nspinor = 1 !!!
361 : 888 : call calc_ceigr(diffg0,nfft,nspinor,Wfd_coarse%ngfft,ceigr)
362 : : end if
363 : :
364 [ + + ]: 13056 : do ib_dense = BSp%lomo_spin(spin), BSp%humo_spin(spin)
365 : : ! ur(ib_dense, ik_dense)
366 : 11200 : call wfd_dense%sym_ur(Cryst,Kmesh_dense,ib_dense,ik_dense,spin,ur_dense)
367 : :
368 [ + + + + : 31192 : if (ANY(diffg0/=0)) then
+ + ]
369 : : !ur_kbz = ur_kbz*e(ig0r)
370 [ + + ]: 25466952 : ur_dense(:) = ur_dense(:)*ceigr(:)
371 : : end if
372 : :
373 : : ! Uncomment for the complete overlap
374 : : !bstart = BSp%lomo_spin(spin); bstop = BSp%humo_spin(spin)
375 : :
376 : : ! Compute only dvv or dcc
377 [ + + ]: 11200 : if (ib_dense <= BSp%homo_spin(spin)) then
378 : : ! if ib_dense is a valence band => loop on valence bands
379 : 4800 : bstart = BSp%lomo_spin(spin); bstop = BSp%homo_spin(spin)
380 : : else
381 : : ! if ib_dense is a conduction band => loop on conduction bands
382 : 6400 : bstart = BSp%lumo_spin(spin); bstop = BSp%humo_spin(spin)
383 : : end if
384 : :
385 [ + + ]: 52800 : do ib_coarse = bstart, bstop
386 : : ! ur(ib_coarse, ik_coarse)
387 : 40000 : call wfd_coarse%sym_ur(Cryst,Kmesh_coarse,ib_coarse,ik_coarse,spin,ur_coarse)
388 : :
389 : : ! ovlp = < u_{ib_coarse,ik_coarse} | u_{ib_dense,ik_dense} >
390 : 40000 : ovlp = xdotc(nfft,ur_coarse,1,ur_dense,1)/nfft
391 : :
392 : : ! Filter too low values
393 [ + + ]: 40000 : if (ABS(ovlp) < threshold) ovlp = czero
394 : :
395 : 51200 : interpolator%overlaps(ib_coarse,ib_dense,ivertex,ik_dense,spin) = ovlp
396 : : end do ! ib_coarse
397 : :
398 : : !DBYG
399 : : ! write(std_out,*) "nb = ",neighbour
400 : : ! write(std_out,*) "(i1,i2,i3,j1,j2,j3) = ",curindices_dense
401 : : ! write(std_out,*) "ib = ",ib_dense
402 : : ! write(std_out,*) "Sum of dbb = ",REAL(SUM(GWPC_CONJG(interpolator%overlaps(:,ib_dense,ivertex,ik_dense,spin))*interpolator%overlaps(:,ib_dense,ivertex,ik_dense,spin))); call flush(std_out)
403 : : !ENDDBYG
404 : :
405 : : end do ! ib_dense
406 : : end do ! ivertex
407 : : end do ! ik_dense
408 : : end do ! spin
409 : :
410 [ - + ]: 4 : ABI_FREE(ur_coarse)
411 [ - + ]: 4 : ABI_FREE(ur_dense)
412 [ - + ]: 4 : ABI_FREE(ceigr)
413 : :
414 : : ! Gather results on each node.
415 : 4 : call xmpi_sum(interpolator%overlaps,Wfd_coarse%comm,ierr)
416 : :
417 : 4 : end subroutine int_compute_overlaps
418 : : !!***
419 : :
420 : : !----------------------------------------------------------------------
421 : :
422 : : !!****f* m_bseinterp/int_preprocess_tables
423 : : !! NAME
424 : : !! int_preprocess_tables
425 : : !!
426 : : !! FUNCTION
427 : : !! Pre-process tables to improve interpolation technique
428 : : !!
429 : : !! INPUTS
430 : : !!
431 : : !! OUTPUT
432 : : !!
433 : : !! SOURCE
434 : :
435 : 4 : subroutine int_preprocess_tables(interpolator,double_grid)
436 : :
437 : : !Argument ------------------------------------
438 : : !scalars
439 : : class(interpolator_t),intent(inout) :: interpolator
440 : : type(double_grid_t),intent(in) :: double_grid
441 : :
442 : : !Local variables -----------------------------
443 : : !scalars
444 : : integer :: iorder,ik_dense,ik_coarse
445 : : integer :: ix,iy,iz,ineighbour,curdim, curj
446 : : real(dp) :: interp_factor
447 : : !arrays
448 : : integer :: allxyz(3),curindices_dense(6)
449 : 4 : integer,allocatable :: curindex(:)
450 : : !*********************************************
451 : :
452 [ - + + - : 12 : ABI_MALLOC(curindex,(double_grid%nbz_coarse))
+ - + - -
+ - + ]
453 [ + + ]: 36 : curindex = 1
454 : :
455 [ + + + + ]: 236 : interpolator%interp_factors = zero
456 : :
457 [ + + ]: 260 : do ik_dense = 1,double_grid%nbz_dense
458 : :
459 : : ! From ik_ibz in the dense mesh -> indices_dense
460 : 256 : iorder = double_grid%iktoint_dense(ik_dense)
461 : : !g01 = double_grid%g0_dense(:,iorder)
462 : :
463 : : ! From indices_dense -> indices_coarse
464 [ + + ]: 1792 : curindices_dense = double_grid%indices_dense(:,iorder)
465 : :
466 : 256 : ik_coarse = double_grid%dense_to_coarse(ik_dense)
467 : :
468 : : ! Compute multi-linear interpolation factors
469 : : ! Loop over the neighbours
470 [ + + ]: 1856 : do ineighbour = 1,interpolator%nvert
471 : : !TODO helper function from [ix,iy,iz] -> ineighbour and vice versa
472 : 1600 : ix = (ineighbour-1)/4
473 : 1600 : iy = (ineighbour-ix*4-1)/2
474 : 1600 : iz = (ineighbour-ix*4-iy*2-1)
475 [ + + ]: 6400 : allxyz = [ix,iy,iz]
476 : 1600 : interp_factor = one
477 [ + + ]: 6400 : do curdim = 1,3
478 [ + + ]: 4800 : if (interpolator%method == BSE_INTERP_RL) then
479 : : cycle
480 [ - + ]: 4608 : else if(interpolator%method == BSE_INTERP_RL2) then
481 [ # # ]: 0 : if (curdim /= 3) cycle
482 : : end if
483 : 4608 : curj = curindices_dense(3+curdim)
484 : : interp_factor = interp_factor*((allxyz(curdim)*(curj*1.0/double_grid%kmult(curdim)))&
485 : 6400 : & +((1-allxyz(curdim))*(1-(curj*1.0/double_grid%kmult(curdim)))))
486 : : end do
487 : 1856 : interpolator%interp_factors(ineighbour,curindex(ik_coarse)) = interp_factor
488 : : end do
489 : :
490 : 260 : curindex(ik_coarse) = curindex(ik_coarse) + 1
491 : : end do
492 : :
493 [ - + ]: 4 : ABI_FREE(curindex)
494 : :
495 : 4 : end subroutine int_preprocess_tables
496 : : !!***
497 : :
498 : : !-------------------------------------------------------------------
499 : :
500 : : !!****f* m_haydock/int_compute_corresp
501 : : !! NAME
502 : : !! int_compute_corresp
503 : : !!
504 : : !! FUNCTION
505 : : !!
506 : : !! INPUTS
507 : : !! BSp<type(excparam)=The parameter for the Bethe-Salpeter run.
508 : : !! grid <double_grid_t>=Correspondence between coarse and fine k-grid
509 : : !! spin=Spin index.
510 : : !!
511 : : !! OUTPUT
512 : : !! corresp(Bsp%nreh(spin),8)= Correspondence between a transition on the
513 : : !! coarse mesh and its i-th neighbour for i in [1,2,..,8].
514 : : !!
515 : : !! TODO:
516 : : !! Some operations are faster if we allocate with shape (8,nreh(spin))
517 : : !!
518 : : !! SOURCE
519 : :
520 : 4 : subroutine int_compute_corresp(interpolator,BSp,double_grid)
521 : :
522 : : !Arguments ------------------------------------
523 : : class(interpolator_t),intent(inout) :: interpolator
524 : : type(excparam),intent(in) :: BSp
525 : : type(double_grid_t),intent(in) :: double_grid
526 : :
527 : : !Local variables ------------------------------
528 : : !scalars
529 : : integer :: spin
530 : : integer :: itt,ik_dense,ik_coarse,iorder,it_coarse
531 : : integer :: ic,iv,ik_coarse0,it_coarse0,iovlp,ix,iy,iz
532 : : !arrays
533 : : integer :: curindices_dense(6),curindices_coarse(3),g0(3),g01(3),neighbour(3)
534 : : !************************************************************************
535 : :
536 [ + + ]: 8 : do spin=1,interpolator%nsppol
537 [ + + ]: 3080 : do itt=1,BSp%nreh_interp(spin)
538 : : ! From dense itt -> ik_dense, ic, iv
539 : 3072 : ik_dense = BSp%Trans_interp(itt,spin)%k
540 : 3072 : ic = BSp%Trans_interp(itt,spin)%c
541 : 3072 : iv = BSp%Trans_interp(itt,spin)%v
542 : :
543 : : ! From ik_dense -> indices_dense
544 : 3072 : iorder = double_grid%iktoint_dense(ik_dense)
545 : 3072 : g01 = double_grid%g0_dense(:,iorder)
546 : :
547 : : ! Index of the k-point in the coarse mesh.
548 : 3072 : ik_coarse0 = double_grid%dense_to_coarse(ik_dense)
549 : 3072 : it_coarse0 = BSp%vcks2t(iv,ic,ik_coarse0,spin)
550 : :
551 : : ! From indices_dense -> indices_coarse
552 [ + + ]: 21504 : curindices_dense = double_grid%indices_dense(:,iorder)
553 : :
554 : : ! Loop over the 8 neighbors.
555 [ + + ]: 22276 : do iovlp = 1,interpolator%nvert
556 : :
557 : : !TODO : helper function from [ix,iy,iz] -> iovlp and vice versa
558 [ + + ]: 19200 : if(interpolator%nvert > 1) then
559 : 18432 : ix = (iovlp-1)/4
560 : 18432 : iy = (iovlp-ix*4-1)/2
561 : 18432 : iz = (iovlp-ix*4-iy*2-1)
562 : : else
563 : 768 : ix = (BSp%rl_nb-1)/4
564 : 768 : iy = (BSp%rl_nb-ix*4-1)/2
565 : 768 : iz = (BSp%rl_nb-ix*4-iy*2-1)
566 : : end if
567 [ + + ]: 76800 : neighbour = [ix,iy,iz]
568 : :
569 [ + + ]: 76800 : curindices_coarse = curindices_dense(1:3) + neighbour(:)
570 : :
571 : : ! From indices_coarse -> ik_ibz in the coarse mesh
572 : : call get_kpt_from_indices_coarse(curindices_coarse,double_grid%maxcomp_coarse,&
573 : 19200 : & double_grid%inttoik_coarse,double_grid%g0_coarse,double_grid%nbz_closedcoarse,ik_coarse,g0)
574 : :
575 : : ! From ik_coarse, ic, iv to it_coarse
576 : 19200 : it_coarse = BSp%vcks2t(iv,ic,ik_coarse,spin)
577 : :
578 : 22272 : interpolator%corresp(it_coarse0,iovlp,spin) = it_coarse
579 : : end do
580 : : end do ! itt
581 : : end do
582 : :
583 : 4 : end subroutine int_compute_corresp
584 : : !!***
585 : :
586 : : !----------------------------------------------------------------------
587 : :
588 : : !!****f* m_bseinterp/interpolator_normalize
589 : : !! NAME
590 : : !! interpolator_normalize
591 : : !!
592 : : !! FUNCTION
593 : : !! Normalize the overlaps so that \sum_{ib} | d_{kk'}^{b,ib} | ^2 = 1
594 : : !!
595 : : !! INPUTS
596 : : !!
597 : : !! OUTPUT
598 : : !!
599 : : !! SOURCE
600 : :
601 : 4 : subroutine interpolator_normalize(interpolator)
602 : :
603 : : !Arguments ---------------------------
604 : : class(interpolator_t),intent(inout) :: interpolator
605 : :
606 : : !Local variables ---------------------
607 : : !scalars
608 : : integer :: spin, ivertex, ib_dense, ik_dense
609 : : complex(gwp) :: sum_ovlp
610 : : !arrays
611 : 4 : complex(gwp),allocatable :: overlaps(:)
612 : : !*****************************************************************************
613 : :
614 [ - + + - : 12 : ABI_MALLOC(overlaps,(interpolator%mband_coarse))
+ - + - -
+ - + ]
615 [ + + ]: 8 : do spin = 1, interpolator%nsppol
616 [ + + ]: 33 : do ivertex = 1, interpolator%nvert
617 [ + + ]: 229 : do ib_dense = 1, interpolator%mband_dense
618 [ + + ]: 13025 : do ik_dense = 1, interpolator%double_grid%nbz_dense
619 [ + + ]: 115200 : overlaps(:) = interpolator%overlaps(:,ib_dense,ivertex,ik_dense,spin)
620 [ + + ]: 115200 : sum_ovlp = SQRT(REAL(SUM(GWPC_CONJG(overlaps(:))*overlaps(:))))
621 [ + + ]: 12800 : if (ABS(sum_ovlp) > tol6) then
622 [ + + ]: 99936 : overlaps(:) = overlaps(:)/sum_ovlp
623 : : else
624 [ + + ]: 15264 : overlaps(:) = czero
625 : : end if
626 [ + + ]: 115400 : interpolator%overlaps(:,ib_dense,ivertex,ik_dense,spin) = overlaps(:)
627 : : end do
628 : : end do
629 : : end do
630 : : end do
631 [ - + ]: 4 : ABI_FREE(overlaps)
632 : :
633 : 4 : end subroutine interpolator_normalize
634 : : !!***
635 : :
636 : : !-------------------------------------------------------------------
637 : :
638 : : !!****f* m_bseinterp/interpolator_free
639 : : !! NAME
640 : : !! interpolator_free
641 : : !!
642 : : !! FUNCTION
643 : : !! Destroy the interpolator object in memory
644 : : !!
645 : : !! SOURCE
646 : :
647 : 23 : subroutine interpolator_free(interpolator)
648 : :
649 : : !Arguments ---------------------------
650 : : class(interpolator_t),intent(inout) :: interpolator
651 : : !*****************************************************************************
652 : :
653 [ + + ]: 23 : ABI_SFREE(interpolator%overlaps)
654 [ + + ]: 23 : ABI_SFREE(interpolator%corresp)
655 [ + + ]: 23 : ABI_SFREE(interpolator%interp_factors)
656 [ + + ]: 23 : if( associated(interpolator%double_grid) ) nullify(interpolator%double_grid)
657 : :
658 : 23 : end subroutine interpolator_free
659 : : !!***
660 : :
661 : : !-------------------------------------------------------------------
662 : :
663 [ # # # # : 0 : end module m_bseinterp
# # # # #
# # # # #
# # # # #
# # # ]
664 : : !!***
|