Line data Source code
1 : !!****m* ABINIT/m_sigtk
2 : !! NAME
3 : !! m_sigtk
4 : !!
5 : !! FUNCTION
6 : !! Helper functions common to electron self-energy calculations. Provides tools to:
7 : !! Define list of k-points and bands in sel-energy matrix elements from input variables.
8 : !!
9 : !! COPYRIGHT
10 : !! Copyright (C) 2008-2026 ABINIT group (MG)
11 : !! This file is distributed under the terms of the
12 : !! GNU General Public License, see ~abinit/COPYING
13 : !! or http://www.gnu.org/copyleft/gpl.txt .
14 : !!
15 : !! SOURCE
16 :
17 : #if defined HAVE_CONFIG_H
18 : #include "config.h"
19 : #endif
20 :
21 : #include "abi_common.h"
22 :
23 : module m_sigtk
24 :
25 : use defs_basis
26 : use m_abicore
27 : use m_errors
28 : use m_ebands
29 : use m_crystal
30 : use m_xmpi
31 : use netcdf
32 : use m_nctk
33 : use m_hdr
34 : use m_dtset
35 : use m_krank
36 :
37 : use m_build_info, only : abinit_version
38 : use m_fstrings, only : sjoin, ltoa, strcat, itoa, ftoa
39 : use m_io_tools, only : open_file
40 : use defs_datatypes, only : pseudopotential_type
41 : use defs_wvltypes, only : wvl_internal_type
42 : use m_gwdefs, only : sigijtab_t, sigijtab_free
43 : use m_esymm, only : esymm_t
44 : use m_pawtab, only : pawtab_type
45 : use m_kpts, only : kpts_ibz_from_kptrlatt, kpts_timrev_from_kptopt, kpts_map
46 :
47 : implicit none
48 :
49 : private
50 :
51 : public :: sigtk_kcalc_from_nkptgw
52 : public :: sigtk_kcalc_from_qprange
53 : public :: sigtk_kcalc_from_gaps
54 : public :: sigtk_kcalc_from_erange
55 : public :: sigtk_kpts_in_erange
56 : public :: sigtk_sigma_tables
57 : public :: sigtk_multiply_by_vc_sqrt
58 : public :: sigtk_dw_tpp_red
59 : !!***
60 :
61 : ! Tables for degenerated KS states.
62 : type, public :: bids_t
63 : integer, allocatable :: vals(:)
64 : end type bids_t
65 :
66 : type, public :: degtab_t
67 : type(bids_t), allocatable :: bids(:)
68 : contains
69 : procedure :: free => degtab_free
70 : end type degtab_t
71 :
72 : public :: degtab_array_free ! Free array of degtab_t objects.
73 : !!***
74 :
75 : contains !=====================================================
76 : !!***
77 :
78 : !!****f* m_sigtk/sigtk_kcalc_from_nkptgw
79 : !! NAME
80 : !! sigtk_kcalc_from_nkptgw
81 : !!
82 : !! FUNCTION
83 : !! Initialize list of k-points and bands for self-energy matrix elements from nkptgw.
84 : !!
85 : !! INPUT
86 : !! dtset<dataset_type>=All input variables for this dataset.
87 : !! mband: Max number of bands.
88 : !!
89 : !! OUTPUT
90 : !! nkcalc: Number of k-points in self-energy matrix elements.
91 : !! kcalc(3, nkcalc): List of k-points where the self-energy is computed.
92 : !! bstart_ks(nkcalc, nsppol): Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
93 : !! nbcalc_ks(nkcalc, nsppol): Number of bands included in self-energy matrix elements for each k-point in kcalc.
94 : !!
95 : !! SOURCE
96 :
97 27 : subroutine sigtk_kcalc_from_nkptgw(dtset, mband, nkcalc, kcalc, bstart_ks, nbcalc_ks)
98 :
99 : !Arguments ------------------------------------
100 : type(dataset_type),intent(in) :: dtset
101 : integer,intent(in) :: mband
102 : integer,intent(out) :: nkcalc
103 : !arrays
104 : real(dp),allocatable,intent(out) :: kcalc(:,:)
105 : integer,allocatable,intent(out) :: bstart_ks(:,:)
106 : integer,allocatable,intent(out) :: nbcalc_ks(:,:)
107 :
108 : !Local variables ------------------------------
109 : !scalars
110 : integer :: spin, ierr, ikcalc
111 : character(len=500) :: msg
112 : ! *************************************************************************
113 :
114 27 : call wrtout(std_out, " Generating list of k-points for self-energy from kptgw and bdgw.")
115 :
116 27 : nkcalc = dtset%nkptgw
117 81 : ABI_MALLOC(kcalc, (3, nkcalc))
118 108 : ABI_MALLOC(bstart_ks, (nkcalc, dtset%nsppol))
119 81 : ABI_MALLOC(nbcalc_ks, (nkcalc, dtset%nsppol))
120 :
121 222 : kcalc = dtset%kptgw(:,1:nkcalc)
122 54 : do spin=1,dtset%nsppol
123 69 : bstart_ks(:,spin) = dtset%bdgw(1,1:nkcalc,spin)
124 96 : nbcalc_ks(:,spin) = dtset%bdgw(2,1:nkcalc,spin) - dtset%bdgw(1,1:nkcalc,spin) + 1
125 : end do
126 :
127 : ! Consistency check on bdgw and mband
128 27 : ierr = 0
129 54 : do spin=1,dtset%nsppol
130 96 : do ikcalc=1,nkcalc
131 69 : if (dtset%bdgw(2,ikcalc,spin) > mband) then
132 0 : ierr = ierr + 1
133 : write(msg,'(a,2(i0,1x),2(a,i0))')&
134 0 : "For (k, s) ",ikcalc,spin," bdgw= ",dtset%bdgw(2,ikcalc,spin), " > mband = ",mband
135 0 : ABI_WARNING(msg)
136 : end if
137 : end do
138 : end do
139 27 : ABI_CHECK(ierr == 0, "Not enough bands in WFK file. See messages above. Aborting now.")
140 :
141 27 : end subroutine sigtk_kcalc_from_nkptgw
142 : !!***
143 :
144 : !!****f* m_sigtk/sigtk_kcalc_from_qprange
145 : !! NAME
146 : !! sigtk_kcalc_from_qprange
147 : !!
148 : !! FUNCTION
149 : !! Use qprange to select the interesting k-points and the corresponding bands.
150 : !!
151 : !! 0 --> Compute the QP corrections only for the fundamental and the direct gap.
152 : !! +num --> Compute the QP corrections for all the k-points in the irreducible zone and include `num`
153 : !! bands above and below the Fermi level.
154 : !! -num --> Compute the QP corrections for all the k-points in the irreducible zone.
155 : !! Include all occupied states and `num` empty states.
156 : !!
157 : !! INPUT
158 : !! dtset<dataset_type>=All input variables for this dataset.
159 : !! cryst<crystal_t>=Crystalline structure
160 : !! ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
161 : !! qprange: See above description
162 : !!
163 : !! OUTPUT
164 : !! nkcalc: Number of k-points in self-energy matrix elements.
165 : !! kcalc(3, nkcalc): List of k-points where the self-energy is computed.
166 : !! bstart_ks(nkcalc, nsppol): Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
167 : !! nbcalc_ks(nkcalc, nsppol): Number of bands included in self-energy matrix elements for each k-point in kcalc.
168 : !!
169 : !! SOURCE
170 :
171 11 : subroutine sigtk_kcalc_from_qprange(dtset, cryst, ebands, qprange, nkcalc, kcalc, bstart_ks, nbcalc_ks)
172 :
173 : !Arguments ------------------------------------
174 : type(dataset_type),intent(in) :: dtset
175 : type(crystal_t),intent(in) :: cryst
176 : type(ebands_t),intent(in) :: ebands
177 : integer,intent(in) :: qprange
178 : integer,intent(out) :: nkcalc
179 : !arrays
180 : real(dp),allocatable,intent(out) :: kcalc(:,:)
181 : integer,allocatable,intent(out) :: bstart_ks(:,:), nbcalc_ks(:,:)
182 :
183 : !Local variables ------------------------------
184 : !scalars
185 : integer :: spin, ik, bstop, mband, sigma_nkbz
186 : !arrays
187 22 : integer :: kptrlatt(3,3), val_indices(ebands%nkpt, ebands%nsppol)
188 11 : real(dp),allocatable :: sigma_wtk(:),sigma_kbz(:,:)
189 : ! *************************************************************************
190 :
191 11 : mband = ebands%mband
192 :
193 11 : val_indices = ebands%get_valence_idx()
194 :
195 32 : if (any(dtset%sigma_ngkpt /= 0)) then
196 4 : call wrtout(std_out, " Generating list of k-points for self-energy from sigma_ngkpt and qprange.")
197 4 : ABI_CHECK(qprange /= 0, "qprange must be != 0")
198 : ! Get %kcalc from sigma_ngkpt
199 4 : kptrlatt = 0
200 4 : kptrlatt(1,1) = dtset%sigma_ngkpt(1); kptrlatt(2,2) = dtset%sigma_ngkpt(2); kptrlatt(3,3) = dtset%sigma_ngkpt(3)
201 : call kpts_ibz_from_kptrlatt(cryst, kptrlatt, dtset%kptopt, dtset%sigma_nshiftk, dtset%sigma_shiftk, &
202 4 : nkcalc, kcalc, sigma_wtk, sigma_nkbz, sigma_kbz)
203 4 : ABI_FREE(sigma_kbz)
204 4 : ABI_FREE(sigma_wtk)
205 : else
206 : ! Include all the k-points in the IBZ.
207 : ! Note that kcalc == ebands%kptns so we can use a single ik index in the loop over k-points.
208 : ! No need to map kcalc onto ebands%kptns.
209 7 : call wrtout(std_out, " nkptgw set to 0 ==> Include all k-points in the IBZ for Sigma_nk.")
210 7 : nkcalc = ebands%nkpt
211 21 : ABI_MALLOC(kcalc, (3, nkcalc))
212 238 : kcalc = ebands%kptns
213 : end if
214 :
215 44 : ABI_MALLOC(bstart_ks, (nkcalc, dtset%nsppol))
216 33 : ABI_MALLOC(nbcalc_ks, (nkcalc, dtset%nsppol))
217 :
218 11 : if (qprange > 0) then
219 11 : call wrtout(std_out, " Using buffer of bands above and below the Fermi level.")
220 22 : do spin=1,dtset%nsppol
221 90 : do ik=1,nkcalc
222 68 : bstart_ks(ik,spin) = max(val_indices(ik,spin) - qprange, 1)
223 68 : bstop = min(val_indices(ik,spin) + qprange, mband)
224 79 : nbcalc_ks(ik,spin) = bstop - bstart_ks(ik,spin) + 1
225 : end do
226 : end do
227 :
228 : else
229 0 : call wrtout(std_out, " Including all occupied states and -qprange empty states.")
230 0 : bstart_ks = 1
231 0 : do spin=1,dtset%nsppol
232 0 : do ik=1,nkcalc
233 0 : nbcalc_ks(ik,spin) = min(val_indices(ik,spin) - qprange, mband)
234 : end do
235 : end do
236 : end if
237 :
238 11 : end subroutine sigtk_kcalc_from_qprange
239 : !!***
240 :
241 : !!****f* m_sigtk/sigtk_kcalc_from_gaps
242 : !! NAME
243 : !! sigtk_kcalc_from_gaps
244 : !!
245 : !! FUNCTION
246 : !! Select list of k-points and bands for self-energy matrix elements so that fundamental and direct gaps are included.
247 : !!
248 : !! INPUT
249 : !! dtset<dataset_type>=All input variables for this dataset.
250 : !! ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
251 : !! gaps<gaps_t>=Store location of gaps.
252 : !!
253 : !! OUTPUT
254 : !! nkcalc: Number of k-points in self-energy matrix elements.
255 : !! kcalc(3, nkcalc): List of k-points where the self-energy is computed.
256 : !! bstart_ks(nkcalc, nsppol): Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
257 : !! nbcalc_ks(nkcalc, nsppol): Number of bands included in self-energy matrix elements for each k-point in kcalc.
258 : !!
259 : !! SOURCE
260 :
261 14 : subroutine sigtk_kcalc_from_gaps(dtset, ebands, gaps, nkcalc, kcalc, bstart_ks, nbcalc_ks)
262 :
263 : !Arguments ------------------------------------
264 : type(dataset_type),intent(in) :: dtset
265 : type(ebands_t),intent(in) :: ebands
266 : type(gaps_t) :: gaps
267 : integer,intent(out) :: nkcalc
268 : !arrays
269 : real(dp),allocatable,intent(out) :: kcalc(:,:)
270 : integer,allocatable,intent(out) :: bstart_ks(:,:)
271 : integer,allocatable,intent(out) :: nbcalc_ks(:,:)
272 :
273 : !Local variables ------------------------------
274 : !scalars
275 : integer :: spin, nsppol, ii, ik_ibz, nk_found, ifo, jj, ib_min, ib_max
276 : logical :: found, changed
277 : !arrays
278 28 : integer :: val_indices(ebands%nkpt, ebands%nsppol), kpos(6)
279 : ! *************************************************************************
280 :
281 : ABI_UNUSED((/dtset%natom/))
282 :
283 14 : call wrtout(std_out, " Including direct and fundamental KS gap in Sigma_nk")
284 28 : ABI_CHECK(maxval(gaps%ierr) == 0, "qprange 0 cannot be used because I cannot find the gap (gap_err !=0)")
285 :
286 14 : nsppol = ebands%nsppol
287 14 : val_indices = ebands%get_valence_idx()
288 :
289 : ! Include the direct and the fundamental KS gap.
290 : ! The problem here is that kptgw and nkptgw do not depend on the spin and therefore
291 : ! we have compute the union of the k-points where the fundamental and the direct gaps are located.
292 14 : nk_found = 1; kpos(1) = gaps%fo_kpos(1,1)
293 :
294 : ! Find the list of `interesting` kpoints.
295 28 : do spin=1,nsppol
296 70 : do ifo=1,3
297 42 : ik_ibz = gaps%fo_kpos(ifo, spin)
298 42 : found = .False.; jj = 0
299 84 : do while (.not. found .and. jj < nk_found)
300 42 : jj = jj + 1; found = (kpos(jj) == ik_ibz)
301 : end do
302 56 : if (.not. found) then
303 10 : nk_found = nk_found + 1; kpos(nk_found) = ik_ibz
304 : end if
305 : end do
306 : end do
307 :
308 : ! Now we can define the list of k-points and the bands range.
309 14 : nkcalc = nk_found
310 42 : ABI_MALLOC(kcalc, (3, nkcalc))
311 56 : ABI_MALLOC(bstart_ks, (nkcalc, nsppol))
312 42 : ABI_MALLOC(nbcalc_ks, (nkcalc, nsppol))
313 :
314 38 : do ii=1,nkcalc
315 24 : ik_ibz = kpos(ii)
316 96 : kcalc(:,ii) = ebands%kptns(:,ik_ibz)
317 62 : do spin=1,nsppol
318 : ! Enlarge initial band range to include degenerate states.
319 24 : ib_min = val_indices(ik_ibz, spin)
320 24 : ib_max = ib_min + 1
321 24 : call ebands%enclose_degbands(ik_ibz, spin, ib_min, ib_max, changed, dtset%symsigma_de)
322 24 : bstart_ks(ii,spin) = ib_min
323 48 : nbcalc_ks(ii,spin) = ib_max - ib_min + 1
324 : end do
325 : end do
326 :
327 14 : end subroutine sigtk_kcalc_from_gaps
328 : !!***
329 :
330 : !!****f* m_sigtk/sigtk_kcalc_from_erange
331 : !! NAME
332 : !! sigtk_kcalc_from_erange
333 : !!
334 : !! FUNCTION
335 : !! Select list of k-points and bands for self-energy matrix elements on the basis of their positions
336 : !! wrt to the (band edges|fermi level) and the value of sigma_erange.
337 : !! Useful when computing electron-lifetimes for transport calculations.
338 : !!
339 : !! INPUT
340 : !! dtset<dataset_type>=All input variables for this dataset.
341 : !! cryst<crystal_t>=Crystalline structure
342 : !! ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
343 : !! gaps<gaps_t>=Store location of gaps.
344 : !! comm: MPI communicator.
345 : !!
346 : !! OUTPUT
347 : !! nkcalc: Number of k-points in self-energy matrix elements.
348 : !! kcalc(3, nkcalc): List of k-points where the self-energy is computed.
349 : !! bstart_ks(nkcalc, nsppol): Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
350 : !! nbcalc_ks(nkcalc, nsppol): Number of bands included in self-energy matrix elements for each k-point in kcalc.
351 : !!
352 : !! SOURCE
353 :
354 14 : subroutine sigtk_kcalc_from_erange(dtset, cryst, ebands, gaps, nkcalc, kcalc, bstart_ks, nbcalc_ks, comm)
355 :
356 : !Arguments ------------------------------------
357 : type(dataset_type),intent(in) :: dtset
358 : type(crystal_t),intent(in) :: cryst
359 : type(ebands_t),intent(in) :: ebands
360 : type(gaps_t),intent(in) :: gaps
361 : integer,intent(in) :: comm
362 : integer,intent(out) :: nkcalc
363 : !arrays
364 : real(dp),allocatable,intent(out) :: kcalc(:,:)
365 : integer,allocatable,intent(out) :: bstart_ks(:,:)
366 : integer,allocatable,intent(out) :: nbcalc_ks(:,:)
367 :
368 : !Local variables ------------------------------
369 : !scalars
370 : integer,parameter :: master = 0
371 : integer :: spin, ik, band, ii, ic, nsppol, tmp_nkpt, sigma_nkbz, my_rank
372 : logical :: found
373 : real(dp) :: cmin, vmax, ee
374 : logical :: assume_gap
375 : character(len=500) :: msg
376 14 : type(krank_t) :: krank
377 : !arrays
378 28 : integer :: kptrlatt(3,3), units(1), kpos(ebands%nkpt)
379 14 : integer,allocatable :: ib_work(:,:,:), sigmak2ebands(:), indkk(:,:)
380 14 : real(dp),allocatable :: sigma_wtk(:),sigma_kbz(:,:),tmp_kcalc(:,:)
381 : ! *************************************************************************
382 :
383 14 : my_rank = xmpi_comm_rank(comm) !; nprocs = xmpi_comm_size(comm)
384 28 : units = [std_out]
385 16 : assume_gap = .not. all(dtset%sigma_erange < zero)
386 :
387 14 : if (my_rank == master) then
388 14 : write(std_out, "(a)")" Selecting k-points and bands according to their position wrt the band edges (sigma_erange)."
389 42 : write(std_out, "(a, 2(f6.3, 1x), a)")" sigma_erange: ", dtset%sigma_erange(:) * Ha_eV, " (eV)"
390 14 : if (assume_gap) then
391 26 : call gaps%print([std_out])
392 26 : ABI_CHECK(maxval(gaps%ierr) == 0, "sigma_erange 0 cannot be used because I cannot find the gap (gap_err !=0)")
393 : end if
394 : end if
395 :
396 50 : if (any(dtset%sigma_ngkpt /= 0)) then
397 2 : call wrtout(std_out, sjoin(" Generating initial list of k-points from sigma_nkpt:", ltoa(dtset%sigma_ngkpt)))
398 : ! Get tentative tmp_nkpt and tmp_kcalc from sigma_ngkpt.
399 2 : kptrlatt = 0
400 2 : kptrlatt(1,1) = dtset%sigma_ngkpt(1); kptrlatt(2,2) = dtset%sigma_ngkpt(2); kptrlatt(3,3) = dtset%sigma_ngkpt(3)
401 : call kpts_ibz_from_kptrlatt(cryst, kptrlatt, dtset%kptopt, dtset%sigma_nshiftk, dtset%sigma_shiftk, &
402 2 : tmp_nkpt, tmp_kcalc, sigma_wtk, sigma_nkbz, sigma_kbz)
403 :
404 2 : ABI_FREE(sigma_kbz)
405 2 : ABI_FREE(sigma_wtk)
406 :
407 : ! Map tmp_kcalc to ebands%kpts
408 :
409 6 : ABI_MALLOC(indkk, (6, tmp_nkpt))
410 :
411 2 : call krank%from_kptrlatt(ebands%nkpt, ebands%kptns, ebands%kptrlatt, compute_invrank=.False.)
412 :
413 2 : if (kpts_map("symrec", ebands%kptopt, cryst, krank, tmp_nkpt, tmp_kcalc, indkk) /= 0) then
414 : write(msg, '(3a)' )&
415 0 : "At least one of the k-points could not be generated from a symmetrical one in the WFK.",ch10,&
416 0 : 'Action: check your WFK file and the value of sigma_nkpt, sigma_shiftk in the input file.'
417 0 : ABI_ERROR(msg)
418 : end if
419 :
420 2 : call krank%free()
421 :
422 6 : ABI_MALLOC(sigmak2ebands, (tmp_nkpt))
423 10 : sigmak2ebands = indkk(1, :)
424 2 : ABI_FREE(tmp_kcalc)
425 2 : ABI_FREE(indkk)
426 :
427 : else
428 : ! Include all the k-points in the IBZ in the initial list.
429 12 : call wrtout(std_out, " Generating initial list of k-points from input ebands%kptns.")
430 12 : tmp_nkpt = ebands%nkpt
431 : ! Trivial map
432 36 : ABI_MALLOC(sigmak2ebands, (tmp_nkpt))
433 10506 : sigmak2ebands = [(ii, ii=1, ebands%nkpt)]
434 : end if
435 :
436 14 : nsppol = ebands%nsppol
437 56 : ABI_MALLOC(ib_work, (2, tmp_nkpt, nsppol))
438 :
439 28 : do spin=1,nsppol
440 :
441 14 : if (assume_gap) then
442 : ! Get CBM and VBM with some tolerance
443 13 : vmax = gaps%vb_max(spin) + tol2 * eV_Ha
444 13 : cmin = gaps%cb_min(spin) - tol2 * eV_Ha
445 : else
446 1 : vmax = ebands%fermie
447 1 : cmin = ebands%fermie
448 : end if
449 :
450 3528 : do ii=1,tmp_nkpt
451 : ! Index of k-point in ebands.
452 3500 : ik = sigmak2ebands(ii)
453 : ! Will use this initial values to understand if k-point is in energy window.
454 3500 : ib_work(1, ii, spin) = huge(1)
455 3500 : ib_work(2, ii, spin) = -huge(1)
456 33688 : do band=1,ebands%nband(ik + (spin-1) * ebands%nkpt)
457 30174 : ee = ebands%eig(band, ik, spin)
458 30174 : if (abs(dtset%sigma_erange(1)) > zero) then
459 3582 : if (ee <= vmax .and. vmax - ee <= abs(dtset%sigma_erange(1))) then
460 38 : ib_work(1, ii, spin) = min(ib_work(1, ii, spin), band)
461 38 : ib_work(2, ii, spin) = max(ib_work(2, ii, spin), band)
462 : !write(std_out, *), "Adding valence band", band, " with ee [eV]: ", ee * Ha_eV
463 : end if
464 : end if
465 33674 : if (abs(dtset%sigma_erange(2)) > zero) then
466 30174 : if (ee >= cmin .and. ee - cmin <= abs(dtset%sigma_erange(2))) then
467 44 : ib_work(1, ii, spin) = min(ib_work(1, ii, spin), band)
468 44 : ib_work(2, ii, spin) = max(ib_work(2, ii, spin), band)
469 : !write(std_out, *)"Adding conduction band", band, " with ee [eV]: ", ee * Ha_eV
470 : end if
471 : end if
472 : end do
473 : end do
474 : end do
475 :
476 : ! Now we can define the list of k-points and the bands range.
477 : ! The main problem here is that kptgw and nkptgw do not depend on the spin and therefore
478 : ! we have to compute the union of the k-points.
479 14 : nkcalc = 0
480 3514 : do ii=1,tmp_nkpt
481 6940 : found = .False.
482 6940 : do spin=1,nsppol
483 6940 : if (ib_work(1, ii, spin) <= ib_work(2, ii, spin)) then
484 : found = .True.; exit
485 : end if
486 : end do
487 3514 : if (found) then
488 60 : nkcalc = nkcalc + 1
489 60 : kpos(nkcalc) = ii
490 : end if
491 : end do
492 :
493 42 : ABI_MALLOC(kcalc, (3, nkcalc))
494 56 : ABI_MALLOC(bstart_ks, (nkcalc, nsppol))
495 42 : ABI_MALLOC(nbcalc_ks, (nkcalc, nsppol))
496 :
497 74 : do ic=1,nkcalc
498 : ! Index in the ib_work array
499 60 : ii = kpos(ic)
500 : ! Index in ebands.
501 60 : ik = sigmak2ebands(ii)
502 240 : kcalc(:,ic) = ebands%kptns(:,ik)
503 134 : do spin=1,nsppol
504 60 : bstart_ks(ic, spin) = 0
505 60 : nbcalc_ks(ic, spin) = 0
506 60 : if (ib_work(1, ii, spin) <= ib_work(2, ii, spin)) then
507 60 : bstart_ks(ic, spin) = ib_work(1, ii, spin)
508 60 : nbcalc_ks(ic, spin) = ib_work(2, ii, spin) - ib_work(1, ii, spin) + 1
509 : end if
510 120 : if (nbcalc_ks(ic, spin) == 0) then
511 0 : ABI_WARNING("Spin-polarized case with nbcalc_ks == 0, don't know if code can handle it!")
512 : end if
513 : end do
514 : end do
515 :
516 14 : if (my_rank == master) then
517 : ! Write info about k-points used in the calculation.
518 : write(msg, "(a, i0, a, 2(f6.3, 1x), a)") &
519 42 : " Found ", nkcalc, " k-points within sigma_erange: ", dtset%sigma_erange(:) * Ha_eV, " (eV)"
520 14 : call wrtout(units, msg)
521 50 : if (any(dtset%sigma_ngkpt /= 0)) then
522 2 : call wrtout(units, sjoin(" These k-points belong to the sigma_ngkpt k-mesh:", ltoa(dtset%sigma_ngkpt)))
523 : end if
524 162 : write(msg, "(2(a, i0))")" min(nbcalc_ks): ", minval(nbcalc_ks), " Max(nbcalc_ks): ", maxval(nbcalc_ks)
525 14 : call wrtout(units, msg)
526 : end if
527 :
528 14 : ABI_FREE(ib_work)
529 14 : ABI_FREE(sigmak2ebands)
530 :
531 14 : end subroutine sigtk_kcalc_from_erange
532 : !!***
533 :
534 : !!****f* m_sigmaph/sigtk_kpts_in_erange
535 : !! NAME
536 : !! sigtk_kpts_in_erange
537 : !!
538 : !! FUNCTION
539 : !! Use star functions interpolation and [[einterp]] to interpolate KS energies onto dense k-mesh
540 : !! defined by [[sigma_ngkpt]] and [[sigma_shiftk]].
541 : !! find k-points inside (electron/hole) pockets according to the values specified by [[sigma_erange]].
542 : !! write kerange.nc file with the tables required by abinit to automate nscf band structure calculations
543 : !! mainly used to prepare eph calculations in which only selected k-points are nededed (imaginary part of self-energies).
544 : !!
545 : !! INPUTS
546 : !! dtset <dataset_type>=all input variables for this dataset
547 : !! cryst<crystal_t>=Crystalline structure
548 : !! ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
549 : !! psps <pseudopotential_type>=all the information about psps
550 : !! pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
551 : !! prefix=Prefix for output file.
552 : !! comm: MPI communicator.
553 : !!
554 : !! SOURCE
555 :
556 2 : subroutine sigtk_kpts_in_erange(dtset, cryst, ebands, psps, pawtab, prefix, comm)
557 :
558 : !Arguments ------------------------------------
559 : !scalars
560 : type(dataset_type),intent(in) :: dtset
561 : type(crystal_t),intent(in) :: cryst
562 : type(ebands_t),intent(in) :: ebands
563 : type(pseudopotential_type),intent(in) :: psps
564 : character(len=*),intent(in) :: prefix
565 : integer,intent(in) :: comm
566 : !arrays
567 : type(pawtab_type),intent(in) :: pawtab(dtset%ntypat*psps%usepaw)
568 :
569 : !Local variables ------------------------------
570 : !scalars
571 : integer,parameter :: master = 0, pertcase0 = 0, image1 = 1
572 : integer :: ii, my_rank, nprocs, spin, ikf_ibz, band, nkpt_inerange, gap_err, unt, ncid, cnt, ncerr
573 : logical :: assume_gap
574 : real(dp) :: ee, cmin, vmax
575 : character(len=500) :: msg
576 : character(len=fnlen) :: path
577 2 : type(ebands_t) :: fine_ebands
578 2 : type(gaps_t) :: gaps, fine_gaps
579 2 : type(wvl_internal_type) :: dummy_wvl
580 2 : type(hdr_type) :: fine_hdr
581 : !arrays
582 : integer :: fine_kptrlatt(3,3), band_block(2), units(2)
583 2 : integer,allocatable :: kshe_mask(:,:,:), krange2ibz(:)
584 : real(dp) :: params(4)
585 : ! *************************************************************************
586 :
587 2 : my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
588 :
589 : ! (-num, -num) activate treatment of metals with energy window around Efermi.
590 4 : assume_gap = .not. all(dtset%sigma_erange < zero)
591 6 : units = [std_out, ab_out]
592 :
593 2 : if (my_rank == master) then
594 2 : call wrtout(units, sjoin(ch10, repeat("=", 92)))
595 2 : call wrtout(units, " Using SKW interpolation to interpolate KS energies onto dense k-mesh.")
596 2 : call wrtout(units, sjoin(" defined by sigma_ngkpt:", trim(ltoa(dtset%sigma_ngkpt))))
597 2 : ABI_CHECK(allocated(dtset%sigma_shiftk), "sigma_nshiftk must be specified in input.")
598 2 : write(std_out, "(2a)") " and sigma_shiftk shifts:"
599 4 : do ii=1,dtset%nshiftk
600 4 : call wrtout(units, sjoin(itoa(ii), ltoa(dtset%sigma_shiftk(:, ii))))
601 : end do
602 :
603 2 : if (assume_gap) then
604 1 : call wrtout(units, " Finding k-points inside (electron/hole) pockets (assuming semiconductor).")
605 : else
606 1 : call wrtout(units, " Finding k-points inside energy window around Fermi level (assuming metal).")
607 : end if
608 6 : write(msg, "(a, 2(f6.3, 1x), a)")" Using sigma_erange: ", dtset%sigma_erange(:) * Ha_eV, " (eV)"
609 2 : call wrtout(units, msg)
610 2 : call wrtout(units, sjoin(" SKW parameters (einterp): ", ltoa(dtset%einterp)))
611 2 : call wrtout(units, sjoin(repeat("=", 92), ch10))
612 : !call ebands%print([std_out], header, prtvol=dtset%prtvol)
613 :
614 : ! Consistency check.
615 2 : if (all(dtset%sigma_erange == zero)) then
616 0 : ABI_ERROR("sigma_erange must be specified in input when calling sigtk_kpts_in_erange.")
617 : end if
618 2 : if (all(dtset%sigma_ngkpt == 0)) then
619 0 : ABI_ERROR("sigma_ngkpt must be specified in input when calling sigtk_kpts_in_erange.")
620 : end if
621 : end if
622 :
623 2 : if (assume_gap) then
624 : ! Compute gaps using input ebands.
625 1 : gaps = ebands%get_gaps(gap_err)
626 1 : if (gap_err /= 0) then
627 0 : ABI_ERROR("Cannot compute fundamental and direct gap (likely metal).")
628 : end if
629 :
630 1 : if (my_rank == master) call gaps%print(units, header="Gaps from input WFK")
631 1 : call gaps%free()
632 : else
633 1 : call wrtout(units, sjoin("Using Fermi level:", ftoa(ebands%fermie * Ha_eV, fmt="f6.2"), " (eV)"))
634 : end if
635 :
636 : ! Interpolate band energies with star functions.
637 : ! In the EPH code, we will need eigens in the IBZ to compute efermi not just energies inside pockets.
638 2 : fine_kptrlatt = 0
639 8 : do ii=1,3
640 8 : fine_kptrlatt(ii, ii) = dtset%sigma_ngkpt(ii)
641 : end do
642 6 : band_block = [1, ebands%mband]
643 10 : params = 0; params(1) = 1; params(2) = 5; if (nint(dtset%einterp(1)) == 1) params = dtset%einterp
644 :
645 : fine_ebands = ebands%interp_kmesh(cryst, params, fine_kptrlatt, &
646 2 : dtset%sigma_nshiftk, dtset%sigma_shiftk, band_block, comm)
647 176 : fine_ebands%istwfk = 1
648 :
649 2 : call fine_ebands%update_occ(dtset%spinmagntarget, prtvol=dtset%prtvol)
650 4 : call fine_ebands%print([std_out], header="FINE EBANDS", prtvol=dtset%prtvol)
651 :
652 2 : if (assume_gap) then
653 : ! Compute gaps using fine_ebands.
654 1 : fine_gaps = fine_ebands%get_gaps(gap_err)
655 1 : if (gap_err /= 0) then
656 0 : ABI_ERROR("Cannot compute fundamental and direct gap (likely metal).")
657 : end if
658 :
659 1 : if (my_rank == master) call fine_gaps%print(units, header="Gaps from SKW interpolated eigenvalues")
660 : end if
661 :
662 : ! Build new header with fine k-mesh (note kptrlatt_orig == kptrlatt)
663 : call fine_hdr%init_lowlvl(fine_ebands, psps, pawtab, dummy_wvl, abinit_version, pertcase0, &
664 : dtset%natom, dtset%nsym, dtset%nspden, dtset%ecut, dtset%pawecutdg, dtset%ecutsm, dtset%dilatmx, &
665 : dtset%intxc, dtset%ixc, dtset%stmbias, dtset%usewvl, dtset%pawcpxocc, dtset%pawspnorb, dtset%ngfft, dtset%ngfftdg, &
666 : dtset%so_psp, dtset%qptn, cryst%rprimd, cryst%xred, cryst%symrel, cryst%tnons, cryst%symafm, cryst%typat, &
667 : dtset%amu_orig(:, image1), dtset%icoulomb, &
668 : dtset%kptopt, dtset%nelect, dtset%ne_qFD, dtset%nh_qFD, dtset%ivalence, dtset%cellcharge(1), &
669 2 : fine_kptrlatt, fine_kptrlatt, dtset%sigma_nshiftk, dtset%sigma_nshiftk, dtset%sigma_shiftk, dtset%sigma_shiftk)
670 :
671 : ! Find k-points inside sigma_erange energy window.
672 : ! Set entry to the number of states inside the pocket at (ikpt, spin)
673 : ! (last index discerns between hole and electron pockets)
674 366 : ABI_ICALLOC(kshe_mask, (fine_ebands%nkpt, ebands%nsppol, 2))
675 :
676 4 : do spin=1,ebands%nsppol
677 : ! Get CBM and VBM with some tolerance.
678 2 : if (assume_gap) then
679 1 : vmax = fine_gaps%vb_max(spin) + tol2 * eV_Ha
680 1 : cmin = fine_gaps%cb_min(spin) - tol2 * eV_Ha
681 : else
682 : ! Note that we use the Fermi level from ebands instead of fine_ebands.
683 1 : vmax = ebands%fermie
684 1 : cmin = ebands%fermie
685 : end if
686 :
687 178 : do ikf_ibz=1,fine_ebands%nkpt
688 3111 : do band=1,ebands%mband
689 2952 : ee = fine_ebands%eig(band, ikf_ibz, spin)
690 : ! Check whether the interpolated eigenvalue is inside the sigma_erange window.
691 2952 : if (abs(dtset%sigma_erange(1)) > zero) then
692 2952 : if (ee <= vmax .and. vmax - ee <= abs(dtset%sigma_erange(1))) then
693 11 : kshe_mask(ikf_ibz, spin, 1) = kshe_mask(ikf_ibz, spin, 1) + 1; exit
694 : end if
695 : end if
696 3098 : if (abs(dtset%sigma_erange(2)) > zero) then
697 2941 : if (ee >= cmin .and. ee - cmin <= abs(dtset%sigma_erange(2))) then
698 6 : kshe_mask(ikf_ibz, spin, 2) = kshe_mask(ikf_ibz, spin, 2) + 1; exit
699 : end if
700 : end if
701 : end do
702 : end do
703 : end do
704 :
705 : ! Build list of k-points inside pockets. Use over dimensioned array.
706 358 : cnt = count(kshe_mask /= 0)
707 6 : ABI_MALLOC(krange2ibz, (cnt))
708 176 : cnt = 0
709 176 : do ikf_ibz=1,fine_ebands%nkpt
710 816 : if (any(kshe_mask(ikf_ibz,:,:) /= 0)) then
711 17 : cnt = cnt + 1; krange2ibz(cnt) = ikf_ibz
712 : end if
713 : end do
714 2 : nkpt_inerange = cnt
715 :
716 : ! Possible extensions that may be implemented at this level:
717 : ! 1. Find image points in the BZ?
718 : ! 2. Compute tetra and q-points for EPH calculation or use +/- wmax window and heuristic approach in sigmaph at runtime?
719 : ! 3. Compute SKW 1st and 2nd derivatives needed to treat Frohlich?
720 :
721 : ! Write output files with k-point list.
722 2 : if (my_rank == master .and. len_trim(prefix) /= 0) then
723 2 : write(std_out, "(a,i0,a,f5.1,a)")" Found: ", nkpt_inerange, " kpoints in sigma_erange energy windows. (nkeff / nkibz): ", &
724 4 : (100.0_dp * nkpt_inerange) / fine_ebands%nkpt, " [%]"
725 :
726 : ! Write text file with Abinit input variables (mainly for testing purposes).
727 2 : path = strcat(prefix, "_KERANGE")
728 2 : if (open_file(path, msg, newunit=unt, form="formatted") /= 0) then
729 0 : ABI_ERROR(msg)
730 : end if
731 2 : write(unt, "(a)")"kptopt 0"
732 2 : write(unt, "(a, i0)")"nkpt ", nkpt_inerange
733 2 : write(unt, "(a)")"kpt"
734 19 : do ii=1,nkpt_inerange
735 19 : write(unt, "(3(es16.8,1x))") fine_ebands%kptns(:, krange2ibz(ii))
736 : end do
737 2 : write(unt, "(a, i0)")"wtk"
738 19 : do ii=1,nkpt_inerange
739 19 : write(unt, "(es16.8)") fine_ebands%wtk(krange2ibz(ii))
740 : end do
741 2 : close(unt)
742 :
743 : ! Write netcdf file used to perform NSCF run and EPH calculations with eph_task = -4.
744 2 : path = strcat(prefix, "_KERANGE.nc")
745 2 : NCF_CHECK(nctk_open_create(ncid, path, xmpi_comm_self))
746 : ! Write crystalline structure, fine_hdr and fine_ebands defined on the fine k-mesh.
747 : ! fine_ebands will be used to compare with the ab-initio NSCF eigenvalues.
748 : !
749 : ! TODO: The size of the KERANGE.nc quickly increases with the k-mesh.
750 : ! It is ~700 Mb for a ~ 300^3 grid due to occ and eigens
751 : ! But these quantities are now used in inkpts so it may be possible to avoid writing them to disk.
752 : !
753 2 : NCF_CHECK(fine_hdr%ncwrite(ncid, fform_from_ext("KERANGE.nc"), nc_define=.True.))
754 2 : NCF_CHECK(cryst%ncwrite(ncid))
755 2 : NCF_CHECK(fine_ebands%ncwrite(ncid))
756 4 : NCF_CHECK(nctk_def_dims(ncid, [nctkdim_t("nkpt_inerange", nkpt_inerange)], defmode=.True.))
757 : ! Define extra arrays.
758 : ncerr = nctk_def_arrays(ncid, [ &
759 : nctkarr_t("kshe_mask", "int", "number_of_kpoints, number_of_spins, two"), &
760 : nctkarr_t("krange2ibz", "int", "nkpt_inerange"), &
761 : nctkarr_t("sigma_erange", "dp", "two"), &
762 : nctkarr_t("einterp", "dp", "four") &
763 10 : ], defmode=.True.)
764 2 : NCF_CHECK(ncerr)
765 : ! Write extra arrays.
766 2 : NCF_CHECK(nctk_set_datamode(ncid))
767 2 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kshe_mask"), kshe_mask))
768 2 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "krange2ibz"), krange2ibz(1:nkpt_inerange)))
769 2 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "sigma_erange"), dtset%sigma_erange))
770 2 : NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "einterp"), params))
771 2 : NCF_CHECK(nf90_close(ncid))
772 : end if
773 :
774 2 : ABI_FREE(kshe_mask)
775 2 : ABI_FREE(krange2ibz)
776 :
777 2 : call fine_gaps%free(); call fine_ebands%free(); call fine_hdr%free()
778 :
779 2 : end subroutine sigtk_kpts_in_erange
780 : !!***
781 :
782 12 : subroutine degtab_free(degtab)
783 : class(degtab_t),intent(inout) :: degtab
784 : integer :: ii
785 46 : do ii=1,size(degtab%bids)
786 46 : ABI_SFREE(degtab%bids(ii)%vals)
787 : end do
788 46 : ABI_FREE(degtab%bids)
789 12 : end subroutine degtab_free
790 :
791 56 : subroutine degtab_array_free(degtab)
792 : class(degtab_t),intent(inout) :: degtab(:,:)
793 :
794 : integer :: jj, ii, ideg
795 :
796 112 : do jj=1,size(degtab, dim=2)
797 284 : do ii=1,size(degtab, dim=1)
798 172 : if (.not. allocated(degtab(ii, jj)%bids)) cycle
799 630 : do ideg=1,size(degtab(ii, jj)%bids)
800 630 : ABI_SFREE(degtab(ii, jj)%bids(ideg)%vals)
801 : end do
802 686 : ABI_SFREE(degtab(ii, jj)%bids)
803 : end do
804 : end do
805 :
806 56 : end subroutine degtab_array_free
807 : !!***
808 :
809 : !----------------------------------------------------------------------
810 :
811 : !!****f* m_sigtk/sigtk_sigma_tables
812 : !! NAME
813 : !! sigtk_sigma_tables
814 : !!
815 : !! FUNCTION
816 : !! Build tables with the band indices used to compute the matrix elements of sigma_x and sigma_c
817 : !! taking into account the kind of self-energies and symmetries from esymm.
818 : !!
819 : !! INPUTS
820 : !! nkcalc: Number of k-points to compute.
821 : !! nkibz: Number of k-points in the IBZ.
822 : !! nsppol: Number of spins.
823 : !! bstart_ks, bstop_ks: First and last band for each (ikcalc, spin).
824 : !! kcalc2ibz: Mapping kcalc --> IBZ.
825 : !! only_diago: True if only diagonal matrix elements are wanted.
826 : !! sigc_is_herm: True is Sigma_c is Hermitian.
827 : !! [esymm]: Band symmetries
828 : !!
829 : !! OUTPUT
830 : !! sigxij_tab, sigcij_tab
831 : !!
832 : !! SOURCE
833 :
834 402 : subroutine sigtk_sigma_tables(nkcalc, nkibz, nsppol, bstart_ks, bstop_ks, kcalc2ibz, &
835 0 : only_diago, sigc_is_herm, sigxij_tab, sigcij_tab, esymm)
836 :
837 : !Arguments ------------------------------------
838 : integer,intent(in) :: nkcalc, nkibz, nsppol
839 : integer,intent(in) :: bstart_ks(nkcalc, nsppol), bstop_ks(nkcalc, nsppol)
840 : logical,intent(in) :: only_diago, sigc_is_herm
841 : integer,intent(in) :: kcalc2ibz(nkcalc)
842 : type(sigijtab_t),allocatable,intent(inout) :: Sigxij_tab(:,:), Sigcij_tab(:,:)
843 : type(esymm_t),optional,intent(in) :: esymm(nkibz, nsppol)
844 :
845 : !Local variables-------------------------------
846 : !scalars
847 : integer :: spin,ikcalc,ik_ibz,bmin,bmax,bcol,brow
848 : integer :: ii,idx_x,idx_c,irr_idx1,irr_idx2
849 : !arrays
850 201 : integer,allocatable :: sigc_bidx(:), sigx_bidx(:)
851 402 : logical :: use_sym_at(nkibz, nsppol)
852 : ! *************************************************************************
853 :
854 201 : if (allocated(Sigxij_tab)) then
855 0 : call sigijtab_free(Sigxij_tab)
856 0 : ABI_FREE(Sigxij_tab)
857 : end if
858 201 : if (allocated(Sigcij_tab)) then
859 0 : call sigijtab_free(Sigcij_tab)
860 0 : ABI_FREE(Sigcij_tab)
861 : end if
862 :
863 1656 : ABI_MALLOC(Sigcij_tab, (nkcalc, nsppol))
864 1455 : ABI_MALLOC(Sigxij_tab, (nkcalc, nsppol))
865 :
866 1638 : use_sym_at = .FALSE.
867 201 : if (present(esymm)) then
868 : ! Create the Sig_ij tables taking advantage of the classification of the bands.
869 0 : do spin=1,nsppol
870 0 : do ikcalc=1,nkcalc
871 0 : ik_ibz = kcalc2ibz(ikcalc)
872 0 : use_sym_at(ik_ibz, spin) = .not. esymm(ik_ibz, spin)%failed()
873 : end do
874 : end do
875 : end if
876 :
877 406 : do spin=1,nsppol
878 1053 : do ikcalc=1,nkcalc
879 647 : ik_ibz = kcalc2ibz(ikcalc)
880 :
881 852 : if (use_sym_at(ik_ibz, spin)) then
882 0 : if (only_diago) then
883 0 : ABI_ERROR("You should not be here!")
884 : end if
885 :
886 0 : bmin = bstart_ks(ikcalc, spin); bmax = bstop_ks(ikcalc, spin)
887 0 : ABI_MALLOC(Sigxij_tab(ikcalc, spin)%col, (bmin:bmax))
888 0 : ABI_MALLOC(Sigcij_tab(ikcalc, spin)%col, (bmin:bmax))
889 :
890 0 : do bcol=bmin,bmax
891 0 : ABI_MALLOC(sigc_bidx, (bmax - bmin + 1))
892 0 : ABI_MALLOC(sigx_bidx, (bmax - bmin + 1))
893 :
894 0 : if (esymm(ik_ibz,spin)%err_status /= 0) then
895 : ! Band classification failed.
896 0 : sigc_bidx = [(ii, ii=bmin, bmax)]
897 0 : idx_c = bmax - bmin + 1
898 0 : sigx_bidx = [(ii,ii=bmin,bcol)] ! Hermitian
899 0 : idx_x = bcol - bmin + 1
900 : else
901 0 : irr_idx2 = esymm(ik_ibz,spin)%b2irrep(bcol)
902 0 : idx_c = 0
903 0 : do brow=bmin,bmax
904 0 : irr_idx1 = esymm(ik_ibz,spin)%b2irrep(brow)
905 0 : if (sigc_is_herm .and. bcol < brow) CYCLE ! Only the upper triangle for HF, SEX, or COHSEX.
906 0 : if (irr_idx1 == irr_idx2) then ! same character, add this row to the list.
907 0 : idx_c = idx_c + 1
908 0 : sigc_bidx(idx_c) = brow
909 : end if
910 : end do
911 : idx_x = 0
912 0 : do brow=bmin,bcol
913 0 : irr_idx1 = esymm(ik_ibz,spin)%b2irrep(brow)
914 : if (bcol<brow) CYCLE ! Sig_x is always Hermitian.
915 0 : if (irr_idx1 == irr_idx2) then ! same character, add this row to the list.
916 0 : idx_x = idx_x +1
917 0 : sigx_bidx(idx_x) = brow
918 : end if
919 : end do
920 : end if
921 :
922 : ! Table for Sigma_x matrix elements taking into account symmetries of the bands.
923 0 : ABI_MALLOC(Sigxij_tab(ikcalc, spin)%col(bcol)%bidx, (idx_x))
924 :
925 0 : Sigxij_tab(ikcalc, spin)%col(bcol)%size1 = idx_x
926 0 : Sigxij_tab(ikcalc, spin)%col(bcol)%bidx(:) = sigx_bidx(1:idx_x)
927 : !write(std_out,*)" Sigxij_tab: ikcalc, spin, bcol ",ikcalc,spin,bcol
928 : !write(std_out,*)" size: ",idx_x,(Sigxij_tab(ikcalc,spin)%col(bcol)%bidx(ii),ii=1,idx_x)
929 : !
930 : ! Table for Sigma_c matrix elements taking into account symmetries of the bands.
931 0 : ABI_MALLOC(Sigcij_tab(ikcalc, spin)%col(bcol)%bidx, (idx_c))
932 :
933 0 : Sigcij_tab(ikcalc, spin)%col(bcol)%size1= idx_c
934 0 : Sigcij_tab(ikcalc, spin)%col(bcol)%bidx(:) = sigc_bidx(1:idx_c)
935 : !write(std_out,*)" Sigcij_tab: ikcalc, spin, bcol ",ikcalc,spin,bcol
936 : !write(std_out,*)" size: ",idx_c,(Sigcij_tab(ikcalc,spin)%col(bcol)%bidx(ii), ii=1,idx_c)
937 :
938 0 : ABI_FREE(sigx_bidx)
939 0 : ABI_FREE(sigc_bidx)
940 : end do ! bcol
941 :
942 : else
943 : ! Symmetries cannot be used for this (k,s).
944 647 : bmin = bstart_ks(ikcalc, spin); bmax = bstop_ks(ikcalc, spin)
945 7392 : ABI_MALLOC(Sigcij_tab (ikcalc, spin)%col, (bmin:bmax))
946 6745 : ABI_MALLOC(Sigxij_tab (ikcalc, spin)%col, (bmin:bmax))
947 :
948 647 : if (only_diago) then
949 : ! QP wavefunctions == KS, therefore only diagonal elements are calculated.
950 1837 : do bcol=bmin,bmax
951 1571 : ABI_MALLOC(Sigcij_tab(ikcalc, spin)%col(bcol)%bidx, (1:1))
952 1571 : Sigcij_tab(ikcalc, spin)%col(bcol)%size1= 1
953 1571 : Sigcij_tab(ikcalc, spin)%col(bcol)%bidx(1) = bcol
954 :
955 1571 : ABI_MALLOC(Sigxij_tab(ikcalc, spin)%col(bcol)%bidx, (1:1))
956 1571 : Sigxij_tab(ikcalc, spin)%col(bcol)%size1 = 1
957 1837 : Sigxij_tab(ikcalc, spin)%col(bcol)%bidx(1) = bcol
958 : end do
959 : else
960 : ! Use QP wavefunctions, Sigma_ij matrix is sparse but we have to classify the states in sigma.
961 : ! The only thing we can do here is filling the entire matrix taking advantage of Hermiticity (if any).
962 4261 : do bcol=bmin,bmax
963 11640 : ABI_MALLOC(Sigxij_tab(ikcalc, spin)%col(bcol)%bidx, (bcol-bmin+1))
964 3880 : Sigxij_tab(ikcalc, spin)%col(bcol)%size1= bcol-bmin+1
965 50520 : Sigxij_tab(ikcalc, spin)%col(bcol)%bidx(:) = [(ii, ii=bmin,bcol)] ! Sigma_x is Hermitian.
966 : !write(std_out,*)"Sigxij_tab: ikcalc, spin, bcol ",ikcalc,spin,bcol,Sigxij_tab(ikcalc,spin)%col(bcol)%bidx(:)
967 :
968 11640 : ABI_MALLOC(sigc_bidx, (bmax-bmin+1))
969 46640 : idx_c = 0
970 46640 : do brow=bmin,bmax
971 42760 : if (sigc_is_herm .and. bcol < brow) CYCLE ! Only the upper triangle of Sigc_ij is needed (SEX, COHSEX).
972 30860 : idx_c = idx_c +1
973 46640 : sigc_bidx(idx_c) = brow
974 : end do
975 11640 : ABI_MALLOC(Sigcij_tab(ikcalc, spin)%col(bcol)%bidx,(idx_c))
976 3880 : Sigcij_tab(ikcalc, spin)%col(bcol)%size1= idx_c
977 34740 : Sigcij_tab(ikcalc, spin)%col(bcol)%bidx(:) = sigc_bidx(1:idx_c)
978 4261 : ABI_FREE(sigc_bidx)
979 : !write(std_out,*)"Sigcij_tab: ikcalc, spin, bcol ",ikcalc,spin,bcol,Sigcij_tab(ikcalc,spin)%col(bcol)%bidx(:)
980 : end do
981 : end if
982 : end if
983 :
984 : end do !ikcalc
985 : end do !spin
986 :
987 201 : end subroutine sigtk_sigma_tables
988 : !!***
989 :
990 : !!****f* m_sigtk/sigtk_multiply_by_vc_sqrt
991 : !! NAME
992 : !! sigtk_multiply_by_vc_sqrt
993 : !!
994 : !! FUNCTION
995 : !! Multiply rhotwg vector by the square root of the Coulomb term taking into account nspinor.
996 : !!
997 : !! INPUTS
998 : !! trans="C" to take the complex conjugate of rhotwg. "N" to use rhotwg directly.
999 : !! npw=Number of PWs.
1000 : !! nspinor: Number of spinor components.
1001 : !! ndat=Number of bands in rhotwh.
1002 : !! vc_sqrt: square root of the Coulomb interaction vc(q,g).
1003 : !!
1004 : !! SIDE EFFECTS
1005 : !! rhotgw:
1006 : !! In input: <k+q|e^{-i(q+g)r|k>
1007 : !! In output: <k+q|e^{-i(q+g)r|k> * vc_sqrt(q, g)
1008 : !!
1009 : !! SOURCE
1010 :
1011 779968 : subroutine sigtk_multiply_by_vc_sqrt(trans, npw, nspinor, ndat, vc_sqrt, rhotwg)
1012 :
1013 : character(len=1),intent(in) :: trans
1014 : integer,intent(in) :: npw, nspinor, ndat
1015 : complex(gwp),intent(in) :: vc_sqrt(npw)
1016 : complex(gwp),intent(inout) :: rhotwg(npw*nspinor, ndat)
1017 :
1018 : !Local variables ------------------------------
1019 : integer :: ii, spad, idat
1020 : !************************************************************************
1021 :
1022 : select case (trans)
1023 : case ("N")
1024 472192 : do idat=1, ndat
1025 708288 : do ii=1,nspinor
1026 236096 : spad = (ii-1) * npw
1027 92831424 : rhotwg(spad+1:spad+npw, idat) = rhotwg(spad+1:spad+npw, idat) * vc_sqrt(1:npw)
1028 : end do
1029 : end do
1030 :
1031 : case ("C")
1032 : ! Take the complex conjugate of rhotwg.
1033 1087744 : do idat=1, ndat
1034 1631616 : do ii=1,nspinor
1035 543872 : spad = (ii-1) * npw
1036 228971904 : rhotwg(spad+1:spad+npw, idat) = GWPC_CONJG(rhotwg(spad+1:spad+npw, idat)) * vc_sqrt(1:npw)
1037 : end do
1038 : end do
1039 :
1040 : case default
1041 779968 : ABI_ERROR(sjoin("Invalid trans", trans))
1042 : end select
1043 :
1044 779968 : end subroutine sigtk_multiply_by_vc_sqrt
1045 : !!***
1046 :
1047 : !!****f* m_sigtk/sigtk_dw_tpp_red
1048 : !! NAME
1049 : !! sigtk_dw_tpp_red
1050 : !!
1051 : !! FUNCTION
1052 : !! Compute T_pp'(q,nu) matrix in reduced coordinates.
1053 : !!
1054 : !! INPUTS
1055 : !!
1056 : !! OUTPUTS
1057 : !!
1058 : !! SOURCE
1059 :
1060 7118 : pure subroutine sigtk_dw_tpp_red(natom, displ_red, tpp_red)
1061 :
1062 : integer,intent(in) :: natom
1063 : real(dp),intent(in) :: displ_red(2, 3, natom)
1064 : complex(dp),intent(out) :: tpp_red(3*natom,3*natom)
1065 :
1066 : !Local variables ------------------------------
1067 : integer :: ip1, ip2, idir1, idir2, ipert1, ipert2
1068 : complex(dp) :: dka, dkap, dkpa, dkpap
1069 : !************************************************************************
1070 :
1071 49826 : do ip2=1,natom*3
1072 42708 : idir2 = mod(ip2-1, 3) + 1; ipert2 = (ip2 - idir2) / 3 + 1
1073 306074 : do ip1=1,natom*3
1074 256248 : idir1 = mod(ip1-1, 3) + 1; ipert1 = (ip1 - idir1) / 3 + 1
1075 : ! (k,a) (k,a')* + (k',a) (k',a')*
1076 256248 : dka = dcmplx(displ_red(1, idir1, ipert1), displ_red(2, idir1, ipert1))
1077 256248 : dkap = dcmplx(displ_red(1, idir2, ipert1), displ_red(2, idir2, ipert1))
1078 256248 : dkpa = dcmplx(displ_red(1, idir1, ipert2), displ_red(2, idir1, ipert2))
1079 256248 : dkpap = dcmplx(displ_red(1, idir2, ipert2), displ_red(2, idir2, ipert2))
1080 298956 : tpp_red(ip1, ip2) = dka * dconjg(dkap) + dkpa * dconjg(dkpap)
1081 : end do
1082 : end do
1083 :
1084 7118 : end subroutine sigtk_dw_tpp_red
1085 : !!***
1086 :
1087 0 : end module m_sigtk
1088 : !!***
|