LCOV - code coverage report
Current view: top level - src/71_wannier - m_abstract_wf.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 72.3 % 480 347
Test Date: 2026-09-19 17:42:43 Functions: 64.4 % 45 29

            Line data    Source code
       1              : !!****m* ABINIT/m_abstract_wf
       2              : !! NAME
       3              : !!  m_abstract_wf
       4              : !!
       5              : !! FUNCTION
       6              : !!  Interface with Wannier90.
       7              : !!  This module contains the abstract type abstract_wf and its children.
       8              : !!  The abstract_wf type is used to store the wavefunctions either in wfd or wfk format.
       9              : !!  And it provide the common interface for both format.
      10              : !!
      11              : !! COPYRIGHT
      12              : !!  Copyright (C) 2005-2026 ABINIT group (BAmadon, CEspejo, FJollet, TRangel, DRH)
      13              : !!  This file is distributed under the terms of the
      14              : !!  GNU General Public License, see ~abinit/COPYING
      15              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      16              : !!
      17              : 
      18              : #if defined HAVE_CONFIG_H
      19              : #include "config.h"
      20              : #endif
      21              : 
      22              : #include "abi_common.h"
      23              : 
      24              : module m_abstract_wf
      25              : 
      26              :  use defs_basis
      27              :  use defs_wannier90
      28              :  use m_abicore
      29              :  use m_errors
      30              :  use m_atomdata
      31              :  use m_xmpi
      32              :  use m_sort
      33              : #ifdef FC_NAG
      34              :  use f90_unix_dir
      35              : #endif
      36              :  use netcdf
      37              :  use m_nctk
      38              :  use m_hdr
      39              :  use m_dtset
      40              :  use m_dtfil
      41              : 
      42              :  use m_build_info,   only : abinit_version
      43              :  use defs_wvltypes,  only : wvl_internal_type
      44              :  use defs_datatypes, only : pseudopotential_type
      45              :  use defs_abitypes,  only : MPI_type
      46              :  use m_io_tools,     only : delete_file
      47              :  use m_fstrings,     only : strcat, sjoin, itoa
      48              :  use m_fftcore,      only : ngfft_seq, get_kg
      49              :  use m_crystal,      only : crystal_t
      50              :  use m_ebands,       only : ebands_t
      51              :  use m_pawtab,       only : pawtab_type
      52              :  use m_pawrhoij,     only : pawrhoij_copy
      53              :  use m_pawcprj,      only : pawcprj_type
      54              :  use m_wfd,          only : wfd_t, wave_t, WFD_STORED
      55              : 
      56              :  implicit none
      57              : 
      58              :  private
      59              : 
      60              : 
      61              : !!***
      62              : 
      63              : 
      64              : !type wann_ksetting_t:
      65              : !  This type is used to store the information about the kpoints
      66              : !  and the MPI distribution of the kpoints.
      67              : !  It is used in the wannier90 interface.
      68              :  type, public:: wann_ksetting_t
      69              :    logical :: has_ovikp =  .False.  !.True. if ovikp is allocated
      70              :    type(crystal_t), pointer :: cryst => null()  ! crystal structure
      71              :    !nkpt: number of kpoints
      72              :     !mband: number of bands
      73              :     !num_nnmax: maximum number of nearest neighbors
      74              :     !nntot: total number of nearest neighbors
      75              :     !nsppol: number of spin polarizations
      76              :    integer :: nkpt=0, mband=0, num_nnmax=0, nntot=0, nsppol=0
      77              :    !rank: rank of the current process
      78              :     !comm: communicator
      79              :     !nprocs: number of processes
      80              :    integer :: rank=-999, comm=-999, nprocs=-999
      81              :    !ovikp: array of size (nkpt, num_nnmax) containing the indices of the nearest neighbors
      82              :    integer, allocatable :: ovikp(:, :)
      83              :    !my_nspin: number of spin polarizations for the current process
      84              :     !my_nkpt: number of kpoints for the current process
      85              :     !my_nkpt_pnn: number of kpoints for the current process including the nearest neighbors
      86              :    integer :: my_nspin,  my_nkpt, my_nkpt_pnn
      87              :    !my_spins: array of size (my_nspin) containing the spin indices for the current process
      88              :     !my_ikpts: array of size (my_nkpt) containing the indices of the kpoints for the current process
      89              :     !my_ikpts_pnn: array of size (my_nkpt_pnn) containing the indices of the kpoints for the current process including the nearest neighbors
      90              :    integer, allocatable :: my_spins(:), my_ikpts(:), my_ikpts_pnn(:)
      91              :    !kkpts: array of size (nkpt, 3) containing the kpoints
      92              :    !my_kkpts: array of size (my_nkpt, 3) containing the kpoints for the current process
      93              :    !my_kkpts_pnn: array of size (my_nkpt_pnn, 3) containing the kpoints for the current process including the nearest neighbors
      94              :    real(dp), pointer :: kkpts(:, :)=> null()
      95              :    real(dp), allocatable :: my_kkpts(:, :), my_kkpts_pnn(:, :)
      96              :  contains
      97              :    procedure :: init => wann_ksetting_init
      98              :    procedure :: set_ovikp => wann_ksetting_set_ovikp
      99              :    procedure :: free => wann_ksetting_free
     100              :    procedure :: get_mpw_gmax => wann_ksetting_get_mpw_gmax
     101              :    procedure :: distribute_mpi => wann_ksetting_distribute_mpi
     102              :    procedure :: get_bks_mask => wann_ksetting_get_bks_mask
     103              :  end type wann_ksetting_t
     104              : 
     105              : 
     106              : 
     107              : !type abstract_wf:
     108              : !  This type is used to store the information about the wavefunctions
     109              : !  and the MPI distribution of the wavefunctions.
     110              : !  It provide the common interface for the wavefunctions.
     111              :  type, public :: abstract_wf
     112              :  !has_paw: .True. if the wavefunctions are PAW wavefunctions
     113              :    logical :: has_paw = .True.
     114              :    !cryst: crystal structure
     115              :     type(crystal_t), pointer :: cryst => null()
     116              :     type(datafiles_type),pointer :: dtfil => null()
     117              :     type(dataset_type),pointer :: dtset => null()
     118              :     !hdr: header, it contains the information about the wavefunctions
     119              :     type(hdr_type), pointer :: hdr => null()
     120              :     !MPI_enreg: MPI type for the wavefunctions
     121              :     type(mpi_type), pointer :: MPI_enreg => null()
     122              :     !psps: pseudopotential information
     123              :     type(pseudopotential_type), pointer :: psps => null()
     124              :     !pawtab: PAW tabulated data
     125              :     type(pawtab_type),pointer :: pawtab(:) => null()
     126              :     !ebands: eigenvalues
     127              :     type(ebands_t), pointer :: ebands => null()
     128              :     !kset: kpoints information
     129              :     type(wann_ksetting_t) :: kset
     130              :     !natom: number of atoms
     131              :     !nspinor: number of spinors
     132              :     !nsppol: number of spin polarizations
     133              :     !mband: number of bands
     134              :     !mkmem: number of kpoints in this process
     135              :     !nkpt: number of kpoints
     136              : 
     137              :     integer :: natom=0, nspinor=0, nsppol=0, mband=0, &
     138              :          & mkmem=0, nkpt=0, rank=-999, nprocs=-999, comm=-999
     139              :   contains
     140              :     !procedure :: init => abstract_wf_init
     141              :     procedure :: abstract_init
     142              :     procedure :: free => abstract_wf_free
     143              :     procedure :: cg_elem => abstract_wf_cg_elem
     144              :     procedure :: cg_elem_complex => abstract_wf_cg_elem_complex
     145              :     procedure :: cprj_elem =>abstract_wf_cprj_elem
     146              :     procedure :: get_cg_ptr => abstract_wf_get_cprj_ptr
     147              :     procedure :: get_cprj_ptr => abstract_wf_get_cprj_ptr
     148              :     procedure :: load_cg => abstract_wf_load_cg
     149              :     !procedure :: show_info
     150              :     procedure :: get_kgs=>  abstract_wf_get_kgs
     151              : 
     152              :  end type abstract_wf
     153              : 
     154              : 
     155              : !type cg_cprj:
     156              : !  This type is used to store the information about the wavefunctions
     157              : !  and the MPI distribution of the wavefunctions.
     158              : !  It is a child of the abstract_wf type and it provides the interface
     159              : !  for the wavefunctions in the CG and CPRJ format.
     160              :  type, public,extends(abstract_wf) ::  cg_cprj
     161              :     real(dp), pointer :: cg(:, :)=>null()
     162              :     type(pawcprj_type), pointer :: cprj(:,:)=>null()
     163              :     integer, pointer :: iwav(:,:,:, :)=>null()
     164              :     integer, allocatable :: icprj(:, :, :)
     165              :   contains
     166              :     procedure :: init => cg_cprj_init !initialize the cg_cprj type
     167              :     procedure :: free => cg_cprj_free !free the cg_cprj type
     168              :     procedure :: compute_index_cprj !compute the index of the cprj
     169              :     procedure :: cg_elem
     170              :     procedure :: cg_elem_complex
     171              :     procedure :: cprj_elem
     172              :     procedure :: get_cg_ptr => cg_cprj_get_cprj_ptr
     173              :     procedure :: get_cprj_ptr => cg_cprj_get_cprj_ptr
     174              :     procedure :: write_cg_and_cprj_tmpfile
     175              :     procedure :: remove_tmpfile
     176              :     procedure :: load_cg
     177              :  end type cg_cprj
     178              : 
     179              : 
     180              : !type wfd_t:
     181              : !  wavefunctions in the WFD format.
     182              :  type, public, extends(abstract_wf) :: wfd_wf
     183              :    ! The working wfd, ebands, etc
     184              :     type(wfd_t), pointer :: wfd => null()
     185              : 
     186              :     type(wave_t), pointer :: waveprt => null()
     187              : 
     188              :     ! if wfd is in IBZ, expand to fullBZ
     189              :     logical :: expanded = .False.
     190              :     integer, allocatable :: bz2ibz(:, :)
     191              :     type(wfd_t), pointer :: wfd_ibz => null()
     192              :     type(ebands_t), pointer :: ebands_ibz => null()
     193              :     type(hdr_type), pointer :: hdr_ibz => null()
     194              : 
     195              :     logical, allocatable :: bks_mask(:, :, :)
     196              :     logical, allocatable :: keep_ur(:, :, :)
     197              : 
     198              :     type(wfd_t) :: wfd_bz
     199              :     type(ebands_t) :: ebands_bz
     200              :     type(hdr_type) :: hdr_bz
     201              :     type(dataset_type) :: dtset_bz
     202              :     type(MPI_type) :: mpi_enreg_bz
     203              :   contains
     204              :     procedure :: init => wfd_wf_init
     205              :     procedure :: free => wfd_wf_free
     206              :     !procedure :: get_ug => wfd_wf_ug
     207              :     procedure :: cg_elem => wfd_cg_elem
     208              :     procedure :: cg_elem_complex => wfd_cg_elem_complex
     209              :     procedure :: cprj_elem =>wfd_cprj_elem
     210              :     procedure :: load_cg => wfd_load_cg
     211              :  end type wfd_wf
     212              : 
     213              :  public :: init_mywfc, compute_iwav, write_cg_and_cprj
     214              : 
     215              : contains
     216              : 
     217              :   !-----------------------------------------------------------------------------
     218              :   !> Initialize the wann_ksetting_t type
     219              :   !> @param self: the wann_ksetting_t type
     220              :   !> @param cryst: the crystal structure
     221              :   !> @param nkpt: number of kpoints
     222              :   !> @param mband: number of bands
     223              :   !> @param nsppol: number of spin polarizations
     224              :   !> @param kkpts: the kpoints
     225              :   !> @param comm: MPI communicator
     226              :   !> @param nprocs: number of processes
     227              :   !> @param rank: rank of the process
     228              :   !-----------------------------------------------------------------------------
     229            5 :   subroutine wann_ksetting_init(self, cryst, nkpt, mband, &
     230            5 :     & nsppol, kkpts, comm, nprocs, rank)
     231              :     class(wann_ksetting_t), intent(inout) :: self
     232              :     type(crystal_t), target, intent(in):: cryst
     233              :     integer, intent(in) :: nkpt, mband, nsppol, comm, nprocs, rank
     234              :     real(dp), target, intent(in) :: kkpts(:, :)
     235            5 :     self%comm=comm
     236            5 :     self%nprocs=nprocs
     237            5 :     self%rank=rank
     238            5 :     self%cryst=>cryst
     239            5 :     self%nkpt=nkpt
     240            5 :     self%mband=mband
     241            5 :     self%nsppol=nsppol
     242            5 :     self%my_nspin = nsppol
     243            5 :     self%kkpts=> kkpts
     244            5 :   end subroutine wann_ksetting_init
     245              : 
     246              : 
     247              : 
     248              :   !-----------------------------------------------------------------------------
     249              :   !> compute the ovikp array (the overlap information of the kpoints)
     250              :   !> @param self: the wann_ksetting_t type
     251              :   !> @param ovikp: the overlap information of the kpoints
     252              :   !> @param nntot: number of nearest neighbors
     253              :   !> @param num_nnmax: maximum number of nearest neighbors
     254              :   !> @param mpi_enreg: MPI information
     255              :   !-----------------------------------------------------------------------------
     256            5 :   subroutine wann_ksetting_set_ovikp(self,  ovikp, nntot, num_nnmax, mpi_enreg)
     257              :     class(wann_ksetting_t), intent(inout) :: self
     258              :     integer, intent(in) ::  nntot, num_nnmax
     259              :     integer, intent(in) :: ovikp(:, :)
     260              :     type(mpi_type), intent(inout) :: mpi_enreg
     261            5 :     if (self%has_ovikp) then
     262            0 :       ABI_ERROR("ovikp already set!")
     263              :     end if
     264            5 :     self%has_ovikp = .True.
     265            5 :     self%nntot = nntot
     266            5 :     self%num_nnmax=num_nnmax
     267           20 :     ABI_MALLOC(self%ovikp, (self%nkpt, num_nnmax))
     268          314 :     self%ovikp(:,:) = ovikp(:, :)
     269            5 :     call self%distribute_mpi(mpi_enreg)
     270            5 :   end subroutine wann_ksetting_set_ovikp
     271              : 
     272              : 
     273              :   !-----------------------------------------------------------------------------
     274              :   !> free the wann_ksetting_t type
     275              :   !> @param self: the wann_ksetting_t type
     276              :   !-----------------------------------------------------------------------------
     277           33 :   subroutine wann_ksetting_free(self)
     278              :     class(wann_ksetting_t), intent(inout) :: self
     279           33 :     nullify(self%cryst)
     280           33 :     nullify(self%kkpts)
     281           33 :     if (self%has_ovikp) then
     282            5 :       ABI_SFREE(self%ovikp)
     283            5 :       ABI_FREE(self%my_spins)
     284            5 :       ABI_FREE(self%my_ikpts)
     285            5 :       ABI_FREE(self%my_kkpts)
     286            5 :       ABI_FREE(self%my_ikpts_pnn)
     287            5 :       ABI_FREE(self%my_kkpts_pnn)
     288              :     end if
     289           33 :   end subroutine wann_ksetting_free
     290              : 
     291              : 
     292              :   !-----------------------------------------------------------------------------
     293              :   !> set the mpi distribution using the information in the wann_ksetting_t type
     294              :   !> @param self: the wann_ksetting_t type
     295              :   !> @param mpi_enreg: MPI information
     296              :   !-----------------------------------------------------------------------------
     297            5 :   subroutine wann_ksetting_distribute_mpi(self, mpi_enreg)
     298              :     class(wann_ksetting_t), intent(inout) :: self
     299              :     type(MPI_type), intent(inout) :: mpi_enreg
     300              :     integer :: ikpt, inn, ik_me, ik_nn, ispin
     301           10 :     logical :: belongs(self%nkpt)
     302              :     integer :: counter
     303            5 :     MPI_enreg%comm_cell=self%comm
     304            5 :     mpi_enreg%me=self%rank
     305            5 :     mpi_enreg%me_kpt=self%rank
     306            5 :     mpi_enreg%nproc = self%nprocs
     307            5 :     MPI_enreg%paral_spinor=0
     308              :     !write(std_out,*) "Distributed mpi:", "rank:",  self%rank, "comm", self%comm
     309              :     !write(std_out,*) "nprocs:", self%nprocs, "me:", mpi_enreg%me, "me_kpt:", mpi_enreg%me_kpt
     310            5 :     if (.not. allocated(mpi_enreg%proc_distrb))then
     311           25 :       ABI_MALLOC(mpi_enreg%proc_distrb, (self%nkpt, self%mband, self%nsppol) )
     312              :     end if
     313         3386 :     mpi_enreg%proc_distrb(:, :, :) =-999
     314              : 
     315              : 
     316            5 :     self%my_nkpt=0
     317            5 :     self%my_nkpt_pnn=0
     318              : 
     319           15 :     ABI_MALLOC(self%my_spins, (self%nsppol))
     320            5 :     self%my_nspin=self%nsppol
     321           10 :     do ispin =1, self%nsppol
     322           10 :       self%my_spins(ispin)=ispin
     323              :     end do
     324              :     ! split kpoints
     325            5 :     call xmpi_split_block(self%nkpt, self%comm, self%my_nkpt, self%my_ikpts)
     326              : 
     327           15 :     ABI_MALLOC(self%my_kkpts, (3, self%my_nkpt))
     328              : 
     329          309 :     belongs(:)=.False.
     330          309 :     do ikpt=1, self%my_nkpt
     331          304 :       ik_me=self%my_ikpts(ikpt)
     332         1216 :       self%my_kkpts(:, ikpt) = self%kkpts(:, ik_me)
     333          304 :       belongs(ik_me) = .True.
     334         3936 :       MPI_enreg%proc_distrb(ik_me,:,:)= self%rank
     335          613 :       do inn=1, self%nntot
     336          304 :         ik_nn=self%ovikp(ikpt, inn)
     337          608 :         belongs(ik_nn) = .True.
     338              :       end do
     339              :     end do
     340              : 
     341            5 :     self%my_nkpt_pnn=0
     342          309 :     do ikpt =1, self%nkpt
     343          309 :       if (belongs(ikpt)) self%my_nkpt_pnn=self%my_nkpt_pnn+1
     344              :     end do
     345              : 
     346           15 :     ABI_MALLOC(self%my_ikpts_pnn, (self%my_nkpt_pnn))
     347           15 :     ABI_MALLOC(self%my_kkpts_pnn, (3, self%my_nkpt_pnn))
     348              : 
     349            5 :     counter=0
     350          309 :     do ikpt =1, self%nkpt
     351          309 :       if (belongs(ikpt)) then
     352          304 :         counter =counter+1
     353          304 :         self%my_ikpts_pnn(counter) = ikpt
     354         1216 :         self%my_kkpts_pnn(:, counter) = self%kkpts(:, ikpt)
     355              :       end if
     356              :     end do
     357              : 
     358              : 
     359            5 :   end subroutine wann_ksetting_distribute_mpi
     360              : 
     361              :   !-----------------------------------------------------------------------------
     362              :   !> using the kpoint information in the wann_ksetting_t type, set the
     363              :   !> bks_mask and keep_ur arrays.
     364              :   !> @param self: the wann_ksetting_t type
     365              :   !> @param bks_mask: the bks_mask array
     366              :   !> @param keep_ur: the keep_ur array
     367              :   !> @param nband: the number of bands
     368              :   !> @param nsppol: the number of spins
     369              :   !> @param keep_ur_value: the value to set the keep_ur array to
     370              :   !-----------------------------------------------------------------------------
     371            5 :   subroutine wann_ksetting_get_bks_mask(self, bks_mask, keep_ur, nband, nsppol, keep_ur_value)
     372              :     class(wann_ksetting_t), intent(inout) :: self
     373              :     integer, intent(in) :: nband, nsppol
     374              :     logical, allocatable, intent(inout) :: bks_mask(:, :, :) ! bank, kpt, spin
     375              :     logical, allocatable, intent(inout) :: keep_ur(:, :, :)
     376              :     logical, intent(in) :: keep_ur_value
     377              :     integer :: ikpt, ispin, inn, ik_nn, ik_me
     378              : 
     379           25 :     ABI_MALLOC(bks_mask, (nband, self%nkpt, nsppol))
     380           20 :     ABI_MALLOC(keep_ur, (nband, self%nkpt, nsppol))
     381         3642 :     bks_mask(:, :, :) = .False.
     382         3642 :     keep_ur(:, :, :) = .False.
     383           10 :     do ispin =1, nsppol
     384          314 :       do ikpt =1 , self%my_nkpt
     385          304 :         ik_me = self%my_ikpts(ikpt)
     386         3936 :         bks_mask(:, ik_me, :) =.True.
     387         3936 :         keep_ur(:, ik_me, :) = keep_ur_value
     388          613 :         do inn =1, self%nntot
     389          304 :           ik_nn=self%ovikp(ikpt, inn)
     390         3632 :           bks_mask(:, ik_nn, ispin)=.True.
     391         3936 :           keep_ur(:, ik_nn, ispin) = keep_ur_value
     392              :         end do
     393              :       end do
     394              :     end do
     395            5 :   end subroutine wann_ksetting_get_bks_mask
     396              : 
     397              : 
     398              : !-----------------------------------------------------------------------------
     399              : !> using the kpoint information in the wann_ksetting_t type, set the
     400              : !> ecut, mpw, and gmax values.
     401              : !> @param self: the wann_ksetting_t type
     402              : !> @param ecut: the ecut value
     403              : !> @param mpw: the mpw value
     404              : !> @param gmax: the gmax array
     405              : !-----------------------------------------------------------------------------
     406            5 :  subroutine wann_ksetting_get_mpw_gmax(self, ecut, mpw, gmax)
     407              :    class(wann_ksetting_t), intent(inout) :: self
     408              :    real(dp),intent(in) :: ecut
     409              :    integer,intent(out) :: mpw, gmax(3)
     410              :    integer,parameter :: istwfk1 = 1
     411              :    !real(dp) :: cpu, wall, gflops !weight_k,
     412              :    !type(gqk_t),pointer :: gqk
     413              :    !arrays
     414              :    integer :: my_gmax(3), onpw, ipw, ii, my_mpw, ierr
     415            5 :    integer,allocatable :: gtmp(:,:)
     416              :    real(dp) :: kk(3)
     417              : 
     418              :    integer :: spin, my_ik
     419              : 
     420              : !----------------------------------------------------------------------
     421              : 
     422            5 :  mpw = 0; gmax = 0
     423              : 
     424              :  ! TODO: This is an hotspot due to the double loop over k and q.
     425              :  ! Should use a geometrical approach to compute mpw and gmax.
     426              : 
     427            5 :  call wrtout(std_out, " Computing mpw. This may take some time for dense k/q meshes...")
     428              :  !call cwtime(cpu, wall, gflops, "start")
     429              : 
     430              :  !do my_is=1,gstore%my_nspins
     431              :  !  gqk => gstore%gqk(my_is)
     432              :  !  spin = gstore%my_spins(my_is)
     433           10 :  do spin =1, self%nsppol
     434              : 
     435          314 :    do my_ik=1,self%my_nkpt_pnn
     436         1216 :      kk = self%my_kkpts_pnn(:, my_ik)
     437              : 
     438              :      ! Compute G sphere, returning npw. Note istwfk == 1.
     439          304 :      call get_kg(kk, istwfk1, ecut, self%cryst%gmet, onpw, gtmp)
     440          304 :      mpw = max(mpw, onpw)
     441        69743 :      do ipw=1,onpw
     442       278060 :        do ii=1,3
     443       277756 :          gmax(ii) = max(gmax(ii), abs(gtmp(ii,ipw)))
     444              :        end do
     445              :      end do
     446          309 :      ABI_FREE(gtmp)
     447              :    end do ! my_ik
     448              :  end do ! my_is
     449              : 
     450            5 :  my_mpw = mpw; call xmpi_max(my_mpw, mpw, self%comm, ierr)
     451            5 :  my_gmax = gmax; call xmpi_max(my_gmax, gmax, self%comm, ierr)
     452              : 
     453            5 :  call wrtout(std_out, sjoin(' Optimal value of mpw: ', itoa(mpw)))
     454              :  !call cwtime_report(" gmax and mpw", cpu, wall, gflops)
     455              : 
     456            5 : end subroutine wann_ksetting_get_mpw_gmax
     457              : 
     458              : 
     459              : !-----------------------------------------------------------------------------
     460              : !> Initialize the abstract_wf type, depending on the type of wavefunction
     461              : !> If the optional wfd, cg/cprj input are present, then the abstract_wf
     462              : !> is initialized as the wfd_wf type or the cg_cprj_wf type.
     463              : !> @param mywfc: the abstract_wf type
     464              : !> @param ebands: the ebands type
     465              : !> @param wfd: the wfd type (optional)
     466              : !> @param cg: the cg array (optional)
     467              : !> @param cprj: the cprj array (optional)
     468              : !> @param cryst: the crystal_t type
     469              : !> @param dtset: the dataset_type type
     470              : !> @param dtfil: the datafiles_type type
     471              : !> @param hdr: the header_type type
     472              : !> @param MPI_enreg: the mpi_type type
     473              : !> @param nprocs: the number of processors
     474              : !> @param psps: the psps_type type
     475              : !> @param pawtab: the pawtab_type type
     476              : !> @param rank: the rank of the processor
     477              : !> @param comm: the communicator
     478              : !-----------------------------------------------------------------------------
     479           19 : subroutine init_mywfc(mywfc, ebands, wfd , cg, cprj, cryst, &
     480           19 :   & dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
     481              :     class(abstract_wf), pointer, intent(inout) :: mywfc
     482              :     type(crystal_t), target, intent(in) :: cryst
     483              :     type(ebands_t), target, optional, intent(in) :: ebands
     484              :     type(wfd_t), target, optional, intent(inout) :: wfd
     485              :     real(dp), target, optional, intent(in):: cg(:, :)
     486              :     type(pawcprj_type), target, optional, intent(in):: cprj(:,:)
     487              :     type(dataset_type),target, intent(in) :: dtset
     488              :     type(datafiles_type),target, intent(in) :: dtfil
     489              :     type(mpi_type), target, intent(inout) :: MPI_enreg
     490              :     type(pseudopotential_type), target, intent(in) :: psps
     491              :     type(pawtab_type), target, optional, intent(in) :: pawtab(:)
     492              :     type(hdr_type), target, intent(in) :: hdr
     493              :     integer, intent(in) :: nprocs, rank, comm
     494              : 
     495           19 :     if(present(cg)) then
     496           14 :        ABI_MALLOC_TYPE_SCALAR(cg_cprj, mywfc)
     497            5 :     else if (present(wfd)) then
     498          815 :        ABI_MALLOC_TYPE_SCALAR(wfd_wf, mywfc)
     499              :     end if
     500              :     select type(mywfc)
     501              :     type is(cg_cprj)
     502              :       call mywfc%init( ebands=ebands, cg=cg, cprj=cprj, cryst=cryst, dtset=dtset, &
     503              :         & dtfil=dtfil, hdr=hdr, MPI_enreg=mpi_enreg, nprocs=nprocs, &
     504           14 :         & psps=psps, pawtab=pawtab, rank=rank, comm=comm)
     505              :     type is(wfd_wf)
     506            5 :        call mywfc%init( ebands, wfd, cryst, dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
     507              :        !call wfd_print_norm(mywfc%wfd, mywfc%hdr)
     508              :     end select
     509           19 :   end subroutine init_mywfc
     510              : 
     511              : !-----------------------------------------------------------------------------
     512              : !> Initialize the abstract_wf type, common part for both wfd_wf and cg_cprj
     513              : !> @param self: the abstract_wf type
     514              : !> @param ebands: the ebands type
     515              : !> @param cryst: the crystal_t type
     516              : !> @param dtset: the dataset_type type
     517              : !> @param dtfil: the datafiles_type type
     518              : !> @param hdr: the header_type type
     519              : !> @param MPI_enreg: the mpi_type type
     520              : !> @param nprocs: the number of processors
     521              : !> @param psps: the psps_type type
     522              : !> @param pawtab: the pawtab_type type
     523              : !> @param rank: the rank of the processor
     524              : !> @param comm: the communicator
     525              : !-----------------------------------------------------------------------------
     526           19 :   subroutine abstract_init(self, ebands, cryst, dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
     527              :     class(abstract_wf), intent(inout) :: self
     528              :     type(crystal_t), target, intent(in) :: cryst
     529              :     type(ebands_t), target, intent(in) :: ebands
     530              :     type(dataset_type),target, intent(in) :: dtset
     531              :     type(datafiles_type),target, intent(in) :: dtfil
     532              :     type(mpi_type), target, intent(inout) :: MPI_enreg
     533              :     type(pseudopotential_type), target, intent(in) :: psps
     534              :     type(pawtab_type), target, optional, intent(in) :: pawtab(:)
     535              :     type(hdr_type), target, intent(in) :: hdr
     536              :     integer, intent(in) :: nprocs, rank, comm
     537           19 :     if(present(pawtab)) self%pawtab => pawtab
     538           19 :     self%ebands => ebands
     539           19 :     self%cryst => cryst
     540           19 :     self%dtset => dtset
     541           19 :     self%dtfil => dtfil
     542           19 :     self%hdr => hdr
     543           19 :     self%MPI_enreg => MPI_enreg
     544           19 :     self%psps => psps
     545           19 :     self%natom = hdr%natom
     546           19 :     self%nspinor = hdr%nspinor
     547           19 :     self%nsppol = hdr%nsppol
     548           19 :     self%mband= hdr%mband
     549           19 :     self%mkmem = dtset%mkmem
     550           19 :     self%nkpt = hdr%nkpt
     551           19 :     self%rank = rank
     552           19 :     self%nprocs = nprocs
     553           19 :     self%comm=comm
     554           19 :   end subroutine abstract_init
     555              : 
     556              : !-----------------------------------------------------------------------------
     557              : !> get one element of the wavefunction for any abstract_wf type
     558              : !> @param self: the abstract_wf type
     559              : !> @param icplx: the complex flag
     560              : !> @param ig: the index of the G vector
     561              : !> @param ispinor: the index of the spinor
     562              : !> @param iband: the index of the band
     563              : !> @param ikpt: the index of the k point
     564              : !> @param isppol: the index of the spin polarization
     565              : !> @return: the element of the wavefunction
     566              : !-----------------------------------------------------------------------------
     567            0 :   function abstract_wf_cg_elem(self, icplx, ig, ispinor, iband, ikpt, isppol ) result(res)
     568              :     class(abstract_wf), intent(inout) :: self
     569              :     integer, intent(in) :: icplx, ig, ispinor, iband, ikpt, isppol
     570              :     real(dp) :: res
     571            0 :     ABI_UNUSED_A(self)
     572              :     ABI_UNUSED(icplx)
     573              :     ABI_UNUSED(ig)
     574              :     ABI_UNUSED(ispinor)
     575              :     ABI_UNUSED(iband)
     576              :     ABI_UNUSED(ikpt)
     577              :     ABI_UNUSED(isppol)
     578              :     ABI_UNUSED(res)
     579            0 :     ABI_ERROR("Function should be overrided:")
     580            0 :   end function abstract_wf_cg_elem
     581              : 
     582              : !-----------------------------------------------------------------------------
     583              : !> get one element of the wavefunction for any abstract_wf type, complex version
     584              : !-----------------------------------------------------------------------------
     585            0 :   function abstract_wf_cg_elem_complex(self,  ig, ispinor, iband, ikpt, isppol ) result(res)
     586              :     class(abstract_wf), intent(inout) :: self
     587              :     integer, intent(in) ::  ig, ispinor, iband, ikpt, isppol
     588              :     complex(dp) :: res
     589            0 :     ABI_UNUSED_A(self)
     590              :     ABI_UNUSED(ig)
     591              :     ABI_UNUSED(ispinor)
     592              :     ABI_UNUSED(iband)
     593              :     ABI_UNUSED(ikpt)
     594              :     ABI_UNUSED(isppol)
     595              :     ABI_UNUSED(res)
     596            0 :     ABI_ERROR("Function should be overrided:")
     597            0 :   end function abstract_wf_cg_elem_complex
     598              : 
     599              : !-----------------------------------------------------------------------------
     600              : !> get a block of the wavefunction for any abstract_wf type.
     601              : !> It should be overrided for each type.
     602              : !> @param self: the abstract_wf type
     603              : !> @param ikpt2: the index of the k point
     604              : !> @param isppol: the index of the spin polarization
     605              : !> @param cg_read: the wavefunction block
     606              : !-----------------------------------------------------------------------------
     607            0 :   subroutine abstract_wf_load_cg(self, ikpt2, isppol, cg_read)
     608              :     class(abstract_wf), intent(inout) :: self
     609              :     integer, intent(in) :: ikpt2, isppol
     610              :     real(dp), intent(inout) :: cg_read(:, :) ! (2, nspinor*mpw*mband )
     611            0 :     ABI_UNUSED_A(self)
     612              :     ABI_UNUSED(ikpt2)
     613              :     ABI_UNUSED(isppol)
     614              :     ABI_UNUSED(cg_read)
     615            0 :     ABI_ERROR("This function abstarct_wf_load_cg should be overrided.")
     616            0 :   end subroutine abstract_wf_load_cg
     617              : 
     618              : 
     619              : 
     620              : !-----------------------------------------------------------------------------
     621              : !> get one cprj element of the wavefunction for any abstract_wf type, complex version,
     622              : !> @param self: the abstract_wf type
     623              : !> @param icplx: the complex flag
     624              : !> @param ispinor: the index of the spinor
     625              : !> @param iband: the index of the band
     626              : !> @param ikpt: the index of the k point
     627              : !> @param isppol: the index of the spin polarization
     628              : !> @param iatom: the index of the atom
     629              : !> @param ilmn: the index of the lmn
     630              : !> @return: the element of the wavefunction
     631              : !-----------------------------------------------------------------------------
     632            0 :   function abstract_wf_cprj_elem(self,icplx,ispinor, iband, ikpt, isppol, iatom, ilmn) result(res)
     633              :     class(abstract_wf), intent(inout) :: self
     634              :     integer, intent(in) :: icplx, ispinor, iband, ikpt, isppol, ilmn, iatom
     635              :     real(dp) :: res
     636            0 :     ABI_UNUSED_A(self)
     637              :     ABI_UNUSED(icplx)
     638              :     ABI_UNUSED(ispinor)
     639              :     ABI_UNUSED(iband)
     640              :     ABI_UNUSED(ikpt)
     641              :     ABI_UNUSED(isppol)
     642              :     ABI_UNUSED(iatom)
     643              :     ABI_UNUSED(ilmn)
     644              :     ABI_UNUSED(res)
     645            0 :     ABI_ERROR("Function should be overrided:")
     646            0 :   end function abstract_wf_cprj_elem
     647              : 
     648              : !-----------------------------------------------------------------------------
     649              : !> get a pointer to the cg part of wavefunction for any abstract_wf type.
     650              : !> It should be overrided for each type.
     651              : !> @param self: the abstract_wf type
     652              : !> @return: the pointer to the wavefunction block, in the form of a 2D array.
     653              : !-----------------------------------------------------------------------------
     654              :   function abstract_wf_get_cg_ptr(self) result(cg)
     655              :     class(abstract_wf), target, intent(inout) :: self
     656              :     real(dp), pointer :: cg(:,:)
     657              :     ABI_UNUSED_A(self)
     658              :     ABI_UNUSED(cg)
     659              :     ABI_ERROR("The function abstract_wf%get_cg_ptr is not implemented")
     660              :   end function abstract_wf_get_cg_ptr
     661              : 
     662              : !-----------------------------------------------------------------------------
     663              : !> get a pointer to the cprj part of wavefunction for any abstract_wf type.
     664              : !> It should be overrided for each type.
     665              : !> @param self: the abstract_wf type
     666              : !> @return: the pointer to the wavefunction block, in the form of a 2D array.
     667              : !-----------------------------------------------------------------------------
     668            0 :   function abstract_wf_get_cprj_ptr(self) result(cprj)
     669              :     class(abstract_wf), target, intent(inout) :: self
     670              :     type(pawcprj_type), pointer :: cprj(:, :)
     671            0 :     ABI_UNUSED_A(self)
     672            0 :     ABI_UNUSED_A(cprj)
     673            0 :     ABI_ERROR("The function abstract_wf%get_cprj_ptr is not implemented")
     674            0 :   end function abstract_wf_get_cprj_ptr
     675              : 
     676              : !-----------------------------------------------------------------------------
     677              : !> get a pointer to the kg of wavefunction for any abstract_wf type.
     678              : !> @param self: the abstract_wf type
     679              : !> @return: the pointer to the kg, in the form of a 2D array.
     680              : !-----------------------------------------------------------------------------
     681            5 :   subroutine abstract_wf_get_kgs(self, ptr_kg)
     682              :     class(abstract_wf), intent(inout) :: self
     683              :     integer,  intent(inout) :: ptr_kg(:, :)
     684              :     integer :: npw_k, ik, ikg, ik_me
     685              :     real(dp) :: ecut_eff
     686            5 :     integer, allocatable :: kg_k(:,:)
     687              :     integer, parameter :: istwfk_1=1
     688       288165 :     ptr_kg(:,:)=zero
     689              :     !ecut_eff = dtset%ecut * dtset%dilatmx **2
     690            5 :     ecut_eff=self%hdr%ecut_eff
     691            5 :     ikg=0
     692          309 :     do ik=1, self%kset%my_nkpt
     693          304 :       ik_me = self%kset%my_ikpts(ik)
     694          304 :       npw_k = self%hdr%npwarr(ik_me)
     695              :       call get_kg(self%ebands%kptns(:,ik_me),istwfk_1,ecut_eff, &
     696          304 :         & self%cryst%gmet,npw_k,kg_k)
     697       278060 :       ptr_kg(:,1+ikg:npw_k+ikg)=kg_k(:, :) !wfd%Kdata(ik)%kg_k(:,:)
     698          304 :       ikg =ikg+npw_k
     699          309 :       ABI_FREE(kg_k)
     700              :     end do
     701            5 :   end subroutine abstract_wf_get_kgs
     702              : 
     703              : 
     704              : !-----------------------------------------------------------------------------
     705              : !> free the memory of the abstract_wf type
     706              : !-----------------------------------------------------------------------------
     707           33 :   subroutine abstract_wf_free(self)
     708              :     class(abstract_wf), intent(inout) :: self
     709           33 :     call self%kset%free()
     710           33 :     nullify(self%cryst)
     711           33 :     nullify(self%dtset)
     712           33 :     nullify(self%dtfil)
     713           33 :     nullify(self%hdr)
     714           33 :     nullify(self%MPI_enreg)
     715           33 :     nullify(self%psps)
     716           33 :     nullify(self%pawtab)
     717           33 :   end subroutine abstract_wf_free
     718              : 
     719              :   ! subroutine show_info(self)
     720              :   !   class(abstract_wf), intent(inout) :: self
     721              :   !   ! cg_elem
     722              :   !   integer :: ipw=3, ispinor=1, ikpt=2, iband=4, isppol=1
     723              :   !   print *, "========showing wf info=============="
     724              :   !   print *, "ipw:", ipw, "  ispinor:", ispinor, "  ikpt:", ikpt, "  iband:", iband, "  isppol:", isppol
     725              :   !   print *, "cg_elem:", self%cg_elem_complex(ipw, ispinor, ikpt, iband, isppol)
     726              :   !   print *, "====end showing wf info=============="
     727              :   ! end subroutine show_info
     728              : 
     729              : !-----------------------------------------------------------------------------
     730              : !> free the memory of the wfd_wf type
     731              : !-----------------------------------------------------------------------------
     732            5 :   subroutine wfd_wf_free(self)
     733              :     class(wfd_wf), intent(inout) :: self
     734              :     ! TODO reenable this
     735            5 :     if (self%expanded) then
     736            5 :       call self%wfd_bz%free()
     737            5 :       call self%hdr_bz%free()
     738            5 :       call self%ebands_bz%free()
     739            5 :       call self%dtset_bz%free()
     740              :       !call self%mpi_enreg_bz%free()
     741            5 :       ABI_FREE(self%bz2ibz)
     742            5 :       ABI_FREE(self%bks_mask)
     743            5 :       ABI_FREE(self%keep_ur)
     744              :     end if
     745            5 :     call self%abstract_wf%free()
     746              : 
     747            5 :   end subroutine wfd_wf_free
     748              : 
     749              : 
     750              : !-----------------------------------------------------------------------------
     751              : !> Initialize the wfd_wf type
     752              : !-----------------------------------------------------------------------------
     753            5 :   subroutine wfd_wf_init(self, ebands, wfd,cryst, dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
     754              :     class(wfd_wf), target, intent(inout) :: self
     755              :     type(ebands_t), target, intent(in) :: ebands
     756              :     type(crystal_t), target, intent(in) :: cryst
     757              :     type(wfd_t), target, intent(inout) :: wfd
     758              :     type(dataset_type),target, intent(in) :: dtset
     759              :     type(datafiles_type),target, intent(in) :: dtfil
     760              :     type(mpi_type), target, intent(inout) :: MPI_enreg
     761              :     type(pseudopotential_type), target, intent(in) :: psps
     762              :     type(pawtab_type), target, optional, intent(in) :: pawtab(:)
     763              :     type(hdr_type), target, intent(in) :: hdr
     764              :     integer, intent(in) :: nprocs, rank, comm
     765              : 
     766              : 
     767              : 
     768            5 :     self%comm=comm
     769            5 :     self%rank=rank
     770            5 :     self%nprocs=nprocs
     771              :     !print *, "set mpi info to wfd_wf", "self%comm", "self%rank", "self%nprocs"
     772              : 
     773            5 :     self%expanded=(dtset%kptopt==1 .or. dtset%kptopt==2)
     774            5 :     if (self%expanded) then
     775              :       ! expand the kpoints to the full BZ
     776            5 :       self%expanded=.True.
     777            5 :       self%ebands_ibz => ebands
     778            5 :       self%wfd_ibz => wfd
     779            5 :       self%hdr_ibz => hdr
     780            5 :       call ebands_and_hdr_expandk()
     781              :       call self%kset%init(cryst=cryst,nkpt=self%hdr_bz%nkpt, mband=self%hdr_bz%mband,  &
     782              :         & nsppol=self%hdr_bz%nsppol,kkpts= self%hdr_bz%kptns, &
     783            5 :         & comm=self%comm, nprocs=self%nprocs, rank=self%rank)
     784              : 
     785            5 :       self%hdr=> self%hdr_bz
     786            5 :       call set_fake_ovikp()
     787              : 
     788            5 :       call wfd_expandk()
     789            5 :       self%wfd=> self%wfd_bz
     790            5 :       call dtset_expandk()
     791              :       call self%abstract_wf%abstract_init(self%ebands_bz, cryst, self%dtset_bz, dtfil, &
     792            5 :         & self%hdr_bz, MPI_enreg, nprocs, psps, pawtab, rank, comm)
     793              :     else ! the kpoints are already in the full BZ and does not need to be expanded
     794            0 :       self%expanded=.False.
     795            0 :       self%wfd => wfd
     796            0 :       self%ebands => ebands
     797            0 :       self%hdr=> hdr
     798              :       call self%kset%init(cryst=cryst,nkpt=hdr%nkpt, mband=hdr%mband,  &
     799              :         & nsppol=hdr%nsppol,kkpts= hdr%kptns, &
     800            0 :         & comm=self%comm, nprocs=self%nprocs, rank=self%rank)
     801            0 :       call set_fake_ovikp()
     802            0 :       call self%abstract_wf%abstract_init(ebands,cryst, dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
     803              :     end if
     804              :   contains
     805              : 
     806              : !-----------------------------------------------------------------------------
     807              : !> subsubroutine of wfd_wf_init
     808              : !> set the ovikp of the kset. fake means that all the kpoints are assumed to be neighbors
     809              : !-----------------------------------------------------------------------------
     810            5 :     subroutine set_fake_ovikp()
     811           10 :       integer :: ovikp(self%hdr%nkpt, 1), i
     812          309 :       do i=1, self%hdr%nkpt
     813          309 :         ovikp(i, 1)=i
     814              :       end do
     815            5 :       call self%kset%set_ovikp(ovikp, 1 , 1, mpi_enreg)
     816            5 :     end subroutine set_fake_ovikp
     817              : 
     818              : 
     819              : 
     820              : !-----------------------------------------------------------------------------
     821              : !> subsubroutine of wfd_wf_init
     822              : !> expand the kpoints to the full BZ
     823              : !-----------------------------------------------------------------------------
     824            5 :     subroutine dtset_expandk()
     825              :       integer :: nkpt
     826            5 :       self%dtset_bz = dtset%copy()
     827            5 :       ABI_FREE(self%dtset_bz%kpt)
     828            5 :       ABI_FREE(self%dtset_bz%kptns)
     829            5 :       ABI_FREE(self%dtset_bz%istwfk)
     830            5 :       ABI_FREE(self%dtset_bz%nband)
     831            5 :       ABI_FREE(self%dtset_bz%wtk)
     832            5 :       nkpt=self%ebands_bz%nkpt
     833            5 :       self%dtset_bz%kptopt=3
     834            5 :       self%dtset_bz%nkpt = nkpt
     835           15 :       ABI_MALLOC(self%dtset_bz%kpt, (3,nkpt))
     836           10 :       ABI_MALLOC(self%dtset_bz%kptns, (3,nkpt ))
     837           15 :       ABI_MALLOC(self%dtset_bz%istwfk, (nkpt ))
     838           10 :       ABI_MALLOC(self%dtset_bz%nband, (nkpt ))
     839           15 :       ABI_MALLOC(self%dtset_bz%wtk, (nkpt))
     840         1221 :       self%dtset_bz%kpt(:,:) = self%ebands_bz%kptns(:,:)
     841         1221 :       self%dtset_bz%kptns(:,:) = self%ebands_bz%kptns(:,:)
     842          309 :       self%dtset_bz%istwfk(:) = 1
     843          309 :       self%dtset_bz%nband(:) = self%hdr_bz%nband(:)
     844          309 :       self%dtset_bz%wtk(:) = self%hdr_bz%wtk(:)
     845            5 :       self%dtset_bz%mkmem = self%kset%my_nkpt
     846            5 :     end subroutine dtset_expandk
     847              : 
     848              : !-----------------------------------------------------------------------------
     849              : !> subsubroutine of wfd_wf_init
     850              : !> expand the ebands and hdr to the full BZ
     851              : !-----------------------------------------------------------------------------
     852            5 :     subroutine ebands_and_hdr_expandk()
     853              :       real(dp) :: ecut_eff, dksqmax
     854            5 :       type(wvl_internal_type) :: dummy_wvl
     855              :       integer:: kptopt3=3
     856              :       character(len=200) :: msg
     857              :       ! NOTE: is this OK to assume so?
     858            5 :       ecut_eff = dtset%ecut * dtset%dilatmx **2
     859              :       call ebands%expandk(cryst=cryst, ecut_eff=ecut_eff, &
     860              :         & force_istwfk1=.True., dksqmax=dksqmax, &
     861            5 :         & bz2ibz=self%bz2ibz, outb=self%ebands_bz)
     862              :   ! Note: test if force_istwfk1 is not set to True, force rotate
     863            5 :       if (dksqmax > tol12) then
     864              :         write(msg, '(3a,es16.6,4a)' )&
     865            0 :           'At least one of the k points could not be generated from a symmetrical one.',ch10,&
     866            0 :           'dksqmax=',dksqmax,ch10,&
     867            0 :           'Action: check your WFK file and k-point input variables',ch10,&
     868            0 :           '        (e.g. kptopt or shiftk might be wrong in the present dataset or the preparatory one.'
     869            0 :         ABI_ERROR(msg)
     870              :       end if
     871              : 
     872              :       call self%hdr_bz%init_lowlvl(self%ebands_bz,psps,pawtab,dummy_wvl,abinit_version,&
     873              :         hdr%pertcase,hdr%natom,hdr%nsym,hdr%nspden,hdr%ecut,dtset%pawecutdg,hdr%ecutsm,dtset%dilatmx,&
     874              :         hdr%intxc,hdr%ixc,hdr%stmbias,hdr%usewvl,dtset%pawcpxocc,dtset%pawspnorb,dtset%ngfft,dtset%ngfftdg,hdr%so_psp,&
     875              :         hdr%qptn,cryst%rprimd,cryst%xred,hdr%symrel,hdr%tnons,hdr%symafm,hdr%typat,hdr%amu,hdr%icoulomb,&
     876              :         kptopt3,dtset%nelect,dtset%ne_qFD,dtset%nh_qFD,dtset%ivalence,dtset%cellcharge(1),&
     877              :         dtset%kptrlatt_orig,dtset%kptrlatt,&
     878            5 :         dtset%nshiftk_orig,dtset%nshiftk,dtset%shiftk_orig,dtset%shiftk)
     879              :       ! End CP modified
     880              : 
     881            5 :       if (psps%usepaw == 1) call pawrhoij_copy(hdr%pawrhoij, self%hdr_bz%pawrhoij)
     882            5 :     end subroutine ebands_and_hdr_expandk
     883              : 
     884              : !-----------------------------------------------------------------------------
     885              : !> subsubroutine of wfd_wf_init
     886              : !> whether the kpoint is irreducible
     887              : !@param[in] ik the index of the kpoint in the full BZ
     888              : !@return true if the kpoint is irreducible
     889              : !-----------------------------------------------------------------------------
     890              :     logical  function isirr(ik)
     891              :       integer, intent(in) :: ik
     892              :       integer :: isym, itimrev, g0(3)
     893              :       !ik_ibz = bz2ibz(ikf,1)
     894              :       isym = self%bz2ibz(ik,2)
     895              :       itimrev = self%bz2ibz(ik,6)
     896              :       g0 = self%bz2ibz(ik,3:5)        ! IS(k_ibz) + g0 = k_bz
     897              :       isirr = (isym == 1 .and. itimrev == 0 .and. all(g0 == 0))
     898              :     end function isirr
     899              : 
     900              : 
     901              : !-----------------------------------------------------------------------------
     902              : !> subsubroutine of wfd_wf_init
     903              : !> expand the wavefunctions to the full BZ
     904              : !-----------------------------------------------------------------------------
     905            5 :     subroutine wfd_expandk()
     906            5 :       integer, allocatable :: istwfk(:)
     907              :       integer :: ik, spin, band
     908            5 :       complex(gwp), allocatable :: ug(:)
     909              :       integer ::  work_ngfft(18),gmax(3),indkk(6,1)
     910            5 :       real(dp),allocatable ::  work(:,:,:,:), cg_kbz(:, :, :)
     911              :       integer ::mpw, mband, npw_kbz, npw_check, size, ik_ibz
     912            5 :       integer,allocatable :: kg_kbz(:,:), kg_check(:,:)
     913              :       real(dp):: kk_bz(3), kk_ibz(3)
     914              :       character(len=500) :: msg
     915              : 
     916            5 :       mband= dtset%mband
     917           15 :       ABI_MALLOC(istwfk, (self%ebands_bz%nkpt))
     918          309 :       istwfk(:) = 1
     919              : 
     920            5 :       call self%kset%get_mpw_gmax(dtset%ecut, mpw, gmax)
     921              : 
     922              :       !mpw = maxval(self%hdr_bz%npwarr)
     923            5 :       mband = self%hdr_bz%mband
     924              :       !call gstore%get_mpw_gmax(ecut, mpw, gmax)
     925           20 :       gmax = gmax + 4 ! FIXME: this is to account for umklapp
     926           20 :       gmax = 2*gmax + 1
     927            5 :       call ngfft_seq(work_ngfft, gmax)
     928              : 
     929              : 
     930           25 :       ABI_MALLOC(work, (2, work_ngfft(4), work_ngfft(5), work_ngfft(6)))
     931           15 :       ABI_MALLOC(kg_kbz, (3, mpw))
     932           20 :       ABI_MALLOC(cg_kbz, (2, mpw*self%hdr_bz%nspinor, self%hdr_bz%mband))
     933              : 
     934              : 
     935              :       call self%kset%get_bks_mask( bks_mask=self%bks_mask, keep_ur=self%keep_ur, &
     936            5 :         & nband=self%hdr_bz%mband, nsppol=hdr%nsppol, keep_ur_value=.False.)
     937         3642 :       self%bks_mask(:,:,:)=.True.
     938              :       call self%wfd_bz%init(Cryst=cryst,Pawtab=pawtab,Psps=psps, &
     939              :         & keep_ur=self%keep_ur,mband=self%hdr_bz%mband,nband=self%ebands_bz%nband, &
     940              :         &nkibz=self%ebands_bz%nkpt,nsppol=dtset%nsppol,bks_mask=self%bks_mask,&
     941              :         &nspden=dtset%nspden,nspinor=hdr%nspinor,ecut=dtset%ecut, &
     942              :         &ecutsm=dtset%ecutsm,dilatmx=dtset%dilatmx, &
     943              :         &istwfk=istwfk,kibz=self%ebands_bz%kptns,ngfft=wfd%ngfft, &
     944              :         &nloalg=wfd%nloalg,prtvol=dtset%prtvol,pawprtvol=dtset%pawprtvol,comm=comm,&
     945            5 :         &  use_fnl_dir0der0 = .False.) ! optional
     946              : 
     947           10 :       do spin =1, dtset%nsppol
     948          314 :         do ik=1, self%ebands_bz%nkpt
     949      4566752 :           work(:, :, :, :) =0.0_dp
     950       288464 :           kg_kbz(:, :)=0
     951      2299856 :           cg_kbz(:, :, :)=0.0_dp
     952          304 :           npw_kbz=self%hdr_bz%npwarr(ik)
     953          304 :           size =self%hdr_bz%nspinor*npw_kbz
     954              :           !print *, "size", npw_kbz
     955              :           !print *, "size", size
     956         2128 :           indkk(:, 1) = self%bz2ibz(ik,: )
     957              :           !TODO: ecut or ecut_eff?
     958              :           !print *, "indkk: ", indkk(:, 1)
     959              : 
     960          304 :           ik_ibz =self%bz2ibz(ik, 1)
     961         1216 :           kk_bz=self%ebands_bz%kptns(:, ik)
     962         1216 :           kk_ibz=self%ebands_ibz%kptns(:,ik_ibz )
     963              : 
     964              : 
     965              :           !Note that we use force_rotate here.
     966              :           !Otherwise the sym_ug_kg gives different npw_kbz as in ebands_bz or hdr_bz.
     967              :           !if the kpoint is in the IBZ.
     968              :           call wfd%sym_ug_kg(ecut=dtset%ecut, &
     969              :             & kk_bz=kk_bz, kk_ibz=kk_ibz, bstart=1, nband=mband, &
     970              :             & spin=spin, mpw=mpw, indkk=indkk, cryst=cryst, &
     971              :             & work_ngfft=work_ngfft, work=work, istwf_kbz=istwfk(ik), &
     972              :             & npw_kbz=npw_kbz, kg_kbz=kg_kbz, cgs_kbz=cg_kbz, &
     973          304 :             & force_rotate=.True.)
     974              : 
     975              :           ! The rotated coefficients are stored in the order defined by kg_kbz.
     976              :           ! get_kgs regenerates this list later for mlwfovlp, so both the set and
     977              :           ! its ordering must agree exactly.
     978          304 :           call get_kg(kk_bz, 1, self%hdr_bz%ecut_eff, cryst%gmet, npw_check, kg_check)
     979          304 :           write(msg, '(a,i0,a,i0,a,i0)') "Inconsistent plane-wave count at full-BZ k-point ", ik, &
     980          608 :             ": sym_ug_kg gives ", npw_kbz, ", get_kg gives ", npw_check
     981          304 :           ABI_CHECK(npw_check == npw_kbz, msg)
     982          304 :           write(msg, '(a,i0)') "Inconsistent G-vector ordering at full-BZ k-point ", ik
     983       278060 :           ABI_CHECK(all(kg_check(:,1:npw_check) == kg_kbz(:,1:npw_kbz)), msg)
     984          304 :           ABI_FREE(kg_check)
     985              : 
     986          304 :           self%hdr_bz%npwarr(ik)=npw_kbz
     987          304 :           self%ebands_bz%npwarr(ik)=npw_kbz
     988          304 :           self%wfd_bz%npwarr(ik)=npw_kbz
     989          304 :           size =self%hdr_bz%nspinor*npw_kbz
     990          912 :           ABI_MALLOC(ug, (size))
     991         3632 :           do band = 1, self%ebands_bz%nband(ik)
     992       739804 :             ug(:)= cmplx(cg_kbz(1, 1:size,band), cg_kbz(2, 1:size, band), kind=gwp)
     993              :             !ug(:) = ug(:) / sqrt(sum(cg_kbz(:, 1:size, band)**2))
     994              :             call self%wfd_bz%push_ug(band, ik, spin, Cryst,ug, &
     995         3632 :               & update_ur=.True., update_cprj=.False.)
     996              :           end do
     997          309 :             ABI_FREE(ug)
     998              :           end do
     999              :       end do
    1000              : 
    1001            5 :       ABI_FREE(cg_kbz)
    1002            5 :       ABI_FREE(kg_kbz)
    1003            5 :       ABI_FREE(work)
    1004            5 :       ABI_FREE(istwfk)
    1005            5 :     end subroutine wfd_expandk
    1006              : 
    1007              : 
    1008              :   end subroutine wfd_wf_init
    1009              : 
    1010              : 
    1011              : 
    1012              : !
    1013              : !  subroutine wfd_build_cache(self, iband, ik, isppol)
    1014              : !    class(wfd_wf), intent(inout) :: self
    1015              : !    integer, intent(in) :: iband, ik, isppol
    1016              : !    integer :: ik_ibz, size
    1017              : !    ik_ibz=ik
    1018              : !    size = self%wfd%npwarr(ik_ibz) * self%wfd%nspinor
    1019              : !    if(allocated(self%cg_cache)) then
    1020              : !       ABI_FREE(self%cg_cache)
    1021              : !    end if
    1022              : !    ABI_MALLOC(self%cg_cache, (2, size))
    1023              : !    call self%wfd%copy_cg(iband, ik_ibz, isppol, self%cg_cache)
    1024              : !    self%iband_c = iband
    1025              : !    self%ikpt_c = ik
    1026              : !    self%isppol_c = isppol
    1027              : !  end subroutine wfd_build_cache
    1028              : 
    1029              : 
    1030              :   ! subroutine wfd_wf_ug(self, iband, ikpt, isppol, ug )
    1031              :   !   class(wfd_Wf), intent(inout) :: self
    1032              :   !   integer, intent(in) ::  iband, ikpt, isppol
    1033              :   !   real(dp), intent(inout) :: ug(:, :)
    1034              :   !   integer :: ik_ibz
    1035              :   !   integer :: npw_k
    1036              :   !   type(wave_t),pointer :: wave
    1037              :   !   character(len=500) :: msg
    1038              :   !   ik_ibz=ikpt
    1039              :   !   !if(.not. (iband==self%iband_c .and. ikpt==self%ikpt_c .and. isppol==self%isppol_c)) then
    1040              :   !      !print *, "Building cache for : ", iband, ikpt, isppol
    1041              :   !      !call self%build_cache(iband, ikpt, isppol)
    1042              :   !   !end if
    1043              :   !   ABI_CHECK(self%wfd%get_wave_ptr(iband, ik_ibz, isppol, wave, msg) == 0, msg)
    1044              :   !   if (.not. wave%has_ug == WFD_STORED) then
    1045              :   !      write(msg,'(a,i0,a,3i0)')" Node ",self%wfd%my_rank," doesn't have (band,ik_ibz,spin): ",iband,ik_ibz,isppol
    1046              :   !      ABI_BUG(msg)
    1047              :   !   end if
    1048              :   !   npw_k = self%Wfd%npwarr(ik_ibz)
    1049              :   !   call xcopy(npw_k*self%Wfd%nspinor, wave%ug, 1, ug, 1)
    1050              :   ! end subroutine wfd_wf_ug
    1051              : 
    1052              : 
    1053              : !---------------------------------------------------------------------
    1054              : !> get one element of the wavefunction in the wfd_Wf object
    1055              : !> override the abstract_wf method
    1056              : !---------------------------------------------------------------------
    1057    459503616 :   function wfd_cg_elem(self, icplx, ig, ispinor, iband, ikpt, isppol ) result(res)
    1058              :     class(wfd_Wf), intent(inout) :: self
    1059              :     integer, intent(in) :: icplx, ig, ispinor, iband, ikpt, isppol
    1060              :     integer :: ik_ibz
    1061              :     real(dp) :: res
    1062              :     complex(dp) :: t
    1063              :     integer :: npw_k
    1064              :     type(wave_t),pointer :: wave
    1065              :     character(len=500) :: msg
    1066    459503616 :     ik_ibz=ikpt
    1067              :     !if(.not. (iband==self%iband_c .and. ikpt==self%ikpt_c .and. isppol==self%isppol_c)) then
    1068              :        !print *, "Building cache for : ", iband, ikpt, isppol
    1069              :        !call self%build_cache(iband, ikpt, isppol)
    1070              :     !end if
    1071    459503616 :     ABI_CHECK(self%wfd%get_wave_ptr(iband, ik_ibz, isppol, wave, msg) == 0, msg)
    1072    459503616 :     if (.not. wave%has_ug == WFD_STORED) then
    1073            0 :        write(msg,'(a,i0,a,3i0)')" Node ",self%wfd%my_rank," doesn't have (band,ik_ibz,spin): ",iband,ik_ibz,isppol
    1074            0 :        ABI_BUG(msg)
    1075              :     end if
    1076    459503616 :     npw_k = self%Wfd%npwarr(ik_ibz)
    1077              :     !call xcopy(npw_k*Wfd%nspinor, wave%ug, 1, ug, 1)
    1078              :     !res = self%cg_cache(icplx, ig+self%hdr%npwarr(ik_ibz)*(ispinor-1))
    1079    459503616 :     t = wave%ug(ig+self%hdr%npwarr(ik_ibz)*(ispinor-1))
    1080    689255424 :     select case(icplx)
    1081              :        case(1)
    1082    229751808 :           res = real(t)
    1083              :        case(2)
    1084    229751808 :           res = aimag(t)
    1085              :        case default
    1086    459503616 :           res=-999999.99_dp
    1087              :        end select
    1088    459503616 :   end function wfd_cg_elem
    1089              : 
    1090              : !---------------------------------------------------------------------
    1091              : !> get one element of the wavefunction in the wfd_Wf object, complex version
    1092              : !> override the abstract_wf method
    1093              : !---------------------------------------------------------------------
    1094      1756336 :   function wfd_cg_elem_complex(self,  ig, ispinor, iband, ikpt, isppol ) result(res)
    1095              :     class(wfd_wf), intent(inout) :: self
    1096              :     integer, intent(in) ::  ig, ispinor, iband, ikpt, isppol
    1097              :     complex(dp) :: res
    1098              :     integer :: ik_ibz
    1099              :     integer :: npw_k
    1100              :     type(wave_t),pointer :: wave
    1101              :     character(len=500) :: msg
    1102      1756336 :     ik_ibz=ikpt
    1103      1756336 :     ABI_CHECK(self%wfd%get_wave_ptr(iband, ik_ibz, isppol, wave, msg) == 0, msg)
    1104      1756336 :     if (.not. wave%has_ug == WFD_STORED) then
    1105            0 :        write(msg,'(a,i0,a,3i0)')" Node ",self%wfd%my_rank," doesn't have (band,ik_ibz,spin): ",iband,ik_ibz,isppol
    1106            0 :        ABI_BUG(msg)
    1107              :     end if
    1108      1756336 :     npw_k = self%Wfd%npwarr(ik_ibz)
    1109      1756336 :     res = wave%ug(ig+self%hdr%npwarr(ik_ibz)*(ispinor-1))
    1110      1756336 :   end function wfd_cg_elem_complex
    1111              : 
    1112              : !---------------------------------------------------------------------
    1113              : !> get a block of the wavefunction in the wfd_Wf object
    1114              : !> override the abstract_wf method
    1115              : !---------------------------------------------------------------------
    1116            0 :   subroutine wfd_load_cg(self, ikpt2, isppol, cg_read)
    1117              :     class(wfd_wf), intent(inout) :: self
    1118              :     integer, intent(in) :: ikpt2, isppol
    1119              :     real(dp), intent(inout) :: cg_read(:, :)
    1120              :     integer :: iband, iblk, size
    1121            0 :     iblk=0
    1122            0 :     size=self%hdr%npwarr(ikpt2) * self%nspinor
    1123            0 :     do iband =1, self%mband
    1124            0 :         call self%wfd%copy_cg(iband, ikpt2, isppol, cg_read(:, iblk+1:iblk+size))
    1125            0 :         iblk = iblk + size
    1126              :     end do
    1127            0 :   end subroutine wfd_load_cg
    1128              : 
    1129              : 
    1130              : 
    1131              : !---------------------------------------------------------------------
    1132              : !> get one cprj element of the wavefunction in the wfd_Wf object
    1133              : !> override the abstract_wf method
    1134              : !---------------------------------------------------------------------
    1135            0 :   function wfd_cprj_elem(self,icplx,ispinor, iband, ikpt, isppol, iatom, ilmn) result(res)
    1136              :     class(wfd_wf), intent(inout) :: self
    1137              :     integer, intent(in) :: icplx, ispinor, iband, ikpt, isppol, ilmn, iatom
    1138              :     real(dp) :: res
    1139            0 :     type(pawcprj_type) :: cprj_out(self%natom,self%nspinor)
    1140              : 
    1141              :     integer :: ik_ibz
    1142              :     !TODO:
    1143            0 :     ik_ibz = ikpt
    1144              :     !call self%wfd%ug2cprj(band=iband,ik_ibz=ik_ibz,spin=ispin,choice=1,idir=0,natom=self%natom,Cryst=self%Cryst ,cwaveprj,sorted=.False.)
    1145              :     call self%wfd%get_cprj( band=iband, ik_ibz=ik_ibz, spin=isppol, &
    1146            0 :          & Cryst=self%cryst, Cprj_out=cprj_out, sorted=.False.)
    1147            0 :     res=cprj_out(iatom, ispinor)%cp(icplx, ilmn)
    1148            0 :   end function wfd_cprj_elem
    1149              : 
    1150              : 
    1151              : !---------------------------------------------------------------------
    1152              : !> get one cpaw element of the wavefunction in the wfd_Wf object, complex version
    1153              : !> override the abstract_wf method
    1154              : !---------------------------------------------------------------------
    1155           14 :   subroutine cg_cprj_init(self, ebands, cg, cprj, cryst, dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
    1156              :     class(cg_cprj), intent(inout) :: self
    1157              :     type(crystal_t), target, intent(in) :: cryst
    1158              :     type(ebands_t), target, intent(in) :: ebands
    1159              :     real(dp), target, optional, intent(in):: cg(:, :)
    1160              :     type(pawcprj_type), target, optional, intent(in):: cprj(:,:)
    1161              :     type(dataset_type),target, intent(in) :: dtset
    1162              :     type(datafiles_type),target, intent(in) :: dtfil
    1163              :     type(mpi_type), target, intent(inout) :: MPI_enreg
    1164              :     type(pseudopotential_type), target, intent(in) :: psps
    1165              :     type(pawtab_type), target, optional, intent(in) :: pawtab(:)
    1166              :     type(hdr_type), target, intent(in) :: hdr
    1167              :     integer, intent(in) :: nprocs, rank, comm
    1168           14 :     call self%abstract_wf%abstract_init(ebands, cryst, dtset, dtfil, hdr, MPI_enreg, nprocs, psps, pawtab, rank, comm)
    1169           14 :     if(present(cg))    self%cg=> cg
    1170           14 :     if(present(cprj) .and. present(pawtab)) then
    1171           14 :        self%has_paw=.True.
    1172              :     end if
    1173           14 :     if(present(cprj)) then
    1174              :       !print *, "cprj linked"
    1175              :       !print *, "before linked", cprj(1,1)%cp(:,:)
    1176           14 :       self%cprj => cprj
    1177              :       !print *, "after linked", self%cprj(1,1)%cp(:,:)
    1178              :     end if
    1179           84 :     ABI_MALLOC(self%iwav,(self%nspinor, self%mband,self%nkpt,self%nsppol))
    1180           14 :     call compute_iwav(MPI_enreg, dtset, hdr, self%iwav, nprocs, rank)
    1181           14 :     call self%compute_index_cprj()
    1182           14 :     if(nprocs>1) then
    1183            0 :        call self%write_cg_and_cprj_tmpfile()
    1184              :     end if
    1185              :     !call self%show_info()
    1186           14 :   end subroutine cg_cprj_init
    1187              : 
    1188              :   !---------------------------------------------------------------------
    1189              :   !> free the cg_cprj object ant the temporary files
    1190              :   !---------------------------------------------------------------------
    1191           14 :   subroutine cg_cprj_free(self)
    1192              :     class(cg_cprj), intent(inout) :: self
    1193           14 :     if(self%nprocs>1) then
    1194            0 :        call self%remove_tmpfile()
    1195              :     end if
    1196           14 :     nullify(self%cg)
    1197           14 :     nullify(self%cprj)
    1198           14 :     call self%abstract_wf%free()
    1199           14 :     ABI_FREE(self%iwav)
    1200           14 :     nullify(self%iwav)
    1201           14 :     ABI_FREE(self%icprj)
    1202           14 :     call self%abstract_wf%free()
    1203           14 :   end subroutine cg_cprj_free
    1204              : 
    1205              :   ! return one entry of cg.
    1206              :   ! parameters:
    1207              :   ! icplx: 1 for real part, 2 for imaginary part
    1208              :   ! ig: index of G vector
    1209              :   ! ispinor: index of spinor
    1210              :   ! iband: index of band
    1211              :   ! ikpt: index of k point
    1212              :   ! isppol: index of spin
    1213   1570800548 :   function cg_elem(self, icplx, ig, ispinor, iband, ikpt, isppol ) result(res)
    1214              :     class(cg_cprj), intent(inout) :: self
    1215              :     integer, intent(in) :: icplx, ig, ispinor, iband, ikpt, isppol
    1216              :     integer :: ind
    1217              :     real(dp) :: res
    1218   1570800548 :     ind=ig+self%iwav(ispinor, iband,ikpt,isppol)
    1219   1570800548 :     res=self%cg(icplx,ind)
    1220   1570800548 :   end function cg_elem
    1221              : 
    1222              : 
    1223              : 
    1224              :   ! return one entry of cg in complex form.
    1225              :   ! Parameters:
    1226              :   ! same as cg_elem, except that icplx is not needed.
    1227            0 :   function cg_elem_complex(self, ig,ispinor, iband, ikpt, isppol) result(res)
    1228              :     class(cg_cprj), intent(inout) :: self
    1229              :     integer, intent(in) ::  ig, ispinor, iband, ikpt, isppol
    1230              :     integer :: ind
    1231              :     complex(dp) :: res
    1232            0 :     ind=ig+self%iwav(ispinor, iband,ikpt,isppol)
    1233            0 :     res=CMPLX(self%cg(1,ind),  self%cg(2,ind), kind=dp)
    1234            0 :   end function cg_elem_complex
    1235              : 
    1236              :   !return a pointer to the cg array in the cg_cprj object.
    1237              :   function cg_cprj_get_cg_ptr(self) result(cg)
    1238              :     class(cg_cprj), target, intent(inout) :: self
    1239              :     real(dp), pointer :: cg(:,:)
    1240              :     cg=> self%cg
    1241              :   end function cg_cprj_get_cg_ptr
    1242              : 
    1243              :   !return a pointer to the cprj array in the cg_cprj object.
    1244         2944 :   function cg_cprj_get_cprj_ptr(self) result(cprj)
    1245              :     class(cg_cprj), target, intent(inout) :: self
    1246              :     type(pawcprj_type), pointer :: cprj(:, :)
    1247         2944 :     cprj=>self%cprj
    1248         2944 :   end function cg_cprj_get_cprj_ptr
    1249              : 
    1250              :   !---------------------------------------------------------------------
    1251              :   !> compute the index of the cprj array.
    1252              :   !---------------------------------------------------------------------
    1253           14 :   subroutine compute_index_cprj(self)
    1254              :     ! FIXME:hexu: this is modified from the m_mlwfovlp,
    1255              :     !     but I think it should be carefully checked.
    1256              :     ! mcprj=nspinor*mband*mkmem*nsppol
    1257              :     ! 1. nspinor=2 case seems to be wrong.
    1258              :     class(cg_cprj), intent(inout) :: self
    1259              :     integer :: ii, ikpt, isppol, iband
    1260           70 :     ABI_MALLOC(self%icprj, (self%mband,self%nkpt,self%nsppol))
    1261           14 :     ii=0
    1262           29 :     do isppol=1,self%nsppol
    1263              :        ! FIXME: check if it should be mkmem or nkpt.
    1264          429 :        do ikpt=1,self%nkpt
    1265              :           ! FIXME: nband has the shape of (nsppol*nkpt).
    1266              :           !nband_k=dtset%nband(ikpt+(isppol-1)*nkpt)
    1267         5615 :           do iband=1,self%dtset%nband(ikpt)
    1268              :              ! FIXME: hexu: should cycle if the kpt is not in this node??
    1269         5200 :              ii=ii+1
    1270         5600 :              self%icprj(iband,ikpt,isppol)=ii
    1271              :           end do
    1272              :        end do
    1273              :     end do
    1274           14 :   end subroutine compute_index_cprj
    1275              : 
    1276              : 
    1277              :   ! get one element of cprj
    1278            0 :   function cprj_elem(self,icplx,ispinor, iband, ikpt, isppol, iatom, ilmn) result(res)
    1279              :     class(cg_cprj), intent(inout) :: self
    1280              :     integer, intent(in) :: icplx, ispinor, iband, ikpt, isppol, ilmn, iatom
    1281              :     real(dp) :: res
    1282              :     integer :: ig
    1283              :     ! TODO: this seems to be better than compute_index_cprj,
    1284              :     ! But should it be mband or nband(ikpt)
    1285              : 
    1286              :     ! mcprj=nspinor*mband*mkmem*nsppol
    1287              :     ! this is the original version in m_mlwfovlp
    1288              :     !ig=iband+(ikpt-1)*self%mband*self%nspinor + &
    1289              :     !     &(isppol-1)*self%mkmem*self%mband*self%nspinor
    1290              : 
    1291              :     ig=ispinor+(iband-1)*self%nspinor+(ikpt-1)*self%mband*self%nspinor + &
    1292            0 :          &(isppol-1)*self%mkmem*self%mband*self%nspinor
    1293            0 :     res= self%cprj(iatom, ig)%cp(icplx, ilmn)
    1294            0 :   end function cprj_elem
    1295              : 
    1296              : !---------------------------------------------------------------------
    1297              : !> write cg and cprj to tmpfile
    1298              : !---------------------------------------------------------------------
    1299            0 :   subroutine write_cg_and_cprj_tmpfile(self)
    1300              :     class(cg_cprj), intent(inout) :: self
    1301              :     call write_cg_and_cprj(self%dtset, self%cg, self%cprj, self%dtfil, self%iwav, &
    1302              :          & self%hdr%npwarr, self%mband, self%natom, &
    1303              :          & self%nsppol, self%nkpt,  self%MPI_enreg, &
    1304            0 :          & self%rank, self%psps, self%pawtab)
    1305            0 :   end subroutine write_cg_and_cprj_tmpfile
    1306              : 
    1307              : !---------------------------------------------------------------------
    1308              : !> remove tmpfile of cg and cprj
    1309              : !---------------------------------------------------------------------
    1310            0 :   subroutine remove_tmpfile(self)
    1311              :     class(cg_cprj), intent(inout) :: self
    1312              :     integer :: isppol, ikpt, ierr
    1313              :     integer :: master=1
    1314              :     character(len=fnlen) :: wfnname
    1315              :     character(len=500) :: message
    1316            0 :     if(self%dtset%prtvol>0) then
    1317            0 :        write(message, '(3a)' ) ch10,&
    1318            0 :             &       '   mlwfovlp :  Removing temporary files with cg and cprj (PAW)',ch10
    1319            0 :        call wrtout(ab_out,message,'COLL')
    1320            0 :        call wrtout(std_out,  message,'COLL')
    1321              :     end if
    1322              :     !
    1323              :     !    Just master  node will remove the files
    1324              :     !
    1325            0 :     if(self%rank==master) then
    1326            0 :        do isppol=1,self%nsppol
    1327            0 :           do ikpt=1,self%nkpt
    1328            0 :              write(wfnname,'(a,I5.5,".",I1)') trim(self%dtfil%fnametmp_cg),ikpt,isppol
    1329            0 :              call delete_file(wfnname,ierr)
    1330            0 :              if(self%psps%usepaw==1) then
    1331            0 :                 write(wfnname,'(a,I5.5,".",I1)') trim(self%dtfil%fnametmp_cprj),ikpt,isppol
    1332            0 :                 call delete_file(wfnname,ierr)
    1333              :              end if
    1334              :           end do !ikpt
    1335              :        end do !isppol
    1336              :     end if
    1337            0 :   end subroutine remove_tmpfile
    1338              : 
    1339              : 
    1340              :   !---------------------------------------------------------------------
    1341              :   !> read cg from tmpfile
    1342              :   !@param[in] ikpt2 index of kpt
    1343              :   !@param[in] isppol index of spin
    1344              :   !@param[out] cg_read cg read from tmpfile
    1345              :   !---------------------------------------------------------------------
    1346            0 :   subroutine load_cg(self, ikpt2, isppol, cg_read)
    1347              :     class(cg_cprj), intent(inout) :: self
    1348              :     integer, intent(in) :: ikpt2, isppol
    1349              :     real(dp), intent(inout) :: cg_read(:, :)
    1350              :     character(len=fnlen) :: cg_file
    1351              :     integer :: npw_k2, ios, ii
    1352              :     character(len=500) :: message
    1353              : 
    1354              :     integer :: iunit , iband2, ipw, index
    1355            0 :     write(cg_file,'(a,I5.5,".",I1)') trim(self%dtfil%fnametmp_cg),ikpt2,isppol
    1356            0 :     iunit=1000+ikpt2+ikpt2*(isppol-1)
    1357            0 :     npw_k2=self%hdr%npwarr(ikpt2)
    1358              : 
    1359            0 :     open (unit=iunit, file=cg_file,form='unformatted',status='old',iostat=ios)
    1360            0 :     if(ios /= 0) then
    1361            0 :        write(message,*) " mlwfovlp_pw: file",trim(cg_file), "not found"
    1362            0 :        ABI_ERROR(message)
    1363              :     end if
    1364              :     !
    1365            0 :     do iband2=1,self%mband
    1366            0 :        do ipw=1,npw_k2*self%nspinor
    1367            0 :           index=ipw+(iband2-1)*npw_k2*self%nspinor
    1368            0 :           read(iunit) (cg_read(ii,index),ii=1,2)
    1369              :           !            if(me==0 .and. ikpt2==4)write(300,*)'ipw,iband2,index',ipw,iband2,index,cg_read(:,index)
    1370              :           !            if(me==1 .and. ikpt2==4)write(301,*)'ipw,iband2,index',ipw,iband2,index,cg_read(:,index)
    1371              :        end do
    1372              :     end do
    1373            0 :     close(iunit)
    1374            0 :   end subroutine load_cg
    1375              : 
    1376              : 
    1377              :   !---------------------------------------------------------------------
    1378              :   !> compute the index of the wavefunctions in the cg array
    1379              :   !---------------------------------------------------------------------
    1380           14 :   subroutine compute_iwav(MPI_enreg, dtset, hdr, iwav, nprocs, rank)
    1381              :     type(mpi_type), intent(in) :: MPI_enreg
    1382              :     type(dataset_type), intent(in) :: dtset
    1383              :     type(hdr_type), intent(in) :: hdr
    1384              :     integer, intent(inout) :: iwav(:, :, :, :)
    1385              :     ! dimension: (nspinor, mband,nkpt,nsppol))
    1386              :     integer, intent(in) :: nprocs, rank
    1387              :     character(len=500) :: message
    1388           28 :     integer :: icg(hdr%nsppol, hdr%nkpt)
    1389              :     integer :: icgtemp, isppol, ikpt, nband_k, npw_k, iband, ispinor
    1390              : 
    1391           14 :     write(message, '(a,a)' ) ch10,&
    1392           28 :          & '   mlwfovlp : compute shifts for g-points '
    1393           14 :     call wrtout(std_out,  message,'COLL')
    1394              :     !----------------------------------------------------------------------
    1395              :     !Compute shifts for g points (icg,iwav)
    1396              :     !(here mband is not used, because shifts are internal variables of abinit)
    1397              :     !----------------------------------------------------------------------
    1398              :     !write(std_out,*) mpw*dtset%nspinor*mband*mkmem*nsppol
    1399              :     !ABI_MALLOC(icg,(nsppol,nkpt))
    1400          750 :     icg=0
    1401           29 :     icgtemp=0
    1402              :     !ABI_MALLOC(iwav,(dtset%mband,nkpt,nsppol))
    1403        12365 :     iwav(:,:,:, :)=0
    1404           29 :     do isppol=1,hdr%nsppol
    1405          429 :        do ikpt=1,hdr%nkpt
    1406              :           !    MPI:cycle over k-points not treated by this node
    1407          400 :           if (nprocs>1 ) then !sometimes we can have just one processor
    1408            0 :              if ( ABS(MPI_enreg%proc_distrb(ikpt,1,isppol)-rank)  /=0) CYCLE
    1409              :           end if
    1410              : 
    1411              :           !    write(std_out,*)'rank',rank,'ikpt',ikpt,'isppol',isppol
    1412          400 :           nband_k=dtset%nband(ikpt+(isppol-1)*hdr%nkpt)
    1413              :           !    write(std_out,*) ikpt+(isppol-1)*nkpt,nkpt
    1414          400 :           npw_k=hdr%npwarr(ikpt)
    1415         5615 :           do iband=1,nband_k
    1416         5200 :              if(iband.gt. dtset%mband) then
    1417            0 :                 write(message,'(a,3i0)')" mband",iband,dtset%mband,nband_k
    1418            0 :                 ABI_ERROR(message)
    1419              :              end if
    1420        11936 :              do ispinor =1, dtset%nspinor
    1421              :                 iwav(ispinor, iband,ikpt,isppol)= &
    1422              :                      !&       (iband-1)*npw_k*dtset%nspinor+icgtemp &
    1423        11936 :                      & (ispinor-1)*npw_k +icgtemp
    1424              :              end do
    1425              :              !icgtemp=icgtemp+ npw_k*dtset%nspinor*nband_k
    1426         5600 :              icgtemp = icgtemp + npw_k
    1427              :           end do ! iband
    1428              :           !    icg(isppol,ikpt)=icgtemp
    1429              :           !    write(std_out,*) "icg", isppol,ikpt,icg(isppol,ikpt)
    1430              :        end do  ! ikpt
    1431              :     end do   ! isppol
    1432              :     !write(std_out,*) "shift for cg computed"
    1433              :     !
    1434              :     !Shifts computed.
    1435           14 :   end subroutine compute_iwav
    1436              : 
    1437              :   !---------------------------------------------------------------------
    1438              :   !> write the cg and cprj arrays into a list of files
    1439              :   !> The name of the files are given by dtset%fnametmp_cg and dtset%fnametmp_cprj
    1440              :   !> The files are written in unformatted format
    1441              :   !---------------------------------------------------------------------
    1442            0 :  subroutine write_cg_and_cprj(dtset, cg, cprj, dtfil, iwav, npwarr, mband, natom, &
    1443            0 :       &nsppol, nkpt,  MPI_enreg, rank, psps, pawtab)
    1444              : 
    1445              :    type(dataset_type),intent(in) :: dtset
    1446              :    type(MPI_type),intent(in) :: mpi_enreg
    1447              :    type(datafiles_type),intent(in) :: dtfil
    1448              :    integer,intent(in):: iwav(:,:,:,:)
    1449              :    real(dp),intent(in) :: cg(:, :)
    1450              :    type(pawcprj_type), intent(in) :: cprj(:, :)
    1451              :    integer, intent(in) :: rank, nsppol, nkpt, mband, natom
    1452              :    integer, intent(in) :: npwarr(nkpt)
    1453              :    type(pseudopotential_type),intent(in) :: psps
    1454              :    !type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
    1455              :    type(pawtab_type),intent(in) :: pawtab(:)
    1456              : 
    1457              :    integer :: ikpt, ikpt2, isppol, iun_plot, npw_k, iband,  i, ipw, ispinor, ig
    1458              :    integer :: iatom,  itypat, lmn_size, ilmn
    1459              :    character(len=fnlen) :: wfnname
    1460              :    character(len=1000) :: message
    1461              : 
    1462            0 :      if(dtset%prtvol>0) then
    1463            0 :        write(message, '(3a)' ) ch10,&
    1464            0 : &       '   mlwfovlp :  Creating temporary files with cg and cprj (PAW)',ch10
    1465            0 :        call wrtout(ab_out,message,'COLL')
    1466            0 :        call wrtout(std_out,  message,'COLL')
    1467              :      end if
    1468              : !
    1469            0 :      do isppol=1,nsppol
    1470            0 :        do ikpt=1,nkpt
    1471              : !
    1472              : !        MPI:cycle over k-points not treated by this node
    1473              : !
    1474            0 :           if ( ABS(MPI_enreg%proc_distrb(ikpt,1,isppol)-rank)  /=0) CYCLE
    1475              : 
    1476              : !        write(std_out,*)'writing kpt ',ikpt,'isppol',isppol,' by node ', rank
    1477            0 :          write(wfnname,'(a,I5.5,".",I1)') trim(dtfil%fnametmp_cg),ikpt,isppol
    1478            0 :          iun_plot=1000+ikpt+ikpt*(isppol-1)
    1479              : 
    1480            0 :          open (unit=iun_plot, file=wfnname,form='unformatted')
    1481            0 :          npw_k=npwarr(ikpt)
    1482            0 :          do iband=1,mband
    1483            0 :             do ispinor = 1, dtset%nspinor
    1484            0 :                do ipw=1,npw_k
    1485            0 :                   write(iun_plot) (cg(i,ipw+iwav(ispinor, iband,ikpt,isppol)),i=1,2)
    1486              :                end do
    1487              :            end do
    1488              :          end do
    1489            0 :          close(iun_plot)
    1490              :        end do !ikpt
    1491              :      end do !isppol
    1492              : !
    1493              : !    In the PAW case we also need to write out cprj into files
    1494              : !
    1495            0 :      if(psps%usepaw==1) then
    1496              : !
    1497              : !      big loop on atoms, kpts, bands and lmn
    1498              :        !print *, "nsppol", nsppol
    1499              :        !print *, "nkpt", nkpt
    1500              :        !print *, "mkmem", dtset%mkmem
    1501              : !
    1502            0 :        ikpt2=0
    1503            0 :        do isppol=1,nsppol
    1504            0 :          do ikpt=1,nkpt
    1505              : !
    1506              : !          MPI:cycle over k-points not treated by this node
    1507              : !
    1508            0 :             if ( ABS(MPI_enreg%proc_distrb(ikpt,1,isppol)-MPI_enreg%me)  /=0) CYCLE
    1509              : 
    1510            0 :            ikpt2=ikpt2+1 !sums just on the k-points treated by this node
    1511              : !
    1512            0 :            write(wfnname,'(a,I5.5,".",I1)') trim(dtfil%fnametmp_cprj),ikpt,isppol
    1513            0 :            iun_plot=1000+ikpt
    1514            0 :            open (unit=iun_plot, file=wfnname,form='unformatted')
    1515              : !
    1516            0 :            do iband=1,mband*dtset%nspinor
    1517              :              !ig=iband+(ikpt2-1)*mband*dtset%nspinor +(isppol-1)*nkpt*mband*dtset%nspinor !index for cprj(:,ig)
    1518              :               ! cprj: only mkmem k-points are stored in this node.
    1519            0 :              ig=iband+(ikpt2-1)*mband*dtset%nspinor +(isppol-1)*dtset%mkmem*mband*dtset%nspinor !index for cprj(:,ig)
    1520              :               !
    1521            0 :              do iatom=1,natom
    1522            0 :                itypat=dtset%typat(iatom)
    1523            0 :                lmn_size=pawtab(itypat)%lmn_size
    1524              : !
    1525            0 :                do ilmn=1,lmn_size
    1526            0 :                  write(iun_plot) (( cprj(iatom,ig)%cp(i,ilmn)),i=1,2)
    1527              :                end do !ilmn
    1528              :              end do !iatom
    1529              :            end do !iband
    1530              : 
    1531            0 :            close(iun_plot)
    1532              :          end do !ikpt
    1533              :        end do !isppol
    1534              :      end if !usepaw==1
    1535            0 :  end subroutine write_cg_and_cprj
    1536              : 
    1537              : 
    1538              :  ! subroutine wfd_print_norm(wfd, hdr)
    1539              :  !   type(wfd_t), intent(in) :: wfd
    1540              :  !   type(hdr_type), intent(in) :: hdr
    1541              :  !   integer :: spin, band, ikpt, size
    1542              :  !   real(dp), allocatable :: cgtemp(:, :)
    1543              :  !   do spin=1, wfd%nsppol
    1544              :  !     do ikpt=1, wfd%nkibz
    1545              :  !       size=wfd%nspinor * hdr%npwarr(ikpt)
    1546              :  !       ABI_MALLOC(cgtemp, (2,  size))
    1547              :  !       do band=1, wfd%mband
    1548              :  !         cgtemp(:, :)=0
    1549              :  !         !if(isirr(ik)) then
    1550              :  !         call wfd%copy_cg(band,ikpt, spin, cgtemp)
    1551              :  !         !print *, "spin:", spin, "band:", band, "ik:", ikpt, "delta:", sum(cgtemp**2)
    1552              :  !       end do
    1553              :  !       ABI_FREE(cgtemp)
    1554              :  !     end do
    1555              :  !   end do
    1556              :  ! end subroutine wfd_print_norm
    1557              : 
    1558              : 
    1559          119 : end module m_abstract_wf
        

Generated by: LCOV version 2.3-1