LCOV - code coverage report
Current view: top level - src/67_common - m_ksdiago.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 22.1 % 754 167
Test Date: 2026-09-20 15:27:41 Functions: 10.5 % 19 2

            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              : !!***
        

Generated by: LCOV version 2.3-1