Line data Source code
1 : !!****m* ABINIT/m_fstab
2 : !! NAME
3 : !! m_fstab
4 : !!
5 : !! FUNCTION
6 : !! Tools for the management of a set of Fermi surface k-points.
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2008-2026 ABINIT group (MG, MVer)
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_fstab
23 :
24 : use defs_basis
25 : use m_abicore
26 : use m_xmpi
27 : use m_errors
28 : use m_krank
29 : use m_htetra
30 : use m_ebands
31 : use m_crystal
32 : use m_dtset
33 :
34 : use m_time, only : cwtime, cwtime_report
35 : use m_fstrings, only : itoa, sjoin, ktoa
36 : use m_numeric_tools, only : bisect
37 : use m_matrix, only : matr3inv
38 : use m_special_funcs, only : gaussian
39 : use m_kpts, only : kpts_timrev_from_kptopt, smpbz, kpts_map
40 :
41 : implicit none
42 :
43 : private
44 : !!***
45 :
46 : !!****t* m_fstab/fstab_t
47 : !! NAME
48 : !! fstab_t
49 : !!
50 : !! FUNCTION
51 : !! Tables with the correspondence between k-points on the Fermi surface (FS) and k-points
52 : !! in the IBZ (i.e. the k-points found in ebands_t).
53 : !! We use `nsppol` fstab_t objects to account for spin polarization and possibly different
54 : !! number of bands crossing the Fermi level.
55 : !!
56 : !! SOURCE
57 :
58 : type,public :: fstab_t
59 :
60 : integer :: spin = -1
61 : ! Spin index
62 :
63 : integer :: nkfs = -1
64 : ! Number of k-points on the Fermi-surface in the full BZ.
65 :
66 : integer :: nktot = -1
67 : !integer :: nkbz = -1
68 : ! Total number of k-points in the initial mesh. Used to compute integrals in the BZ.
69 :
70 : integer :: nkibz = -1
71 : ! Number of points in the IBZ
72 :
73 : integer :: bmin = -1, bmax = -1
74 : ! Min and max band index included in the calculation.
75 : ! Note that these values are obtained by taking the union over the k-points in the FS
76 : ! For each k-point, we usually have a different number of states crossing eF given by bstart_cnt_ibz.
77 :
78 : integer :: maxnb = -1
79 : ! Max number of bands on the FS i.e.: bmax - bmin + 1.
80 :
81 : integer :: eph_intmeth = 1
82 : ! Integration method.
83 : ! 1 for gaussian (including adaptive broadening if eph_fsmear is negative.
84 : ! |2| for tetrahedra.
85 : ! 2 for the optimized tetrahedron method.
86 : ! -2 for the linear tetrahedron method.
87 :
88 : integer :: nene = -1
89 : ! Number of chemical potential values used for inelastic integration.
90 :
91 : real(dp) :: eph_fsmear
92 : ! Gaussian broadening. Negative value activates adaptive gaussian broadening.
93 : ! See https://journals.aps.org/prb/pdf/10.1103/PhysRevB.92.075405
94 :
95 : real(dp) :: min_smear = tol9
96 : ! Used for the adaptive gaussian broadening: use min_smear if the broadening computed from the group velocity
97 : ! is smaller than this value to avoid divergences in the gaussian.
98 :
99 : real(dp) :: enemin
100 : ! Minimal chemical potential value used for inelastic integration.
101 :
102 : real(dp) :: deltaene
103 : ! Chemical potential increment for inelastic integration.
104 :
105 : type(krank_t) :: krank
106 : ! rank/inverse_rank pair for the k-points on the FS (kpts).
107 :
108 : integer,allocatable :: indkk_fs(:,:)
109 : ! (6, nkfs)
110 : ! Table giving the correspondence between a point in the FS-BZ and the IBZ:
111 : !
112 : ! indkk_fs(1,:) Mapping FS-BZ --> k-points in the IBZ (taken from ebands_t)
113 : ! indkk_fs(2,:) The index of the symmetry S such that kfs = tim_sign * S(k_ibz) + G0
114 : ! indkk_fs(3:5,:) The reduced components of G0.
115 : ! indkk_fs(6,:) 1 if time-reversal was used to generate the k-point, 0 otherwise
116 : !
117 : ! NB: The table is generated using the symrel convention and can therefore be used to
118 : ! symmetrize wavefunctions in k-space.
119 :
120 : integer,allocatable :: bstart_cnt_ibz(:,:)
121 : ! (2, nkibz)
122 : ! The indices of the bands within the energy window (depends on fsk)
123 : ! Note that we use the k-point index in the IBZ.
124 : !
125 : ! bstcnt(1, :) The index of the first band inside the energy window (start)
126 : ! bstcnt(2, :) Number of bands on the FS (count)
127 :
128 : real(dp) :: klatt(3, 3)
129 : ! Reciprocal of lattice vectors for full kpoint grid. Used by init_tetra
130 :
131 : real(dp) :: kmesh_cartvec(3,3)
132 : ! vectors defining the k-mesh (stored as column vector in Cartesian coords.
133 : ! Used to implement the adaptive gaussian broadening.
134 :
135 : real(dp),allocatable :: kpts(:,:)
136 : ! (3, nkfs)
137 : ! Reduced coordinates of the BZ k-points on the Fermi surface.
138 :
139 : real(dp),allocatable :: vk(:,:), vkq(:,:)
140 : ! (3, mnb)
141 : ! Velocities in cartesian coordinates. Used to implement the adaptive gaussian broadening
142 : ! Values are filled by the caller (e.g. phgamma) inside the loop over k-points.
143 :
144 : real(dp),allocatable :: tetra_wtk(:,:)
145 : ! (maxnb, nkibz)
146 : ! Weights for FS integration with tetrahedron method
147 : ! Note that the weights are dimensioned with nkibz
148 : ! (1, :) corresponds to %bmin
149 :
150 : real(dp),allocatable :: tetra_wtk_ene(:,:,:)
151 : ! (maxnb, nkibz, nene)
152 : ! Weights for FS integration with tetrahedron method for all chemical potentials
153 : ! Note that the weights are dimensioned with nkibz
154 : ! (1, :) corresponds to %bmin
155 :
156 : real(dp),allocatable :: dbldelta_tetra_weights_kfs(:,:,:)
157 : ! (maxnb, maxnb, nkfs)
158 : ! (1, 1, :) corresponds to %bmin
159 :
160 : contains
161 :
162 : procedure :: free => fstab_free
163 : ! Free memory.
164 :
165 : procedure :: findkg0 => fstab_findkg0
166 : ! Find the index of the k-point on the FS
167 :
168 : procedure :: get_dbldelta_weights => fstab_get_dbldelta_weights
169 : ! Compute weights for the integration of the double-delta.
170 :
171 : end type fstab_t
172 :
173 : public :: fstab_init ! Initialize the object.
174 : public :: fstab_print ! Print the object
175 : !!***
176 :
177 : !----------------------------------------------------------------------
178 :
179 : contains !============================================================
180 : !!***
181 :
182 : !!****f* m_fstab/fstab_free
183 : !! NAME
184 : !! fstab_free
185 : !!
186 : !! FUNCTION
187 : !! Free memory
188 : !!
189 : !! SOURCE
190 :
191 5 : subroutine fstab_free(fstab)
192 :
193 : !Arguments ------------------------------------
194 : class(fstab_t),intent(inout) :: fstab
195 : ! ************************************************************************
196 :
197 : ! integer
198 5 : ABI_SFREE(fstab%indkk_fs)
199 5 : ABI_SFREE(fstab%bstart_cnt_ibz)
200 :
201 : ! real
202 5 : ABI_SFREE(fstab%kpts)
203 5 : ABI_SFREE(fstab%vk)
204 5 : ABI_SFREE(fstab%vkq)
205 5 : ABI_SFREE(fstab%tetra_wtk)
206 5 : ABI_SFREE(fstab%tetra_wtk_ene)
207 5 : ABI_SFREE(fstab%dbldelta_tetra_weights_kfs)
208 :
209 : ! types
210 5 : call fstab%krank%free()
211 :
212 5 : end subroutine fstab_free
213 : !!***
214 :
215 : !----------------------------------------------------------------------
216 :
217 : !!****f* m_fstab/fstab_init
218 : !! NAME
219 : !! fstab_init
220 : !!
221 : !! FUNCTION
222 : !! Initialize the tables for the FS integration.
223 : !!
224 : !! INPUTS
225 : !! ebands<ebands_t>=The object describing the band structure.
226 : !! cryst<crystal_t>=Info on the crystalline structure.
227 : !! dtset:
228 : !! eph_fsewin=Energy window in Hartree. Only states in [efermi-fsewin, efermi+fsewin] are included.
229 : !! eph_intmeth=Flag selecting the integration method.
230 : !! kptrlatt(3,3)=k-point lattice specification
231 : !! nshiftk= number of shift vectors.
232 : !! shiftk(3,nshiftk)=shift vectors for k point generation
233 : !! comm=MPI communicator.
234 : !!
235 : !! OUTPUT
236 : !! fstab(nsppol)=Tables with the correspondence between points of the Fermi surface (FS)
237 : !! and the k-points in ebands_t.
238 : !! tetra: Tetrahedron object.
239 : !!
240 : !! TODO
241 : !! Use a different algorithm to select k-points if tetra. First compute tetra weights
242 : !! then k-points contributing to FS integrals are selected according to some threshold.
243 : !!
244 : !! SOURCE
245 :
246 15 : subroutine fstab_init(fstab, ebands, cryst, dtset, tetra, comm)
247 :
248 : !Arguments ------------------------------------
249 : !scalars
250 : type(ebands_t),intent(in) :: ebands
251 : type(crystal_t),intent(in) :: cryst
252 : type(dataset_type),intent(in) :: dtset
253 : type(htetra_t),intent(out) :: tetra
254 : integer,intent(in) :: comm
255 : !arrays
256 : type(fstab_t),target,intent(out) :: fstab(ebands%nsppol)
257 :
258 : !Local variables-------------------------------
259 : !scalars
260 : integer,parameter :: option0 = 0, brav1 = 1, bcorr0 = 0
261 : integer :: nkfs,spin,band,nband_k,i1,i2,ib,blow,ik_bz,ik_ibz,nkibz
262 : integer :: ik,mkpt,nkbz,ierr, nene,ifermi
263 : real(dp),parameter :: max_occ1 = one
264 : real(dp) :: elow,ehigh,ebis,enemin,enemax,deltaene,cpu,wall,gflops
265 : logical :: in_win
266 : character(len=80) :: errstr
267 : character(len=5000) :: msg
268 : type(fstab_t),pointer :: fs
269 5 : type(krank_t) :: krank
270 : !arrays
271 : integer :: kptrlatt(3,3)
272 5 : integer,allocatable :: full2ebands(:,:),bz2ibz(:), fs2bz(:),indkk(:,:) !,fs2ibz(:)
273 : real(dp) :: rlatt(3,3), klatt(3,3)
274 5 : real(dp),allocatable :: kbz(:,:), tmp_eigen(:),bdelta(:,:),btheta(:,:)
275 : ! *************************************************************************
276 :
277 5 : call cwtime(cpu, wall, gflops, "start")
278 :
279 80 : if (any(cryst%symrel(:,:,1) /= identity_3d) .and. any(abs(cryst%tnons(:,1)) > tol10) ) then
280 0 : ABI_ERROR('The first symmetry is not the identity operator!')
281 : end if
282 :
283 5 : nkibz = ebands%nkpt
284 65 : kptrlatt = dtset%kptrlatt
285 : !call kpts_ibz_from_kptrlatt(cryst, kptrlatt, ebands%kptopt, dtset%nshiftk, dtset%shiftk, &
286 : ! nkibz, kibz, wtk, nkbz, kbz, &
287 : ! new_kptrlatt, new_shiftk) ! Optional
288 :
289 : ! Call smpbz to get the full grid of k-points `kbz`
290 : ! brav1=1 is able to treat all bravais lattices (same option used in getkgrid)
291 : mkpt= kptrlatt(1,1)*kptrlatt(2,2)*kptrlatt(3,3) &
292 : +kptrlatt(1,2)*kptrlatt(2,3)*kptrlatt(3,1) &
293 : +kptrlatt(1,3)*kptrlatt(2,1)*kptrlatt(3,2) &
294 : -kptrlatt(1,2)*kptrlatt(2,1)*kptrlatt(3,3) &
295 : -kptrlatt(1,3)*kptrlatt(2,2)*kptrlatt(3,1) &
296 5 : -kptrlatt(1,1)*kptrlatt(2,3)*kptrlatt(3,2)
297 :
298 15 : ABI_MALLOC(kbz, (3, mkpt))
299 :
300 5 : call smpbz(brav1, std_out, kptrlatt, mkpt, nkbz, dtset%nshiftk, option0, dtset%shiftk, kbz)
301 :
302 : ! Find correspondence BZ --> IBZ
303 : ! Note that we use symrel so these tables can be used to symmetrize wavefunctions.
304 15 : ABI_MALLOC(indkk, (6, nkbz))
305 :
306 5 : call krank%from_kptrlatt(ebands%nkpt, ebands%kptns, kptrlatt, compute_invrank=.False.)
307 :
308 5 : if (kpts_map("symrel", ebands%kptopt, cryst, krank, nkbz, kbz, indkk) /= 0) then
309 : write(msg, '(10a)' ) &
310 0 : 'The WFK file cannot be used to start the present calculation ',ch10, &
311 0 : 'It was asked that the wavefunctions be accurate, but',ch10, &
312 0 : 'at least one of the k points could not be generated from a symmetrical one.',ch10, &
313 0 : 'Action: check your WFK file and k-point input variables',ch10, &
314 0 : ' (e.g. kptopt or shiftk might be wrong in the present dataset or the preparatory one.'
315 0 : ABI_ERROR(msg)
316 : end if
317 :
318 5 : call krank%free()
319 5 : call cwtime_report(" fstab_init%krank", cpu, wall, gflops)
320 :
321 17930 : ABI_ICALLOC(full2ebands, (6, nkbz))
322 :
323 2565 : do ik_bz=1,nkbz
324 2560 : full2ebands(1, ik_bz) = indkk(1, ik_bz) ! ik_ibz
325 2560 : full2ebands(2, ik_bz) = indkk(2, ik_bz) ! isym
326 10240 : full2ebands(3:5, ik_bz) = indkk(3:5, ik_bz) ! g0
327 2565 : full2ebands(6, ik_bz) = indkk(6, ik_bz) ! itimrev
328 : end do
329 5 : ABI_FREE(indkk)
330 :
331 : ! Select only the k-points in the BZ that are sufficiently close to the FS.
332 : ! FIXME: Do not know why but lambda depends on eph_fsewin if gaussian.
333 5 : ABI_CHECK(dtset%eph_fsewin > tol12, "dtset%eph_fsewin < tol12")
334 5 : elow = ebands%fermie - dtset%eph_fsewin
335 5 : ehigh = ebands%fermie + dtset%eph_fsewin
336 5 : ebis = elow - abs(elow) * 0.001_dp
337 :
338 : ! Allocate workspace arrays.
339 : !ABI_MALLOC(fs2ibz, (nkbz))
340 15 : ABI_MALLOC(fs2bz, (nkbz))
341 :
342 10 : do spin=1,ebands%nsppol
343 5 : fs => fstab(spin)
344 5 : fs%spin = spin
345 15 : ABI_MALLOC(fs%bstart_cnt_ibz, (2, nkibz))
346 440 : fs%bstart_cnt_ibz = -1
347 :
348 : ! Find k-points on the FS associated to this spin.
349 5 : nkfs = 0
350 2565 : do ik_bz=1,nkbz
351 2560 : ik_ibz = full2ebands(1, ik_bz)
352 2560 : nband_k = ebands%nband(ik_ibz + (spin-1)*nkibz)
353 :
354 2560 : blow = bisect(ebands%eig(:nband_k, ik_ibz, spin), ebis)
355 2560 : if (blow == 0) blow = 1
356 : !if (blow == nband_k .or. blow == 0) cycle ! out of range
357 : !write(std_out,*)"here with blow: ", blow,nband_k
358 : !write(std_out,*)"eig_blow, eig_max, elow, ehigh:", &
359 : ! ebands%eig(blow, ik_ibz, spin), ebands%eig(nband_k, ik_ibz, spin), elow,ehigh
360 :
361 : in_win = .False.; i1 = huge(1); i2 = -1
362 14415 : do band=blow,nband_k
363 : !if (ebands%eig(band, ik_ibz, spin) > ehigh) exit
364 : !write(std_out,*)band, ebands%eig(band, ik_ibz, spin) >= elow, ebands%eig(band, ik_ibz, spin) <= ehigh
365 14415 : if (ebands%eig(band, ik_ibz, spin) >= elow .and. ebands%eig(band, ik_ibz, spin) <= ehigh) then
366 690 : in_win = .True.; i1 = min(i1, band); i2 = max(i2, band)
367 : end if
368 : end do
369 :
370 2565 : if (in_win) then
371 : ! Add this k-point and the corresponding bands.
372 : !write(std_out,*)"in win"
373 690 : nkfs = nkfs + 1
374 : !fs2ibz(nkfs) = ik_ibz
375 690 : fs2bz(nkfs) = ik_bz
376 750 : if (any(fs%bstart_cnt_ibz(:, ik_ibz) /= [-1, -1])) then
377 1980 : ABI_CHECK(all(fs%bstart_cnt_ibz(:, ik_ibz) == [i1, i2-i1+1]), "bstart_cnt_ibz!")
378 : end if
379 2070 : fs%bstart_cnt_ibz(:, ik_ibz) = [i1, i2-i1+1]
380 : end if
381 : end do ! ik_bz
382 :
383 : ! Build fstab_t for this spin.
384 5 : fs%nkibz = nkibz; fs%nkfs = nkfs; fs%nktot = nkbz
385 15 : ABI_MALLOC(fs%kpts, (3, nkfs))
386 15 : ABI_MALLOC(fs%indkk_fs, (6, nkfs))
387 695 : do ik=1,nkfs
388 : !ik_ibz = fs2ibz(ik)
389 690 : ik_bz = fs2bz(ik)
390 2760 : fs%kpts(:,ik) = kbz(:, ik_bz)
391 4835 : fs%indkk_fs(:, ik) = full2ebands(:, ik_bz)
392 : end do
393 :
394 : ! Define band indices enclosing states on the FS.
395 : ! Note that we need all k-points for a given band when computing weights with tetrahedron.
396 : ! This means that we have to be careful when selecting the weight associated to a given pair
397 : ! (band_kq, kq), (band_k, k).
398 : ! Then we have to rearrange the weights
399 5 : fs%bmin = huge(1); fs%bmax = -huge(1)
400 150 : do ik_ibz=1,nkibz
401 145 : if (fs%bstart_cnt_ibz(1, ik_ibz) /= -1) then
402 30 : fs%bmin = min(fs%bmin, fs%bstart_cnt_ibz(1,ik_ibz))
403 : end if
404 150 : if (fs%bstart_cnt_ibz(2, ik_ibz) /= -1) then
405 30 : fs%bmax = max(fs%bmax, fs%bstart_cnt_ibz(1,ik_ibz) + fs%bstart_cnt_ibz(2,ik_ibz) - 1)
406 : end if
407 : end do
408 :
409 : !write(std_out,*)"bmin, bmax for tetra: ",fs%bmin, fs%bmax
410 5 : ABI_CHECK(fs%bmin /= huge(1) .and. fs%bmax /= -huge(1), "No point on the Fermi surface!")
411 5 : fs%maxnb = fs%bmax - fs%bmin + 1
412 :
413 : ! DEBUG: use same number of bands for each k-point on the FS.
414 : !do ik_ibz=1,nkibz
415 : ! if (fs%bstart_cnt_ibz(1, ik_ibz) /= -1) then
416 : ! fs%bstart_cnt_ibz(1, ik_ibz) = fs%bmin
417 : ! fs%bstart_cnt_ibz(2, ik_ibz) = fs%maxnb
418 : ! end if
419 : !end do
420 :
421 55 : ABI_CALLOC(fs%vk, (3, fs%maxnb))
422 50 : ABI_CALLOC(fs%vkq, (3, fs%maxnb))
423 :
424 10 : call fs%krank%init(nkfs, fs%kpts)
425 : end do ! spin
426 :
427 5 : call cwtime_report(" fstab_init%fs_build:", cpu, wall, gflops)
428 :
429 : ! fix window around fermie for tetrahedron or gaussian weight calculation
430 : ! this is spin independent
431 5 : nene = 100 ! TODO: make this variable and maybe temperature dependent???
432 5 : deltaene = two * dtset%eph_fsewin / dble(nene-1)
433 5 : ifermi = int(nene / 2)
434 5 : enemin = ebands%fermie - dble(ifermi-1)*deltaene
435 5 : enemax = enemin + dble(nene-1)*deltaene
436 :
437 65 : rlatt = kptrlatt
438 5 : call matr3inv(rlatt, klatt)
439 :
440 : ! Setup FS integration
441 10 : do spin=1,ebands%nsppol
442 5 : fs => fstab(spin)
443 5 : fs%nene = nene
444 5 : fs%enemin = enemin
445 5 : fs%deltaene = deltaene
446 5 : fs%eph_intmeth = dtset%eph_intmeth
447 5 : fs%eph_fsmear = dtset%eph_fsmear
448 :
449 65 : fs%klatt = klatt
450 20 : fs%kmesh_cartvec(:, 1) = cryst%gprimd(:,1)*klatt(1,1) + cryst%gprimd(:,2)*klatt(2,1) + cryst%gprimd(:,3)*klatt(3,1)
451 20 : fs%kmesh_cartvec(:, 2) = cryst%gprimd(:,1)*klatt(1,2) + cryst%gprimd(:,2)*klatt(2,2) + cryst%gprimd(:,3)*klatt(3,2)
452 25 : fs%kmesh_cartvec(:, 3) = cryst%gprimd(:,1)*klatt(1,3) + cryst%gprimd(:,2)*klatt(2,3) + cryst%gprimd(:,3)*klatt(3,3)
453 : ! TODO: It seems that two_pi is not needed here!
454 : !fs%kmesh_cartvec = two_pi * fs%kmesh_cartvec
455 : !do i1=1,3
456 : ! write(std_out, *)"klatt:", klatt(:, i1)
457 : ! write(std_out, *)"gprimd:", cryst%gprimd(:, i1)
458 : ! write(std_out, *)"cartvec:", fs%kmesh_cartvec(:, i1)
459 : !end do
460 : end do
461 :
462 10 : ABI_MALLOC(bz2ibz, (nkbz))
463 2570 : bz2ibz = full2ebands(1, :)
464 5 : call tetra%init(bz2ibz, cryst%gprimd, klatt, kbz, nkbz, ebands%kptns, nkibz, ierr, errstr, comm)
465 5 : ABI_CHECK(ierr == 0, errstr)
466 5 : ABI_FREE(bz2ibz)
467 :
468 5 : if (abs(dtset%eph_intmeth) == 2) then
469 : ! TODO: compute weights on the fly to reduce memory? nene should be set to zero if not used!
470 6 : ABI_MALLOC(tmp_eigen, (nkibz))
471 6 : ABI_MALLOC(btheta, (nene, nkibz))
472 4 : ABI_MALLOC(bdelta, (nene, nkibz))
473 :
474 4 : do spin=1,ebands%nsppol
475 2 : fs => fstab(spin)
476 :
477 : ! Allocate tables used to store tetrahedron weights.
478 1942 : ABI_CALLOC(fs%dbldelta_tetra_weights_kfs, (fs%maxnb, fs%maxnb, fs%nkfs))
479 182 : ABI_CALLOC(fs%tetra_wtk, (fs%maxnb, nkibz))
480 17610 : ABI_CALLOC(fs%tetra_wtk_ene, (fs%maxnb, nkibz, fs%nene))
481 :
482 8 : do band=fs%bmin,fs%bmax
483 : ! Get the contribution of this band
484 124 : tmp_eigen = ebands%eig(band, :nkibz, spin)
485 :
486 : ! Calculate general integration weights at each irred kpoint
487 : ! as in Blochl et al PRB 49 16223 [[cite:Bloechl1994a]]
488 : call tetra%blochl_weights(tmp_eigen, enemin, enemax, max_occ1, fs%nene, nkibz, &
489 4 : bcorr0, btheta, bdelta, xmpi_comm_self)
490 :
491 : ! Save weights in the correct position.
492 4 : ib = band - fs%bmin + 1
493 122 : do ik_ibz=1,nkibz
494 116 : fs%tetra_wtk(ib, ik_ibz) = bdelta(ifermi, ik_ibz) * nkibz
495 11720 : fs%tetra_wtk_ene(ib, ik_ibz, 1:fs%nene) = bdelta(1:fs%nene, ik_ibz) * nkibz
496 : end do
497 : end do ! band
498 : end do ! spin
499 :
500 2 : ABI_FREE(tmp_eigen)
501 2 : ABI_FREE(btheta)
502 2 : ABI_FREE(bdelta)
503 : end if
504 :
505 : !ABI_FREE(fs2ibz)
506 5 : ABI_FREE(fs2bz)
507 5 : ABI_FREE(kbz)
508 5 : ABI_FREE(full2ebands)
509 :
510 5 : call cwtime_report(" fstab_init%fs_weights:", cpu, wall, gflops)
511 15 : if (xmpi_comm_rank(comm) == 0) call fstab_print(fstab, [std_out, ab_out])
512 :
513 25 : end subroutine fstab_init
514 : !!***
515 :
516 : !----------------------------------------------------------------------
517 :
518 : !!****f* m_fstab/fstab_findkg0
519 : !! NAME
520 : !! fstab_findkg0
521 : !!
522 : !! FUNCTION
523 : !! Return the index `ik_fs` of the k-point `kpt` in the FS-BZ. Return -1 if not found.
524 : !!
525 : !! INPUTS
526 : !! kpt(3)=K-point in reduced coordinates
527 : !!
528 : !! OUTPUT
529 : !! g0=Reciprocal lattice vector such that kpt = fstab%kpts(:, ik_fs) + g0
530 : !!
531 : !! SOURCE
532 :
533 9792 : integer function fstab_findkg0(fstab, kpt, g0) result(ik_fs)
534 :
535 : !Arguments ------------------------------------
536 : !scalars
537 : class(fstab_t),intent(in) :: fstab
538 : !arrays
539 : integer,intent(out) :: g0(3)
540 : real(dp),intent(in) :: kpt(3)
541 : ! *************************************************************************
542 :
543 9792 : ik_fs = fstab%krank%get_index(kpt)
544 9792 : if (ik_fs /= -1) then
545 17600 : g0 = nint(kpt - fstab%kpts(:, ik_fs))
546 : else
547 21568 : g0 = huge(1)
548 : end if
549 :
550 9792 : end function fstab_findkg0
551 : !!***
552 :
553 : !----------------------------------------------------------------------
554 :
555 : !!****f* m_fstab/fstab_get_dbldelta_weights
556 : !! NAME
557 : !! fstab_get_dbldelta_weights
558 : !!
559 : !! FUNCTION
560 : !! Return the weights for the integration of the double-delta on the Fermi-surface
561 : !!
562 : !! INPUTS
563 : !! ebands<ebands_type>=GS band structure.
564 : !! ik_ibz=Index of the k-point in the IBZ
565 : !! spin=Spin index
566 : !! nesting=Used in tetra. Set to 1 if tetra Weights cannot be computed with Tetrahedron due to nesting.
567 : !! In this case, we fallback to adaptive gaussian.
568 : !!
569 : !! OUTPUT
570 : !! wtk(fs%maxnb, fs%maxnb)=Weights for FS integration.
571 : !!
572 : !! SOURCE
573 :
574 2864 : subroutine fstab_get_dbldelta_weights(fs, ebands, ik_fs, ik_ibz, ikq_ibz, spin, nesting, wtk)
575 :
576 : !Arguments ------------------------------------
577 : !scalars
578 : class(fstab_t),intent(in) :: fs
579 : class(ebands_t),intent(in) :: ebands
580 : integer,intent(in) :: ik_fs, ik_ibz, ikq_ibz, spin, nesting
581 : !arrays
582 : real(dp),intent(out) :: wtk(fs%maxnb, fs%maxnb)
583 :
584 : !Local variables-------------------------------
585 : !scalars
586 : integer :: bstart_k, nband_k, bstart_kq, nband_kq, ib1, band1, ib2, band2, ii
587 : logical :: use_adaptive
588 : real(dp) :: g1, g2, sigma, abc(3)
589 : ! *************************************************************************
590 :
591 2864 : bstart_k = fs%bstart_cnt_ibz(1, ik_ibz); nband_k = fs%bstart_cnt_ibz(2, ik_ibz)
592 2864 : ABI_CHECK(nband_k >= 1 .and. nband_k <= fs%maxnb, "Wrong nband_k")
593 :
594 2864 : bstart_kq = fs%bstart_cnt_ibz(1, ikq_ibz); nband_kq = fs%bstart_cnt_ibz(2, ikq_ibz)
595 2864 : ABI_CHECK(nband_kq >= 1 .and. nband_kq <= fs%maxnb, "Wrong nband_kq")
596 :
597 20048 : wtk = zero
598 2864 : if (fs%eph_intmeth == 1 .or. nesting /= 0) then
599 : ! Gaussian method: constant or adaptive method from group velocities if eph_fsmear is negative.
600 1536 : sigma = fs%eph_fsmear
601 1536 : use_adaptive = fs%eph_fsmear < zero .or. abs(fs%eph_intmeth) == 2
602 3072 : do ib2=1,nband_k
603 1536 : band2 = ib2 + bstart_k - 1
604 1536 : if (use_adaptive) then
605 4464 : do ii=1,3
606 14508 : abc(ii) = abs(dot_product(fs%vk(:, ib2), fs%kmesh_cartvec(:,ii)))
607 : end do
608 5580 : sigma = max(maxval(abc), fs%min_smear)
609 : !write(std_out, *)"sigma:", sigma * Ha_eV
610 : end if
611 1536 : g2 = gaussian(ebands%eig(band2, ik_ibz, spin) - ebands%fermie, sigma)
612 4608 : do ib1=1,nband_kq
613 1536 : band1 = ib1 + bstart_kq - 1
614 1536 : if (use_adaptive) then
615 4464 : do ii=1,3
616 14508 : abc(ii) = abs(dot_product(fs%vkq(:, ib1), fs%kmesh_cartvec(:,ii)))
617 : end do
618 5580 : sigma = max(maxval(abc), fs%min_smear)
619 : end if
620 1536 : g1 = gaussian(ebands%eig(band1, ikq_ibz, spin) - ebands%fermie, sigma)
621 3072 : wtk(ib1, ib2) = (g1 * g2) / fs%nktot
622 : end do
623 : end do
624 :
625 1328 : else if (abs(fs%eph_intmeth) == 2) then
626 : ! Tetrahedron method. Copy weights in the correct position.
627 2656 : do ib2=1,nband_k
628 1328 : band2 = ib2 + bstart_k - fs%bmin
629 3984 : do ib1=1,nband_kq
630 1328 : band1 = ib1 + bstart_kq - fs%bmin
631 : ! libtetrabz_dbldelta seems to report weights in this order.
632 2656 : wtk(ib1, ib2) = fs%dbldelta_tetra_weights_kfs(band1, band2, ik_fs)
633 : end do
634 : end do
635 :
636 : else
637 0 : ABI_ERROR(sjoin("Wrong integration method:", itoa(fs%eph_intmeth)))
638 : end if
639 :
640 2864 : end subroutine fstab_get_dbldelta_weights
641 : !!***
642 :
643 : !----------------------------------------------------------------------
644 :
645 : !!****f* m_fstab/fstab_print
646 : !! NAME
647 : !! fstab_print
648 : !!
649 : !! FUNCTION
650 : !! Print info on the object.
651 : !!
652 : !! INPUTS
653 : !! units=unit numbers for output
654 : !! [header]=Header string.
655 : !! [prtvol]=verbosity level
656 : !!
657 : !! SOURCE
658 :
659 10 : subroutine fstab_print(fstab, units, header, prtvol)
660 :
661 : !Arguments ------------------------------------
662 : !scalars
663 : class(fstab_t),target,intent(in) :: fstab(:)
664 : integer,intent(in) :: units(:)
665 : character(len=*),optional,intent(in) :: header
666 : integer,optional,intent(in) :: prtvol
667 :
668 : !Local variables-------------------------------
669 : !scalars
670 : integer :: my_prtvol,spin
671 : character(len=5000) :: msg
672 : ! *************************************************************************
673 :
674 5 : my_prtvol = 0; if (present(prtvol)) my_prtvol = prtvol
675 :
676 5 : msg = ' ==== Fermi surface info ==== '
677 5 : if (PRESENT(header)) msg=' ==== '//TRIM(ADJUSTL(header))//' ==== '
678 5 : call wrtout(units, msg)
679 :
680 8 : select case (fstab(1)%eph_intmeth)
681 : case (1)
682 3 : if (fstab(1)%eph_fsmear > zero) then
683 1 : write(msg,"(a,f5.1,a)")" FS integration done with gaussian method and broadening:", &
684 2 : fstab(1)%eph_fsmear * Ha_eV, " (meV)"
685 : else
686 2 : write(msg,"(a)")" FS integration done with adaptive gaussian method"
687 : end if
688 : case (2)
689 2 : write(msg,"(a)")" FS integration done with tetrahedron method"
690 : case (-2)
691 0 : write(msg,"(a)")" FS integration done with optimized tetrahedron method"
692 : case default
693 5 : ABI_ERROR(sjoin("Invalid value for eph_intmeth:", itoa(fstab(1)%eph_intmeth)))
694 : end select
695 :
696 5 : call wrtout(units, msg)
697 :
698 5 : write(msg,"(a,i0)")" Total number of k-points in the full mesh: ",fstab(1)%nktot
699 5 : call wrtout(units, msg)
700 : !write(msg,"(a,f5.1)")" Energy window: ",fstab(1)%eph_fsewin * Ha_eV, " (eV)
701 : !call wrtout(units, msg)
702 :
703 10 : do spin=1,size(fstab)
704 5 : associate (fs => fstab(spin))
705 5 : write(msg,"(a,i0)")" For spin: ",spin
706 5 : call wrtout(units, msg)
707 : write(msg,"(a,i0,a,f5.1,a)") &
708 5 : " Number of BZ k-points close to the Fermi surface: ",fs%nkfs," [", (100.0_dp * fs%nkfs) / fs%nktot, " %]"
709 5 : call wrtout(units, msg)
710 5 : write(msg,"(a,i0)")" Maximum number of bands crossing the Fermi level: ",fs%maxnb
711 5 : call wrtout(units, msg)
712 150 : write(msg,"(2(a,i0))")" min band: ", minval(fs%bstart_cnt_ibz(1,:), mask=fs%bstart_cnt_ibz(1,:) /= -1)
713 5 : call wrtout(units, msg)
714 5 : write(msg,"(2(a,i0))")" Max band: ", maxval(fs%bstart_cnt_ibz(1,:) + fs%bstart_cnt_ibz(2,:) - 1, &
715 155 : mask=fs%bstart_cnt_ibz(1,:) /= -1)
716 10 : call wrtout(units, msg)
717 : end associate
718 : end do
719 :
720 5 : end subroutine fstab_print
721 : !!***
722 :
723 0 : end module m_fstab
724 : !!***
|