LCOV - code coverage report
Current view: top level - src/95_drive - m_wfk_analyze.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 50.4 % 224 113
Test Date: 2026-09-21 22:40:37 Functions: 66.7 % 3 2

            Line data    Source code
       1              : !!****m* ABINIT/m_wfk_analyze
       2              : !! NAME
       3              : !!  m_wfk_analyze
       4              : !!
       5              : !! FUNCTION
       6              : !!  Post-processing tools for WFK file
       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_wfk_analyze
      23              : 
      24              :  use, intrinsic :: iso_c_binding
      25              :  use defs_basis
      26              :  use m_abicore
      27              :  use m_xmpi
      28              :  use m_errors
      29              :  use m_hdr
      30              :  use m_crystal
      31              :  use m_ebands
      32              :  use m_nctk
      33              :  use m_wfd
      34              :  use m_dtset
      35              :  use m_dtfil
      36              :  use m_distribfft
      37              : 
      38              :  use m_io_tools,        only : iomode_from_fname, get_unit
      39              :  use defs_datatypes,    only : pseudopotential_type
      40              :  use defs_abitypes,     only : mpi_type
      41              :  use m_time,            only : timab
      42              :  use m_fstrings,        only : strcat, sjoin, itoa, ftoa, ltoa, ktoa
      43              :  use m_fftcore,         only : print_ngfft
      44              :  use m_mpinfo,          only : destroy_mpi_enreg, initmpi_seq, init_mpi_enreg
      45              :  use m_esymm,           only : esymm_t, esymm_free
      46              :  use m_ddk,             only : ddkstore_t
      47              :  use m_ksdiago,         only : psbands_t
      48              :  use m_pawang,          only : pawang_type
      49              :  use m_pawrad,          only : pawrad_type
      50              :  use m_pawtab,          only : pawtab_type, pawtab_print, pawtab_get_lsize
      51              :  use m_paw_an,          only : paw_an_type, paw_an_init, paw_an_free, paw_an_nullify
      52              :  use m_paw_ij,          only : paw_ij_type, paw_ij_init, paw_ij_free, paw_ij_nullify
      53              :  use m_pawfgrtab,       only : pawfgrtab_type, pawfgrtab_free, pawfgrtab_init, pawfgrtab_print
      54              :  use m_pawrhoij,        only : pawrhoij_type, pawrhoij_alloc, pawrhoij_copy, pawrhoij_free, pawrhoij_inquire_dim
      55              :  use m_pawdij,          only : pawdij, symdij
      56              :  use m_pawfgr,          only : pawfgr_type, pawfgr_init, pawfgr_destroy
      57              :  use m_paw_sphharm,     only : setsym_ylm
      58              :  use m_paw_init,        only : pawinit, paw_gencond
      59              :  use m_paw_nhat,        only : nhatgrid
      60              :  use m_paw_tools,       only : chkpawovlp
      61              :  use m_paw_correlations,only : pawpuxinit
      62              :  use m_paw_pwaves_lmn,  only : paw_pwaves_lmn_t, paw_pwaves_lmn_init, paw_pwaves_lmn_free
      63              :  use m_classify_bands,  only : classify_bands, dmats_t
      64              :  use m_kpts,            only : kpts_ibz_from_kptrlatt
      65              :  use m_pspini,          only : pspini
      66              :  use m_sigtk,           only : sigtk_kpts_in_erange
      67              :  use m_iowf,            only : prtkbff
      68              :  use m_wfd_wannier,     only : wfd_run_wannier
      69              :  use m_wfk,             only : wfk_to_bz, wfk_t, wfk_read_eigenvalues, wfk_check_symtab
      70              : 
      71              :  implicit none
      72              : 
      73              :  private
      74              : !!***
      75              : 
      76              :  public :: wfk_analyze
      77              : !!***
      78              : 
      79              : contains
      80              : !!***
      81              : 
      82              : !!****f* ABINIT/wfk_analyze
      83              : !! NAME
      84              : !!  wfk_analyze
      85              : !!
      86              : !! FUNCTION
      87              : !! Main routine implementing postprocessing tools for the WFK file.
      88              : !! Main differences wrt cut3d:
      89              : !!
      90              : !!   - MPI support.
      91              : !!   - No interactive prompt.
      92              : !!   - Run the analysis once, store all the important results in netcdf files
      93              : !!     and use python tools to analyze data
      94              : !!
      95              : !! INPUTS
      96              : !! acell(3)=Length scales of primitive translations (bohr)
      97              : !! codvsn=Code version
      98              : !! dtfil<datafiles_type>=Variables related to files.
      99              : !! dtset<dataset_type>=All input variables for this dataset.
     100              : !! pawang<pawang_type)>=PAW angular mesh and related data.
     101              : !! pawrad(ntypat*usepaw)<pawrad_type>=Paw radial mesh and related data.
     102              : !! pawtab(ntypat*usepaw)<pawtab_type>=Paw tabulated starting data.
     103              : !! psps<pseudopotential_type>=Variables related to pseudopotentials.
     104              : !!   Before entering the first time in the routine, a significant part of psps has been initialized :
     105              : !!   the integers dimekb,lmnmax,lnmax,mpssang,mpssoang,mpsso,mgrid,ntypat,n1xccc,usepaw,useylm,
     106              : !!   and the arrays dimensioned to npsp. All the remaining components of psps are to be initialized in
     107              : !!   the call to pspini. The next time the code enters bethe_salpeter, psps might be identical to the
     108              : !!   one of the previous dtset, in which case, no reinitialisation is scheduled in pspini.F90.
     109              : !! rprim(3,3)=Dimensionless real space primitive translations.
     110              : !! xred(3,natom)=Reduced atomic coordinates.
     111              : !!
     112              : !! NOTES
     113              : !!
     114              : !! ON THE USE OF FFT GRIDS:
     115              : !! =================
     116              : !! In case of PAW:
     117              : !! ---------------
     118              : !!    Two FFT grids are used:
     119              : !!    - A "coarse" FFT grid (defined by ecut) for the application of the Hamiltonian on the plane waves basis.
     120              : !!      It is defined by nfft, ngfft, mgfft, ...
     121              : !!      Hamiltonian, wave-functions, density related to WFs (rhor here), ... are expressed on this grid.
     122              : !!    - A "fine" FFT grid (defined) by ecutdg) for the computation of the density inside PAW spheres.
     123              : !!      It is defined by nfftf, ngfftf, mgfftf, ... Total density, potentials, ... are expressed on this grid.
     124              : !! In case of norm-conserving:
     125              : !! ---------------------------
     126              : !!    - Only the usual FFT grid (defined by ecut) is used. It is defined by nfft, ngfft, mgfft, ...
     127              : !!      For compatibility reasons, (nfftf,ngfftf,mgfftf) are set equal to (nfft,ngfft,mgfft) in that case.
     128              : !!
     129              : !! SOURCE
     130              : 
     131           12 : subroutine wfk_analyze(acell, codvsn, dtfil, dtset, pawang, pawrad, pawtab, psps, rprim, xred)
     132              : 
     133              : !Arguments ------------------------------------
     134              : !scalars
     135              :  character(len=8),intent(in) :: codvsn
     136              :  type(datafiles_type),intent(in) :: dtfil
     137              :  type(dataset_type),intent(inout) :: dtset
     138              :  type(pawang_type),intent(inout) :: pawang
     139              :  type(pseudopotential_type),intent(inout) :: psps
     140              : !arrays
     141              :  real(dp),intent(in) :: acell(3),rprim(3,3),xred(3,dtset%natom)
     142              :  type(pawrad_type),intent(inout) :: pawrad(psps%ntypat*psps%usepaw)
     143              :  type(pawtab_type),intent(inout) :: pawtab(psps%ntypat*psps%usepaw)
     144              : 
     145              : !Local variables ------------------------------
     146              : !scalars
     147              :  integer,parameter :: master = 0, formeig0 = 0
     148              :  integer :: comm,nprocs,my_rank,mgfftf,nfftf !,nfftf_tot
     149              :  integer :: optcut,optgr0,optgr1,optgr2,optrad,psp_gencond,ii
     150              :  !integer :: option,option_test,option_dij,optrhoij
     151              :  integer :: band,ik_ibz,spin,nband_k, islice, ib, mpw, mcg, nb, npw_k ! first_band,last_band,
     152              :  integer :: ierr,usexcnhat, sc_mode, nspinor, nsto
     153              :  integer :: cplex,cplex_dij,cplex_rhoij,ndij,nspden_rhoij,gnt_option
     154              :  real(dp),parameter :: spinmagntarget=-99.99_dp
     155              :  real(dp) :: ecore,ecut_eff,ecutdg_eff,gsqcutc_eff,gsqcutf_eff,gsqcut_shp, gs_fermie
     156              :  !real(dp) :: cpu,wall,gflops
     157              :  !real(dp) :: ex_energy,gsqcutc_eff,gsqcutf_eff,nelect,norm,oldefermi
     158              :  character(len=500) :: msg
     159              :  character(len=fnlen) :: wfk0_path, outwfk_path
     160              :  logical :: call_pawinit !, use_paw_aeur
     161           36 :  type(hdr_type) :: wfk0_hdr, hdr_bz, out_hdr
     162         1248 :  type(crystal_t) :: cryst, cryst_dtset
     163           24 :  type(ebands_t) :: ebands, ebands_bz
     164              :  type(pawfgr_type) :: pawfgr
     165              :  !type(paw_dmft_type) :: paw_dmft
     166           12 :  type(mpi_type) :: mpi_enreg
     167           12 :  type(wfd_t) :: wfd
     168           12 :  type(ddkstore_t) :: ds
     169           96 :  type(wfk_t) :: in_wfk, out_wfk
     170           12 :  type(dmats_t) :: dmats
     171              :  !type(dataset_type) :: my_dtset
     172              : !arrays
     173           24 :  integer :: ngfftc(18),ngfftf(18), units(2), band_block(2), bstart, brange_spin(2, dtset%nsppol)
     174              :  integer :: nkibz_full, nkbz_full, ikbz, nstar_fail
     175           12 :  integer,allocatable :: l_size_atm(:), kg_k(:,:)
     176           24 :  real(dp),allocatable :: wtk_full(:), kibz_full(:,:), kbz_full(:,:)
     177              :  real(dp),parameter :: k0(3)=zero
     178           12 :  real(dp),pointer :: gs_eigen(:,:,:)
     179           12 :  real(dp),allocatable :: eig_k(:), occ_k(:), thetas(:) !, out_cg(:,:), work(:,:,:,:), allcg_k(:,:)
     180           12 :  real(dp),allocatable,target :: cg_k(:,:)
     181           12 :  complex(gwp),allocatable :: ur_ae(:)
     182           12 :  complex(dp),pointer :: cg_k_cplx(:,:)
     183           12 :  complex(dp),allocatable :: ps_ug(:,:)
     184           12 :  logical,allocatable :: keep_ur(:,:,:),bks_mask(:,:,:)
     185              :  real(dp) :: tsec(2)
     186           12 :  type(Pawrhoij_type),allocatable :: pawrhoij(:)
     187           12 :  type(pawfgrtab_type),allocatable :: pawfgrtab(:)
     188              :  !type(paw_ij_type),allocatable :: paw_ij(:)
     189              :  !type(paw_an_type),allocatable :: paw_an(:)
     190              :  !type(esymm_t),allocatable :: esymm(:,:)
     191           12 :  type(paw_pwaves_lmn_t),allocatable :: Paw_onsite(:)
     192           12 :  type(psbands_t),allocatable :: psb_ks(:,:)
     193              : !************************************************************************
     194              : 
     195              :  DBG_ENTER('COLL')
     196              : 
     197              :  ! abirules!
     198              :  if (.False.) write(std_out,*)acell,codvsn,rprim,xred
     199           36 :  units = [std_out, ab_out]
     200              : 
     201           12 :  comm = xmpi_world; nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
     202              : 
     203           12 :  wfk0_path = dtfil%fnamewffk
     204           12 :  if (my_rank == master) then
     205              :    ! Accept WFK file in Fortran or netcdf format.
     206           12 :    if (nctk_try_fort_or_ncfile(wfk0_path, msg) /= 0) then
     207            0 :      ABI_ERROR(sjoin("Cannot find GS WFK file:", ch10, msg))
     208              :    end if
     209              :  end if
     210           12 :  call xmpi_bcast(wfk0_path, master, comm, ierr)
     211           12 :  call wrtout(ab_out, sjoin("- Reading GS states from WFK file:", wfk0_path))
     212              : 
     213              :  !call cwtime(cpu,wall,gflops,"start")
     214              : 
     215              :  ! Construct crystal and ebands from the GS WFK file.
     216           12 :  call wfk_read_eigenvalues(wfk0_path, gs_eigen, wfk0_hdr, comm) !,gs_occ)
     217           12 :  call wfk0_hdr%vs_dtset(dtset)
     218           12 :  nspinor = dtset%nspinor
     219              : 
     220              :  ! Get fermie from the GS calculation.
     221              :  ! NB: It might understimate the real Fermi level, especially if the den was computed on a shifted k-mesh
     222              :  ! at present it's only used to implement pseudobands
     223           12 :  gs_fermie = wfk0_hdr%fermie
     224              : 
     225           12 :  cryst = wfk0_hdr%get_crystal()
     226           12 :  call cryst%print(header="Crystal structure from WFK file")
     227              : 
     228              :  ! Compare structure with the one computed from input file.
     229           12 :  cryst_dtset = dtset%get_crystal(1)
     230           12 :  if (cryst%compare(cryst_dtset, header=" Comparing WFK crystal with crystal from dtset") /= 0) then
     231            0 :    ABI_ERROR("Crystal structure from WFK and dataser do not agree! Check messages above!")
     232              :  end if
     233           12 :  call cryst_dtset%free()
     234              : 
     235          119 :  call ebands%from_hdr(wfk0_hdr, maxval(wfk0_hdr%nband), gs_eigen)
     236              : 
     237              :  !call ebands%update_occ(spinmagntarget)
     238           24 :  call ebands%print([std_out], header="Ground state energies", prtvol=dtset%prtvol)
     239           12 :  ABI_FREE(gs_eigen)
     240              : 
     241              :  call pawfgr_init(pawfgr,dtset,mgfftf,nfftf,ecut_eff,ecutdg_eff,ngfftc,ngfftf,&
     242           12 :                   gsqcutc_eff=gsqcutc_eff,gsqcutf_eff=gsqcutf_eff,gmet=cryst%gmet,k0=k0)
     243              : 
     244           24 :  call print_ngfft([std_out], ngfftc, header='Coarse FFT mesh used for the wavefunctions')
     245           24 :  call print_ngfft([std_out], ngfftf, header='Dense FFT mesh used for densities and potentials')
     246              : 
     247              :  ! Fake MPI_type for the sequential part.
     248           12 :  call initmpi_seq(mpi_enreg)
     249           12 :  call mpi_enreg%distribfft%init_seq('c',ngfftc(2),ngfftc(3),'all')
     250           12 :  call mpi_enreg%distribfft%init_seq('f',ngfftf(2),ngfftf(3),'all')
     251              : 
     252              :  ! ===========================================
     253              :  ! === Open and read pseudopotential files ===
     254              :  ! ===========================================
     255           12 :  call pspini(dtset,dtfil,ecore,psp_gencond,gsqcutc_eff,gsqcutf_eff,pawrad,pawtab,psps,cryst%rprimd,comm_mpi=comm)
     256              : 
     257              :  ! ============================
     258              :  ! ==== PAW initialization ====
     259              :  ! ============================
     260           12 :  if (dtset%usepaw == 1) then
     261            1 :    call chkpawovlp(cryst%natom,cryst%ntypat,dtset%pawovlp,pawtab,cryst%rmet,cryst%typat,cryst%xred)
     262              : 
     263            1 :    cplex_dij=nspinor; cplex=1; ndij=1
     264              : 
     265            5 :    ABI_MALLOC(pawrhoij,(cryst%natom))
     266              :    call pawrhoij_inquire_dim(cplex_rhoij=cplex_rhoij,nspden_rhoij=nspden_rhoij,&
     267            1 :                              nspden=Dtset%nspden,spnorb=Dtset%pawspnorb,cpxocc=Dtset%pawcpxocc)
     268            1 :    call pawrhoij_alloc(pawrhoij,cplex_rhoij,nspden_rhoij,nspinor,dtset%nsppol,cryst%typat,pawtab=pawtab)
     269              : 
     270              :    ! Initialize values for several basic arrays
     271            1 :    gnt_option=1;if (dtset%pawxcdev==2.or.(dtset%pawxcdev==1.and.dtset%positron/=0)) gnt_option=2
     272              : 
     273              :    ! Test if we have to call pawinit
     274            1 :    call paw_gencond(dtset,gnt_option,"test",call_pawinit)
     275              : 
     276            1 :    if (psp_gencond==1 .or. call_pawinit) then
     277            0 :      call timab(553,1,tsec)
     278            0 :      gsqcut_shp = two*abs(dtset%diecut)*dtset%dilatmx**2/pi**2
     279              :      call pawinit(dtset%effmass_free,gnt_option,gsqcut_shp,zero,dtset%pawlcutd,dtset%pawlmix,&
     280              :                   psps%mpsang,dtset%pawnphi,cryst%nsym,dtset%pawntheta,pawang,Pawrad,&
     281            0 :                   dtset%pawspnorb,pawtab,dtset%pawxcdev,dtset%ixc,dtset%usepotzero)
     282            0 :      call timab(553,2,tsec)
     283              : 
     284              :      ! Update internal values
     285            0 :      call paw_gencond(dtset,gnt_option,"save",call_pawinit)
     286              : 
     287              :    else
     288            1 :      if (pawtab(1)%has_kij  ==1) pawtab(1:cryst%ntypat)%has_kij  =2
     289            1 :      if (pawtab(1)%has_nabla==1) pawtab(1:cryst%ntypat)%has_nabla=2
     290              :    end if
     291              : 
     292            2 :    psps%n1xccc=MAXVAL(pawtab(1:cryst%ntypat)%usetcore)
     293              : 
     294              :    ! Initialize optional flags in pawtab to zero
     295              :    ! (Cannot be done in Pawinit since the routine is called only if some pars. are changed)
     296            2 :    pawtab(:)%has_nabla = 0
     297            2 :    pawtab(:)%usepawu   = 0
     298            2 :    pawtab(:)%useexexch = 0
     299            2 :    pawtab(:)%exchmix   =zero
     300            2 :    pawtab(:)%lamb_shielding   =zero
     301              : 
     302            1 :    call setsym_ylm(cryst%gprimd,pawang%l_max-1,cryst%nsym,dtset%pawprtvol,cryst%rprimd,cryst%symrec,pawang%zarot)
     303              : 
     304              :    ! Initialize and compute data for DFT+U
     305              :    !paw_dmft%use_dmft=dtset%usedmft
     306              :    !call pawpuxinit(dtset%dmatpuopt,dtset%exchmix,dtset%f4of2_sla,dtset%f6of2_sla,&
     307              :    !    .false.,dtset%jpawu,dtset%lexexch,dtset%lpawu,cryst%ntypat,pawang,dtset%pawprtvol,&
     308              :    !    Pawrad,pawtab,dtset%upawu,dtset%usedmft,dtset%useexexch,dtset%usepawu)
     309              :    !ABI_CHECK(paw_dmft%use_dmft==0,"DMFT not available")
     310              :    !call destroy_sc_dmft(paw_dmft)
     311              : 
     312            1 :    if (my_rank == master) call pawtab_print(pawtab, unit=std_out)
     313              : 
     314              :    ! Get Pawrhoij from the header of the WFK file.
     315            1 :    call pawrhoij_copy(wfk0_hdr%pawrhoij,pawrhoij)
     316              : 
     317              :    ! Variables/arrays related to the fine FFT grid.
     318            5 :    ABI_MALLOC(pawfgrtab,(cryst%natom))
     319            1 :    call pawtab_get_lsize(pawtab,l_size_atm,cryst%natom,cryst%typat)
     320              :    cplex=1
     321            1 :    call pawfgrtab_init(pawfgrtab,cplex,l_size_atm,dtset%nspden,dtset%typat)
     322            1 :    ABI_FREE(l_size_atm)
     323              : 
     324            2 :    usexcnhat=maxval(pawtab(:)%usexcnhat)
     325              :    ! 0 if Vloc in atomic data is Vbare    (Blochl s formulation)
     326              :    ! 1 if Vloc in atomic data is VH(tnzc) (Kresse s formulation)
     327            1 :    call wrtout(std_out,sjoin("using usexcnhat= ",itoa(usexcnhat)))
     328              :    !
     329              :    ! Identify parts of the rectangular grid where the density has to be calculated ===
     330              :    !optcut=0; optgr0=dtset%pawstgylm; optgr1=0; optgr2=0; optrad=1-dtset%pawstgylm
     331              :    !if (dtset%xclevel==2 .and. usexcnhat>0) optgr1=dtset%pawstgylm
     332            1 :    optcut=1; optgr0=1; optgr1=1; optgr2=1; optrad=1
     333              : 
     334              :    call nhatgrid(cryst%atindx1,cryst%gmet,cryst%natom,cryst%natom,cryst%nattyp,ngfftf,cryst%ntypat,&
     335            1 :                 optcut,optgr0,optgr1,optgr2,optrad,pawfgrtab,pawtab,cryst%rprimd,cryst%typat,cryst%ucvol,cryst%xred)
     336              : 
     337            3 :    call pawfgrtab_print(pawfgrtab,cryst%natom,unit=std_out,prtvol=dtset%pawprtvol)
     338              : 
     339              :    !ABI_MALLOC(ks_nhat,(nfftf,dtset%nspden))
     340              :    !ks_nhat=zero
     341              :  else
     342           11 :    ABI_MALLOC(pawfgrtab,(0))
     343              :  end if !End of PAW Initialization
     344              : 
     345           14 :  select case (dtset%wfk_task)
     346              : 
     347              :  case (WFK_TASK_FULLBZ, WFK_TASK_OPTICS_FULLBZ)
     348              :    ! Read wfk0_path and build WFK in full BZ.
     349            2 :    if (my_rank == master) then
     350            2 :      outwfk_path = dtfil%fnameabo_wfk; if (dtset%iomode == IO_MODE_ETSF) outwfk_path = nctk_ncify(outwfk_path)
     351            2 :      call wfk_to_bz(wfk0_path, dtset, psps, pawtab, outwfk_path, hdr_bz, ebands_bz)
     352            2 :      call ebands_bz%free()
     353              : 
     354              :      ! Write KB form factors.
     355            2 :      if (dtset%prtkbff == 1 .and. dtset%iomode == IO_MODE_ETSF .and. dtset%usepaw == 0) then
     356            1 :        call prtkbff(outwfk_path, hdr_bz, psps, dtset%prtvol)
     357              :      end if
     358            2 :      call hdr_bz%free()
     359              :    end if
     360            2 :    call xmpi_barrier(comm)
     361              : 
     362            2 :    if (dtset%wfk_task == WFK_TASK_OPTICS_FULLBZ) then
     363              :      ! Calculate the DDK matrix elements from the WFK file in the full BZ.
     364              :      ! This is needed for computing non-linear properties in optics as symmetries are not
     365              :      ! implemented correctly.
     366              :      ds%only_diago = .False.
     367            0 :      call ds%compute_ddk(outwfk_path, dtfil%filnam_ds(4), dtset, psps, pawtab, ngfftc, comm)
     368            0 :      call ds%free()
     369              :    end if
     370              : 
     371              :  case (WFK_TASK_KPTS_ERANGE)
     372            2 :    call sigtk_kpts_in_erange(dtset, cryst, ebands, psps, pawtab, dtfil%filnam_ds(4), comm)
     373              : 
     374              :  case (WFK_TASK_DDK, WFK_TASK_DDK_DIAGO)
     375              :    ! Calculate the DDK matrix elements from the WFK file
     376            3 :    ds%only_diago = .False.; if (dtset%wfk_task == WFK_TASK_DDK_DIAGO) ds%only_diago = .True.
     377            3 :    call ds%compute_ddk(wfk0_path, dtfil%filnam_ds(4), dtset, psps, pawtab, ngfftc, comm)
     378            3 :    call ds%free()
     379              : 
     380              :  case (WFK_TASK_EINTERP)
     381              :    ! Band structure interpolation from eigenvalues computed on the k-mesh.
     382            0 :    call ebands%interpolate_kpath(dtset, cryst, [0, 0], dtfil%filnam_ds(4), comm)
     383              : 
     384              :  case (WFK_TASK_CHECK_SYMTAB)
     385            0 :    call wfk_check_symtab(wfk0_path, comm)
     386              : 
     387              :  case (WFK_TASK_CLASSIFY)
     388              :    ! Band classification.
     389              : 
     390              :    ! New version
     391              :    ! Compute the mixing matrices D^{k}(S) from the wavefunctions stored in wfd_t.
     392            0 :    do spin=1,dtset%nsppol
     393            0 :      brange_spin(:,spin) = [1, dtset%mband]
     394              :    end do
     395            0 :    call dmats%init(wfk0_path, dtset, cryst, brange_spin, ngfftf, pawtab, psps, comm)
     396              : 
     397            0 :    if (my_rank == master) then
     398            0 :      call dmats%check([std_out], dtset%prtvol)
     399            0 :      call dmats%classify(dtset%prtvol)
     400              : 
     401              :      ! Independently validate the group-conjugation D-matrix reconstruction (dmats%check_star)
     402              :      ! by testing EVERY k-point in the full BZ mesh, not just the IBZ points dmats was built
     403              :      ! from: each full-BZ k-point is the symmetry-star image of some IBZ k-point, so this
     404              :      ! exercises dmats_get_star_dmats's multable/toinv composition logic (and, in particular,
     405              :      ! its still-unverified two-step analytic phase formula) across the whole mesh.
     406              :      call kpts_ibz_from_kptrlatt(cryst, ebands%kptrlatt, ebands%kptopt, ebands%nshiftk, ebands%shiftk, &
     407            0 :                                  nkibz_full, kibz_full, wtk_full, nkbz_full, kbz_full)
     408              : 
     409            0 :      nstar_fail = 0
     410            0 :      do spin=1,dtset%nsppol
     411            0 :        do ikbz=1,nkbz_full
     412            0 :          call dmats%check_star(spin, kbz_full(:,ikbz), [std_out], dtset%prtvol, ierr)
     413            0 :          if (ierr /= 0) then
     414            0 :            nstar_fail = nstar_fail + 1
     415              :            call wrtout(units, sjoin("check_star FAILED for spin:", itoa(spin), &
     416            0 :                        ", kbz:", ktoa(kbz_full(:,ikbz)), ", ierr:", itoa(ierr)))
     417              :          end if
     418              :        end do
     419              :      end do
     420              :      call wrtout(units, sjoin("check_star: tested", itoa(nkbz_full * dtset%nsppol), &
     421            0 :                  "(k,spin) points in the full BZ, failures:", itoa(nstar_fail)))
     422              : 
     423            0 :      ABI_FREE(kibz_full)
     424            0 :      ABI_FREE(wtk_full)
     425            0 :      ABI_FREE(kbz_full)
     426              :    end if
     427            0 :    call dmats%free()
     428              : 
     429              : #if 0
     430              :    ! old implementation
     431              :    call read_wfd()
     432              : 
     433              :    ABI_MALLOC(esymm,(wfd%nkibz,wfd%nsppol))
     434              :    use_paw_aeur=.False. ! should pass ngfftf but the dense mesh is not forced to be symmetric
     435              : 
     436              :    do spin=1,wfd%nsppol
     437              :      do ik_ibz=1,wfd%nkibz
     438              :        first_band = 1
     439              :        last_band  = wfd%nband(ik_ibz,spin)
     440              :        call classify_bands(wfd,use_paw_aeur,first_band,last_band,ik_ibz,spin,wfd%ngfft,&
     441              :        cryst,ebands,pawtab,pawrad,pawang,psps,dtset%tolsym,esymm(ik_ibz,spin))
     442              :      end do
     443              :    end do
     444              : 
     445              :    call esymm_free(esymm)
     446              :    ABI_FREE(esymm)
     447              : #endif
     448              : 
     449              :  !case (WFK_TASK_UR)
     450              :  !  ! plot KSS wavefunctions. Change bks_mask to select particular states.
     451              :  !  ABI_MALLOC(bks_mask,(Wfd%mband,Wfd%nkibz,Wfd%nsppol))
     452              :  !  bks_mask=.False.; bks_mask(1:4,1,1)=.True.
     453              :  !  call wfd%plot_ur(Cryst,Psps,Pawtab,Pawrad,ngfftf,bks_mask)
     454              :  !  ABI_FREE(bks_mask)
     455              : 
     456              :  case (WFK_TASK_PSEUDOBANDS)
     457            0 :    if (my_rank /= master) goto 100 ! NO MPI parallelism here
     458              : 
     459              :    ! out_hdr is the header the STO_WFK file.
     460            0 :    call wfk0_hdr%copy(out_hdr)
     461              : 
     462              :    ! Pre-compute slices for all k-points and spin so that we know the new number of bands in STO_WFK file.
     463            0 :    ABI_MALLOC(psb_ks, (ebands%nkpt, ebands%nsppol))
     464            0 :    do spin=1,ebands%nsppol
     465            0 :      do ik_ibz=1,ebands%nkpt
     466            0 :        associate (psb => psb_ks(ik_ibz, spin))
     467            0 :        nband_k = ebands%nband(ik_ibz + (spin-1)*ebands%nkpt)
     468            0 :        call psb%init(dtset, nband_k, ebands%eig(:, ik_ibz, spin), gs_fermie)
     469              :        ! Change the number of bands to account for pseudo bands.
     470              :        !print *, "nb_tot:", psb%nb_tot
     471            0 :        out_hdr%nband(ik_ibz + (spin-1)*ebands%nkpt) = psb%nb_tot
     472              :        end associate
     473              :      end do
     474              :    end do
     475              : 
     476              :    ! Compute new value of bantot
     477              :    ! TODO: Have to change all arrays in outhdr_hdr depending on nband_ks
     478            0 :    out_hdr%bantot = sum(out_hdr%nband)
     479            0 :    out_hdr%mband = maxval(out_hdr%nband)
     480            0 :    ABI_RECALLOC(out_hdr%occ, (out_hdr%bantot))
     481              : 
     482            0 :    outwfk_path = strcat(dtfil%filnam_ds(4), "_STO_WFK")
     483            0 :    if (dtset%iomode == IO_MODE_ETSF) outwfk_path = nctk_ncify(outwfk_path)
     484            0 :    call out_wfk%open_write(out_hdr, outwfk_path, formeig0, dtset%iomode, get_unit(), xmpi_comm_self)
     485              : 
     486            0 :    call in_wfk%open_read(wfk0_path, formeig0, iomode_from_fname(wfk0_path), get_unit(), xmpi_comm_self)
     487              : 
     488              :    ! The output arrays eig_k and occ_k contain the *full* set of eigenvalues and occupation
     489              :    ! factors stored in the file and are dimensioned with mband.
     490            0 :    ABI_MALLOC(eig_k, (wfk0_hdr%mband))
     491            0 :    ABI_MALLOC(occ_k, (wfk0_hdr%mband))
     492            0 :    mpw = maxval(wfk0_hdr%npwarr)
     493            0 :    ABI_MALLOC(kg_k, (3, mpw))
     494              :    !print *, "mpw:", mpw
     495            0 :    sc_mode = xmpio_single
     496              : 
     497            0 :    do spin=1,ebands%nsppol
     498            0 :      do ik_ibz=1,ebands%nkpt
     499            0 :        associate (psb => psb_ks(ik_ibz, spin))
     500              :        ! Read and write protected states.
     501            0 :        band_block = [1, psb%nb_protected]
     502            0 :        nb = band_block(2) - band_block(1) + 1
     503            0 :        npw_k = wfk0_hdr%npwarr(ik_ibz)
     504            0 :        mcg = npw_k * nspinor * nb
     505            0 :        ABI_MALLOC(cg_k, (2, mcg))
     506              : 
     507              :        call in_wfk%read_band_block(band_block, ik_ibz, spin, sc_mode, &
     508            0 :                                    kg_k=kg_k, cg_k=cg_k, eig_k=eig_k, occ_k=occ_k)
     509              : 
     510              :        !call wrtout(std_out, sjoin(" About to write islice:", itoa(0), "with band block:", ltoa(band_block)))
     511            0 :        eig_k(1:psb%nb_tot) = psb%ps_eig(:) ! Change eigenvalues to account for pseudo bands
     512              :        !occ_k = ???
     513              :        call out_wfk%write_band_block(band_block, ik_ibz, spin, sc_mode, &
     514            0 :                                      kg_k=kg_k, cg_k=cg_k, eig_k=eig_k, occ_k=occ_k)
     515            0 :        ABI_FREE(cg_k)
     516              : 
     517              :        ! ========================================
     518              :        ! Build pseudobands and write them to disk
     519              :        ! ========================================
     520            0 :        bstart = psb%nb_protected + 1
     521            0 :        do islice=1,psb%nslices
     522            0 :          band_block = psb%subspace(1:2, islice)
     523            0 :          nb = band_block(2) - band_block(1) + 1
     524            0 :          mcg = npw_k * nspinor * nb
     525            0 :          ABI_MALLOC(cg_k, (2, mcg))
     526              : 
     527            0 :          call in_wfk%read_band_block(band_block, ik_ibz, spin, sc_mode, cg_k=cg_k)
     528            0 :          call c_f_pointer(c_loc(cg_k), cg_k_cplx, [npw_k*nspinor, nb])
     529              : 
     530              :          ! Allocate pseudobands.
     531            0 :          nsto = psb%subspace(3, islice)
     532            0 :          ABI_CALLOC(ps_ug, (npw_k*nspinor, nsto))
     533            0 :          ABI_MALLOC(thetas, (nb))
     534              : 
     535            0 :          if (nsto == 1) then
     536              :            ! Use KS state.
     537            0 :            ps_ug = cg_k_cplx
     538              :          else
     539              :            ! Multiply by random phases.
     540            0 :            do ii=1,nsto
     541            0 :              call random_number(thetas)
     542            0 :              do ib=1,nb
     543            0 :                ps_ug(:,ii) = ps_ug(:,ii) + cg_k_cplx(:,ib) * exp(j_dpc*two_pi*thetas(ib)) / sqrt(one * nsto)
     544              :              end do
     545              :            end do
     546              :          end if
     547              : 
     548            0 :          band_block = [bstart, bstart + psb%subspace(3, islice) - 1]
     549              :          !call wrtout(std_out, sjoin(" About to write islice:", itoa(islice), "with band block:", ltoa(band_block)))
     550            0 :          call out_wfk%write_band_block(band_block, ik_ibz, spin, sc_mode, cg_k=cg_k)
     551              :                                        !kg_k=kg_k, cg_k=cg_k, eig_k=eig_k, occ_k=occ_k)
     552            0 :          bstart = bstart + psb%subspace(3, islice)
     553              : 
     554            0 :          ABI_FREE(thetas)
     555            0 :          ABI_FREE(cg_k)
     556            0 :          ABI_FREE(ps_ug)
     557              :        end do ! islice
     558              : 
     559            0 :        call psb%free()
     560              :        end associate
     561              :      end do ! ik_ibz
     562              :    end do ! spin
     563              : 
     564            0 :    ABI_FREE(eig_k)
     565            0 :    ABI_FREE(occ_k)
     566            0 :    ABI_FREE(kg_k)
     567            0 :    call in_wfk%close(); call out_wfk%close(); call out_hdr%free()
     568              : 
     569              :    ! DEBUG section. Try to read the output WFK file.
     570              :    !call out_wfk%open_read(outwfk_path, formeig0, iomode_from_fname(outwfk_path), get_unit(), xmpi_comm_self)
     571              :    !do spin=1,ebands%nsppol
     572              :    !  do ik_ibz=1,ebands%nkpt
     573              :    !    nband_k = out_wfk%hdr%nband(ik_ibz + (spin-1)*ebands%nkpt)
     574              :    !    band_block = [1, nband_k]
     575              :    !    call out_wfk%read_band_block(band_block, ik_ibz, spin, sc_mode, &
     576              :    !                                 kg_k=kg_k, cg_k=cg_k, eig_k=eig_k, occ_k=occ_k)
     577              :    !  end do
     578              :    !end do
     579              :    !call out_wfk%close()
     580              : 
     581              :  case (WFK_TASK_PAW_AEPSI)
     582              :    ! Compute AE PAW wavefunction in real space on the dense FFT mesh.
     583            0 :    call read_wfd()
     584              : 
     585            0 :    ABI_CHECK(wfd%usepaw == 1, "Not a PAW run")
     586            0 :    ABI_MALLOC(paw_onsite, (cryst%natom))
     587              :    call paw_pwaves_lmn_init(paw_onsite,cryst%natom,cryst%natom,cryst%ntypat, &
     588            0 :                             cryst%rprimd,cryst%xcart,pawtab,pawrad,pawfgrtab)
     589              : 
     590              :    ! Use dense FFT mesh
     591            0 :    call wfd%change_ngfft(cryst,psps,ngfftf)
     592            0 :    band = 1; spin = 1; ik_ibz = 1
     593              : 
     594            0 :    ABI_MALLOC(ur_ae, (wfd%nfft*wfd%nspinor))
     595            0 :    call wfd%paw_get_aeur(band,ik_ibz,spin,cryst,paw_onsite,psps,pawtab,pawfgrtab,ur_ae)
     596            0 :    ABI_FREE(ur_ae)
     597              : 
     598            0 :    call paw_pwaves_lmn_free(paw_onsite)
     599            0 :    ABI_FREE(paw_onsite)
     600              : 
     601              :  case (WFK_TASK_WANNIER)
     602              :    ! Construct Wannier functions.
     603              : 
     604              :    ! This part was implemented by gmatteo to debug GaAs with a 8x8x8 k-mesh.
     605              : 
     606              :    !if (wfk0_hdr%kptopt == 1) then
     607              :    !  ! Generate WFK in the full BZ (only master works here)
     608              :    !  outwfk_path = dtfil%fnameabo_wfk; if (dtset%iomode == IO_MODE_ETSF) outwfk_path = nctk_ncify(outwfk_path)
     609              :    !  if (my_rank == master) then
     610              :    !    call wrtout(units, sjoin("- Generating WFK file with kpoints in the full BZ and istwfk == 1", outwfk_path))
     611              :    !    call wfk_to_bz(wfk0_path, dtset, psps, pawtab, outwfk_path, hdr_bz, ebands_bz)
     612              :    !    call ebands_bz%free(); call hdr_bz%free()
     613              :    !  end if
     614              :    !  call xmpi_barrier(comm)
     615              :    !  my_dtset = dtset%copy()
     616              :    !  ebands_bz = wfk_read_ebands(outwfk_path, comm, hdr_bz)
     617              :    !  call hdr_transfer_nkpt_arrays(hdr_bz, my_dtset)
     618              :    !  my_dtset%kptopt = hdr_bz%kptopt
     619              :    !  call hdr_bz%vs_dtset(my_dtset)
     620              :    !  call wfd_run_wannier__(outwfk_path, my_dtset, ebands_bz, hdr_bz)
     621              :    !  call ebands_bz%free(); call hdr_bz%free(); call my_dtset%free()
     622              : 
     623              :    !else
     624            5 :      call wfk0_hdr%vs_dtset(dtset)
     625            5 :      call wfd_run_wannier__(wfk0_path, dtset, ebands, wfk0_hdr)
     626              :    !end if
     627              : 
     628              :  case default
     629           12 :    ABI_ERROR(sjoin("Wrong wfk_task:", itoa(dtset%wfk_task)))
     630              :  end select
     631              : 
     632              : 100 continue
     633              : 
     634              :  ! Free memory
     635           12 :  call cryst%free(); call ebands%free(); call wfd%free(); call destroy_mpi_enreg(mpi_enreg); call wfk0_hdr%free()
     636           12 :  call pawfgr_destroy(pawfgr)
     637              : 
     638              :  ! Deallocation for PAW.
     639           12 :  if (dtset%usepaw==1) then
     640            1 :    call pawrhoij_free(pawrhoij)
     641            3 :    ABI_FREE(pawrhoij)
     642            1 :    call pawfgrtab_free(pawfgrtab)
     643              :    !call paw_ij_free(paw_ij)
     644              :    !ABI_FREE(paw_ij)
     645              :    !call paw_an_free(paw_an)
     646              :    !ABI_FREE(paw_an)
     647              :  end if
     648           26 :  ABI_FREE(pawfgrtab)
     649              : 
     650              :  DBG_EXIT('COLL')
     651              : 
     652              :  contains
     653              : !!***
     654              : 
     655              : !!****f* wfk_analyze/read_wfd
     656              : !! NAME
     657              : !!  read_wfd
     658              : !!
     659              : !! FUNCTION
     660              : !!  Initialize the wavefunction descriptor from file.
     661              : !!
     662              : !! SOURCE
     663              : 
     664            0 : subroutine read_wfd()
     665              : 
     666            0 :  ABI_MALLOC(keep_ur, (ebands%mband, ebands%nkpt, ebands%nsppol))
     667            0 :  ABI_MALLOC(bks_mask, (ebands%mband, ebands%nkpt, ebands%nsppol))
     668            0 :  keep_ur = .False.; bks_mask = .True.
     669              : 
     670              :  call wfd%init(cryst,pawtab,psps,keep_ur,ebands%mband,ebands%nband,ebands%nkpt,dtset%nsppol,bks_mask,&
     671              :    dtset%nspden,dtset%nspinor,ecut_eff,dtset%ecutsm,dtset%dilatmx,wfk0_hdr%istwfk,ebands%kptns,ngfftc,&
     672            0 :    dtset%nloalg,dtset%prtvol,dtset%pawprtvol,comm)
     673              : 
     674            0 :  ABI_FREE(keep_ur)
     675            0 :  ABI_FREE(bks_mask)
     676              : 
     677            0 :  call wfd%read_wfk(wfk0_path, iomode_from_fname(wfk0_path))
     678              : 
     679            0 : end subroutine read_wfd
     680              : 
     681            5 : subroutine wfd_run_wannier__(wfk_filepath, dtset_, ebands_, hdr_)
     682              : 
     683              :  type(dataset_type),intent(in) :: dtset_
     684              :  character(len=*),intent(in) :: wfk_filepath
     685              :  type(ebands_t),intent(in) :: ebands_
     686              :  type(hdr_type),intent(in) :: hdr_
     687              : 
     688           25 :  ABI_MALLOC(keep_ur, (ebands_%mband, ebands_%nkpt, ebands_%nsppol))
     689           20 :  ABI_MALLOC(bks_mask, (ebands_%mband, ebands_%nkpt, ebands_%nsppol))
     690          941 :  keep_ur = .False.; bks_mask = .True.
     691              : 
     692              :  ! Impose istwfk = 1 for all k-points. This is also done in respfn (see inkpts)
     693              :  ! wfd_read_wfk will handle a possible conversion if WFK contains istwfk /= 1.
     694              :  !wfk0_hdr%istwfk = 1; ebands%istwfk = 1; dtset%istwfk = 1
     695              : 
     696              :  call wfd%init(cryst, pawtab, psps, keep_ur, ebands_%mband, ebands_%nband, ebands_%nkpt, dtset_%nsppol, bks_mask, &
     697              :    dtset_%nspden,  dtset_%nspinor, ecut_eff, dtset_%ecutsm, dtset_%dilatmx, hdr_%istwfk, ebands_%kptns, ngfftc, &
     698            5 :    dtset_%nloalg, dtset_%prtvol, dtset_%pawprtvol, comm)
     699              : 
     700            5 :  ABI_FREE(keep_ur)
     701            5 :  ABI_FREE(bks_mask)
     702            5 :  call wfd%read_wfk(wfk_filepath, iomode_from_fname(wfk_filepath))
     703              : 
     704              :  call wfd_run_wannier(cryst=cryst, ebands=ebands_, hdr=hdr_, mpi_enreg=mpi_enreg, &
     705              :                       ngfftc=ngfftc, ngfftf=ngfftf, wfd=wfd, dtset=dtset_, dtfil=dtfil,  &
     706            5 :                       pawang=pawang, pawrad=pawrad, pawtab=pawtab, psps=psps)
     707              : 
     708            5 : end subroutine wfd_run_wannier__
     709              : 
     710              : end subroutine wfk_analyze
     711              : !!***
     712              : 
     713              : subroutine hdr_transfer_nkpt_arrays(hdr, dtset)
     714              : 
     715              :   use m_copy, only : alloc_copy
     716              : 
     717              :   class(hdr_type),intent(in) :: hdr
     718              :   type(dataset_type),intent(inout) :: dtset
     719              : 
     720              :   ABI_SFREE(dtset%istwfk)
     721              :   ABI_SFREE(dtset%kpt)
     722              :   ABI_SFREE(dtset%kptns)
     723              :   ABI_SFREE(dtset%occ_orig)
     724              :   ABI_SFREE(dtset%wtk)
     725              :   ABI_SFREE(dtset%kptns_hf)  ! Free HF k-points as well.
     726              :   ABI_SFREE(dtset%nband)
     727              : 
     728              :   dtset%nkpt = hdr%nkpt
     729              :   call alloc_copy(hdr%istwfk, dtset%istwfk)
     730              :   call alloc_copy(hdr%nband, dtset%nband)
     731              :   call alloc_copy(hdr%kptns, dtset%kpt)
     732              :   call alloc_copy(hdr%kptns, dtset%kptns)
     733              :   !call alloc_copy(hdr%occ, dtset%occ_orig(:,1)
     734              :   call alloc_copy(hdr%wtk, dtset%wtk)
     735              :   call alloc_copy(hdr%kptns, dtset%kptns_hf)
     736              : 
     737              : end subroutine hdr_transfer_nkpt_arrays
     738              : 
     739              : end module m_wfk_analyze
     740              : !!***
        

Generated by: LCOV version 2.3-1