Line data Source code
1 : !!****m* ABINIT/m_ksdiago
2 : !! NAME
3 : !! m_ksdiago
4 : !!
5 : !! FUNCTION
6 : !! Direct diagonalization of the KS Hamiltonian H_k(G,G')
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2008-2026 ABINIT group (MG)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public License, see ~abinit/COPYING
12 : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : !!
14 : !! SOURCE
15 :
16 : #if defined HAVE_CONFIG_H
17 : #include "config.h"
18 : #endif
19 :
20 : #include "abi_common.h"
21 :
22 : module m_ksdiago
23 :
24 : use, intrinsic :: iso_c_binding
25 : use defs_basis
26 : use m_abicore
27 : use m_errors
28 : use m_xmpi
29 : use m_xomp
30 : use m_hamiltonian
31 : use m_distribfft
32 : use libxc_functionals
33 : use m_ebands
34 : use m_nctk
35 : use m_dtfil
36 : use m_hdr
37 : use m_wfk
38 :
39 : use defs_datatypes, only : pseudopotential_type
40 : use defs_abitypes, only : MPI_type
41 : use m_gwdefs, only : GW_TOLQ0, GW_Q0_DEFAULT !, cone_gw, czero_gw, j_gw
42 : use m_dtset, only : dataset_type
43 : use m_fstrings, only : toupper, ktoa, itoa, sjoin, ftoa, ltoa
44 : use m_io_tools, only : iomode_from_fname, get_unit
45 : use m_yaml, only : yamldoc_t, yamldoc_open
46 : use m_numeric_tools, only : blocked_loop
47 : use m_time, only : cwtime, cwtime_report, timab
48 : use m_geometry, only : metric, normv
49 : use m_hide_lapack, only : xhegv_cplex, xheev_cplex, xheevx_cplex, xhegvx_cplex
50 : use m_slk, only : slkmat_dp_t, slk_processor_t, block_dist_1d, &
51 : compute_eigen_problem, compute_generalized_eigen_problem
52 : use m_bz_mesh, only : findnq, findq, findqg0, identk
53 : use m_kg, only : mkkin, mkkpg
54 : use m_crystal, only : crystal_t
55 : use m_fftcore, only : kpgsph, get_kg
56 : use m_fft_mesh, only : calc_ceigr, get_gfft
57 : use m_fft, only : fftpac, uplan_t, fftbox_plan3_t, zerosym
58 : use m_cgtools, only : set_istwfk
59 : use m_electronpositron, only : electronpositron_type
60 : use m_mpinfo, only : destroy_mpi_enreg, initmpi_seq
61 : use m_pawtab, only : pawtab_type
62 : use m_paw_ij, only : paw_ij_type
63 : use m_pawcprj, only : pawcprj_type, pawcprj_alloc, pawcprj_free, pawcprj_reorder, &
64 : pawcprj_set_zero, pawcprj_mpi_sum, pawcprj_copy
65 : use m_cgprj, only : getcprj
66 : use m_pawfgr, only : pawfgr_type
67 : use m_initylmg, only : initylmg
68 : use m_mkffnl, only : mkffnl
69 : use m_getghc, only : getghc, multithreaded_getghc
70 : use m_wfd, only : wfd_t
71 : use m_vcoul, only : vcgen_t
72 : use m_occ, only : get_fact_spin_tol_empty
73 : use m_pstat, only : pstat_proc
74 :
75 : implicit none
76 :
77 : private
78 : !!***
79 :
80 : !!****t* m_ksdiago/ugb_t
81 : !! NAME
82 : !! ugb_t
83 : !!
84 : !! FUNCTION
85 : !! This object stores the wavefunctions for given (k-point, spin) in a
86 : !! PBLAS matrix distributed over bands (columns)
87 : !!
88 : !! SOURCE
89 :
90 : type, public :: ugb_t
91 :
92 : integer :: istwf_k = -1
93 : ! Storage mode of cg_k.
94 :
95 : integer :: nspinor = -1
96 : ! Number of spinors.
97 :
98 : integer :: npw_k = -1
99 : ! Number of planewaves.
100 :
101 : integer :: npwsp = -1
102 : ! nnpw_k * nspinor.
103 :
104 : integer :: nband_k = - 1
105 : ! Total number of bands (global)
106 :
107 : integer :: my_bstart = -1, my_bstop = - 1, my_nband = - 1
108 : ! 1) Initial band
109 : ! 2) Last band
110 : ! 3) Number of bands treated by this proc. 0 if idle proc.
111 :
112 : logical :: has_idle_procs
113 : ! True if there are procs in comm who don't own any column.
114 :
115 : integer,pointer :: comm
116 : ! pointer to MPI communicator in mat
117 :
118 : type(slk_processor_t) :: processor
119 :
120 : type(slkmat_dp_t) :: mat
121 : ! PBLAS matrix with MPI-distributed Fourier components (double precision)
122 : ! Local buffer: (2, npwsp * my_nband)
123 : ! Global matrix: (npwsp, nband_k)
124 :
125 : integer, allocatable :: kg_k(:,:)
126 : ! (3, npw_k)
127 : ! G-vectors in reduced coordinates.
128 :
129 : real(dp), contiguous, pointer :: cg_k(:,:,:)
130 : ! (2, npwsp * my_nband)
131 : ! NB: This is a pointer to mat%buffer_cplx
132 :
133 : type(pawcprj_type),allocatable :: cprj_k(:,:)
134 : ! (natom, nspinor * my_nband))
135 : ! PAW projections ordered according to natom and NOT according to typat.
136 : ! NOTE my_nband
137 :
138 : contains
139 :
140 : procedure :: from_diago => ugb_from_diago
141 : ! Build object by direct diagonalization of the KS Hamiltonian.
142 :
143 : procedure :: from_wfk_file => ugb_from_wfk_file
144 : ! Build object from WFK file.
145 :
146 : procedure :: free => ugb_free
147 : ! Free memory.
148 :
149 : procedure :: print => ugb_print
150 : ! Print info on object.
151 :
152 : procedure :: collect_cprj => ugb_collect_cprj
153 : ! Collect a subset of PAW cprj on all processors.
154 :
155 : end type ugb_t
156 : !!***
157 :
158 : !!****t* m_ksdiago/hyb_t
159 : !! NAME
160 : !! hyb_t
161 : !!
162 : !! FUNCTION
163 : !!
164 : !! SOURCE
165 :
166 : type, public :: hyb_t
167 :
168 : integer :: nkibz = -1, nkbz = -1
169 : integer :: nqibz = -1, nqbz = -1
170 :
171 : integer :: mg0(3) = [2, 2, 2]
172 : ! Max shifts to account for umklapps.
173 :
174 : type(wfd_t) :: wfd
175 : type(vcgen_t) :: vcgen
176 : type(ebands_t) :: ebands
177 :
178 : real(dp),allocatable :: kibz(:,:), kbz(:,:)
179 : real(dp),allocatable :: qibz(:,:), qbz(:,:), wtq(:)
180 :
181 : integer,allocatable :: kbz2ibz(:,:)
182 : ! kbz2ibz(6, nkbz))
183 :
184 : integer,allocatable :: kbz2ibz_symrel(:,:)
185 : ! kbz2ibz_symrel(6, nkbz))
186 :
187 : integer,allocatable :: qbz2ibz(:,:)
188 : ! qbz2ibz(6, nqbz))
189 :
190 : contains
191 :
192 : procedure :: from_wfk_file => hyb_from_wfk_file
193 : ! Build object from WFK file
194 :
195 : !procedure :: print => hyb_print
196 : ! Print info on object.
197 :
198 : procedure :: free => hyb_free
199 : ! Free memory.
200 :
201 : end type hyb_t
202 : !!***
203 :
204 : !!****t* m_ksdiago/ddiago_ctl_type
205 : !! NAME
206 : !! ddiago_ctl_type
207 : !!
208 : !! FUNCTION
209 : !! Structure storing the variables controlling the direct diagonalization of the Kohn-Sham Hamiltonian.
210 : !! Mainly used for debugging (and in the KSS code!)
211 : !!
212 : !! SOURCE
213 :
214 : type, public :: ddiago_ctl_type
215 :
216 : integer :: spin
217 : ! The spin component of the Hamiltonian (1 if nspinor==1 or nsppol==1).
218 :
219 : integer :: istwf_k
220 : ! Option defining whether time-reversal symmetry is used at particular k-points
221 : ! If 0, the code will automatically use TR symmetry if possible (depending on the k-point)
222 :
223 : integer :: nband_k
224 : ! Number of bands to be calculated.
225 :
226 : integer :: npw_k
227 : ! The number of planes waves for the wavefunctions taking into account time-reversal symmetry.
228 :
229 : integer :: npwtot
230 : ! The number of planes waves in the Hamiltonian without taking into account istwf_k
231 :
232 : integer :: nspinor
233 : ! Number of spinorial components.
234 :
235 : integer :: prtvol
236 : ! Flag controlling the verbosity.
237 :
238 : integer :: use_scalapack
239 : ! 0 if diagonalization is done in sequential on each node.
240 : ! 1 to use scalapack
241 : ! TODO Not implemented
242 :
243 : real(dp) :: abstol
244 : ! used for RANGE= "V", "I", and "A" when do_full_diago=.FALSE.
245 : ! The absolute error tolerance for the eigenvalues. An approximate eigenvalue is accepted
246 : ! as converged when it is determined to lie in an interval [a,b] of width less than or equal to
247 : !
248 : ! ABSTOL + EPS * max( |a|,|b| ) ,
249 : !
250 : ! where EPS is the machine precision. If ABSTOL is less than or equal to zero, then EPS*|T| will be used in its place,
251 : ! where |T| is the 1-norm of the tridiagonal matrix obtained by reducing A to tridiagonal form.
252 : !
253 : ! Eigenvalues will be computed most accurately when ABSTOL is
254 : ! set to twice the underflow threshold 2*DLAMCH('S'), not zero.
255 : ! If this routine returns with INFO>0, indicating that some
256 : ! eigenvectors did not converge, try setting ABSTOL to 2*DLAMCH('S').
257 :
258 : real(dp) :: ecut
259 : ! The cutoff energy for the plane wave basis set.
260 :
261 : real(dp) :: ecutsm
262 : ! Smearing energy for plane wave kinetic energy (Ha)
263 :
264 : real(dp) :: effmass_free
265 : ! Effective mass for electrons (usually one).
266 :
267 : logical :: do_full_diago
268 : ! Specifies whether direct or partial diagonalization will be performed.
269 : ! Meaningful only if RANGE='A'.
270 :
271 : integer :: ilu(2)
272 : ! If RANGE='I', the indices (in ascending order) of the smallest and largest eigenvalues to be returned.
273 : ! il=ilu(1), iu=ilu(2) where
274 : ! 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0. NOT used if RANGE = 'A' or 'V'.
275 :
276 : integer :: nloalg(3)
277 :
278 : real(dp) :: kpoint(3)
279 : ! The k-point in reduced coordinates at which the Hamiltonian is diagonalized.
280 :
281 : real(dp) :: vlu(2)
282 : ! If RANGE='V', the lower and upper bounds of the interval to
283 : ! be searched for eigenvalues. vl=vlu(1) and vu=vlu(2) with VL < VU.
284 : ! Not referenced if RANGE = 'A' or 'I'.
285 :
286 : character(len=1) :: jobz
287 : ! character defining whether wavefunctions are required (lapack option).
288 : ! "N": Compute eigenvalues only;
289 : ! "V": Compute eigenvalues and eigenvectors.
290 :
291 : character(len=1) :: range
292 : ! character defining the subset of eigenstates that will be calculated (lapack option).
293 : ! "A": all eigenvalues will be found.
294 : ! "V": all eigenvalues in the half-open interval (VL,VU] will be found.
295 : ! "I": the IL-th through IU-th eigenvalues will be found.
296 :
297 : !$character(len=fnlen) :: fname
298 : ! The name of the file storing the eigenvectors and eigenvalues (only if jobz="V")
299 :
300 : end type ddiago_ctl_type
301 : !!***
302 :
303 :
304 : !!****t* m_ksdiago/psbands_t
305 : !! NAME
306 : !! psbands_t
307 : !!
308 : !! FUNCTION
309 : !!
310 : !! SOURCE
311 :
312 : type, public :: psbands_t
313 :
314 : integer :: nb_tot = -1
315 : ! Total number of states (protected + pseudo bands)
316 :
317 : integer :: nb_protected = -1
318 : ! Number of protected bands.
319 :
320 : integer :: nslices = -1
321 : ! Number of slices.
322 :
323 : integer :: maxsto_per_slice = -1
324 : ! Max number of pseudo bands per slice.
325 :
326 : real(dp) :: efrac
327 :
328 : integer,allocatable :: subspace(:,:)
329 : ! (3, nslices)
330 : ! For each slice, the first and last band index and the number of pseudo bands in the slice.
331 :
332 : real(dp),allocatable :: ps_eig(:)
333 : ! (nb_tot)
334 : ! eigenvalues (KS + pseudo energies)
335 :
336 : contains
337 :
338 : procedure :: init => psbands_init
339 : ! Initialize the object
340 :
341 : procedure :: band2slice => psbands_band2slice
342 : ! Return the slice index from the band index.
343 :
344 : procedure :: free => psbands_free
345 : ! Free memory.
346 :
347 : end type psbands_t
348 : !!***
349 :
350 : public :: ksdiago
351 : public :: init_ddiago_ctl
352 :
353 : !!***
354 :
355 : contains
356 : !!***
357 :
358 : !!****f* m_ksdiago/ksdiago
359 : !! NAME
360 : !! ksdiago
361 : !!
362 : !! FUNCTION
363 : !! This routine performs the direct diagonalization of the Kohn-Sham Hamiltonian
364 : !! for a given k-point and spin. The routine drives the following operations:
365 : !!
366 : !! 1) Re-computing <G|H|G_prim> matrix elements for all (G, G_prim).
367 : !! starting from the knowledge of the local potential on the real-space FFT mesh.
368 : !!
369 : !! 2) Diagonalizing H in the plane-wave basis.
370 : !!
371 : !! It is called in outkss.F90 during the generation of the KSS file
372 : !! needed for a GW post-treatment. Since many-body calculations usually
373 : !! require a large number of eigenstates eigen-functions, a direct
374 : !! diagonalization of the Hamiltonian might reveal more stable than iterative
375 : !! techniques that might be problematic when several high energy states are required.
376 : !! The main drawback of the direct diagonalization is the bad scaling with the size
377 : !! of the basis set (npw**3) and the large memory requirements.
378 : !!
379 : !! INPUTS
380 : !! kpoint(3)
381 : !! prtvol=Integer Flags defining verbosity level
382 : !! ecut=cut-off energy for plane wave basis sphere (Ha)
383 : !! mgfftc=maximum size of 1D FFTs (coarse mesh).
384 : !! natom=number of atoms in cell.
385 : !! nfftf=(effective) number of FFT grid points in the dense FFT mesh (for this processor)
386 : !! (nfftf=nfft for norm-conserving potential runs)
387 : !! nspinor=number of spinorial components of the wavefunctions
388 : !! nsppol=1 for unpolarized, 2 for spin-polarized
389 : !! nspden=number of density components
390 : !! pawtab(psps%ntypat*psps%usepaw) <type(pawtab_type)>=paw tabulated starting data
391 : !! pawfgr<pawfgr_type>=fine grid parameters and related data
392 : !! paw_ij(natom) <type(paw_ij_type)>=paw arrays given on (i,j) channels
393 : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
394 : !! rprimd(3,3)=dimensional primitive translations for real space (bohr)
395 : !! vtrial(nfftf,nspden)=the trial potential
396 : !! xred(3,natom)=reduced dimensionless atomic coordinates
397 : !! comm=MPI communicator.
398 : !! [electronpositron] <electronpositron_type>=quantities for the electron-positron annihilation.
399 : !! nfftc=Number of points in the coarse FFT mesh.
400 : !! ngfftc(18)=Info about 3D FFT for the coarse mesh, see ~abinit/doc/variables/vargs.htm#ngfft
401 : !! Diago_ctl<ddiago_ctl_type>=Datatype storing variables and options controlling the direct diagonalization.
402 : !!
403 : !! OUTPUT
404 : !! ierr=Status error.
405 : !! onband_diago
406 : !!
407 : !! SIDE EFFECTS
408 : !! eig_ene(:)=Pointer used for allocating and storing the eigenvalues (hartree)
409 : !! input: pointer to NULL
410 : !! output: eig_ene(onband_diago)=The calculatated eigenvalues in ascending order.
411 : !!
412 : !! eig_vec(:,:,:)=Pointer used for allocating and holding the wave functions at this k-point and spin.
413 : !! input: pointer to NULL
414 : !! output: eig_vec(2,npw_k*nspinor,onband_diago)=The calculated eigenvectors.
415 : !!
416 : !! cprj_k(natom,nspinor*onband_diago) PAW only===
417 : !! input: pointer to NULL
418 : !! output: Projected eigenstates <Proj_i|Cnk> from output eigenstates.
419 : !!
420 : !! NOTES
421 : !! * The routine can be time consuming (in particular when computing <G1|H|G2> elements for all (G1,G2)).
422 : !! So, it is recommended to call it once per run.
423 : !!
424 : !! * The routine RE-compute all Hamiltonian terms. So it is equivalent to an additional electronic SCF cycle.
425 : !! (This has no effect is convergence was reached.
426 : !! If not, eigenvalues/vectors may differs from the conjugate gradient ones)
427 : !!
428 : !! * Please, do NOT pass Dtset% to this routine. Either use a local variable properly initialized
429 : !! or add the additional variable to ddiago_ctl_type and change the creation method accordingly.
430 : !! ksdiago is designed such that it is possible to diagonalize the Hamiltonian at an arbitrary k-point
431 : !! or spin (not efficient but easy to code). Therefore ksdiago is useful non only for
432 : !! the KSS generation but also for testing more advanced iterative algorithms as well as interpolation techniques.
433 : !!
434 : !! SOURCE
435 :
436 10 : subroutine ksdiago(Diago_ctl, nband_k, nfftc, mgfftc, ngfftc, natom, &
437 10 : typat, nfftf, nspinor, nspden, nsppol, pawtab, pawfgr, paw_ij,&
438 10 : psps, rprimd, vtrial, xred, onband_diago, eig_ene, eig_vec, cprj_k, comm, ierr,&
439 : electronpositron) ! Optional arguments
440 :
441 : !Arguments ------------------------------------
442 : !scalars
443 : integer,intent(in) :: mgfftc,natom,comm,nband_k,nfftf,nsppol,nspden,nspinor,nfftc
444 : integer,intent(out) :: ierr, onband_diago
445 : type(pseudopotential_type),intent(in) :: psps
446 : type(pawfgr_type),intent(in) :: pawfgr
447 : type(ddiago_ctl_type),intent(in) :: Diago_ctl
448 : !arrays
449 : integer,intent(in) :: typat(natom), ngfftc(18)
450 : real(dp),intent(in) :: rprimd(3,3)
451 : real(dp),intent(inout) :: vtrial(nfftf,nspden)
452 : real(dp),intent(in) :: xred(3,natom)
453 : real(dp),pointer :: eig_ene(:),eig_vec(:,:,:)
454 : type(pawcprj_type),pointer :: cprj_k(:,:)
455 : type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
456 : type(paw_ij_type),intent(in) :: paw_ij(natom*psps%usepaw)
457 : type(electronpositron_type),optional,pointer :: Electronpositron
458 :
459 : !Local variables-------------------------------
460 : !scalars
461 : integer,parameter :: mkmem1 = 1, tim_getghc = 4, paral_kgb0 = 0, master = 0, ndat1 = 1, ncomp1 = 1
462 : integer :: cprj_choice,cpopt,dimffnl,ib,ider,idir,spin,npw_k
463 : integer :: ikg,istwf_k,exchn2n3d,prtvol
464 : integer :: jj,n1,n2,n3,n4,n5,n6,negv,nkpg,nproc,npw_k_test,my_rank,optder
465 : integer :: type_calc,sij_opt,igsp2,cplex_ghg,iband,ibs1,ibs2
466 : real(dp),parameter :: lambda0 = zero
467 : real(dp) :: ucvol,ecutsm,effmass_free,size_mat,ecut
468 : logical :: do_full_diago
469 : character(len=50) :: jobz,range
470 : character(len=80) :: frmt1,frmt2
471 : character(len=10) :: stag(2)
472 : character(len=500) :: msg
473 10 : type(MPI_type) :: mpi_enreg_seq
474 10 : type(gs_hamiltonian_type) :: gs_hamk
475 : !arrays
476 : integer :: nloalg(3)
477 10 : integer,allocatable :: kg_k(:,:)
478 : real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3),kptns_(3,1),kpoint(3),ylmgr_dum(1,1,1)
479 10 : real(dp),allocatable :: ph3d(:,:,:),bras(:,:),ffnl(:,:,:,:),kinpw(:),kpg_k(:,:)
480 10 : real(dp),allocatable :: vlocal(:,:,:,:),ylm_k(:,:),dum_ylm_gr_k(:,:,:), vxctaulocal(:,:,:,:,:)
481 10 : real(dp),allocatable :: ghc(:,:),gvnlxc(:,:),gsc(:,:),ghg_mat(:,:,:),gsg_mat(:,:,:)
482 10 : real(dp),pointer :: cwavef(:,:)
483 10 : type(pawcprj_type),allocatable :: cwaveprj(:,:)
484 : ! *********************************************************************
485 :
486 10 : nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
487 :
488 10 : if (nproc > 1) then
489 0 : ABI_WARNING("ksdiago not supported in parallel. Running in sequential.")
490 : end if
491 :
492 10 : call initmpi_seq(mpi_enreg_seq) ! Fake MPI_type for sequential part.
493 10 : call mpi_enreg_seq%distribfft%init_seq('c', ngfftc(2), ngfftc(3), 'all')
494 10 : if (pawfgr%usefinegrid /= 0) then
495 0 : call mpi_enreg_seq%distribfft%init_seq('f', pawfgr%ngfft(2), pawfgr%ngfft(3), 'all')
496 : end if
497 :
498 10 : spin = Diago_ctl%spin
499 40 : kpoint = Diago_ctl%kpoint
500 10 : istwf_k = Diago_ctl%istwf_k
501 : !% nband_k = Diago_ctl%nband_k
502 10 : npw_k = Diago_ctl%npw_k
503 40 : nloalg = Diago_ctl%nloalg
504 10 : ecut = Diago_ctl%ecut
505 10 : ecutsm = Diago_ctl%ecutsm
506 10 : effmass_free = Diago_ctl%effmass_free
507 10 : prtvol = Diago_ctl%prtvol
508 :
509 10 : call metric(gmet, gprimd, -1, rmet, rprimd, ucvol)
510 :
511 30 : if (nsppol == 1) stag = [' ',' ']
512 10 : if (nsppol == 2) stag = ['SPIN UP: ','SPIN DOWN:']
513 :
514 : ! The coarse FFT mesh.
515 10 : n1 = ngfftc(1); n2 = ngfftc(2); n3 = ngfftc(3)
516 10 : n4 = ngfftc(4); n5 = ngfftc(5); n6 = ngfftc(6)
517 :
518 : !====================
519 : !=== Check input ====
520 : !====================
521 10 : ierr = 0
522 :
523 : ! istwfk must be 1 for each k-point
524 10 : if (istwf_k/=1) then
525 : write(msg,'(7a)')&
526 0 : ' istwfk /= 1 not allowed:',ch10,&
527 0 : ' States output not programmed for time-reversal symmetry.',ch10,&
528 0 : ' Action: change istwfk in input file (put it to 1 for all kpt).',ch10,&
529 0 : ' Program does not stop but _KSS file will not be created...'
530 0 : ABI_WARNING(msg)
531 0 : ierr = ierr + 1
532 : end if
533 :
534 10 : if (ierr /= 0) RETURN ! Houston we have a problem!
535 :
536 : ! Initialize the Hamiltonian datatype on the coarse FFT mesh.
537 10 : if (present(electronpositron)) then
538 : call gs_hamk%init(psps, pawtab, nspinor, nsppol, nspden, natom, typat, xred, nfftc, &
539 0 : mgfftc, ngfftc, rprimd, nloalg, paw_ij=paw_ij, usecprj=0, electronpositron=electronpositron)
540 : else
541 : call gs_hamk%init(psps, pawtab, nspinor, nsppol, nspden, natom, typat, xred, nfftc, &
542 10 : mgfftc, ngfftc, rprimd, nloalg, paw_ij=paw_ij, usecprj=0)
543 : end if
544 :
545 : ! Check on the number of stored bands.
546 10 : onband_diago = nband_k
547 10 : if (nband_k==-1 .or. nband_k >= npw_k*nspinor) then
548 0 : onband_diago = npw_k*nspinor
549 0 : write(msg,'(4a,i0)')ch10,&
550 0 : ' Since the number of bands to be computed was -1 or',ch10,&
551 0 : ' too large, it has been set to the maximum value npw_k*nspinor: ',npw_k*nspinor
552 0 : call wrtout(std_out, msg)
553 : end if
554 :
555 : !do_full_diago = (onband_diago==npw_k*nspinor)
556 10 : do_full_diago = Diago_ctl%do_full_diago
557 :
558 10 : if (do_full_diago) then
559 0 : write(msg,'(6a)')ch10,&
560 0 : ' Since the number of bands to be computed',ch10,&
561 0 : ' is equal to the number of G-vectors found for this kpt,',ch10,&
562 0 : ' the program will perform complete diagonalization.'
563 : else
564 10 : write(msg,'(6a)')ch10,&
565 10 : ' Since the number of bands to be computed',ch10,&
566 10 : ' is less than the number of G-vectors found,',ch10,&
567 20 : ' the program will perform partial diagonalization.'
568 : end if
569 10 : if (prtvol > 0) call wrtout(std_out, msg)
570 :
571 : ! Set up local potential vlocal with proper dimensioning, from vtrial.
572 : ! Select spin component of interest if nspden<=2 as nvloc==1, for nspden==4, nvloc==4
573 : ! option=2: vtrial(n1*n2*n3,ispden) --> vlocal(nd1,nd2,nd3) real case
574 :
575 60 : ABI_MALLOC(vlocal, (n4, n5, n6, gs_hamk%nvloc))
576 : !if (with_vxctau) then
577 : ! ABI_MALLOC(vxctaulocal,(n4,n5,n6,gs_hamk%nvloc,4))
578 : !end if
579 :
580 : ! Set up local potential vlocal on the coarse FFT mesh from vtrial taking into account the spin.
581 :
582 : call gspot_transgrid_and_pack(spin, psps%usepaw, paral_kgb0, nfftc, ngfftc, nfftf, &
583 10 : nspden, gs_hamk%nvloc, ncomp1, pawfgr, mpi_enreg_seq, vtrial, vlocal)
584 10 : call gs_hamk%load_spin(spin, vlocal=vlocal, with_nonlocal=.true.)
585 :
586 : ! This for meta-gga.
587 : !if (with_vxctau) then
588 : ! call gspot_transgrid_and_pack(spin, psps%usepaw, paral_kgb0, nfftc, ngfftc, nfftf, &
589 : ! nspden, gs_hamk%nvloc, 4, pawfgr, mpi_enreg, vxctau, vxctaulocal)
590 : ! call gs_hamk%load_spin(spin, vxctaulocal=vxctaulocal)
591 : !end if
592 :
593 : ! Calculate G-vectors, for this k-point. Count also the number of planewaves as a check.
594 10 : exchn2n3d = 0; ikg = 0
595 30 : ABI_MALLOC(kg_k, (3, npw_k))
596 :
597 10 : call kpgsph(ecut, exchn2n3d, gmet, ikg, 0, istwf_k, kg_k, kpoint, 0, mpi_enreg_seq, 0, npw_k_test)
598 10 : ABI_CHECK(npw_k_test == npw_k, "npw_k_test/=npw_k")
599 10 : call kpgsph(ecut,exchn2n3d,gmet,ikg,0,istwf_k,kg_k,kpoint,mkmem1,mpi_enreg_seq,npw_k,npw_k_test)
600 :
601 : !========================
602 : !==== Kinetic energy ====
603 : !========================
604 30 : ABI_MALLOC(kinpw, (npw_k))
605 10 : call mkkin(ecut, ecutsm, effmass_free, gmet, kg_k, kinpw, kpoint, npw_k, 0, 0)
606 :
607 : !================================
608 : !==== Non-local form factors ====
609 : !================================
610 40 : ABI_MALLOC(ylm_k, (npw_k, psps%mpsang**2*psps%useylm))
611 :
612 10 : if (psps%useylm == 1) then
613 0 : optder = 0
614 0 : ABI_MALLOC(dum_ylm_gr_k, (npw_k, 3+6*(optder/2),psps%mpsang**2))
615 0 : kptns_(:,1) = kpoint
616 :
617 : ! Here mband is not used if paral_compil_kpt=0
618 : call initylmg(gprimd, kg_k, kptns_, mkmem1, mpi_enreg_seq, psps%mpsang, npw_k, [nband_k], 1, &
619 0 : [npw_k], 1, optder, rprimd, ylm_k, dum_ylm_gr_k)
620 :
621 0 : ABI_FREE(dum_ylm_gr_k)
622 : end if
623 :
624 : ! Compute (k+G) vectors (only if useylm=1)
625 10 : nkpg = 3 * nloalg(3)
626 40 : ABI_MALLOC(kpg_k, (npw_k, nkpg))
627 10 : if (nkpg > 0) call mkkpg(kg_k, kpg_k, kpoint, nkpg, npw_k)
628 :
629 : ! Compute nonlocal form factors ffnl at all (k+G):
630 10 : idir=0; ider=0; dimffnl=1+ider ! Now the derivative is not needed anymore.
631 50 : ABI_MALLOC(ffnl, (npw_k, dimffnl, psps%lmnmax, psps%ntypat))
632 :
633 : call mkffnl(psps%dimekb, dimffnl, psps%ekb, ffnl, psps%ffspl, gmet, gprimd, ider, idir, psps%indlmn, &
634 : kg_k, kpg_k, kpoint, psps%lmnmax, psps%lnmax, psps%mpsang, psps%mqgrid_ff, nkpg, npw_k, &
635 10 : psps%ntypat, psps%pspso, psps%qgrid_ff, rmet, psps%usepaw, psps%useylm, ylm_k, ylmgr_dum)
636 :
637 10 : ABI_FREE(ylm_k)
638 :
639 : ! Load k-dependent part in the Hamiltonian datastructure
640 40 : ABI_MALLOC(ph3d, (2, npw_k, gs_hamk%matblk))
641 : call gs_hamk%load_k(kpt_k=kpoint, istwf_k=istwf_k, npw_k=npw_k, kinpw_k=kinpw, &
642 10 : kg_k=kg_k, kpg_k=kpg_k, ffnl_k=ffnl, ph3d_k=ph3d, compute_ph3d=.true., compute_gbound=.true.)
643 :
644 : ! Prepare call to getghc.
645 10 : type_calc = 0 ! For applying the whole Hamiltonian
646 10 : sij_opt = 0; if (psps%usepaw==1) sij_opt = 1 ! For PAW, <k+G|S|k+G"> is also needed.
647 :
648 10 : cpopt = -1 ! If cpopt=-1, <p_lmn|in> (and derivatives) are computed here (and not saved)
649 : if (psps%usepaw==1.and..FALSE.) then ! TODO Calculate <p_lmn|k+G>.
650 : cpopt = 0 ! <p_lmn|in> are computed here and saved
651 : end if
652 :
653 30 : ABI_MALLOC(ghc, (2, npw_k*nspinor*ndat1))
654 20 : ABI_MALLOC(gvnlxc, (2, npw_k*nspinor*ndat1))
655 30 : ABI_MALLOC(gsc, (2, npw_k*nspinor*ndat1*(sij_opt+1)/2))
656 :
657 10 : cplex_ghg = 2
658 10 : size_mat = cplex_ghg*(npw_k*nspinor)**2*dp*b2Mb
659 10 : write(msg,'(a,f0.3,a)')" Out-of-memory in ghg_mat. Memory required by the Hamiltonian matrix: ",size_mat," [Mb]."
660 40 : ABI_STAT_MALLOC(ghg_mat, (cplex_ghg, npw_k*nspinor, npw_k*nspinor), ierr)
661 10 : ABI_CHECK(ierr == 0, msg)
662 10 : write(msg,'(a,f0.3,a)')" Out-of-memory in gsg_mat. Memory required by the PAW overlap operator: ",size_mat," [Mb]."
663 40 : ABI_STAT_MALLOC(gsg_mat, (cplex_ghg, npw_k*nspinor, npw_k*nspinor*psps%usepaw), ierr)
664 10 : ABI_CHECK(ierr == 0, msg)
665 :
666 : ! cwaveprj is ordered by atom type, see nonlop_ylm.
667 20 : ABI_MALLOC(cwaveprj, (natom, nspinor*(1+cpopt)*gs_hamk%usepaw))
668 : if (cpopt == 0) call pawcprj_alloc(cwaveprj, 0, gs_hamk%dimcprj)
669 :
670 : ! Initialize plane-wave array with zeros
671 8708 : ABI_CALLOC(bras, (2, npw_k*nspinor))
672 10 : if (prtvol > 0) call wrtout(std_out, ' Calculating <G|H|G''> elements')
673 :
674 : ! Loop over the |beta,G''> component.
675 2906 : do igsp2=1,npw_k*nspinor
676 2896 : bras(1, igsp2) = one
677 :
678 : ! Get <:|H|beta,G''> and <:|S_{PAW}|beta,G''>
679 : call getghc(cpopt, bras, cwaveprj, ghc, gsc, gs_hamk, gvnlxc, lambda0, mpi_enreg_seq, ndat1, &
680 2896 : prtvol, sij_opt, tim_getghc, type_calc)
681 :
682 : ! Fill the upper triangle.
683 1265485 : ghg_mat(:,1:igsp2,igsp2) = ghc(:,1:igsp2)
684 2896 : if (psps%usepaw == 1) gsg_mat(:,1:igsp2,igsp2) = gsc(:,1:igsp2)
685 :
686 : ! Reset the |G,beta> component that has been treated.
687 2906 : bras(1, igsp2) = zero
688 : end do
689 :
690 : ! Free workspace memory allocated so far.
691 10 : ABI_FREE(bras)
692 10 : ABI_FREE(kinpw)
693 10 : ABI_FREE(vlocal)
694 10 : ABI_FREE(ghc)
695 10 : ABI_FREE(gvnlxc)
696 10 : ABI_FREE(gsc)
697 : ABI_SFREE(vxctaulocal)
698 :
699 : if (psps%usepaw == 1 .and. cpopt == 0) call pawcprj_free(Cwaveprj)
700 10 : ABI_FREE(cwaveprj)
701 :
702 : !===========================================
703 : !=== Diagonalization of <G|H|G''> matrix ===
704 : !===========================================
705 30 : ABI_MALLOC(eig_ene, (onband_diago))
706 40 : ABI_MALLOC(eig_vec, (cplex_ghg, npw_k*nspinor, onband_diago))
707 :
708 10 : jobz = Diago_ctl%jobz !jobz="Vectors"
709 :
710 10 : if (do_full_diago) then
711 : ! Full diagonalization
712 0 : write(msg,'(6a,i0)')ch10,&
713 0 : ' Begin full diagonalization for kpt: ',trim(ktoa(kpoint)), stag(spin), ch10,&
714 0 : ' Matrix size: ', npw_k*nspinor
715 0 : call wrtout(std_out, msg)
716 :
717 0 : if (psps%usepaw == 0) then
718 0 : call xheev_cplex(jobz, "Upper", cplex_ghg, npw_k*nspinor, ghg_mat, eig_ene, msg, ierr)
719 : else
720 0 : call xhegv_cplex(1, jobz, "Upper", cplex_ghg, npw_k*nspinor, ghg_mat, gsg_mat, eig_ene, msg, ierr)
721 : end if
722 0 : ABI_CHECK(ierr == 0, msg)
723 0 : eig_vec(:,:,:)= ghg_mat
724 :
725 : else
726 : ! Partial diagonalization
727 10 : range = Diago_ctl%range !range="Irange"
728 :
729 10 : write(msg,'(2a,3es16.8,3a,i0,a,i0)')ch10,&
730 10 : ' Begin partial diagonalization for kpt= ',kpoint, stag(spin),ch10,&
731 20 : ' - Size of mat.=',npw_k*nspinor,' - # out_nband: ',onband_diago
732 10 : call wrtout(std_out, msg)
733 :
734 10 : if (psps%usepaw == 0) then
735 : call xheevx_cplex(jobz, range, "Upper", cplex_ghg, npw_k*nspinor, ghg_mat, zero, zero,&
736 10 : 1, onband_diago, -tol8, negv, eig_ene, eig_vec, npw_k*nspinor, msg, ierr)
737 : else
738 : call xhegvx_cplex(1, jobz, range, "Upper", cplex_ghg, npw_k*nspinor, ghg_mat, gsg_mat, zero, zero,&
739 0 : 1, onband_diago, -tol8, negv, eig_ene, eig_vec, npw_k*nspinor, msg, ierr)
740 : end if
741 10 : ABI_CHECK(ierr == 0, msg)
742 : end if
743 :
744 10 : ABI_FREE(ghg_mat)
745 10 : ABI_FREE(gsg_mat)
746 :
747 10 : if (prtvol > 0 .and. my_rank == master) then
748 : ! Write eigenvalues.
749 0 : frmt1 = '(8x,9(1x,f7.2))'; frmt2 = '(8x,9(1x,f7.2))'
750 0 : write(msg,'(2a,3x,a)')' Eigenvalues in eV for kpt: ', trim(ktoa(kpoint)), stag(spin)
751 0 : call wrtout(std_out, msg)
752 :
753 0 : write(msg,frmt1)(eig_ene(ib)*Ha_eV,ib=1,MIN(9,onband_diago))
754 0 : call wrtout(std_out, msg)
755 0 : if (onband_diago >9 ) then
756 0 : do jj=10,onband_diago,9
757 0 : write(msg, frmt2) (eig_ene(ib)*Ha_eV,ib=jj,MIN(jj+8,onband_diago)); call wrtout(std_out, msg)
758 : end do
759 : end if
760 : end if
761 :
762 : !========================================================
763 : !==== Calculate <Proj_i|Cnk> from output eigenstates ====
764 : !========================================================
765 10 : if (psps%usepaw == 1) then
766 :
767 0 : ABI_MALLOC(cprj_k,(natom, nspinor*onband_diago))
768 0 : call pawcprj_alloc(cprj_k, 0, gs_hamk%dimcprj)
769 :
770 0 : idir = 0; cprj_choice = 1 ! Only projected wave functions.
771 :
772 0 : do iband=1,onband_diago
773 0 : ibs1 = nspinor * (iband - 1) + 1
774 0 : ibs2 = ibs1; if (nspinor == 2) ibs2=ibs2+1
775 0 : cwavef => eig_vec(1:2,1:npw_k,iband)
776 :
777 : call getcprj(cprj_choice, 0, cwavef, cprj_k(:,ibs1:ibs2), &
778 : gs_hamk%ffnl_k, idir, gs_hamk%indlmn, gs_hamk%istwf_k, gs_hamk%kg_k, &
779 : gs_hamk%kpg_k, gs_hamk%kpt_k, gs_hamk%lmnmax, gs_hamk%mgfft, mpi_enreg_seq, 1, &
780 : gs_hamk%natom, gs_hamk%nattyp, gs_hamk%ngfft, gs_hamk%nloalg, gs_hamk%npw_k, gs_hamk%nspinor, &
781 0 : gs_hamk%ntypat, gs_hamk%phkxred, gs_hamk%ph1d, gs_hamk%ph3d_k, gs_hamk%ucvol, gs_hamk%useylm)
782 : end do
783 :
784 : ! Reorder the cprj (order is now the same as in input file)
785 0 : call pawcprj_reorder(cprj_k, gs_hamk%atindx1)
786 : end if ! usepaw
787 :
788 : ! Free memory.
789 10 : ABI_FREE(kpg_k)
790 10 : ABI_FREE(kg_k)
791 10 : ABI_FREE(ph3d)
792 10 : ABI_FREE(ffnl)
793 :
794 10 : call destroy_mpi_enreg(mpi_enreg_seq)
795 10 : call gs_hamk%free()
796 10 : call xmpi_barrier(comm)
797 :
798 20 : end subroutine ksdiago
799 : !!***
800 : !----------------------------------------------------------------------
801 :
802 : !!****f* m_ksdiago/init_ddiago_ctl
803 : !! NAME
804 : !! init_ddiago_ctl
805 : !!
806 : !! FUNCTION
807 : !!
808 : !! INPUTS
809 : !!
810 : !! OUTPUT
811 : !!
812 : !! SOURCE
813 :
814 10 : subroutine init_ddiago_ctl(Dctl, jobz, spin, nspinor, ecut, kpoint, nloalg, gmet, &
815 : nband_k, istwf_k, ecutsm, effmass_free, abstol, range, ilu, vlu, use_scalapack, prtvol)
816 :
817 : !Arguments ------------------------------------
818 : !scalars
819 : integer,intent(in) :: spin,nspinor
820 : integer,optional,intent(in) :: istwf_k,prtvol,use_scalapack,nband_k
821 : real(dp),intent(in) :: ecut
822 : real(dp),optional,intent(in) :: ecutsm,effmass_free
823 : real(dp),optional,intent(in) :: abstol
824 : character(len=*),intent(in) :: jobz
825 : character(len=*),optional,intent(in) :: range
826 : type(ddiago_ctl_type),intent(out) :: Dctl
827 : !arrays
828 : integer,intent(in) :: nloalg(3)
829 : integer,optional,intent(in) :: ilu(2)
830 : real(dp),intent(in) :: kpoint(3)
831 : real(dp),optional,intent(in) :: vlu(2)
832 : real(dp),intent(in) :: gmet(3,3)
833 :
834 : !Local variables-------------------------------
835 : !scalars
836 : integer :: npw_k
837 : logical :: ltest
838 : character(len=500) :: msg
839 10 : type(MPI_type) :: mpi_enreg_seq
840 : !arrays
841 10 : integer,allocatable :: kg_k(:,:)
842 : ! *************************************************************************
843 :
844 10 : call initmpi_seq(mpi_enreg_seq) ! Fake MPI_type.
845 :
846 10 : Dctl%spin = spin
847 10 : Dctl%nspinor = nspinor
848 40 : Dctl%kpoint = kpoint
849 :
850 10 : if (PRESENT(istwf_k)) then
851 10 : Dctl%istwf_k = istwf_k
852 : else
853 0 : Dctl%istwf_k = set_istwfk(kpoint)
854 : end if
855 :
856 10 : ABI_CHECK(Dctl%istwf_k == 1, "istwf_k/=1 not coded")
857 :
858 10 : Dctl%jobz = toupper(jobz(1:1))
859 10 : Dctl%range = "A"
860 10 : if (PRESENT(range)) Dctl%range = toupper(range)
861 :
862 10 : Dctl%ecut = ecut
863 10 : Dctl%ecutsm = zero; if (PRESENT(ecutsm)) Dctl%ecutsm = ecutsm
864 10 : Dctl%effmass_free = one; if (PRESENT(effmass_free)) Dctl%effmass_free = effmass_free
865 40 : Dctl%nloalg = nloalg
866 10 : Dctl%prtvol = 0; if (PRESENT(prtvol)) Dctl%prtvol = prtvol
867 10 : Dctl%abstol = -tol8; if (PRESENT(abstol)) Dctl%abstol = abstol
868 :
869 10 : ABI_MALLOC(kg_k,(3,0))
870 :
871 : ! Total number of G-vectors for this k-point with istwf_k=1.
872 10 : call kpgsph(ecut,0,gmet,0,0,1,kg_k,kpoint,0,mpi_enreg_seq,0,Dctl%npwtot)
873 :
874 : ! G-vectors taking into account time-reversal symmetry.
875 10 : call kpgsph(ecut,0,gmet,0,0,istwf_k,kg_k,kpoint,0,mpi_enreg_seq,0,npw_k)
876 :
877 10 : Dctl%npw_k = npw_k
878 10 : ABI_FREE(kg_k)
879 :
880 10 : Dctl%do_full_diago = .FALSE.
881 :
882 10 : SELECT CASE (Dctl%range)
883 : CASE ("A")
884 :
885 : ! Check on the number of stored bands.
886 10 : Dctl%nband_k=-1
887 10 : if (PRESENT(nband_k)) Dctl%nband_k=nband_k
888 :
889 10 : if (Dctl%nband_k==-1.or.Dctl%nband_k>=npw_k*nspinor) then
890 0 : Dctl%nband_k=npw_k*nspinor
891 0 : write(msg,'(4a)')ch10,&
892 0 : 'Since the number of bands to be computed was (-1) or',ch10,&
893 0 : 'too large, it has been set to the max. value npw_k*nspinor. '
894 0 : if (Dctl%prtvol>0) call wrtout(std_out, msg)
895 : else
896 10 : Dctl%nband_k=nband_k
897 : end if
898 :
899 10 : Dctl%do_full_diago = (Dctl%nband_k==npw_k*nspinor)
900 :
901 10 : if (Dctl%do_full_diago) then
902 0 : write(msg,'(6a)')ch10,&
903 0 : 'Since the number of bands to be computed',ch10,&
904 0 : 'is equal to the number of G-vectors found for this k-point,',ch10,&
905 0 : 'the program will perform complete diagonalization.'
906 : else
907 10 : write(msg,'(6a)')ch10,&
908 10 : 'Since the number of bands to be computed',ch10,&
909 10 : 'is less than the number of G-vectors found,',ch10,&
910 20 : 'the program will perform partial diagonalization.'
911 : end if
912 10 : if (Dctl%prtvol>0) call wrtout(std_out, msg)
913 :
914 : CASE ("I")
915 0 : if (.not.PRESENT(ilu)) then
916 0 : ABI_ERROR(" ilu must be specified when range=I ")
917 : end if
918 0 : Dctl%ilu = ilu
919 :
920 0 : ltest = ( ( ilu(2)>=ilu(1) ) .and. ilu(1)>=1 .and. ilu(2)<=Dctl%npwtot )
921 0 : write(msg,'(a,2i0)')" Illegal value for ilu: ",ilu
922 0 : ABI_CHECK(ltest,msg)
923 0 : Dctl%nband_k= ilu(2)-ilu(1)+1
924 :
925 : CASE ("V")
926 0 : if (.not.PRESENT(vlu)) then
927 0 : ABI_ERROR(" vlu must be specified when range=V ")
928 : end if
929 0 : Dctl%vlu = vlu
930 :
931 0 : Dctl%nband_k=-1 !??
932 :
933 0 : ltest = (vlu(2)>vlu(1))
934 0 : write(msg,'(a,2f0.3)')" Illegal value for vlu: ",vlu
935 0 : ABI_CHECK(ltest,msg)
936 :
937 : CASE DEFAULT
938 10 : ABI_ERROR(" Unknown value for range: "//TRIM(Dctl%range))
939 : END SELECT
940 :
941 : ! Consider the case in which we asked for the entire set of eigenvectors
942 : ! but the number of bands is less that npw_k. Therefore have to prepare the call to ZHEEVX.
943 : ! TODO this has to be done in a cleaner way.
944 10 : if (Dctl%range == "A" .and. .not. dctl%do_full_diago) then
945 10 : Dctl%range="I"
946 10 : Dctl%ilu(1) = 1
947 10 : Dctl%ilu(2) = npw_k*nspinor
948 10 : Dctl%nband_k= npw_k*nspinor
949 : end if
950 :
951 10 : Dctl%use_scalapack=0
952 10 : if (PRESENT(use_scalapack)) Dctl%use_scalapack=use_scalapack
953 10 : ABI_CHECK(Dctl%use_scalapack==0," scalapack mode not coded yet")
954 :
955 10 : call destroy_mpi_enreg(mpi_enreg_seq)
956 :
957 10 : end subroutine init_ddiago_ctl
958 : !!***
959 :
960 : !!****f* m_ksdiago/ugb_from_diago
961 : !! NAME
962 : !! ugb_from_diago
963 : !!
964 : !! FUNCTION
965 : !! This routine performs the direct diagonalization of the Kohn-Sham Hamiltonian
966 : !! for a given k-point and spin using Scalapack/ELPA.
967 : !!
968 : !! INPUTS
969 : !! spin= spin index.
970 : !! istwf_k= Storage mode for wavefunctions.
971 : !! kpoint(3)= k-point in reduced coordinates
972 : !! ecut= Cutoff energy
973 : !! gs_fermie=Fermi level as computed from the previous GS run.
974 : !! nband_k=Number of bands
975 : !! prtvol=Verbosity level
976 : !! nfftf=(effective) number of FFT grid points in the dense FFT mesh (for this processor)
977 : !! (nfftf=nfft for norm-conserving potential runs)
978 : !! pawtab(psps%ntypat*psps%usepaw) <type(pawtab_type)>=paw tabulated starting data
979 : !! pawfgr<pawfgr_type>=fine grid parameters and related data
980 : !! paw_ij(natom) <type(paw_ij_type)>=paw arrays given on (i,j) channels
981 : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
982 : !! vtrial(nfftf,nspden)=the trial potential
983 : !! comm=MPI communicator.
984 : !! nfftc=Number of points in the coarse FFT mesh.
985 : !! ngfftc(18)=Info about 3D FFT for the coarse mesh, see ~abinit/doc/variables/vargs.htm#ngfft
986 : !! [electronpositron] <electronpositron_type>=quantities for the electron-positron annihilation.
987 : !!
988 : !! OUTPUT
989 : !! eig_k(1:nband_k)=The calculatated eigenvalues in ascending order.
990 : !!
991 : !! SOURCE
992 :
993 0 : subroutine ugb_from_diago(ugb, spin, istwf_k, kpoint, ecut, gs_fermie, nband_k, ngfftc, nfftf, &
994 0 : dtset, pawtab, pawfgr, paw_ij, cryst, psps, vtrial, eig_k, hyb, comm, &
995 : electronpositron) ! Optional arguments
996 :
997 : !Arguments ------------------------------------
998 : !scalars
999 : class(ugb_t),target,intent(out) :: ugb
1000 : integer,intent(in) :: spin, istwf_k
1001 : real(dp),intent(in) :: kpoint(3), ecut, gs_fermie
1002 : type(dataset_type),intent(in) :: dtset
1003 : integer,intent(in) :: comm,nfftf
1004 : integer,intent(inout) :: nband_k
1005 : type(crystal_t),intent(in) :: cryst
1006 : type(pseudopotential_type),intent(in) :: psps
1007 : type(pawfgr_type),intent(in) :: pawfgr
1008 : type(hyb_t),intent(inout) :: hyb
1009 : !arrays
1010 : integer,intent(in) :: ngfftc(18)
1011 : real(dp),intent(inout) :: vtrial(nfftf,dtset%nspden)
1012 : !real(dp),intent(inout) :: vxctau(nfftf, dtset%nspden, 4*usevxctau)
1013 : real(dp),allocatable,intent(out) :: eig_k(:)
1014 : type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
1015 : type(paw_ij_type),intent(in) :: paw_ij(cryst%natom*psps%usepaw)
1016 : type(electronpositron_type),optional,pointer :: electronpositron
1017 :
1018 : !Local variables-------------------------------
1019 : !scalars
1020 : integer,parameter :: mkmem1 = 1, tim_getghc = 4, paral_kgb0 = 0, master = 0, ncomp1 = 1
1021 : integer :: cprj_choice,cpopt,dimffnl,ib,ider,idir,npw_k,nfftc,mgfftc, igs, ige, omp_nt
1022 : integer :: jj,n1,n2,n3,n4,n5,n6,nkpg,nproc,my_rank,optder, ib_glob, nb_glob, ib_loc
1023 : integer :: type_calc,sij_opt,igsp2_start,ig, my_ib, ibs1, ipwsp, islice, igsp_loc, my_npwsp
1024 : integer :: npwsp, col_bsize, nsppol, nspinor, nspden, loc2_size, il_g1, il_g2, ig1, ig2, ierr, min_my_nband, band_sum
1025 : integer :: idat, ndat, batch_size, h_size !, mene_found
1026 : integer :: ik_ibz, ik_bz, isym_k, trev_k, g0_k(3), g0(3)
1027 : integer :: iq_bz !, isym_q, trev_q !, g0_q(3) iq_ibz
1028 : real(dp),parameter :: lambda0 = zero
1029 : real(dp) :: cpu, wall, gflops, mem_mb, f_bsum, fact_spin, tol_empty_in, tol_empty, gsq_max, inv_sqrt_ucvol, rcut
1030 : logical :: do_full_diago, haveit, isirr_k, q_is_gamma ! isirr_q,
1031 : character(len=80) :: frmt1
1032 : character(len=10) :: stag(2)
1033 : character(len=500) :: msg
1034 0 : type(MPI_type) :: mpi_enreg_seq
1035 0 : type(gs_hamiltonian_type) :: gs_hamk
1036 0 : type(slkmat_dp_t) :: ghg_mat, gsg_mat, ghg_4diag, gsg_4diag, eigvec
1037 : type(slk_processor_t) :: proc_1d, proc_4diag
1038 0 : type(uplan_t) :: uplan_k
1039 : type(fftbox_plan3_t) :: box_plan
1040 0 : type(psbands_t) :: psb
1041 : !arrays
1042 0 : integer,allocatable :: gfft(:,:)
1043 : real(dp) :: kptns_(3,1), ylmgr_dum(1,1,1), tsec(2), ksum(3), kk_ibz(3), kgw_m_ksum(3), qq_bz(3), my_gw_qlwl(3) ! q0(3),
1044 0 : real(dp),allocatable :: ph3d(:,:,:), ffnl(:,:,:,:), kinpw(:), kpg_k(:,:), thetas(:,:)
1045 0 : real(dp),allocatable :: vlocal(:,:,:,:), ylm_k(:,:), dum_ylm_gr_k(:,:,:), eig_ene(:), ghc(:,:), gvnlxc(:,:), gsc(:,:), vcg_qbz(:,:)
1046 0 : real(dp),target,allocatable :: bras(:,:)
1047 0 : complex(dp),allocatable :: ps_ug(:,:,:)
1048 0 : complex(gwp),allocatable :: cbras_box(:,:), cbras_g(:,:), vc_sqrt(:), ur(:), rfg_box(:,:)
1049 0 : type(pawcprj_type),allocatable :: cwaveprj(:,:)
1050 : ! *********************************************************************
1051 :
1052 0 : call timab(1919, 1, tsec)
1053 0 : nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
1054 :
1055 : ! See sequence of calls in vtorho.
1056 : ! Check that usekden is not 0 if want to use vxctau
1057 : !with_vxctau = dtset%usekden/=0
1058 :
1059 0 : if (dtset%usekden/=0) then
1060 0 : ABI_ERROR("nscf_init with mgga not yet coded")
1061 : end if
1062 : ! Check if want to use vxctau
1063 : !with_vxctau = (present(vxctau).and.usevxctau/=0)
1064 :
1065 : !====================
1066 : !=== Check input ====
1067 : !====================
1068 0 : if (all(istwf_k /= [1, 2])) then
1069 0 : ABI_ERROR(sjoin("istwfk:", itoa(istwf_k), "not allowed:"))
1070 : end if
1071 :
1072 0 : if (istwf_k == 2) then
1073 0 : ABI_ERROR("istwfk == 2 with direct diago is still under development")
1074 : !ABI_WARNING("istwfk == 2 with direct diago is still under development")
1075 : end if
1076 :
1077 0 : if (dtset%ixc < 0) then
1078 0 : if (libxc_functionals_ismgga() .and. .not. libxc_functionals_is_potential_only()) then
1079 0 : ABI_ERROR("meta-gga functionals are not compatible with direct diagonalization!")
1080 : end if
1081 : end if
1082 :
1083 : ! MPI_type for sequential part.
1084 0 : call initmpi_seq(mpi_enreg_seq)
1085 0 : call mpi_enreg_seq%distribfft%init_seq('c', ngfftc(2), ngfftc(3), 'all')
1086 0 : if (pawfgr%usefinegrid /= 0) then
1087 0 : call mpi_enreg_seq%distribfft%init_seq('f', pawfgr%ngfft(2), pawfgr%ngfft(3), 'all')
1088 : end if
1089 :
1090 0 : nspinor = dtset%nspinor; nsppol = dtset%nsppol; nspden = dtset%nspden
1091 0 : if (nsppol == 1) stag = [' ',' ']
1092 0 : if (nsppol == 2) stag = ['SPIN UP: ','SPIN DOWN:']
1093 :
1094 : ! Get g-vectors from kpt and ecut.
1095 0 : call get_kg(kpoint, istwf_k, ecut, cryst%gmet, npw_k, ugb%kg_k)
1096 0 : npwsp = npw_k * nspinor
1097 :
1098 : ! The coarse FFT mesh for the application of the Hamiltonian.
1099 0 : n1 = ngfftc(1); n2 = ngfftc(2); n3 = ngfftc(3)
1100 0 : n4 = ngfftc(4); n5 = ngfftc(5); n6 = ngfftc(6)
1101 0 : nfftc = product(ngfftc(1:3)); mgfftc = maxval(ngfftc(1:3))
1102 :
1103 : ! Initialize the Hamiltonian on the coarse FFT mesh.
1104 0 : if (present(electronpositron)) then
1105 : call gs_hamk%init(psps, pawtab, nspinor, nsppol, nspden, cryst%natom, cryst%typat, cryst%xred, nfftc, &
1106 0 : mgfftc, ngfftc, cryst%rprimd, dtset%nloalg, paw_ij=paw_ij, usecprj=0, gpu_option=dtset%gpu_option, electronpositron=electronpositron)
1107 : else
1108 : call gs_hamk%init(psps, pawtab, nspinor, nsppol, nspden, cryst%natom, cryst%typat, cryst%xred, nfftc, &
1109 0 : mgfftc, ngfftc, cryst%rprimd, dtset%nloalg, paw_ij=paw_ij, usecprj=0, gpu_option=dtset%gpu_option)
1110 : end if
1111 :
1112 : ! Check on the number of stored bands.
1113 0 : if (nband_k == -1 .or. nband_k >= npwsp) then
1114 0 : nband_k = npwsp
1115 0 : write(msg,'(4a, i0)')ch10,&
1116 0 : ' Since the number of bands to be computed was -1 or',ch10,&
1117 0 : ' too large, it has been set to the maximum value. npw_k*nspinor: ',npwsp
1118 0 : call wrtout(std_out, msg)
1119 : end if
1120 :
1121 0 : do_full_diago = nband_k == npwsp
1122 :
1123 : ! Set up local potential vlocal with proper dimensioning, from vtrial.
1124 : ! Select spin component of interest if nspden<=2 as nvloc==1, for nspden==4, nvloc==4
1125 : ! option=2: vtrial(n1*n2*n3,ispden) --> vlocal(nd1,nd2,nd3) real case
1126 :
1127 0 : ABI_MALLOC(vlocal, (n4, n5, n6, gs_hamk%nvloc))
1128 : call gspot_transgrid_and_pack(spin, psps%usepaw, paral_kgb0, nfftc, ngfftc, nfftf, &
1129 0 : nspden, gs_hamk%nvloc, ncomp1, pawfgr, mpi_enreg_seq, vtrial, vlocal)
1130 0 : call gs_hamk%load_spin(spin, vlocal=vlocal, with_nonlocal=.true.)
1131 :
1132 : ! TODO: This for meta-gga.
1133 : !if (with_vxctau) then
1134 : ! call gspot_transgrid_and_pack(spin, psps%usepaw, paral_kgb0, nfftc, ngfftc, nfftf, &
1135 : ! nspden, gs_hamk%nvloc, 4, pawfgr, mpi_enreg, vxctau, vxctaulocal)
1136 : ! call gs_hamk%load_spin(spin, vxctaulocal=vxctaulocal)
1137 : !end if
1138 :
1139 : !========================
1140 : !==== Kinetic energy ====
1141 : !========================
1142 0 : ABI_MALLOC(kinpw, (npw_k))
1143 0 : call mkkin(ecut, dtset%ecutsm, dtset%effmass_free, cryst%gmet, ugb%kg_k, kinpw, kpoint, npw_k, 0, 0)
1144 :
1145 : !================================
1146 : !==== Non-local form factors ====
1147 : !================================
1148 0 : ABI_MALLOC(ylm_k, (npw_k, psps%mpsang**2*psps%useylm))
1149 :
1150 0 : if (psps%useylm == 1) then
1151 0 : optder = 0
1152 0 : ABI_MALLOC(dum_ylm_gr_k, (npw_k, 3+6*(optder/2),psps%mpsang**2))
1153 0 : kptns_(:,1) = kpoint
1154 :
1155 : ! NB: Here mband is not used if paral_compil_kpt = 0
1156 : call initylmg(cryst%gprimd, ugb%kg_k, kptns_, mkmem1, mpi_enreg_seq, psps%mpsang, npw_k, [nband_k], 1, &
1157 0 : [npw_k], 1, optder, cryst%rprimd, ylm_k, dum_ylm_gr_k)
1158 :
1159 0 : ABI_FREE(dum_ylm_gr_k)
1160 : end if
1161 :
1162 : ! Compute (k+G) vectors (only if useylm=1)
1163 0 : nkpg = 3 * dtset%nloalg(3)
1164 0 : ABI_MALLOC(kpg_k, (npw_k, nkpg))
1165 0 : if (nkpg > 0) call mkkpg(ugb%kg_k, kpg_k, kpoint, nkpg, npw_k)
1166 :
1167 : ! Compute nonlocal form factors ffnl at all (k+G):
1168 0 : idir=0; ider=0; dimffnl=1+ider ! Now the derivative is not needed anymore.
1169 0 : ABI_MALLOC(ffnl, (npw_k, dimffnl, psps%lmnmax, psps%ntypat))
1170 :
1171 : call mkffnl(psps%dimekb, dimffnl, psps%ekb, ffnl, psps%ffspl, cryst%gmet, cryst%gprimd, ider, idir, psps%indlmn, &
1172 : ugb%kg_k, kpg_k, kpoint, psps%lmnmax, psps%lnmax, psps%mpsang, psps%mqgrid_ff, nkpg, npw_k, &
1173 0 : psps%ntypat, psps%pspso, psps%qgrid_ff, cryst%rmet, psps%usepaw, psps%useylm, ylm_k, ylmgr_dum)
1174 :
1175 0 : ABI_FREE(ylm_k)
1176 :
1177 : ! Load k-dependent part of the Hamiltonian.
1178 0 : ABI_MALLOC(ph3d, (2, npw_k, gs_hamk%matblk))
1179 : call gs_hamk%load_k(kpt_k=kpoint, istwf_k=istwf_k, npw_k=npw_k, kinpw_k=kinpw, &
1180 0 : kg_k=ugb%kg_k, kpg_k=kpg_k, ffnl_k=ffnl, ph3d_k=ph3d, compute_ph3d=.true., compute_gbound=.true.)
1181 :
1182 : ! Prepare call to getghc.
1183 0 : type_calc = 0 ! For applying the whole Hamiltonian
1184 0 : sij_opt = 0; if (psps%usepaw==1) sij_opt = 1 ! For PAW, <k+G|S|k+G"> is also needed.
1185 :
1186 0 : cpopt = -1
1187 0 : if (psps%usepaw == 1) cpopt = 0 ! <p_lmn|in> are computed here and saved
1188 :
1189 : ! Init 1D PBLAS grid to block-distribute H along columns.
1190 0 : call proc_1d%init(comm, grid_dims=[1, nproc])
1191 0 : h_size = npwsp; if (istwf_k == 2) h_size = 2*npwsp - 1
1192 :
1193 0 : ABI_CHECK(block_dist_1d(h_size, nproc, col_bsize, msg), msg)
1194 0 : call ghg_mat%init(h_size, h_size, proc_1d, istwf_k, size_blocs=[h_size, col_bsize])
1195 0 : if (psps%usepaw == 1) call gsg_mat%init(h_size, h_size, proc_1d, istwf_k, size_blocs=[h_size, col_bsize])
1196 :
1197 : ! Estimate memory
1198 0 : mem_mb = ghg_mat%locmem_mb()
1199 0 : mem_mb = two * (psps%usepaw + 1) * mem_mb + mem_mb ! last term for eigvec matrix
1200 0 : call wrtout(std_out, sjoin(" Local memory for scalapack matrices:", ftoa(mem_mb, fmt="(f8.1)"), ' [Mb] <<< MEM'))
1201 :
1202 : ! Define batch size for the application of the Hamiltonian
1203 : ! This is useful if OpenMP is activated thus we use multiples of omp_nt.
1204 0 : omp_nt = xomp_get_num_threads(open_parallel=.True.)
1205 0 : batch_size = 8 * omp_nt
1206 0 : if (istwf_k == 2) batch_size = 1 ! FIXME
1207 : !batch_size = 1
1208 0 : if (gs_hamk%gpu_option == ABI_GPU_OPENMP) then
1209 0 : batch_size = 32
1210 : end if
1211 :
1212 0 : call wrtout(std_out, sjoin(" Building H^KS with batch_size:", itoa(batch_size)))
1213 :
1214 0 : ABI_MALLOC(bras, (2, npwsp * batch_size))
1215 : ! cwaveprj is ordered by atom type, see nonlop_ylm.
1216 0 : ABI_MALLOC(cwaveprj, (cryst%natom, nspinor*(1+cpopt)*gs_hamk%usepaw*batch_size))
1217 0 : if (cpopt == 0) call pawcprj_alloc(cwaveprj, 0, gs_hamk%dimcprj)
1218 0 : ABI_MALLOC(ghc, (2, npwsp * batch_size))
1219 0 : ABI_MALLOC(gvnlxc, (2, npwsp * batch_size))
1220 0 : ABI_MALLOC(gsc, (2, npwsp * batch_size*(sij_opt+1)/2))
1221 :
1222 : ! Loop over the |beta,G''> component.
1223 0 : call cwtime(cpu, wall, gflops, "start")
1224 0 : loc2_size = ghg_mat%size_local(2)
1225 :
1226 0 : if (my_rank == master) call pstat_proc%print(_PSTAT_ARGS_)
1227 :
1228 0 : do il_g2=1, loc2_size, batch_size
1229 : ! Operate on ndat g-vectors starting at the igsp2_start global index.
1230 0 : igsp2_start = ghg_mat%loc2gcol(il_g2)
1231 0 : ndat = blocked_loop(il_g2, loc2_size, batch_size)
1232 :
1233 0 : bras = zero
1234 0 : if (istwf_k == 1) then
1235 0 : do idat=0,ndat-1
1236 0 : bras(1, igsp2_start + idat * npwsp + idat) = one
1237 : end do
1238 : else
1239 : ! only istwf_k == 2 is coded here. NB: there's a check at the beginning of this routine.
1240 0 : do idat=0,ndat-1
1241 0 : if (igsp2_start + idat <= npwsp) then
1242 : ! Cosine term
1243 0 : bras(1, igsp2_start + idat*npwsp + idat) = half
1244 0 : if (igsp2_start == 1) bras(1, igsp2_start + idat*npwsp + idat) = one
1245 : else
1246 : ! Sine term
1247 : !ig = igsp2_start - npwsp + 1
1248 0 : ig = igsp2_start - npwsp + 1 + 1 ! This should be OK
1249 0 : bras(2, ig + idat*npwsp + idat) = half
1250 : end if
1251 : end do
1252 : end if
1253 :
1254 : ! Get <:|H|beta,G''> and <:|S_{PAW}|beta,G''>
1255 : call multithreaded_getghc(cpopt, bras, cwaveprj, ghc, gsc, gs_hamk, gvnlxc, lambda0, mpi_enreg_seq, ndat, &
1256 0 : dtset%prtvol, sij_opt, tim_getghc, type_calc)
1257 :
1258 : ! Now fill my local buffer of ghg/gsg.
1259 0 : if (istwf_k == 1) then
1260 : ! Complex wavefunctions.
1261 0 : do idat=0,ndat-1
1262 0 : igs = 1 + idat * npwsp; ige = igs + npwsp - 1
1263 0 : ghg_mat%buffer_cplx(:, il_g2+idat) = cmplx(ghc(1, igs:ige), ghc(2, igs:ige), kind=dp)
1264 : end do
1265 0 : if (psps%usepaw == 1) then
1266 0 : do idat=0,ndat-1
1267 0 : igs = 1 + idat * npwsp; ige = igs + npwsp - 1
1268 0 : gsg_mat%buffer_cplx(:, il_g2+idat) = cmplx(gsc(1,igs:ige), gsc(2,igs:ige), kind=dp)
1269 : end do
1270 : end if
1271 :
1272 : else
1273 : ! Real wavefunctions.
1274 0 : do idat=0,ndat-1
1275 0 : igs = 1 + idat*npwsp; ige = igs + npwsp - 1
1276 : !if (igsp2_start == 1 .or. igsp2_start == npwsp + 1 .and. idat == 0) then
1277 : ! ghc(:, igs:ige) = tol3 !; print *, ghc(:, igs:ige)
1278 : !end if
1279 0 : ghg_mat%buffer_real(1:npwsp, il_g2+idat) = ghc(1, igs:ige) ! CC or CS
1280 0 : ghg_mat%buffer_real(npwsp+1:, il_g2+idat) = -ghc(2, igs+1:ige) ! SC or SS. Note igs+1
1281 : end do
1282 0 : if (psps%usepaw == 1) then
1283 0 : NOT_IMPLEMENTED_ERROR()
1284 : !gsg_mat%buffer_real(...)
1285 : end if
1286 : end if ! istwf_k
1287 : end do ! il_g2
1288 :
1289 : ! MG: DEBUG
1290 : !call wrtout(std_out, " WARNING: Setting H_KS to zero for debugging purposes!"); ghg_mat%buffer_cplx = czero
1291 0 : call cwtime_report(" build H^KS_g1g2", cpu, wall, gflops)
1292 :
1293 : ! Free workspace memory allocated so far.
1294 0 : ABI_FREE(bras)
1295 0 : ABI_FREE(kinpw)
1296 0 : ABI_FREE(vlocal)
1297 0 : ABI_FREE(ghc)
1298 0 : ABI_FREE(gvnlxc)
1299 0 : ABI_FREE(gsc)
1300 0 : if (psps%usepaw == 1 .and. cpopt == 0) call pawcprj_free(cwaveprj)
1301 0 : ABI_FREE(cwaveprj)
1302 :
1303 : ! ==================================
1304 : ! Compute Fock operator F^k_{g1,g2}
1305 : ! ==================================
1306 0 : if (dtset%usefock == 1) then
1307 : !if (.False.) then
1308 0 : call cwtime(cpu, wall, gflops, "start")
1309 0 : call wrtout(std_out, sjoin(" Building Fock operator F^k_{g1,g2} with batch_size:", itoa(batch_size)))
1310 0 : ABI_CHECK(dtset%usepaw == 0, "DIRECT DIAGO OF FOCK OPERATOR WITH PAW IS NOT CODED!")
1311 0 : inv_sqrt_ucvol = one / sqrt(cryst%ucvol)
1312 :
1313 0 : call hyb%wfd%change_ngfft(cryst, psps, ngfftc)
1314 :
1315 0 : ABI_MALLOC(ur, (nfftc*nspinor))
1316 0 : ABI_MALLOC(cbras_g, (npw_k*nspinor, batch_size))
1317 0 : ABI_MALLOC(cbras_box, (nfftc*nspinor, batch_size))
1318 0 : ABI_MALLOC(rfg_box, (nfftc*nspinor, batch_size))
1319 0 : ABI_MALLOC(vc_sqrt, (nfftc))
1320 0 : ABI_MALLOC(vcg_qbz, (nfftc, hyb%nqbz))
1321 :
1322 : ! Set tolerance used to decide if a band is empty.
1323 0 : tol_empty_in = 0.01_dp
1324 0 : call get_fact_spin_tol_empty(nsppol, nspinor, tol_empty_in, fact_spin, tol_empty)
1325 :
1326 : ! Precompute the Coulomb term here to avoid tons of calls inside the loop over ig2.
1327 : ! Get g-vectors in the FFT box for vcoul.
1328 0 : ABI_MALLOC(gfft, (3, nfftc))
1329 0 : call get_gfft(ngfftc, kpoint, cryst%gmet, gsq_max, gfft)
1330 :
1331 0 : my_gw_qlwl(:) = GW_Q0_DEFAULT; if (dtset%gw_nqlwl > 0) my_gw_qlwl = dtset%gw_qlwl(:,1)
1332 : !my_gw_qlwl = zero
1333 0 : do ik_bz=1,hyb%nkbz
1334 0 : ksum = hyb%kbz(:, ik_bz)
1335 0 : kgw_m_ksum = kpoint - ksum
1336 : !print *, "kpoint", kpoint, "ksum:", ksum
1337 0 : call findqg0(iq_bz, g0, kgw_m_ksum, hyb%nqbz, hyb%qbz, hyb%mG0)
1338 0 : ABI_CHECK(all(g0 == 0), sjoin("g0 = ", ltoa(g0)))
1339 0 : qq_bz = hyb%qbz(:,iq_bz)
1340 0 : q_is_gamma = normv(qq_bz, cryst%gmet, "G") < GW_TOLQ0
1341 0 : call hyb%vcgen%get_vc_sqrt(qq_bz, nfftc, gfft, my_gw_qlwl, cryst, vc_sqrt, comm, vc=vcg_qbz(:,iq_bz))
1342 : ! A non-positive value of rcut activates the recipe of Spencer & Alavi, PRB 77, 193110 (2008) [[cite:Spencer2008]].
1343 0 : rcut = (cryst%ucvol * hyb%nkbz * 3.d0 / four_pi) ** third
1344 : !vcgen%i_sz = two_pi * rcut**2
1345 0 : if (q_is_gamma) then
1346 : !vcg_qbz(1,iq_bz) = two_pi * rcut**2 ! FIXME: This is used in GW
1347 : !vcg_qbz(1,iq_bz) = hyb%vcgen%i_sz
1348 0 : vcg_qbz(1,iq_bz) = two_pi/three * rcut**2 ! FIXME: This is used in m_fock
1349 : !vcg_qbz(1,iq_bz) = zero
1350 : end if
1351 : !vcg_qbz(2:,iq_bz) = vcg_qbz(2:,iq_bz) * (inv_sqrt_ucvol**2)
1352 0 : vcg_qbz(:,iq_bz) = vcg_qbz(:,iq_bz) * (inv_sqrt_ucvol**2)
1353 0 : vcg_qbz(:,iq_bz) = one
1354 0 : call zerosym(vcg_qbz(:,iq_bz), 1, n1, n2, n3)
1355 : end do ! ik_bz
1356 0 : ABI_FREE(gfft)
1357 :
1358 : ! Build plans for (dense, g-sphere) FFTs.
1359 0 : call box_plan%from_ngfft(ngfftc, nspinor*batch_size, dtset%gpu_option)
1360 0 : call uplan_k%init(npw_k, nspinor, batch_size, ngfftc, istwf_k, ugb%kg_k, gwp, dtset%gpu_option)
1361 :
1362 : ! Blocked loop over the columns of F^k_{g1,g2}.
1363 0 : do ig2=1, npwsp, batch_size
1364 0 : ndat = blocked_loop(ig2, npwsp, batch_size)
1365 : ! Fill cbras_box(r) with e^{ig2.r}.
1366 0 : do idat=1,ndat
1367 0 : call calc_ceigr(ugb%kg_k(:,ig2+idat-1), nfftc, nspinor, ngfftc, cbras_box(:,idat))
1368 0 : cbras_box(:,idat) = cbras_box(:,idat) * inv_sqrt_ucvol
1369 : end do
1370 :
1371 : ! ==============================
1372 : ! ==== Sum over k in the BZ ====
1373 : ! ==============================
1374 0 : rfg_box = zero
1375 0 : do ik_bz=1,hyb%nkbz
1376 0 : ksum = hyb%kbz(:, ik_bz)
1377 : ! Parallelism over k-points.
1378 : !if (.not. hyb%wfd%ihave_ug(0, ik_ibz, spin)) cycle
1379 :
1380 : ! Find the symmetrical image of ksum in the IBZ
1381 : ! FIXME: Be careful with the symmetry conventions here and the interplay between umklapp in q and FFT
1382 0 : ik_ibz = hyb%kbz2ibz_symrel(1, ik_bz); isym_k = hyb%kbz2ibz_symrel(2, ik_bz)
1383 0 : trev_k = hyb%kbz2ibz_symrel(6, ik_bz); g0_k = hyb%kbz2ibz_symrel(3:5, ik_bz)
1384 : isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
1385 0 : kk_ibz = hyb%kibz(:, ik_ibz)
1386 :
1387 : ! Identify q and G0 where q + G0 = k_GW - ksum
1388 : !kgw_m_ksum = kpoint - ksum
1389 : !call findqg0(iq_bz, g0, kgw_m_ksum, hyb%nqbz, hyb%qbz, hyb%mG0)
1390 : !ABI_CHECK(all(g0 == 0), sjoin("g0 = ", ltoa(g0)))
1391 :
1392 : !qq_bz = hyb%qbz(:, iq_bz)
1393 : !iq_ibz = hyb%qbz2ibz(1, iq_bz); isym_q = hyb%qbz2ibz(2, iq_bz)
1394 : !trev_q = hyb%qbz2ibz(6, iq_bz); g0_q = hyb%qbz2ibz(3:5, iq_bz)
1395 : !isirr_q = (isym_q == 1 .and. trev_q == 0 .and. all(g0_q == 0))
1396 :
1397 : !! Find the corresponding irreducible q-point.
1398 : !! NB: non-zero umklapp G_o is not allowed. There's a check in setup_sigma
1399 : !!call qmesh%get_BZ_item(iq_bz, qbz, iq_ibz, isym_q, itim_q)
1400 : !q_is_gamma = normv(qq_bz, cryst%gmet, "G") < GW_TOLQ0
1401 :
1402 : ! ==========================
1403 : ! Sum over (occupied) bands
1404 : ! ==========================
1405 0 : do band_sum=1, hyb%wfd%nband(ik_ibz, spin)
1406 : ! MPI parallelism over bands.
1407 0 : if (.not. hyb%wfd%ihave_ug(band_sum, ik_ibz, spin)) cycle
1408 0 : f_bsum = hyb%ebands%occ(band_sum, ik_ibz, spin) * fact_spin; if (abs(f_bsum) <= tol_empty) cycle
1409 :
1410 : !print *, "band_sum, ik_ibz, spin", band_sum, ik_ibz, spin
1411 0 : call hyb%wfd%get_ur(band_sum, ik_ibz, spin, ur)
1412 0 : ur = ur * inv_sqrt_ucvol
1413 0 : do idat=1,ndat
1414 0 : cbras_box(:,idat) = f_bsum * conjg(ur) * cbras_box(:,idat)
1415 : end do
1416 :
1417 : ! FFT r --> g and multiply by v(g,q) on the FFT box.
1418 0 : call box_plan%execute(cbras_box(:,1), -1, ndat=ndat)
1419 0 : do idat=1,ndat
1420 0 : cbras_box(:,idat) = cbras_box(:,idat) * vcg_qbz(:, iq_bz)
1421 : end do
1422 : ! FFT g --> r, multiply by u(r) and accumulate in rfg_box
1423 0 : call box_plan%execute(cbras_box(:,1), +1, ndat=ndat)
1424 0 : do idat=1,ndat
1425 0 : rfg_box(:,idat) = rfg_box(:,idat) + cbras_box(:,idat) * ur
1426 : end do
1427 : end do ! band_sum
1428 : end do ! ik_bz
1429 :
1430 : ! FFT r --> g_sphere and MPI sum partial contributions.
1431 0 : call uplan_k%execute_rg(ndat, rfg_box(:,1), cbras_g(:,1))
1432 0 : call xmpi_sum(cbras_g, hyb%wfd%comm_spin(spin), ierr)
1433 0 : cbras_g = - cbras_g * sqrt(cryst%ucvol)
1434 : !cbras_g = - half * cbras_g * sqrt(cryst%ucvol)
1435 : !cbras_g = - 10000 * cbras_g / (hyb%nkbz*cryst%ucvol) ! * alpha_hyb
1436 : !cbras_g = - sqrt(cryst%ucvol) * cbras_g ! / (hyb%nkbz*cryst%ucvol) ! * alpha_hyb
1437 : !cbras_g = -half * inv_sqrt_ucvol * cbras_g / (hyb%nkbz*cryst%ucvol) ! * alpha_hyb
1438 : !cbras_g = - cbras_g / (hyb%nkbz * cryst%ucvol) ! * alpha_hyb
1439 : !cbras_g = -half * sqrt(cryst%ucvol) * cbras_g !/ (hyb%nkbz*cryst%ucvol) ! * alpha_hyb
1440 :
1441 : ! Update my local buffer of ghg_mat.
1442 0 : do idat=1,ndat
1443 0 : do ig1=1,npwsp
1444 : ! From global to local indices.
1445 0 : call ghg_mat%glob2loc(ig1, ig2+idat-1, il_g1, il_g2, haveit); if (.not. haveit) cycle
1446 : !print *, "ig1, idat, cbras_g", ig1, idat, cbras_g(ig1, idat)
1447 0 : if (istwf_k == 1) then
1448 : ! Complex wavefunctions.
1449 0 : ghg_mat%buffer_cplx(il_g1, il_g2) = ghg_mat%buffer_cplx(il_g1, il_g2) + cbras_g(ig1,idat)
1450 : else
1451 : ! Real wavefunctions.
1452 0 : NOT_IMPLEMENTED_ERROR()
1453 : end if ! istwf_k
1454 : end do ! ig1
1455 : end do ! idat
1456 :
1457 : end do ! ig2
1458 :
1459 0 : ABI_FREE(vc_sqrt)
1460 0 : ABI_FREE(vcg_qbz)
1461 0 : ABI_FREE(cbras_box)
1462 0 : ABI_FREE(rfg_box)
1463 0 : ABI_FREE(cbras_g)
1464 0 : ABI_FREE(ur)
1465 0 : call uplan_k%free(); call box_plan%free()
1466 0 : call cwtime_report(" build Fock_g1g2", cpu, wall, gflops)
1467 : end if ! usefock
1468 :
1469 : !===========================================
1470 : !=== Diagonalization of <G|H|G''> matrix ===
1471 : !===========================================
1472 0 : ABI_MALLOC(eig_ene, (h_size))
1473 :
1474 : ! Change size block. Use 2D rectangular grid of processors for diagonalization, if possible.
1475 0 : call proc_4diag%init(comm)
1476 0 : call ghg_mat%change_size_blocs(ghg_4diag, processor=proc_4diag, free=.True.)
1477 0 : if (psps%usepaw == 1) call gsg_mat%change_size_blocs(gsg_4diag, processor=proc_4diag, free=.True.)
1478 : !call ghg_mat%copy(ghg_4diag); call ghg_mat%free()
1479 :
1480 : ! NB: global H shape is (h_size, h_size) even for partial diago.
1481 : ! then one extracts the (hsize, nband_k) sub-matrix before returning.
1482 0 : call ghg_4diag%copy(eigvec)
1483 0 : if (my_rank == master) call pstat_proc%print(_PSTAT_ARGS_)
1484 :
1485 : #ifndef HAVE_LINALG_ELPA
1486 : call wrtout([std_out, ab_out], &
1487 0 : "- WARNING: Using ScaLAPACK for diagonalization, but ELPA library is highly recommended for both efficiency and memory reasons.")
1488 : #endif
1489 :
1490 0 : if (do_full_diago) then
1491 0 : write(msg,'(5a, (a,i0), 2a)')ch10,&
1492 0 : ' Begin full diagonalization for kpt: ',trim(ktoa(kpoint)), stag(spin), ch10,&
1493 0 : " H_gg' Matrix size: ",npwsp, ", Scalapack grid: ", trim(ltoa(ghg_4diag%processor%grid%dims))
1494 0 : call wrtout(std_out, msg)
1495 0 : call cwtime(cpu, wall, gflops, "start")
1496 0 : if (psps%usepaw == 0) then
1497 : !call ghg_4diag%pzheev("V", "U", eigvec, eig_ene)
1498 0 : call compute_eigen_problem(ghg_4diag%processor, ghg_4diag, eigvec, eig_ene, comm, istwf_k)
1499 : else
1500 0 : call compute_generalized_eigen_problem(ghg_4diag%processor, ghg_4diag, gsg_4diag, eigvec, eig_ene, comm, istwf_k)
1501 : end if
1502 0 : call cwtime_report(" full_diago", cpu, wall, gflops)
1503 :
1504 : else
1505 0 : write(msg,'(6a,i0,(a,i0), 2a)') ch10,&
1506 0 : ' Begin partial diagonalization for kpt: ',trim(ktoa(kpoint)), stag(spin), ch10,&
1507 0 : " H_gg' Matrix size: ",npwsp,', nband_k: ', nband_k,", Scalapack grid: ", trim(ltoa(ghg_4diag%processor%grid%dims))
1508 0 : call wrtout(std_out, msg)
1509 :
1510 0 : call cwtime(cpu, wall, gflops, "start")
1511 0 : if (psps%usepaw == 0) then
1512 : !call ghg_4diag%pzheevx("V", "I", "U", zero, zero, 1, nband_k, -tol8, eigvec, mene_found, eig_ene)
1513 0 : call compute_eigen_problem(ghg_4diag%processor, ghg_4diag, eigvec, eig_ene, comm, istwf_k, nev=nband_k)
1514 : else
1515 : !call ghg_4diag%pzhegvx(1, "V", "I", "U", gsg_4diag, zero, zero, 1, nband_k, -tol8, eigvec, mene_found, eig_ene)
1516 : call compute_generalized_eigen_problem(ghg_4diag%processor, ghg_4diag, gsg_4diag, eigvec, eig_ene, comm, istwf_k, &
1517 0 : nev=nband_k)
1518 : end if
1519 0 : call cwtime_report(" partial_diago", cpu, wall, gflops)
1520 : end if
1521 :
1522 0 : if (my_rank == master) then
1523 0 : call pstat_proc%print(_PSTAT_ARGS_)
1524 : ! Write eigenvalues.
1525 0 : frmt1 = '(8x,*(1x,f7.3))'
1526 0 : write(msg, '(2a,3x,a)')' Eigenvalues in eV for kpt: ', trim(ktoa(kpoint)), stag(spin); call wrtout(std_out, msg)
1527 0 : write(msg, frmt1)(eig_ene(ib)*Ha_eV,ib=1,min(9,nband_k)); call wrtout(std_out, msg)
1528 : ! HYB DEBUG
1529 : !call wrtout(std_out, "hyb%ebands")
1530 : !write(msg, frmt1)(hyb%ebands%eig(ib,1,spin)*Ha_eV, ib=1,min(9,hyb%ebands%mband)); call wrtout(std_out, msg)
1531 0 : if (nband_k > 9 .and. dtset%prtvol > 0) then
1532 0 : do jj=10,nband_k,9
1533 0 : write(msg, frmt1) (eig_ene(ib)*Ha_eV,ib=jj,min(jj+8,nband_k)); call wrtout(std_out, msg)
1534 : end do
1535 : end if
1536 : end if
1537 :
1538 : ! Free memory
1539 0 : call ghg_4diag%free(); call gsg_4diag%free(); call proc_1d%free()
1540 :
1541 : ! ================
1542 : ! Stochastic bands
1543 : ! ================
1544 : !if (dtset%nb_protected /= 0) then
1545 : if (.False.) then
1546 : call wrtout(std_out, " Generating stochastic bands...")
1547 : ! Initial setup.
1548 : call psb%init(dtset, h_size, eig_ene, gs_fermie) !, nband_k)
1549 : my_npwsp = eigvec%size_local(1)
1550 : nb_glob = eigvec%size_global(2)
1551 : ABI_CALLOC(ps_ug, (my_npwsp, psb%maxsto_per_slice, psb%nslices))
1552 : ABI_MALLOC(thetas, (nb_glob, psb%maxsto_per_slice))
1553 :
1554 : ! Loop over global bands.
1555 : do ib_glob=1, nb_glob
1556 : ! Need the same random phases on all MPI procs.
1557 : if (eigvec%processor%my_rank == master) call random_number(thetas)
1558 : call xmpi_bcast(thetas, master, eigvec%processor%comm, ierr)
1559 :
1560 : ! Get slice index from ib_glob.
1561 : islice = psb%band2slice(ib_glob); if (islice == -1) cycle
1562 : !band_block = psb%subspace(1:2, islice)
1563 : !nb_in_slice = psb%subspace(3,islice)
1564 :
1565 : ! Loop over global PW index.
1566 : do ipwsp=1,npwsp
1567 : call eigvec%glob2loc(ipwsp, ib_glob, igsp_loc, ib_loc, haveit); if (.not. haveit) cycle
1568 : do ib=1,psb%subspace(3,islice)
1569 : ps_ug(igsp_loc, ib, islice) = ps_ug(igsp_loc, ib, islice) + &
1570 : eigvec%buffer_cplx(igsp_loc, ib_loc) * exp(j_dpc*two_pi*thetas(ib_glob,ib))
1571 : end do
1572 : end do
1573 : end do ! ib_glob
1574 : ABI_FREE(thetas)
1575 :
1576 : ! Normalize
1577 : ! TODO: Need MPI communicator over columns here.
1578 : !call xmpi_sum(ps_ug, eigvec%column_comm, ierr)
1579 : do islice=1,psb%nslices
1580 : do ib=1,psb%subspace(3,islice)
1581 : if (psb%subspace(3,islice) == 1) cycle
1582 : ps_ug(:,ib,islice) = ps_ug(:,ib,islice) / sqrt(one * psb%subspace(3,islice))
1583 : end do
1584 : end do
1585 :
1586 : ! Now insert ps_ug in the right position in eigevec
1587 : do ib_glob=1, nb_glob
1588 : islice = psb%band2slice(ib_glob); if (islice == -1) cycle
1589 : !band_start = 1 + (islice - 1) * psb%nb_per_slice
1590 : ! Loop over global PW index.
1591 : do ipwsp=1,npwsp
1592 : call eigvec%glob2loc(ipwsp, ib_glob, igsp_loc, ib_loc, haveit); if (.not. haveit) cycle
1593 : !do ib=1,psb%nb_per_slice
1594 : ! eigvec%buffer_cplx(igsp_loc, ib_loc) = ps_ug(igsp_loc, ib, islice)
1595 : !end do
1596 : end do
1597 : end do
1598 :
1599 : ABI_FREE(ps_ug)
1600 :
1601 : ! here we change the value of nband_k and eig_k.
1602 : nband_k = psb%nb_tot
1603 : ABI_MALLOC(eig_k, (nband_k))
1604 : eig_k = psb%ps_eig
1605 :
1606 : else
1607 : ! No pseudo bands.
1608 0 : ABI_MALLOC(eig_k, (nband_k))
1609 0 : eig_k(:) = eig_ene(1:nband_k)
1610 : end if
1611 :
1612 : ! Now transfer eigvec to the ugb datastructure using 1d grid (block column distribution).
1613 0 : call wrtout(std_out, " Moving to PBLAS block column distribution...")
1614 0 : call cwtime(cpu, wall, gflops, "start")
1615 :
1616 0 : call ugb%processor%init(comm, grid_dims=[1, nproc])
1617 0 : ABI_CHECK(block_dist_1d(nband_k, nproc, col_bsize, msg), msg)
1618 0 : call eigvec%cut(h_size, nband_k, ugb%mat, size_blocs=[h_size, col_bsize], processor=ugb%processor, free=.True.)
1619 0 : call proc_4diag%free()
1620 :
1621 : ! =================
1622 : ! Build ugb object
1623 : ! =================
1624 0 : ugb%istwf_k = istwf_k
1625 0 : ugb%nspinor = nspinor
1626 0 : ugb%npw_k = npw_k
1627 0 : ugb%npwsp = npwsp
1628 0 : ugb%nband_k = nband_k
1629 0 : ugb%comm => ugb%mat%processor%comm
1630 :
1631 0 : ugb%my_bstart = ugb%mat%loc2gcol(1)
1632 0 : ugb%my_bstop = ugb%mat%loc2gcol(ugb%mat%size_local(2))
1633 0 : ugb%my_nband = ugb%my_bstop - ugb%my_bstart + 1
1634 :
1635 0 : if (ugb%my_nband > 0) then
1636 0 : call c_f_pointer(c_loc(ugb%mat%buffer_cplx), ugb%cg_k, shape=[2, npwsp, ugb%my_nband])
1637 : else
1638 0 : ugb%my_nband = 0; ugb%cg_k => null()
1639 : end if
1640 :
1641 0 : call xmpi_min(ugb%my_nband, min_my_nband, comm, ierr)
1642 0 : ugb%has_idle_procs = min_my_nband == 0
1643 :
1644 0 : if (psps%usepaw == 1 .and. ugb%my_nband > 0) then
1645 : ! Calculate <Proj_i|Cnk> from output eigenstates. Note array allocated with ugb%my_nband
1646 0 : ABI_MALLOC(ugb%cprj_k, (cryst%natom, nspinor * ugb%my_nband))
1647 0 : call pawcprj_alloc(ugb%cprj_k, 0, gs_hamk%dimcprj)
1648 0 : idir = 0; cprj_choice = 1 ! Only projected wave functions.
1649 :
1650 0 : do my_ib=1,ugb%my_nband
1651 0 : ibs1 = nspinor * (my_ib - 1) + 1
1652 : call getcprj(cprj_choice, 0, ugb%cg_k(:,:,my_ib), ugb%cprj_k(:,ibs1), &
1653 : gs_hamk%ffnl_k, idir, gs_hamk%indlmn, gs_hamk%istwf_k, gs_hamk%kg_k, &
1654 : gs_hamk%kpg_k, gs_hamk%kpt_k, gs_hamk%lmnmax, gs_hamk%mgfft, mpi_enreg_seq, 1, &
1655 : gs_hamk%natom, gs_hamk%nattyp, gs_hamk%ngfft, gs_hamk%nloalg, gs_hamk%npw_k, gs_hamk%nspinor, &
1656 0 : gs_hamk%ntypat, gs_hamk%phkxred, gs_hamk%ph1d, gs_hamk%ph3d_k, gs_hamk%ucvol, gs_hamk%useylm)
1657 : end do
1658 :
1659 : ! Reorder the cprj (order is now the same as in the input file)
1660 0 : call pawcprj_reorder(ugb%cprj_k, gs_hamk%atindx1)
1661 : end if ! usepaw
1662 :
1663 0 : call cwtime_report(" block column distribution completed", cpu, wall, gflops)
1664 :
1665 : ! Free memory.
1666 :
1667 0 : ABI_FREE(eig_ene)
1668 0 : ABI_FREE(kpg_k)
1669 0 : ABI_FREE(ph3d)
1670 0 : ABI_FREE(ffnl)
1671 0 : call destroy_mpi_enreg(mpi_enreg_seq); call gs_hamk%free(); call psb%free()
1672 :
1673 0 : if (my_rank == master) call pstat_proc%print(_PSTAT_ARGS_)
1674 :
1675 0 : call timab(1919, 2, tsec)
1676 :
1677 0 : end subroutine ugb_from_diago
1678 : !!***
1679 :
1680 : !!****f* m_ksdiago/ugb_from_wfk_file
1681 : !! NAME
1682 : !! ugb_from_wfk_file
1683 : !!
1684 : !! FUNCTION
1685 : !! Initialize an ugb_t instance from a WFK file.
1686 : !!
1687 : !! INPUTS
1688 : !! spin: spin index.
1689 : !! kpoint(3)
1690 : !! comm=MPI communicator.
1691 : !!
1692 : !! OUTPUT
1693 : !! eig_k(1:nband_k)=The calculatated eigenvalues in ascending order.
1694 : !!
1695 : !! SOURCE
1696 :
1697 0 : subroutine ugb_from_wfk_file(ugb, ik_ibz, spin, istwf_k, kpoint, nband_k, &
1698 : dtset, dtfil, cryst, eig_k, comm)
1699 :
1700 : use m_wfk
1701 :
1702 : !Arguments ------------------------------------
1703 : !scalars
1704 : class(ugb_t),target,intent(out) :: ugb
1705 : integer,intent(in) :: ik_ibz, spin, istwf_k
1706 : real(dp),intent(in) :: kpoint(3)
1707 : type(dataset_type),intent(in) :: dtset
1708 : type(datafiles_type),intent(in) :: dtfil
1709 : integer,intent(in) :: nband_k, comm
1710 : type(crystal_t),intent(in) :: cryst
1711 : !arrays
1712 : real(dp),allocatable,intent(out) :: eig_k(:)
1713 :
1714 : !Local variables-------------------------------
1715 : !scalars
1716 : integer,parameter :: master = 0, formeig0 = 0
1717 : integer :: ierr, bcast_comm, color, min_my_nband
1718 : integer :: nprocs, my_rank, nbsum, npwsp, bstart, bstop, band_step, nb, npw_k, col_bsize, band, ib, il_b, iloc
1719 : logical :: have_band
1720 0 : type(ebands_t) :: wfk_ebands
1721 0 : type(wfk_t) :: wfk
1722 0 : type(hdr_type) :: wfk_hdr
1723 : character(len=fnlen) :: wfk_path
1724 : character(len=500) :: msg
1725 : !type(gs_hamiltonian_type) :: gs_hamk
1726 : !arrays
1727 : integer :: units(2)
1728 0 : real(dp),target,allocatable :: cg_work(:,:,:)
1729 0 : real(dp),contiguous, pointer :: cg_k(:,:)
1730 : ! *********************************************************************
1731 :
1732 0 : nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
1733 0 : units(:) = [std_out, ab_out]
1734 :
1735 0 : wfk_path = dtfil%fnamewffk
1736 0 : if (my_rank == master) then
1737 0 : if (nctk_try_fort_or_ncfile(wfk_path, msg) /= 0) then
1738 0 : ABI_ERROR(sjoin("Cannot find HYBRYD WFK file:", wfk_path, ". Error:", msg))
1739 : end if
1740 0 : call wrtout(units, sjoin("- Reading HYBRID orbitals from WFK file:", wfk_path), pre_newlines=2)
1741 : end if
1742 :
1743 : ! Broadcast filenames (needed because they might have been changed if we are using netcdf files)
1744 0 : call xmpi_bcast(wfk_path, master, comm, ierr)
1745 :
1746 : ! Read energies and performs some basic consistency checks.
1747 0 : wfk_ebands = wfk_read_ebands(wfk_path, comm, out_hdr=wfk_hdr)
1748 0 : call wfk_hdr%vs_dtset(dtset)
1749 0 : ABI_CHECK_IEQ(dtset%ixc, wfk_hdr%ixc, "dtset%ixc /= wfk_hdr%ixc")
1750 0 : ABI_CHECK(all(abs(wfk_hdr%kptns(:,ik_ibz) - kpoint) < tol6), "Different kpoint")
1751 0 : ABI_CHECK_IRANGE(nband_k, 1, wfk_ebands%mband, "nband_k > mband.")
1752 :
1753 0 : ABI_MALLOC(eig_k, (nband_k))
1754 0 : eig_k = wfk_ebands%eig(1:nband_k, ik_ibz, spin)
1755 :
1756 0 : npw_k = wfk_hdr%npwarr(ik_ibz)
1757 0 : npwsp = npw_k * wfk_hdr%nspinor
1758 0 : ABI_CHECK_IEQ(istwf_k, wfk_hdr%istwfk(ik_ibz), "different istwfk_k")
1759 :
1760 : ! Init scalapack matrix
1761 0 : call ugb%processor%init(comm, grid_dims=[1, nprocs])
1762 0 : ABI_CHECK(block_dist_1d(nband_k, nprocs, col_bsize, msg), msg)
1763 0 : call ugb%mat%init(npwsp, nband_k, ugb%processor, 1, size_blocs=[-1, col_bsize])
1764 :
1765 0 : ABI_MALLOC(ugb%kg_k, (3, npw_k))
1766 :
1767 : ! Master reads and broadcasts. Much faster on lumi
1768 0 : if (my_rank == master) then
1769 0 : call wfk%open_read(wfk_path, formeig0, iomode_from_fname(wfk_path), get_unit(), xmpi_comm_self)
1770 : end if
1771 :
1772 : ! TODO: Optimize this part
1773 : ! Find band_step that gives good compromise between memory and efficiency.
1774 : !band_step = memb_limited_step(1, nbsum, 2*npwsp, xmpi_bsize_dp, 1024.0_dp)
1775 0 : band_step = 200
1776 : !band_step = 100
1777 0 : nbsum = nband_k
1778 0 : do bstart=1, nbsum, band_step
1779 0 : bstop = min(bstart + band_step - 1, nbsum); nb = bstop - bstart + 1
1780 :
1781 0 : ABI_MALLOC(cg_work, (2, npwsp, nb)) ! This array is always dp
1782 0 : if (my_rank == master) then
1783 0 : call c_f_pointer(c_loc(cg_work), cg_k, shape=[2, npwsp * nb])
1784 0 : call wfk%read_band_block([bstart, bstop], ik_ibz, spin, xmpio_single, kg_k=ugb%kg_k, cg_k=cg_k)
1785 : end if
1786 :
1787 0 : call xmpi_bcast(ugb%kg_k, master, comm, ierr)
1788 :
1789 : ! Create communicator with master and all procs requiring this set of bands block (color == 1)
1790 0 : color = 0
1791 0 : do band=bstart, bstop
1792 0 : call ugb%mat%glob2loc(1, band, iloc, il_b, have_band)
1793 0 : if (have_band) then
1794 0 : color = 1; exit
1795 : end if
1796 : end do
1797 0 : if (my_rank == master) color = 1
1798 0 : call xmpi_comm_split(comm, color, my_rank, bcast_comm, ierr)
1799 :
1800 0 : if (color == 1) then
1801 0 : call xmpi_bcast(cg_work, master, bcast_comm, ierr)
1802 : endif
1803 0 : call xmpi_comm_free(bcast_comm)
1804 :
1805 : ! Copy my portion of cg_work to buffer_cplx (here we have dp --> sp conversion).
1806 0 : if (color == 1) then
1807 0 : do band=bstart, bstop
1808 0 : ib = band - bstart + 1
1809 0 : call ugb%mat%glob2loc(1, band, iloc, il_b, have_band); if (.not. have_band) cycle
1810 0 : ugb%mat%buffer_cplx(:, il_b) = cmplx(cg_work(1,:,ib), cg_work(2,:,ib), kind=gwp)
1811 : end do
1812 : end if
1813 0 : ABI_FREE(cg_work)
1814 : end do ! bstart
1815 :
1816 0 : if (my_rank == master) call wfk%close()
1817 :
1818 : ! =================
1819 : ! Build ugb object
1820 : ! =================
1821 0 : ugb%istwf_k = istwf_k
1822 0 : ugb%nspinor = wfk_hdr%nspinor
1823 0 : ugb%npw_k = npw_k
1824 0 : ugb%npwsp = npwsp
1825 0 : ugb%nband_k = nband_k
1826 0 : ugb%comm => ugb%mat%processor%comm
1827 :
1828 0 : ugb%my_bstart = ugb%mat%loc2gcol(1)
1829 0 : ugb%my_bstop = ugb%mat%loc2gcol(ugb%mat%size_local(2))
1830 0 : ugb%my_nband = ugb%my_bstop - ugb%my_bstart + 1
1831 :
1832 0 : if (ugb%my_nband > 0) then
1833 0 : call c_f_pointer(c_loc(ugb%mat%buffer_cplx), ugb%cg_k, shape=[2, ugb%npwsp, ugb%my_nband])
1834 : else
1835 0 : ugb%my_nband = 0
1836 0 : ugb%cg_k => null()
1837 : end if
1838 :
1839 0 : call xmpi_min(ugb%my_nband, min_my_nband, comm, ierr)
1840 0 : ugb%has_idle_procs = min_my_nband == 0
1841 :
1842 : ! TODO
1843 0 : if (dtset%usepaw == 1 .and. ugb%my_nband > 0) then
1844 0 : ABI_ERROR("ugb_from_wfk does not support PAW")
1845 : ! Calculate <Proj_i|Cnk> from output eigenstates. Note array allocated with ugb%my_nband
1846 0 : ABI_MALLOC(ugb%cprj_k, (cryst%natom, ugb%nspinor * ugb%my_nband))
1847 : !call pawcprj_alloc(ugb%cprj_k, 0, gs_hamk%dimcprj)
1848 : !idir = 0; cprj_choice = 1 ! Only projected wave functions.
1849 :
1850 : !do my_ib=1,ugb%my_nband
1851 : ! ibs1 = nspinor * (my_ib - 1) + 1
1852 : ! call getcprj(cprj_choice, 0, ugb%cg_k(:,:,my_ib), ugb%cprj_k(:,ibs1), &
1853 : ! gs_hamk%ffnl_k, idir, gs_hamk%indlmn, gs_hamk%istwf_k, gs_hamk%kg_k, &
1854 : ! gs_hamk%kpg_k, gs_hamk%kpt_k, gs_hamk%lmnmax, gs_hamk%mgfft, mpi_enreg_seq, &
1855 : ! gs_hamk%natom, gs_hamk%nattyp, gs_hamk%ngfft, gs_hamk%nloalg, gs_hamk%npw_k, gs_hamk%nspinor, &
1856 : ! gs_hamk%ntypat, gs_hamk%phkxred, gs_hamk%ph1d, gs_hamk%ph3d_k, gs_hamk%ucvol, gs_hamk%useylm)
1857 : !end do
1858 :
1859 : !! Reorder the cprj (order is now the same as in the input file)
1860 : !call pawcprj_reorder(ugb%cprj_k, gs_hamk%atindx1)
1861 : end if ! usepaw
1862 :
1863 0 : call ugb%print(units, dtset%prtvol)
1864 :
1865 0 : call wfk_hdr%free(); call wfk_ebands%free()
1866 :
1867 0 : end subroutine ugb_from_wfk_file
1868 : !!***
1869 :
1870 : !----------------------------------------------------------------------
1871 :
1872 : !!****f* m_gwr/ugb_free
1873 : !! NAME
1874 : !! ugb_free
1875 : !!
1876 : !! FUNCTION
1877 : !! Free dynamic memory.
1878 : !!
1879 : !! SOURCE
1880 :
1881 0 : subroutine ugb_free(ugb)
1882 :
1883 : !Arguments ------------------------------------
1884 : class(ugb_t),intent(inout) :: ugb
1885 : ! *************************************************************************
1886 :
1887 0 : call ugb%mat%free()
1888 0 : call ugb%processor%free()
1889 0 : ABI_SFREE(ugb%kg_k)
1890 0 : ugb%cg_k => null()
1891 0 : ugb%comm => null()
1892 :
1893 0 : if (allocated(ugb%cprj_k)) then
1894 0 : call pawcprj_free(ugb%cprj_k)
1895 0 : ABI_FREE(ugb%cprj_k)
1896 : end if
1897 :
1898 0 : end subroutine ugb_free
1899 : !!***
1900 :
1901 : !----------------------------------------------------------------------
1902 :
1903 : !!****f* m_gwr/ugb_print
1904 : !! NAME
1905 : !! ugb_print
1906 : !!
1907 : !! FUNCTION
1908 : !! Print info on the object.
1909 : !!
1910 : !! SOURCE
1911 :
1912 0 : subroutine ugb_print(ugb, units, prtvol, header)
1913 :
1914 : !Arguments ------------------------------------
1915 : class(ugb_t),intent(in) :: ugb
1916 : integer,intent(in) :: units(:), prtvol
1917 : character(len=*),optional,intent(in) :: header
1918 :
1919 : !Local variables-------------------------------
1920 : character(len=500) :: msg
1921 : type(yamldoc_t) :: ydoc
1922 : ! *************************************************************************
1923 :
1924 : ABI_UNUSED(prtvol)
1925 :
1926 0 : msg = ' ==== Info on the ugb_t object ==== '; if (present(header)) msg = ' ==== '//trim(adjustl(header))//' ==== '
1927 0 : call wrtout(units, msg)
1928 :
1929 0 : ydoc = yamldoc_open('ugb_t') !, width=11, real_fmt='(3f8.3)')
1930 0 : call ydoc%add_int("istwf_k", ugb%istwf_k)
1931 0 : call ydoc%add_int("nspinor", ugb%nspinor)
1932 0 : call ydoc%add_int("npw_k", ugb%npw_k)
1933 0 : call ydoc%add_int("nband_k", ugb%nband_k)
1934 0 : call ydoc%add_int("my_bstart", ugb%my_bstart)
1935 0 : call ydoc%add_int("my_bstop", ugb%my_bstop)
1936 0 : call ydoc%add_int("my_nband", ugb%my_nband)
1937 0 : call ydoc%write_units_and_free(units)
1938 :
1939 0 : end subroutine ugb_print
1940 : !!***
1941 : !----------------------------------------------------------------------
1942 :
1943 : !!****f* m_ksdiago/ugb_collect_cprj
1944 : !! NAME
1945 : !! ugb_collect_cprj
1946 : !!
1947 : !! FUNCTION
1948 : !! This is a collective routine that returns in `out_cprj` the PAW projections
1949 : !! for `nb` bands starting at `band_start` NB: `out_cprj` is supposed to be allocated in the parent
1950 : !!
1951 : !! SOURCE
1952 :
1953 0 : subroutine ugb_collect_cprj(ugb, nspinor, nb, band_start, out_cprj)
1954 :
1955 : !Arguments ------------------------------------
1956 : class(ugb_t),intent(in) :: ugb
1957 : integer,intent(in) :: nspinor, nb, band_start
1958 : type(pawcprj_type),intent(inout) :: out_cprj(:,:)
1959 :
1960 : !Local variables-------------------------------
1961 : integer :: ierr, my_ibs, out_ibs, band, cnt
1962 : ! *************************************************************************
1963 :
1964 0 : ABI_CHECK_IEQ(size(ugb%cprj_k, dim=1), size(out_cprj, dim=1), "size1 should be the same")
1965 0 : ABI_CHECK_IGEQ(size(out_cprj, dim=2), nb*nspinor, "size2 too small!")
1966 :
1967 : ! TODO: Numb algorithm based on xmpi_sum. Might be optimized.
1968 0 : call pawcprj_set_zero(out_cprj)
1969 :
1970 0 : cnt = nspinor - 1
1971 0 : do band=band_start, band_start+nb-1
1972 0 : if (band >= ugb%my_bstart .and. band <= ugb%my_bstop) then
1973 0 : my_ibs = 1 + (band - ugb%my_bstart) * nspinor
1974 0 : out_ibs = 1 + (band - band_start) * nspinor
1975 0 : call pawcprj_copy(ugb%cprj_k(:,my_ibs:my_ibs+cnt), out_cprj(:,out_ibs:out_ibs+cnt))
1976 : end if
1977 : end do
1978 :
1979 0 : call pawcprj_mpi_sum(out_cprj, ugb%comm, ierr)
1980 :
1981 0 : end subroutine ugb_collect_cprj
1982 : !!***
1983 :
1984 : !----------------------------------------------------------------------
1985 :
1986 : !!****f* m_gwr/hyb_from_wfk_file
1987 : !! NAME
1988 : !! hyb_from_wfk_file
1989 : !!
1990 : !! FUNCTION
1991 : !! Read the WFK file compute with HYBRID functional
1992 : !!
1993 : !! SOURCE
1994 :
1995 0 : subroutine hyb_from_wfk_file(hyb, cryst, dtfil, dtset, psps, pawtab, ngfftc, diago_pool, comm)
1996 :
1997 : use m_krank
1998 : use m_kpts
1999 :
2000 : !Arguments ------------------------------------
2001 : class(hyb_t),intent(out) :: hyb
2002 : type(crystal_t),intent(in) :: cryst
2003 : type(datafiles_type),intent(in) :: dtfil
2004 : type(dataset_type),intent(in) :: dtset
2005 : type(pseudopotential_type),intent(in) :: psps
2006 : type(pawtab_type),intent(inout) :: pawtab(psps%ntypat*psps%usepaw)
2007 : type(xmpi_pool2d_t),intent(in) :: diago_pool
2008 : integer,intent(in) :: ngfftc(18), comm
2009 :
2010 : !Local variables ------------------------------
2011 : integer,parameter :: master = 0
2012 : integer :: nprocs, my_rank, ierr, mband, nkibz, nsppol, spin, ik_ibz, ebands_kptopt ! b1, b2,
2013 : real(dp) :: vc_ecut
2014 : character(len=5000) :: msg
2015 0 : type(hdr_type) :: wfk_hdr
2016 0 : type(crystal_t) :: wfk_cryst
2017 0 : type(krank_t) :: krank_ibz ! qrank,
2018 : character(len=fnlen) :: wfk_path
2019 : integer :: nqbzX
2020 : integer :: units(2)
2021 0 : integer,allocatable :: nband(:,:), wfd_istwfk(:), qtab(:), qtabi(:), qtabo(:)
2022 0 : real(dp),allocatable :: qbz(:,:), wtk(:), wtq(:)
2023 0 : logical,allocatable :: bks_mask(:,:,:), keep_ur(:,:,:)
2024 : !************************************************************************
2025 :
2026 0 : nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
2027 0 : units(:) = [std_out, ab_out]
2028 :
2029 0 : wfk_path = dtfil%fnamewffk
2030 0 : if (my_rank == master) then
2031 0 : if (nctk_try_fort_or_ncfile(wfk_path, msg) /= 0) then
2032 0 : ABI_ERROR(sjoin("Cannot find HYBRYD WFK file:", wfk_path, ". Error:", msg))
2033 : end if
2034 0 : call wrtout(units, sjoin("- Reading HYBRID orbitals from WFK file:", wfk_path), pre_newlines=2)
2035 : end if
2036 :
2037 : ! Broadcast filenames (needed because they might have been changed if we are using netcdf files)
2038 0 : call xmpi_bcast(wfk_path, master, comm, ierr)
2039 :
2040 : ! Construct crystal and hyb%ebands from the GS WFK file.
2041 0 : hyb%ebands = wfk_read_ebands(wfk_path, comm, out_hdr=wfk_hdr)
2042 0 : call wfk_hdr%vs_dtset(dtset)
2043 0 : ABI_CHECK_IEQ(dtset%ixc, wfk_hdr%ixc, "dtset%ixc /= wfk_hdr%ixc")
2044 :
2045 0 : wfk_cryst = wfk_hdr%get_crystal()
2046 0 : if (cryst%compare(wfk_cryst, header=" Comparing input crystal with WFK crystal") /= 0) then
2047 0 : ABI_ERROR("Crystal structure from input and from WFK file do not agree! Check messages above!")
2048 : end if
2049 : !call wfk_cryst%print(header="crystal structure from WFK file")
2050 0 : call wfk_cryst%free()
2051 : ! TODO: Add more consistency checks e.g. nkibz,...
2052 : !cryst = wfk_hdr%get_crystal()
2053 : !call cryst%print(header="crystal structure from WFK file")
2054 :
2055 0 : nkibz = hyb%ebands%nkpt; nsppol = hyb%ebands%nsppol
2056 0 : mband = hyb%ebands%mband
2057 :
2058 : ! Initialize the wave function descriptor.
2059 : ! Only wavefunctions for the symmetrical imagine of the k wavevectors
2060 : ! treated by this MPI rank are stored.
2061 0 : ABI_MALLOC(nband, (nkibz, nsppol))
2062 0 : ABI_MALLOC(bks_mask, (mband, nkibz, nsppol))
2063 0 : ABI_MALLOC(keep_ur, (mband, nkibz, nsppol))
2064 0 : nband = mband; bks_mask = .False.; keep_ur = .False.
2065 :
2066 : ! Set tolerance used to decide if a band is empty
2067 : !tol_empty_in = 0.01_dp
2068 : !call get_fact_spin_tol_empty(nsppol, nspinor, tol_empty_in, fact_spin, tol_empty)
2069 :
2070 : !do hyb_ik_ibz=1,nkibz
2071 0 : do spin=1,nsppol
2072 0 : if (all(.not. diago_pool%treats(:, spin))) cycle ! MPI distribution of collinear spins.
2073 0 : do ik_ibz=1,nkibz
2074 0 : bks_mask(:, ik_ibz, spin) = .True.
2075 : !bks_mask(b1:b2, ik_ibz, spin) = .True.
2076 : end do
2077 : end do
2078 : !end do
2079 :
2080 : ! Impose istwfk = 1 for all k-points.
2081 : ! wfd_read_wfk will handle a possible conversion if the WFK contains istwfk /= 1.
2082 0 : ABI_MALLOC(wfd_istwfk, (nkibz))
2083 0 : wfd_istwfk = 1 !; wfd_istwfk = wfk_hdr%istwf_k
2084 :
2085 : call hyb%wfd%init(cryst, pawtab, psps, keep_ur, mband, nband, nkibz, dtset%nsppol, bks_mask, &
2086 : dtset%nspden, dtset%nspinor, dtset%ecut, dtset%ecutsm, dtset%dilatmx, wfd_istwfk, hyb%ebands%kptns, ngfftc, &
2087 0 : dtset%nloalg, dtset%prtvol, dtset%pawprtvol, comm)
2088 :
2089 0 : call hyb%wfd%print([std_out], header="Wavefunctions for Hybrid WKF file")
2090 :
2091 0 : ABI_FREE(nband)
2092 0 : ABI_FREE(keep_ur)
2093 0 : ABI_FREE(wfd_istwfk)
2094 0 : ABI_FREE(bks_mask)
2095 :
2096 0 : call wfk_hdr%free()
2097 :
2098 : ! Read wavefunctions.
2099 0 : call hyb%wfd%read_wfk(wfk_path, iomode_from_fname(wfk_path))
2100 :
2101 : ! This piece of code is taken from m_gwr.
2102 :
2103 : ! =======================
2104 : ! Setup k-mesh and q-mesh
2105 : ! =======================
2106 : ! Get full kBZ associated to hyb%ebands
2107 : call kpts_ibz_from_kptrlatt(cryst, hyb%ebands%kptrlatt, hyb%ebands%kptopt, hyb%ebands%nshiftk, hyb%ebands%shiftk, &
2108 0 : hyb%nkibz, hyb%kibz, wtk, hyb%nkbz, hyb%kbz) !, bz2ibz=bz2ibz)
2109 : !new_kptrlatt=gwr%kptrlatt, new_shiftk=gwr%kshift,
2110 : !bz2ibz=new%ind_qbz2ibz) # FIXME
2111 0 : ABI_FREE(wtk)
2112 :
2113 : ! In principle kibz should be equal to hyb%ebands%kptns.
2114 0 : ABI_CHECK_IEQ(hyb%nkibz, hyb%ebands%nkpt, "nkibz != hyb%ebands%nkpt")
2115 0 : ABI_CHECK(all(abs(hyb%ebands%kptns - hyb%kibz) < tol12), "hyb%ebands%kibz != hyb%kibz")
2116 :
2117 : ! Note symrec convention.
2118 0 : ebands_kptopt = hyb%ebands%kptopt
2119 0 : call krank_ibz%from_kptrlatt(hyb%nkibz, hyb%kibz, hyb%ebands%kptrlatt, compute_invrank=.False.)
2120 :
2121 0 : ABI_MALLOC(hyb%kbz2ibz, (6, hyb%nkbz))
2122 0 : if (kpts_map("symrec", ebands_kptopt, cryst, krank_ibz, hyb%nkbz, hyb%kbz, hyb%kbz2ibz) /= 0) then
2123 0 : ABI_ERROR("Cannot map kBZ to IBZ!")
2124 : end if
2125 :
2126 : ! Order kbz by stars and rearrange entries in kbz2ibz table.
2127 0 : call kpts_pack_in_stars(hyb%nkbz, hyb%kbz, hyb%kbz2ibz)
2128 :
2129 0 : if (my_rank == master) then
2130 0 : call kpts_map_print(units, " Mapping kBZ --> kIBZ", "symrec", hyb%kbz, hyb%kibz, hyb%kbz2ibz, dtset%prtvol)
2131 : end if
2132 :
2133 : ! Table with symrel conventions for the symmetrization of the wfs.
2134 0 : ABI_MALLOC(hyb%kbz2ibz_symrel, (6, hyb%nkbz))
2135 0 : if (kpts_map("symrel", ebands_kptopt, cryst, krank_ibz, hyb%nkbz, hyb%kbz, hyb%kbz2ibz_symrel) /= 0) then
2136 0 : ABI_ERROR("Cannot map kBZ to IBZ!")
2137 : end if
2138 0 : call krank_ibz%free()
2139 :
2140 : ! Setup qIBZ, weights and BZ.
2141 : ! Always use q --> -q symmetry even in systems without inversion
2142 : ! TODO: Might add input variable to rescale the q-mesh.
2143 :
2144 : ! Find the number of q-points such that q = k1-k2.
2145 0 : call findnq(hyb%nkbz, hyb%kbz, cryst%nsym, cryst%symrec, cryst%symafm, hyb%nqibz, cryst%timrev)
2146 :
2147 : ! Find the coordinates of the q-points in the IBZ.
2148 0 : ABI_MALLOC(hyb%qibz, (3, hyb%nqibz))
2149 0 : call findq(hyb%nkbz, hyb%kbz, cryst%nsym, cryst%symrec, cryst%symafm, cryst%gprimd, hyb%nqibz, hyb%qibz, cryst%timrev)
2150 0 : ABI_CHECK(all(abs(hyb%qibz(:,1)) < tol16), "First qpoint in qibz should be Gamma!")
2151 :
2152 : ! HM: the bz2ibz produced above is incomplete, I do it here using listkk
2153 : !ABI_MALLOC(hyb%qbz2ibz, (6, hyb%nqbz))
2154 : !qrank = krank_from_kptrlatt(hyb%nqibz, hyb%qibz, qptrlatt, compute_invrank=.False.)
2155 :
2156 : !if (kpts_map("symrec", qtimrev1, cryst, qrank, hyb%nqbz, hyb%qbz, hyb%qbz2ibz) /= 0) then
2157 : ! ABI_ERROR("Cannot map qBZ to IBZ!")
2158 : !end if
2159 : !call qrank%free()
2160 :
2161 : ! Order qbz by stars and rearrange entries in qbz2ibz table.
2162 : !call kpts_pack_in_stars(hyb%nqbz, hyb%qbz, hyb%qbz2ibz)
2163 : !if (my_rank == master) then
2164 : ! call kpts_map_print(units, " Mapping qBZ --> qIBZ", "symrec", hyb%qbz, hyb%qibz, hyb%qbz2ibz, dtset%prtvol)
2165 : !end if
2166 :
2167 0 : nqbzX = hyb%nqibz*cryst%nsym*cryst%timrev ! Maximum possible number
2168 0 : ABI_MALLOC(qbz, (3, nqbzX))
2169 0 : ABI_MALLOC(wtq, (hyb%nqibz))
2170 0 : ABI_MALLOC(qtab, (nqbzX))
2171 0 : ABI_MALLOC(qtabi, (nqbzX))
2172 0 : ABI_MALLOC(qtabo, (nqbzX))
2173 :
2174 0 : call identk(hyb%qibz, hyb%nqibz, nqbzX, cryst%nsym, cryst%timrev, cryst%symrec, cryst%symafm, qbz, qtab, qtabi, qtabo, hyb%nqbz, wtq)
2175 :
2176 0 : ABI_MALLOC(hyb%qbz, (3, hyb%nqibz))
2177 0 : hyb%qbz = qbz(:,1:hyb%nqibz)
2178 :
2179 0 : ABI_FREE(qbz)
2180 0 : ABI_FREE(wtq)
2181 0 : ABI_FREE(qtab)
2182 0 : ABI_FREE(qtabi)
2183 0 : ABI_FREE(qtabo)
2184 :
2185 : ! TODO: MC technique does not seem to work as expected, even in the legacy code.
2186 0 : vc_ecut = dtset%ecut ! * four
2187 : call hyb%vcgen%init(cryst, hyb%ebands%kptrlatt, hyb%nkbz, hyb%nqibz, hyb%nqbz, hyb%qbz, &
2188 0 : dtset%rcut, dtset%gw_icutcoul, dtset%vcutgeo, vc_ecut, comm)
2189 :
2190 0 : end subroutine hyb_from_wfk_file
2191 : !!***
2192 :
2193 : !----------------------------------------------------------------------
2194 :
2195 : !!****f* m_gwr/hyb_free
2196 : !! NAME
2197 : !! hyb_free
2198 : !!
2199 : !! FUNCTION
2200 : !! Free dynamic memory.
2201 : !!
2202 : !! SOURCE
2203 :
2204 0 : subroutine hyb_free(hyb)
2205 :
2206 : !Arguments ------------------------------------
2207 : class(hyb_t),intent(inout) :: hyb
2208 : ! *************************************************************************
2209 :
2210 0 : ABI_SFREE(hyb%kibz)
2211 0 : ABI_SFREE(hyb%kbz)
2212 0 : ABI_SFREE(hyb%qibz)
2213 0 : ABI_SFREE(hyb%qbz)
2214 0 : ABI_SFREE(hyb%wtq)
2215 0 : ABI_SFREE(hyb%kbz2ibz)
2216 0 : ABI_SFREE(hyb%kbz2ibz_symrel)
2217 0 : ABI_SFREE(hyb%qbz2ibz)
2218 :
2219 : ! Free datatypes
2220 0 : call hyb%wfd%free(); call hyb%vcgen%free(); call hyb%ebands%free()
2221 :
2222 0 : end subroutine hyb_free
2223 : !!***
2224 :
2225 : !!****f* m_ksdiago/psbands_init
2226 : !! NAME
2227 : !! psbands_init
2228 : !!
2229 : !! FUNCTION
2230 : !!
2231 : !! INPUTS
2232 : !!
2233 : !! OUTPUT
2234 : !!
2235 : !! SOURCE
2236 :
2237 0 : subroutine psbands_init(psb, dtset, eig_size, eig_k, gs_fermie)
2238 :
2239 : !Arguments ------------------------------------
2240 : class(psbands_t),intent(out) :: psb
2241 : class(dataset_type),target,intent(in) :: dtset
2242 : integer,intent(in) :: eig_size
2243 : real(dp),intent(in) :: gs_fermie
2244 : !arrays
2245 : real(dp),intent(in) :: eig_k(eig_size)
2246 :
2247 : !Local variables-------------------------------
2248 : !scalars
2249 : integer :: islice, ib, cnt, units(2), first_band, last_band, nb
2250 : real(dp) :: first_eig, last_eig
2251 0 : real(dp),allocatable :: tmp_eig_k(:)
2252 : ! *********************************************************************
2253 :
2254 : ABI_UNUSED(dtset%natom)
2255 :
2256 : ! Shift energies wrt the input Fermi level.
2257 0 : ABI_MALLOC(tmp_eig_k, (eig_size))
2258 0 : tmp_eig_k = eig_k - gs_fermie
2259 :
2260 0 : psb%nb_protected = huge(1)
2261 : !psb%nb_protected = dtset%nb_protected
2262 : !psb%maxsto_per_slice = dtset%nb_per_slice
2263 : ! TODO
2264 0 : psb%efrac = 0.02_dp ! dtset%efrac
2265 :
2266 : ! Compute nslices and subspace
2267 : ! TODO: Add possibility of treating occupied states as well?
2268 0 : ABI_MALLOC(psb%subspace, (3, eig_size))
2269 0 : first_band = psb%nb_protected + 1
2270 0 : psb%nslices = 0
2271 :
2272 : do while (first_band > 0)
2273 : first_eig = tmp_eig_k(first_band)
2274 : last_eig = first_eig + (first_eig * psb%efrac)
2275 : last_band = get_band_with_energy_small_than(first_band+1, eig_size, last_eig)
2276 : psb%nslices = psb%nslices + 1
2277 : psb%subspace(1, psb%nslices) = first_band
2278 : if (last_band == -1) then
2279 : psb%subspace(2, psb%nslices) = eig_size
2280 : else
2281 : psb%subspace(2, psb%nslices) = last_band
2282 : end if
2283 : nb = psb%subspace(2, psb%nslices) - psb%subspace(1, psb%nslices) + 1
2284 : if (last_band == first_band) then
2285 : ! Won't use pseudo bands in this case.
2286 : psb%subspace(3, psb%nslices) = 1
2287 : else
2288 : !psb%subspace(3, psb%nslices) = min(dtset%nb_per_slice, nb)
2289 : end if
2290 : first_band = last_band + 1
2291 : !write(std_out,'(a,i0,a,*(1x,i0))')" islice: ", psb%nslices, " subspace:", psb%subspace(:, psb%nslices)
2292 : end do
2293 :
2294 : ! Copy eigenvalues of the protected states.
2295 0 : psb%nb_tot = psb%nb_protected + sum(psb%subspace(3,1:psb%nslices))
2296 0 : ABI_MALLOC(psb%ps_eig, (psb%nb_tot))
2297 0 : psb%ps_eig(1:psb%nb_protected) = tmp_eig_k(1:psb%nb_protected)
2298 :
2299 : cnt = 0
2300 : do islice=1,psb%nslices
2301 : first_band = psb%subspace(1, islice)
2302 : last_band = psb%subspace(2, islice)
2303 : ! Take average of eigenvalues inside the slice.
2304 : do ib=1,psb%subspace(3, islice)
2305 : cnt = cnt + 1
2306 : psb%ps_eig(psb%nb_protected + cnt) = sum(tmp_eig_k(first_band:last_band)) / dble(last_band - first_band + 1)
2307 : end do
2308 : end do
2309 0 : ABI_FREE(tmp_eig_k)
2310 :
2311 0 : psb%ps_eig = psb%ps_eig + gs_fermie
2312 :
2313 0 : units = [std_out, ab_out]
2314 0 : call wrtout(units, ' Stochastic pseudobands setup:', pre_newlines=1)
2315 0 : call wrtout(units, sjoin(' Number of stochastic subspaces: ', itoa(psb%nslices)))
2316 : !call wrtout(units, sjoin(' Number of stochastic pseudobands per subspace: ', itoa(dtset%nb_per_slice)))
2317 0 : call wrtout(units, sjoin(' Original number of bands: ', itoa(eig_size)))
2318 0 : call wrtout(units, sjoin(' Number of bands in the protection window: ', itoa(psb%nb_protected)))
2319 0 : call wrtout(units, sjoin(' Final number of bands: ', itoa(psb%nb_tot)), newlines=1)
2320 :
2321 : !if (dtset%prtvol > 5) then
2322 : ! do islice=1,psb%nslices
2323 : ! write(msg,'(a,i0,a,*(1x,i0))')" islice: ", psb%nslices, " subspace:", psb%subspace(:, psb%nslices)
2324 : ! call wrtout(units, msg)
2325 : ! end do
2326 : !end if
2327 :
2328 : contains
2329 :
2330 : integer function get_band_with_energy_small_than(idx_start, idx_end, energy) result(band)
2331 : integer, intent(in) :: idx_start, idx_end
2332 : integer :: ib
2333 : real(dp), intent(in) :: energy
2334 :
2335 : band = -1
2336 : do ib=idx_start,idx_end
2337 : if (tmp_eig_k(ib) > energy) then
2338 : band = ib - 1; return
2339 : end if
2340 : end do
2341 : end function get_band_with_energy_small_than
2342 :
2343 : end subroutine psbands_init
2344 : !!***
2345 :
2346 : !!****f* m_ksdiago/psbands_band2slice
2347 : !! NAME
2348 : !! psbands_band2slice
2349 : !!
2350 : !! FUNCTION
2351 : !! Return the slice index from the band index. -1 if band is protected.
2352 : !!
2353 : !! SOURCE
2354 :
2355 0 : integer function psbands_band2slice(psb, band) result(islice)
2356 :
2357 : !Arguments ------------------------------------
2358 : class(psbands_t),intent(in) :: psb
2359 : integer,intent(in) :: band
2360 : ! *********************************************************************
2361 :
2362 0 : do islice=1,psb%nslices
2363 0 : if (band >= psb%subspace(1,islice) .and. &
2364 0 : band <= psb%subspace(2,islice)) return
2365 : end do
2366 0 : islice = -1
2367 :
2368 : end function psbands_band2slice
2369 : !!***
2370 :
2371 : !!****f* m_ksdiago/psbands_free
2372 : !! NAME
2373 : !! psbands_free
2374 : !!
2375 : !! FUNCTION
2376 : !! Free memory
2377 : !!
2378 : !! SOURCE
2379 :
2380 0 : subroutine psbands_free(psb)
2381 :
2382 : !Arguments ------------------------------------
2383 : class(psbands_t),intent(inout) :: psb
2384 : ! *********************************************************************
2385 :
2386 0 : ABI_SFREE(psb%ps_eig)
2387 0 : ABI_SFREE(psb%subspace)
2388 :
2389 0 : end subroutine psbands_free
2390 : !!***
2391 :
2392 0 : end module m_ksdiago
2393 : !!***
|