!{\src2tex{textfont=tt}}
!!****m* ABINIT/m_bandfft_kpt
!! NAME
!!  m_results_gs
!!
!! FUNCTION
!!  This module provides the definition of the bandfft_kpt_type
!!  used for kgb parallelization.
!!
!! COPYRIGHT
!! Copyright (C) 2011-2014 ABINIT group (FJ,MT)
!! This file is distributed under the terms of the
!! GNU General Public License, see ~abinit/COPYING
!! or http://www.gnu.org/copyleft/gpl.txt .
!!
!! PARENTS
!!
!! CHILDREN
!!
!! SOURCE

#if defined HAVE_CONFIG_H
#include "config.h"
#endif

#include "abi_common.h"

MODULE m_bandfft_kpt

 use defs_basis
 use defs_abitypes
 use m_profiling
 use m_errors
 use m_xmpi

 implicit none

 private
!!***

!!****t* m_bandfft_kpt/bandfft_kpt_type
!! NAME
!! bandfft_kpt_type
!!
!! FUNCTION
!! The bandfft_kpt_type structured datatype gather different information
!! about the triple band-fft-kpt parallelisation :
!! tabs which are distributed over all the three dimensions and stored during
!! the calculation, dimensions of messages exchange during the calculations...
!! i.e.: all the informations which were spread over the entire code before and
!! recomputed at each iline, istep or itime STEP with a large probability to
!! make a mistake.
!!
!! SOURCE

 type, public :: bandfft_kpt_type

! WARNING : if you modify this datatype, please check whether there might be creation/destruction/copy routines,
! declared in another part of ABINIT, that might need to take into account your modification.

  integer :: flag1_is_allocated             ! determine if the following data are allocated or not
  integer :: npw_tot                        ! array holding the total number of plane waves for each k point
  integer :: ndatarecv                      ! total number of values received by the processor and sent
                                            ! by the other processors band
  integer, allocatable :: kg_k_gather(:,:)  ! planewave coordinates
                                            ! (of the processor + sent by other processors band)
  integer, allocatable :: recvcounts(:)     ! number of values received by the  processor from each processor band
  integer, allocatable :: sendcounts(:)     ! number of values sent   by the  processor to   each processor band
  integer, allocatable :: rdispls   (:)     ! positions of values received by the processor from each processor band
  integer, allocatable :: sdispls   (:)     ! postions of values sent by the processor to each processor band
  integer, allocatable :: gbound(:,:)       ! sphere boundary info: gbound(2*mgfft+8,2)

  integer :: flag2_is_allocated                 ! determine if the following data are allocated or not
  real(dp), allocatable :: ffnl_gather(:,:,:,:) ! ffnl tab (of the processor + sent by other processors band)
  real(dp), allocatable :: kinpw_gather(:)      ! kinpw tab (of the processor + sent by other processors band)
  real(dp), allocatable :: ph3d_gather(:,:,:)   ! ph3d tab (of the processor + sent by other processors band)
  real(dp), allocatable :: kpg_k_gather(:,:)    ! kpg_k tab (of the processor + sent by other processors band)


  integer :: flag3_is_allocated             ! determine if the following data are allocated or not
  integer :: istwf_k                        ! input option parameter that describes the storage of wfs
  integer :: idatarecv0                     ! position of the planewave coordinates (0,0,0)
  integer :: ndatarecv_tot                  ! total number of received values by the processor
                                            ! (ndatarecv   + number of received opposited planewave coordinates)
  integer :: ndatasend_sym                  ! number of sent values to the processors fft to create opposited
                                            ! planewave coordinates
  integer, allocatable :: kg_k_gather_sym(:,:)  ! planewave coordinates
                                            ! (kg_k_gather + opposited planewave coordinates sent by the processors fft)
  integer, allocatable :: rdispls_sym(:)        ! positions of values received by the processor from each processor fft
  integer, allocatable :: recvcounts_sym(:)     ! number of values received by the  processor from each processor fft
  integer, allocatable :: recvcounts_sym_tot(:) ! number of values received by each processor from the  other processors fft
  integer, allocatable :: sdispls_sym(:)        ! postions of values sent by the processor to each processor fft
  integer, allocatable :: sendcounts_sym(:)     ! number of values sent   by the  processor to each processor fft
  integer, allocatable :: sendcounts_sym_all(:) ! number of values sent   by each processor to the other processors fft
  integer, allocatable :: tab_proc(:)           ! positions of opposited planewave coordinates in the list of the processors fft

  logical          :: have_to_reequilibrate ! indicates weather we will have to reequilibrate and allocate all these stuff
  integer          :: npw_fft               ! Number of plane waves during fft step
  integer, allocatable :: indices_pw_fft(:)     !  Indices for sorting pw like pw
  integer, allocatable :: sendcount_fft (:)     ! Number of pw to send to others proc fft
  integer, allocatable :: senddisp_fft(:)       ! Positions for sending
  integer, allocatable :: recvcount_fft(:)      ! Number of pw to receive from others proc fft
  integer, allocatable :: recvdisp_fft(:)       ! Positions for receiving
  integer, allocatable :: kg_k_fft(:,:)         ! planewaves coordinates

 end type bandfft_kpt_type

!public procedures.
 public :: init1_bandfft_kpt
 public :: init2_bandfft_kpt
 public :: destroy_bandfft_kpt
 public :: copy_bandfft_kpt
!!***

 ! MG: WHY DO YOU NEED THIS GLOBAL POINTER? WHY DON'T YOU USE MPI_ENREG FOR STORING THIS OBJECT!
 type(bandfft_kpt_type),save,public,pointer :: bandfft_kpt(:) => null()
    ! Contains all the informations related to the band/FFT parallelism
    ! which depends on kpt exists only if mpi_enreg%paral_kgb==1

CONTAINS

!===========================================================
!!***

!!****f* m_bandfft_kpt/init1_bandfft_kpt
!! NAME
!!  init1_bandfft_kpt
!!
!! FUNCTION
!!  Init all (or part of) scalars and pointers in a bandfft_kpt datastructure
!!
!! INPUTS
!!  istwfk(nkpt)       = input option parameter that describes the storage of wfs
!!  kg(3,mpw*mkmem)    = dimensionless coords of G vecs in basis sphere at k point
!!  mgfft              = maximum single fft dimension (IN)
!!  mkmem              = number of k points which can fit in memory; set to 0 if use disk
!!  mpi_enreg          = informations about MPI parallelization
!!  mpw                = maximum number of planewaves as dimensioned in calling routine
!!  nband(nkpt*nsppol) = number of bands at each k point
!!  nkpt               = number of k points
!!  npwarr(nkpt)       = array holding npw for each k point, taking into account
!!                       the effect of istwfk, and the spreading over processors
!!  nsppol             = 1 for unpolarized, 2 for polarized
!!
!! OUTPUT
!!
!!---------------------------------------------------------------------
!!  within the bandfft_kpt data_type : Initialize and compute
!!---------------------------------------------------------------------
!!  gbound             = sphere boundary info
!!  idatarecv0         = position of the planewave coordinates (0,0,0)
!!  istwf_k            = input option parameter that describes the storage of wfs
!!  kg_k_gather        = planewave coordinates
!!                       (of the processor + sended by other processors band)
!!  kg_k_gather_sym    = planewave coordinates
!!                       (kg_k_gather + opposited planewave coordinates sended by the processors fft)
!!  ndatarecv          = total number of values received by the processor and sended
!!                       by the other processors band
!!  ndatasend_sym      = number of sended values to the processors fft to create opposited
!!                       planewave coordinates
!!  ndatarecv_tot      = total number of received values by the processor
!!                       (ndatarecv   + number of received opposited planewave coordinates)
!!  recvcounts         = number of values received by the  processor from each processor band
!!  recvcounts_sym     = number of values received by the  processor from each processor fft
!!  recvcounts_sym_tot = number of values received by each processor from the  other processors fft
!!  rdispls            = positions of values received by the processor from each processor band
!!  rdispls_sym        = positions of values received by the processor from each processor fft
!!  sendcounts         = number of values sended   by the  processor to   each processor band
!!  sendcounts_sym     = number of values sended   by the  processor to   each processor fft
!!  sendcounts_sym_all = number of values sended   by each processor to the other processors fft
!!  sdispls            = postions of values sended by the processor to each processor band
!!  sdispls_sym        = postions of values sended by the processor to each processor fft
!!  tab_proc           = positions of opposited planewave coordinates in the list of the
!!                       processors fft
!! SIDE EFFECTS
!!  bandfft_kpt_in=<type(bandfft_kpt)>=bandfft_kpt datastructure
!!
!! PARENTS
!!      gstate
!!
!! CHILDREN
!!
!! SOURCE

subroutine init1_bandfft_kpt(bandfft_kpt_in,istwfk,kg,mgfft,mkmem,mpi_enreg,mpw,nband,nkpt,npwarr,nsppol)


!This section has been created automatically by the script Abilint (TD).
!Do not modify the following lines by hand.
#undef ABI_FUNC
#define ABI_FUNC 'init1_bandfft_kpt'
 use interfaces_32_util
 use interfaces_52_fft_mpi_noabirule
!End of the abilint section

 implicit none

!Arguments ------------------------------------
!scalars
 integer,intent(in) :: mgfft,mkmem,mpw,nkpt,nsppol
 type(bandfft_kpt_type),pointer :: bandfft_kpt_in(:)
 type(MPI_type),intent(inout) :: mpi_enreg
!arrays
 integer,intent(in) :: istwfk(nkpt),nband(nkpt*nsppol)
 integer,intent(in) :: kg(3,mpw*mkmem),npwarr(nkpt)

!Local variables-------------------------------
!scalars
 integer :: comm_band,comm_fft,idatarecv,idatarecv0,ierr,ikg,ikpt,ikpt_this_proc,iproc,isppol,istwf_k,itest,jsendloc
 integer :: me_fft,me_kpt,n2,nband_k,ndatarecv,ndatarecv_tot,ndatasend_sym,nproc_band,nproc_fft,npw_fft,npw_k,npw_tot
 character(len=500)  :: message
!arrays
 integer,allocatable :: buff_kg(:,:),gbound(:,:),indices_pw_fft(:),kg_k(:,:),kg_k_fft(:,:),kg_k_gather(:,:)
 integer,allocatable :: kg_k_gather_all(:,:),kg_k_gather_send(:,:),kg_k_gather_sym(:,:)
 integer,allocatable :: npw_per_proc(:)
 integer,allocatable :: rdispls(:),rdispls_all(:),rdispls_sym(:),rdispls_sym_loc(:)
 integer,allocatable :: recvcounts(:),recvcounts_sym(:),recvcounts_fft(:),recvcounts_sym_loc(:),recvcounts_sym_tot(:)
 integer,allocatable :: recvdisp_fft(:),sdispls(:),sdispls_sym_loc(:),sdispls_sym(:)
 integer,allocatable :: sendcounts(:),sendcounts_fft(:),sendcounts_sym(:),sendcounts_sym_all(:),sendcounts_sym_loc(:)
 integer,allocatable :: senddisp_fft(:),sum_kg(:),tab_proc(:)

! *********************************************************************

 If(mpi_enreg%paral_kgb/=1) then
   nullify(bandfft_kpt_in)
   return
 end if

!---------------------------------------------
!Initialisation
!---------------------------------------------
 nproc_fft    = mpi_enreg%nproc_fft
 nproc_band   = mpi_enreg%nproc_band

 me_fft       = mpi_enreg%me_fft
 me_kpt       = mpi_enreg%me_kpt

 comm_band    = mpi_enreg%comm_band
 comm_fft     = mpi_enreg%comm_fft

!=============================================================================
!Compute and store various tabs in bandfft_kpt(ikpt) data_struc
!These ones will be used in following subroutines:
!vtorho, mkrho, prep_nonlop, prep_fourwf, prep_getghc...
!=============================================================================

 ABI_DATATYPE_ALLOCATE(bandfft_kpt_in,(mkmem))

 ABI_ALLOCATE(sdispls       ,(nproc_band))
 ABI_ALLOCATE(sendcounts    ,(nproc_band))
 ABI_ALLOCATE(rdispls       ,(nproc_band))
 ABI_ALLOCATE(recvcounts    ,(nproc_band))
 ABI_ALLOCATE(sendcounts_fft,(nproc_fft))
 ABI_ALLOCATE(senddisp_fft  ,(nproc_fft))
 ABI_ALLOCATE(recvcounts_fft,(nproc_fft))
 ABI_ALLOCATE(recvdisp_fft  ,(nproc_fft))

 bandfft_kpt_in(:)%flag1_is_allocated=0
 bandfft_kpt_in(:)%flag2_is_allocated=0
 bandfft_kpt_in(:)%flag3_is_allocated=0

 do isppol=1,nsppol
   ikg=0
   do ikpt=1,nkpt
     npw_k=npwarr(ikpt)
     istwf_k=istwfk(ikpt)
     nband_k=nband(ikpt+(isppol-1)*nkpt)
     if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me_kpt))cycle
     ikpt_this_proc=mpi_enreg%my_kpttab(ikpt)
     if ((ikpt_this_proc > mkmem).or.(ikpt_this_proc==0)) then
       message = ' this bandfft tab is not allocated !'
       MSG_ERROR(message)
     end if
     if (bandfft_kpt_in(ikpt_this_proc)%flag1_is_allocated==0) then
       ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%gbound    ,(2*mgfft+8,2))
       ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%recvcounts,(nproc_band))
       ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%sendcounts,(nproc_band))
       ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%rdispls   ,(nproc_band))
       ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%sdispls   ,(nproc_band))
       bandfft_kpt_in(ikpt_this_proc)%flag1_is_allocated=1
     end if

!    Initialize various quantities for the reequilibration step
     bandfft_kpt_in(ikpt_this_proc)%have_to_reequilibrate = .false.
     bandfft_kpt_in(ikpt_this_proc)%npw_fft = 0

     call xmpi_allgather(npw_k,recvcounts,comm_band,ierr)
     rdispls(1)=0
     do iproc=2,nproc_band
       rdispls(iproc)=rdispls(iproc-1)+recvcounts(iproc-1)
     end do
     ndatarecv=rdispls(nproc_band)+recvcounts(nproc_band)

     ABI_ALLOCATE(kg_k_gather,(3,ndatarecv))
     ABI_ALLOCATE(kg_k,(3,npw_k))
     kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
     call xmpi_allgatherv(kg_k,3*npw_k,kg_k_gather,3*recvcounts(:),3*rdispls(:),comm_band,ierr)

     sendcounts(:)=npw_k*mpi_enreg%bandpp
     do iproc=1,nproc_band
       sdispls(iproc)=(iproc-1)*npw_k*mpi_enreg%bandpp
     end do

!    ============================================================================
!    Here we compute gbound, as well for istwf_k=1 as for istwf_k=2 and store it
!    ============================================================================
     !MG: Why don't we compute gbound locally by just computing the full G-sphere from ecut
     ABI_ALLOCATE(npw_per_proc,(nproc_fft))
     ABI_ALLOCATE(rdispls_all,(nproc_fft))
     ABI_ALLOCATE(gbound,(2*mgfft+8,2))
     if (mgfft>0) gbound(:,:)=0
     if (istwf_k==1) then
       call xmpi_allgather(ndatarecv,npw_per_proc,mpi_enreg%comm_fft,ierr)
       rdispls_all(1)=0
       do iproc=2,nproc_fft
         rdispls_all(iproc)=rdispls_all(iproc-1)+npw_per_proc(iproc-1)
       end do
       npw_tot=rdispls_all(nproc_fft)+npw_per_proc(nproc_fft)
       ABI_ALLOCATE(kg_k_gather_all,(3,npw_tot))
       call xmpi_allgatherv(kg_k_gather,&
&       3*ndatarecv,kg_k_gather_all,3*npw_per_proc(:),3*rdispls_all,mpi_enreg%comm_fft,ierr)
       if (mgfft>0) then
         call sphereboundary(gbound,istwf_k,kg_k_gather_all,mgfft,npw_tot)
       end if

     else if (istwf_k==2) then

!      ============================================================================
!      In this case, we have to add the opposite values in the kg_k_gather tab
!      before computing gbound
!      ============================================================================

!      Allocation
       ABI_ALLOCATE(tab_proc          ,(ndatarecv))
       ABI_ALLOCATE(sendcounts_sym    ,(nproc_fft))
       ABI_ALLOCATE(sendcounts_sym_all,(nproc_fft*nproc_fft))
       ABI_ALLOCATE(sdispls_sym       ,(nproc_fft))
       ABI_ALLOCATE(recvcounts_sym    ,(nproc_fft))
       ABI_ALLOCATE(recvcounts_sym_tot,(nproc_fft))
       ABI_ALLOCATE(rdispls_sym       ,(nproc_fft))
       ABI_ALLOCATE(sendcounts_sym_loc,(nproc_fft))
       ABI_ALLOCATE(sdispls_sym_loc   ,(nproc_fft))
       ABI_ALLOCATE(recvcounts_sym_loc,(nproc_fft))
       ABI_ALLOCATE(rdispls_sym_loc   ,(nproc_fft))

!      Initialisation
       tab_proc(:)            = 0
       sendcounts_sym(:)      = 0
       sendcounts_sym_all(:)  = 0
       sdispls_sym(:)         = 0
       recvcounts_sym(:)      = 0
       recvcounts_sym_tot(:)  = 0

!      Localisation of kg_k==[0 0 0]
       ABI_ALLOCATE(sum_kg,(ndatarecv))
       idatarecv0    = -1
       ndatasend_sym = ndatarecv
       sum_kg=sum(abs(kg_k_gather),1)
       if (count(sum_kg==0)/=0) then
         do idatarecv=1,ndatarecv
           if (sum_kg(idatarecv)==0) idatarecv0=idatarecv
         end do
         ndatasend_sym = ndatarecv-1
       end if

!      Localisation of the processor where the vector -k2 is
       n2 = mpi_enreg%distribfft%n2_coarse
       do idatarecv=1,ndatarecv
         if (idatarecv/=idatarecv0) then
           tab_proc(idatarecv)   = mpi_enreg%distribfft%tab_fftwf2_distrib(modulo(-kg_k_gather(2,idatarecv),n2) + 1)
         else
           tab_proc(idatarecv) = -1
         end if
       end do

!      Number of values send by the processor to the others
       do iproc=1,nproc_fft
         sendcounts_sym(iproc) = count(tab_proc(:)==(iproc-1))
       end do

!      Save sendcounts_sym for each processor in sendcounts_sym_all
!      knowed by all processors of comm_fft
       rdispls_sym(1)=0
       do iproc=2,nproc_fft
         rdispls_sym(iproc)= nproc_fft*(iproc-1)
       end do
       recvcounts_sym(:)=nproc_fft
       call xmpi_allgatherv(sendcounts_sym(:),nproc_fft,&
&        sendcounts_sym_all(:),recvcounts_sym,rdispls_sym,comm_fft,ierr)

!      Calculation of the dimension of kg_k_gather_sym for each processor
!      recvcounts_sym_tot is knowed by all processors of comm_fft
       call xmpi_sum(sendcounts_sym,recvcounts_sym_tot,nproc_fft,comm_fft,ierr)

!      Dimension of kg_k_gather_sym
       ndatarecv_tot = ndatarecv+recvcounts_sym_tot(me_fft+1)

!      Intialize kg_k_gather_sym
       ABI_ALLOCATE(kg_k_gather_sym,(3,ndatarecv_tot))
       kg_k_gather_sym(:,:)=0
       kg_k_gather_sym(:,1:ndatarecv) = kg_k_gather(:,:)

!      Allocation and initialisation
       ABI_ALLOCATE(kg_k_gather_send,(3,ndatasend_sym))
       kg_k_gather_send(:,:)=0

!      The values are sorted in blocks
       jsendloc=0
       do iproc=1,nproc_fft

!        Position of the beginning of the block
         sdispls_sym(iproc)=jsendloc

!        Creation of the blocks
         do idatarecv=1,ndatarecv
           if (tab_proc(idatarecv)==(iproc-1)) then
             jsendloc=jsendloc+1
             kg_k_gather_send(:,jsendloc)  = -kg_k_gather(:,idatarecv)
           end if
         end do
       end do

!      Position of received data
       rdispls_sym(1)= ndatarecv
       recvcounts_sym(1)= sendcounts_sym_all((me_fft+1))
       do iproc=2,nproc_fft
         rdispls_sym(iproc)    = rdispls_sym(iproc-1) + &
         sendcounts_sym_all((me_fft+1)+(iproc-2)*nproc_fft)
         recvcounts_sym(iproc) = sendcounts_sym_all((me_fft+1)+(iproc-1)*nproc_fft)
       end do

!      Exchange of kg_k
       sendcounts_sym_loc = sendcounts_sym*3
       sdispls_sym_loc    = sdispls_sym   *3
       recvcounts_sym_loc = recvcounts_sym*3
       rdispls_sym_loc    = rdispls_sym   *3
       call xmpi_alltoallv(kg_k_gather_send(:,:),sendcounts_sym_loc,sdispls_sym_loc,&
&       kg_k_gather_sym(:,:) ,recvcounts_sym_loc,rdispls_sym_loc,comm_fft,ierr)

!      Store the following data in the bandfft_kpt_in data_struc
       ikpt_this_proc=mpi_enreg%my_kpttab(ikpt)
       if (bandfft_kpt_in(ikpt_this_proc)%flag3_is_allocated==0) then
         ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%kg_k_gather_sym,(3,ndatarecv_tot))
         ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%rdispls_sym,(nproc_fft))
         ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%recvcounts_sym,(nproc_fft))
         ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%recvcounts_sym_tot,(nproc_fft))
         ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%sdispls_sym,(nproc_fft))
         ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%sendcounts_sym,(nproc_fft))
         ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%sendcounts_sym_all,(nproc_fft*nproc_fft))
         ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%tab_proc,(ndatarecv))
         bandfft_kpt_in(ikpt_this_proc)%flag3_is_allocated=1
       end if

       bandfft_kpt_in(ikpt_this_proc)%idatarecv0           =idatarecv0
       bandfft_kpt_in(ikpt_this_proc)%ndatarecv_tot        =ndatarecv_tot
       bandfft_kpt_in(ikpt_this_proc)%ndatasend_sym        =ndatasend_sym
       bandfft_kpt_in(ikpt_this_proc)%kg_k_gather_sym(:,:) =kg_k_gather_sym(:,:)
       bandfft_kpt_in(ikpt_this_proc)%rdispls_sym(:)       =rdispls_sym(:)
       bandfft_kpt_in(ikpt_this_proc)%recvcounts_sym(:)    =recvcounts_sym(:)
       bandfft_kpt_in(ikpt_this_proc)%recvcounts_sym_tot(:)=recvcounts_sym_tot(:)
       bandfft_kpt_in(ikpt_this_proc)%sdispls_sym(:)       =sdispls_sym(:)
       bandfft_kpt_in(ikpt_this_proc)%sendcounts_sym(:)    =sendcounts_sym(:)
       bandfft_kpt_in(ikpt_this_proc)%sendcounts_sym_all(:)=sendcounts_sym_all(:)
       bandfft_kpt_in(ikpt_this_proc)%tab_proc(:)          =tab_proc(:)

       ABI_DEALLOCATE(tab_proc)
       ABI_DEALLOCATE(sendcounts_sym)
       ABI_DEALLOCATE(sendcounts_sym_all)
       ABI_DEALLOCATE(sdispls_sym)
       ABI_DEALLOCATE(recvcounts_sym)
       ABI_DEALLOCATE(recvcounts_sym_tot)
       ABI_DEALLOCATE(rdispls_sym)
       ABI_DEALLOCATE(kg_k_gather_sym)
       ABI_DEALLOCATE(sendcounts_sym_loc)
       ABI_DEALLOCATE(recvcounts_sym_loc)
       ABI_DEALLOCATE(sdispls_sym_loc)
       ABI_DEALLOCATE(rdispls_sym_loc)
       ABI_DEALLOCATE(kg_k_gather_send)
       ABI_DEALLOCATE(sum_kg)

!      Then compute gbound
       call xmpi_allgather(ndatarecv_tot,npw_per_proc,mpi_enreg%comm_fft,ierr)
       rdispls_all(1)=0
       do iproc=2,nproc_fft
         rdispls_all(iproc)=rdispls_all(iproc-1)+npw_per_proc(iproc-1)
       end do
       npw_tot=rdispls_all(nproc_fft)+npw_per_proc(nproc_fft)
       ABI_ALLOCATE(kg_k_gather_all,(3,npw_tot))
       call xmpi_allgatherv(bandfft_kpt_in(ikpt_this_proc)%kg_k_gather_sym,&
&       3*ndatarecv_tot,kg_k_gather_all,3*npw_per_proc(:),3*rdispls_all,mpi_enreg%comm_fft,ierr)
       if (mgfft>0) then
         call sphereboundary(gbound,istwf_k,kg_k_gather_all,mgfft,npw_tot)
       end if

!      Only calculations with istwfk=1 or 2
     else
       write(message, '(a,i0,a)' )' the value istwfk=',istwf_k,' is not allowed in case of bandfft parallelization!'
       MSG_BUG(message)
     end if
     ABI_DEALLOCATE(kg_k_gather_all)
     ABI_DEALLOCATE(npw_per_proc)
     ABI_DEALLOCATE(rdispls_all)
!    ============================================================================
!    End of gbound
!    ============================================================================
     itest=0
     n2 = mpi_enreg%distribfft%n2_coarse
     do idatarecv=1,ndatarecv
      iproc=mpi_enreg%distribfft%tab_fftwf2_distrib(modulo(kg_k_gather(2,idatarecv),n2)+1)
      if (iproc/=me_fft) itest=itest+1
     end do
     call xmpi_sum(itest,mpi_enreg%comm_fft,ierr)
     bandfft_kpt_in(ikpt_this_proc)%have_to_reequilibrate=(itest>0)
     if(bandfft_kpt_in(ikpt_this_proc)%have_to_reequilibrate) then
       n2 = mpi_enreg%distribfft%n2_coarse
       sendcounts_fft(:) = zero
       recvcounts_fft(:) = zero
       senddisp_fft(:) = zero
       recvdisp_fft(:) = zero
       do idatarecv = 1 ,ndatarecv
          iproc = mpi_enreg%distribfft%tab_fftwf2_distrib(modulo(kg_k_gather(2,idatarecv),n2) + 1)
          sendcounts_fft(iproc + 1) =  sendcounts_fft(iproc + 1)  + 1
       end do
       call xmpi_alltoall(sendcounts_fft,1,recvcounts_fft,1,mpi_enreg%comm_fft,ierr)
       do iproc =2, nproc_fft
          senddisp_fft(iproc) =  senddisp_fft(iproc - 1)  + sendcounts_fft(iproc-1)
          recvdisp_fft(iproc) =  recvdisp_fft(iproc - 1)  + recvcounts_fft(iproc-1)
       end do
       npw_fft = recvdisp_fft(nproc_fft) + recvcounts_fft(nproc_fft) ! nb plane wave for fourwf call
       ABI_ALLOCATE(buff_kg,(3,ndatarecv)) ! for sorting kg_k
       ABI_ALLOCATE(kg_k_fft,(3,npw_fft))
       ABI_ALLOCATE(indices_pw_fft,(ndatarecv))
       !filling of sorted send buffers
       sendcounts_fft(:) = zero
       do idatarecv = 1 ,ndatarecv
          iproc = mpi_enreg%distribfft%tab_fftwf2_distrib(modulo(kg_k_gather(2,idatarecv),n2) + 1)
          sendcounts_fft(iproc + 1) =  sendcounts_fft(iproc + 1)  + 1
          indices_pw_fft(idatarecv) =  senddisp_fft(iproc+1) + sendcounts_fft(iproc+1)
          buff_kg(1:3,indices_pw_fft(idatarecv))  =  kg_k_gather(1:3,idatarecv)
       end do

       call xmpi_alltoallv(buff_kg, 3*sendcounts_fft, 3*senddisp_fft, &
&            kg_k_fft,3*recvcounts_fft, 3*recvdisp_fft, mpi_enreg%comm_fft,ierr)

       ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%kg_k_fft, (3,npw_fft) )
       ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%indices_pw_fft, (ndatarecv))
       ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%sendcount_fft, (nproc_fft))
       ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%senddisp_fft, (nproc_fft))
       ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%recvcount_fft, (nproc_fft))
       ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%recvdisp_fft, (nproc_fft))
       bandfft_kpt_in(ikpt_this_proc)%npw_fft                 = npw_fft
       bandfft_kpt_in(ikpt_this_proc)%indices_pw_fft(:) = indices_pw_fft(:)
       bandfft_kpt_in(ikpt_this_proc)%sendcount_fft (:) = sendcounts_fft (:)
       bandfft_kpt_in(ikpt_this_proc)%senddisp_fft(:)   = senddisp_fft(:)
       bandfft_kpt_in(ikpt_this_proc)%recvcount_fft(:)  = recvcounts_fft(:)
       bandfft_kpt_in(ikpt_this_proc)%recvdisp_fft(:)   = recvdisp_fft(:)
       bandfft_kpt_in(ikpt_this_proc)%kg_k_fft(:,:)     = kg_k_fft(:,:)
       ABI_DEALLOCATE(buff_kg )
       ABI_DEALLOCATE(kg_k_fft)
       ABI_DEALLOCATE(indices_pw_fft)
     end if
!    Tabs which are common to istwf_k=1 and 2
     if (.not. allocated(bandfft_kpt_in(ikpt_this_proc)%kg_k_gather)) then
       ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%kg_k_gather,(3,ndatarecv))
     end if
     bandfft_kpt_in(ikpt_this_proc)%recvcounts(:)   =recvcounts(:)
     bandfft_kpt_in(ikpt_this_proc)%sendcounts(:)   =sendcounts(:)
     bandfft_kpt_in(ikpt_this_proc)%rdispls(:)      =rdispls(:)
     bandfft_kpt_in(ikpt_this_proc)%sdispls(:)      =sdispls(:)
     bandfft_kpt_in(ikpt_this_proc)%gbound(:,:)     =gbound(:,:)
     bandfft_kpt_in(ikpt_this_proc)%kg_k_gather(:,:)=kg_k_gather(:,:)
     bandfft_kpt_in(ikpt_this_proc)%ndatarecv       =ndatarecv
     bandfft_kpt_in(ikpt_this_proc)%istwf_k         =istwf_k
     bandfft_kpt_in(ikpt_this_proc)%npw_tot         =npw_tot
     ABI_DEALLOCATE(kg_k_gather)
     ABI_DEALLOCATE(kg_k)
     ABI_DEALLOCATE(gbound)

     ikg=ikg+npw_k
   end do
 end do
 ABI_DEALLOCATE(recvcounts)
 ABI_DEALLOCATE(sendcounts)
 ABI_DEALLOCATE(rdispls)
 ABI_DEALLOCATE(sdispls)
 ABI_DEALLOCATE(sendcounts_fft)
 ABI_DEALLOCATE(senddisp_fft)
 ABI_DEALLOCATE(recvcounts_fft)
 ABI_DEALLOCATE(recvdisp_fft)

!=============================================================================
!End of computation and storage of the bandfft_kpt(ikpt) data_struc
!=============================================================================

end subroutine init1_bandfft_kpt
!!***
!----------------------------------------------------------------------

!!****f* m_bandfft_kpt/init2_bandfft_kpt
!! NAME
!!  init2_bandfft_kpt
!!
!! FUNCTION
!!  Init part of scalars and pointers in a bandfft_kpt datastructure
!!
!! INPUTS
!!
!!  dimffnl=second dimension of ffnl (1+number of derivatives)
!!  ffnl_gather(ndatarecv,dimffnl,lmnmax,ntypat)=nonlocal form factors on basis sphere.
!!  kinpw_gather(:)=(modified) kinetic energy for each plane wave (Hartree)
!!  kpg_k_gather(ndatarecv,nkpg)=k+G vector for a given k point
!!  lmnmax=if useylm=1, max number of (l,m,n) comp. over all type of psps
!!        =if useylm=0, max number of (l,n)   comp. over all type of psps
!!  matblk=dimension of the array ph3d
!!  mkmem =number of k points which can fit in memory; set to 0 if use disk
!!  ndatarecv= dimension of the arrays
!!  nkpg=second dimension of kpg_k (0 if useylm=0)
!!  ntypat=number of types of atoms in unit cell.
!!  option=1 if gbound have to be updated
!!         0 otherwise
!!  ph3d_gather(2,ndatarecv,matblk)=3-dim structure factors, for each atom and plane wave.

!! OUTPUT
!!
!! SIDE EFFECTS
!!
!! PARENTS
!!      prep_bandfft_tabs
!!
!! CHILDREN
!!
!! SOURCE

subroutine init2_bandfft_kpt(bandfft_kpt_in,dimffnl,ffnl_gather,ikpt_this_proc,kinpw_gather,kpg_k_gather,lmnmax,matblk,&
&                   mkmem,ndatarecv,nkpg,ntypat,option,ph3d_gather)


!This section has been created automatically by the script Abilint (TD).
!Do not modify the following lines by hand.
#undef ABI_FUNC
#define ABI_FUNC 'init2_bandfft_kpt'
!End of the abilint section

 implicit none

!Arguments -------------------------------
 integer, intent(in)    :: dimffnl,ikpt_this_proc,lmnmax,matblk,mkmem,ndatarecv,nkpg,ntypat,option
 type(bandfft_kpt_type), intent(inout) :: bandfft_kpt_in (mkmem)
!Local variables-------------------------------

 real(dp),intent(in) :: ffnl_gather(ndatarecv,dimffnl,lmnmax,ntypat)
 real(dp),intent(in) :: kinpw_gather(:)
 real(dp),intent(in) :: kpg_k_gather(ndatarecv,nkpg),ph3d_gather(2,ndatarecv,matblk)

! *********************************************************************

 if (bandfft_kpt_in(ikpt_this_proc)%flag2_is_allocated==1) then
   ABI_DEALLOCATE(bandfft_kpt_in(ikpt_this_proc)%ffnl_gather)
   ABI_DEALLOCATE(bandfft_kpt_in(ikpt_this_proc)%ph3d_gather)
   if (option==1) then
     ABI_DEALLOCATE(bandfft_kpt_in(ikpt_this_proc)%kinpw_gather)
   end if
   if (allocated(bandfft_kpt_in(ikpt_this_proc)%kpg_k_gather)) then
     ABI_DEALLOCATE(bandfft_kpt_in(ikpt_this_proc)%kpg_k_gather)
   end if
 end if
 ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%ffnl_gather,(ndatarecv,dimffnl,lmnmax,ntypat))
 ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%ph3d_gather,(2,ndatarecv,matblk))
 bandfft_kpt_in(ikpt_this_proc)%ffnl_gather(:,:,:,:)=ffnl_gather(:,:,:,:)
 bandfft_kpt_in(ikpt_this_proc)%ph3d_gather(:,:,:)  =ph3d_gather(:,:,:)
 if (option==1) then
   ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%kinpw_gather,(ndatarecv))
   bandfft_kpt_in(ikpt_this_proc)%kinpw_gather(:)    =kinpw_gather(:)
 end if
 ABI_ALLOCATE(bandfft_kpt_in(ikpt_this_proc)%kpg_k_gather,(ndatarecv,nkpg))
 bandfft_kpt_in(ikpt_this_proc)%kpg_k_gather(:,:)  =kpg_k_gather(:,:)
 bandfft_kpt_in(ikpt_this_proc)%flag2_is_allocated=1


end subroutine init2_bandfft_kpt
!!***

!----------------------------------------------------------------------

!!****f* m_bandfft_kpt/destroy_bandfft_kpt
!! NAME
!!  destroy_bandfft_kpt
!!
!! FUNCTION
!!  Clean and destroy a bandfft_kpt datastructure
!!
!! INPUTS
!!
!! OUTPUT
!!
!! SIDE EFFECTS
!!
!!
!! PARENTS
!!      gstate
!!
!! CHILDREN
!!
!! SOURCE

subroutine destroy_bandfft_kpt(bandfft_kpt_dum,mpi_enreg)


!This section has been created automatically by the script Abilint (TD).
!Do not modify the following lines by hand.
#undef ABI_FUNC
#define ABI_FUNC 'destroy_bandfft_kpt'
 use interfaces_32_util
!End of the abilint section

 implicit none


!Arguments ------------------------------------
 type(bandfft_kpt_type), pointer :: bandfft_kpt_dum (:)
 type(MPI_type), intent(inout) :: mpi_enreg
!Local variables-------------------------------
 integer :: ikpt_this_proc,isppol,ikpt,mkmem,nband,nkpt,nsppol
 character(len=500) :: msg

! ***********************************************************************

 if (xmpi_paral==0) return

 if (associated(bandfft_kpt_dum)) then
   mkmem =size(bandfft_kpt_dum)
   nkpt=size(mpi_enreg%proc_distrb,1)
   nband=size(mpi_enreg%proc_distrb,2)
   nsppol=size(mpi_enreg%proc_distrb,3)
   if (nsppol==0.or.nkpt==0) then
     msg=' mpi_enreg%proc_distrb should be allocated !'
     MSG_BUG(msg)
   end if
   nkpt=size(mpi_enreg%my_kpttab)
   if (nkpt==0) then
     msg=' mpi_enreg%my_kpttab should be allocated !'
     MSG_BUG(msg)
   end if
   do isppol=1,nsppol
     do ikpt=1,nkpt
       if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband,isppol,mpi_enreg%me_kpt)) cycle
       ikpt_this_proc=mpi_enreg%my_kpttab(ikpt)
       if ((ikpt_this_proc>mkmem) .or.(ikpt_this_proc<=0)) then
         msg=' The bandfft tab cannot be deallocated !'
         MSG_BUG(msg)
       end if
       if (allocated(bandfft_kpt_dum(ikpt_this_proc)%kg_k_gather)) then
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%kg_k_gather)
       end if
       if (bandfft_kpt_dum(ikpt_this_proc)%flag1_is_allocated==1) then
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%gbound)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%recvcounts)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%sendcounts)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%rdispls)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%sdispls)
         bandfft_kpt_dum(ikpt_this_proc)%flag1_is_allocated=0
       end if
       if (bandfft_kpt_dum(ikpt_this_proc)%flag2_is_allocated==1) then
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%ffnl_gather)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%kinpw_gather)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%kpg_k_gather)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%ph3d_gather)
         bandfft_kpt_dum(ikpt_this_proc)%flag2_is_allocated=0
       end if
       if (bandfft_kpt_dum(ikpt_this_proc)%flag3_is_allocated==1) then
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%kg_k_gather_sym)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%rdispls_sym)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%recvcounts_sym)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%recvcounts_sym_tot)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%sdispls_sym)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%sendcounts_sym)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%sendcounts_sym_all)
         ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%tab_proc)
         bandfft_kpt_dum(ikpt_this_proc)%flag3_is_allocated=0
       end if
       if(bandfft_kpt_dum(ikpt_this_proc)%have_to_reequilibrate) then
          ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%indices_pw_fft)
          ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%sendcount_fft)
          ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%senddisp_fft)
          ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%recvcount_fft)
          ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%recvdisp_fft)
          ABI_DEALLOCATE(bandfft_kpt_dum(ikpt_this_proc)%kg_k_fft)
          bandfft_kpt_dum(ikpt_this_proc)%npw_fft = 0
          bandfft_kpt_dum(ikpt_this_proc)%have_to_reequilibrate=.false.
       endif
     end do
   end do
   ABI_DATATYPE_DEALLOCATE(bandfft_kpt_dum)
   nullify(bandfft_kpt_dum)
 end if

end subroutine destroy_bandfft_kpt
!!***

!!****f* m_bandfft_kpt/copy_bandfft_kpt
!! NAME
!!  copy_bandfft_kpt
!!
!! FUNCTION
!!  Copy a bandfft_kpt datastructure into another
!!
!! INPUTS
!!  bandfft_kpt_in=<type(bandfft_kpt_type)>=input bandfft_kpt datastructure
!!
!! OUTPUT
!!  bandfft_kpt_out=<type(bandfft_kpt_type)>=output bandfft_kpt datastructure
!!
!! PARENTS
!!
!! CHILDREN
!!
!! SOURCE

subroutine copy_bandfft_kpt(bandfft_kpt_in,bandfft_kpt_out,mpi_enreg1,opt_bandfft)


!This section has been created automatically by the script Abilint (TD).
!Do not modify the following lines by hand.
#undef ABI_FUNC
#define ABI_FUNC 'copy_bandfft_kpt'
 use interfaces_32_util
!End of the abilint section

 implicit none

!Arguments ------------------------------------
!scalars
 integer,intent(in) :: opt_bandfft
 type(bandfft_kpt_type),pointer :: bandfft_kpt_in(:)
 type(bandfft_kpt_type),pointer :: bandfft_kpt_out(:)
 type(MPI_type),intent(inout) :: mpi_enreg1

!Local variables-------------------------------
!scalars
 integer :: ikpt,isppol,jkpt

! *********************************************************************

!Optional pointers
 if (opt_bandfft==0) then
   nullify(bandfft_kpt_out)
 else if (opt_bandfft==1) then
   if (associated(bandfft_kpt_in)) then
     ABI_DATATYPE_ALLOCATE(bandfft_kpt_out,(size(bandfft_kpt_in)))
     do isppol=1,size(mpi_enreg1%proc_distrb,3)
       do ikpt=1,size(mpi_enreg1%proc_distrb,1)
         sz1=size(mpi_enreg1%proc_distrb,2)
         if(proc_distrb_cycle(mpi_enreg1%proc_distrb,ikpt,1,sz1,isppol,mpi_enreg1%me_kpt)) then
           cycle
         end if
         jkpt=mpi_enreg1%my_kpttab(ikpt)
!          if (associated(bandfft_kpt_in(jkpt)%ind_kg_mpi_to_seq)) then
!            sz1=size(bandfft_kpt_in(jkpt)%ind_kg_mpi_to_seq)
!            ABI_ALLOCATE(bandfft_kpt_out(jkpt)%ind_kg_mpi_to_seq,(sz1))
!            bandfft_kpt_out(jkpt)%ind_kg_mpi_to_seq= &
! &           bandfft_kpt_in(jkpt)%ind_kg_mpi_to_seq
!          else
!            nullify(bandfft_kpt_out(jkpt)%ind_kg_mpi_to_seq)
!          end if
         if (allocated(bandfft_kpt_in(jkpt)%kg_k_gather)) then
           sz1=size(bandfft_kpt_in(jkpt)%kg_k_gather,1)
           sz2=size(bandfft_kpt_in(jkpt)%kg_k_gather,2)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%kg_k_gather,(sz1,sz2))
           bandfft_kpt_out(jkpt)%kg_k_gather= &
&           bandfft_kpt_in(jkpt)%kg_k_gather
         end if
         bandfft_kpt_out(jkpt)%flag1_is_allocated=bandfft_kpt_in(jkpt)%flag1_is_allocated
         if (allocated(bandfft_kpt_in(jkpt)%gbound)) then
           sz1=size(bandfft_kpt_in(jkpt)%gbound,1)
           sz2=size(bandfft_kpt_in(jkpt)%gbound,2)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%gbound,(sz1,sz2))
           bandfft_kpt_out(jkpt)%gbound= &
&           bandfft_kpt_in(jkpt)%gbound
         end if
         if (allocated(bandfft_kpt_in(jkpt)%recvcounts)) then
           sz1=size(bandfft_kpt_in(jkpt)%recvcounts)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%recvcounts,(sz1))
           bandfft_kpt_out(jkpt)%recvcounts= &
&           bandfft_kpt_in(jkpt)%recvcounts
         end if
         if (allocated(bandfft_kpt_in(jkpt)%sendcounts)) then
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%sendcounts,(size(bandfft_kpt_in(jkpt)%sendcounts)))
           bandfft_kpt_out(jkpt)%sendcounts= &
&           bandfft_kpt_in(jkpt)%sendcounts
         end if
         if (allocated(bandfft_kpt_in(jkpt)%rdispls)) then
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%rdispls,(size(bandfft_kpt_in(jkpt)%rdispls)))
           bandfft_kpt_out(jkpt)%rdispls= &
&           bandfft_kpt_in(jkpt)%rdispls
         end if
         if (allocated(bandfft_kpt_in(jkpt)%sdispls)) then
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%sdispls,(size(bandfft_kpt_in(jkpt)%sdispls)))
           bandfft_kpt_out(jkpt)%sdispls= &
&           bandfft_kpt_in(jkpt)%sdispls
         end if
         bandfft_kpt_out(jkpt)%flag2_is_allocated=bandfft_kpt_in(jkpt)%flag2_is_allocated
         if (allocated(bandfft_kpt_in(jkpt)%ffnl_gather)) then
           sz1=size(bandfft_kpt_in(jkpt)%ffnl_gather,1)
           sz2=size(bandfft_kpt_in(jkpt)%ffnl_gather,2)
           sz3=size(bandfft_kpt_in(jkpt)%ffnl_gather,3)
           sz4=size(bandfft_kpt_in(jkpt)%ffnl_gather,4)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%ffnl_gather,(sz1,sz2,sz3,sz4))
           bandfft_kpt_out(jkpt)%ffnl_gather= &
&           bandfft_kpt_in(jkpt)%ffnl_gather
         end if
         if (allocated(bandfft_kpt_in(jkpt)%kinpw_gather)) then
           sz1=size(bandfft_kpt_in(jkpt)%kinpw_gather)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%kinpw_gather,(sz1))
           bandfft_kpt_out(jkpt)%kinpw_gather= &
&           bandfft_kpt_in(jkpt)%kinpw_gather
         end if
         if (allocated(bandfft_kpt_in(jkpt)%ph3d_gather)) then
           sz1=size(bandfft_kpt_in(jkpt)%ph3d_gather,1)
           sz2=size(bandfft_kpt_in(jkpt)%ph3d_gather,2)
           sz3=size(bandfft_kpt_in(jkpt)%ph3d_gather,3)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%ph3d_gather,(sz1,sz2,sz3))
           bandfft_kpt_out(jkpt)%ph3d_gather= &
&           bandfft_kpt_in(jkpt)%ph3d_gather
         end if
         if (allocated(bandfft_kpt_in(jkpt)%kpg_k_gather)) then
           sz1=size(bandfft_kpt_in(jkpt)%kpg_k_gather,1)
           sz2=size(bandfft_kpt_in(jkpt)%kpg_k_gather,2)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%kpg_k_gather,(sz1,sz2))
           bandfft_kpt_out(jkpt)%kpg_k_gather= &
&           bandfft_kpt_in(jkpt)%kpg_k_gather
         end if
         bandfft_kpt_out(jkpt)%flag3_is_allocated=bandfft_kpt_in(jkpt)%flag3_is_allocated
         if (allocated(bandfft_kpt_in(jkpt)%kg_k_gather_sym)) then
           sz1=size(bandfft_kpt_in(jkpt)%kg_k_gather_sym,1)
           sz2=size(bandfft_kpt_in(jkpt)%kg_k_gather_sym,2)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%kg_k_gather_sym,(sz1,sz2))
           bandfft_kpt_out(jkpt)%kg_k_gather_sym= &
&           bandfft_kpt_in(jkpt)%kg_k_gather_sym
         end if
         if (allocated(bandfft_kpt_in(jkpt)%rdispls_sym)) then
           sz1=size(bandfft_kpt_in(jkpt)%rdispls_sym)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%rdispls_sym,(sz1))
           bandfft_kpt_out(jkpt)%rdispls_sym= &
&           bandfft_kpt_in(jkpt)%rdispls_sym
         end if
         if (allocated(bandfft_kpt_in(jkpt)%recvcounts_sym)) then
           sz1=size(bandfft_kpt_in(jkpt)%recvcounts_sym)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%recvcounts_sym,(sz1))
           bandfft_kpt_out(jkpt)%recvcounts_sym= &
&           bandfft_kpt_in(jkpt)%recvcounts_sym
         end if
         if (allocated(bandfft_kpt_in(jkpt)%recvcounts_sym_tot)) then
           sz1=size(bandfft_kpt_in(jkpt)%recvcounts_sym_tot)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%recvcounts_sym_tot,(sz1))
           bandfft_kpt_out(jkpt)%recvcounts_sym_tot= &
&           bandfft_kpt_in(jkpt)%recvcounts_sym_tot
         end if
         if (allocated(bandfft_kpt_in(jkpt)%sdispls_sym)) then
           sz1=size(bandfft_kpt_in(jkpt)%sdispls_sym)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%sdispls_sym,(sz1))
           bandfft_kpt_out(jkpt)%sdispls_sym= &
&           bandfft_kpt_in(jkpt)%sdispls_sym
         end if
         if (allocated(bandfft_kpt_in(jkpt)%sendcounts_sym)) then
           sz1=size(bandfft_kpt_in(jkpt)%sendcounts_sym)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%sendcounts_sym,(sz1))
           bandfft_kpt_out(jkpt)%sendcounts_sym= &
&           bandfft_kpt_in(jkpt)%sendcounts_sym
         end if
         if (allocated(bandfft_kpt_in(jkpt)%sendcounts_sym_all)) then
           sz1=size(bandfft_kpt_in(jkpt)%sendcounts_sym_all)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%sendcounts_sym_all,(sz1))
           bandfft_kpt_out(jkpt)%sendcounts_sym_all= &
&           bandfft_kpt_in(jkpt)%sendcounts_sym_all
         end if
         if (allocated(bandfft_kpt_in(jkpt)%tab_proc)) then
           sz1=size(bandfft_kpt_in(jkpt)%tab_proc)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%tab_proc,(sz1))
           bandfft_kpt_out(jkpt)%tab_proc= &
           bandfft_kpt_in(jkpt)%tab_proc
         end if
         if (bandfft_kpt_in(jkpt)%have_to_reequilibrate) then
           bandfft_kpt_out(jkpt)%have_to_reequilibrate = .true.
           bandfft_kpt_out(jkpt)%npw_fft = bandfft_kpt_in(jkpt)%npw_fft
           sz1=size(bandfft_kpt_in(jkpt)%indices_pw_fft)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%indices_pw_fft,(sz1))
           bandfft_kpt_out(jkpt)%indices_pw_fft=bandfft_kpt_in(jkpt)%indices_pw_fft
           sz1=size(bandfft_kpt_in(jkpt)%sendcount_fft)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%sendcount_fft,(sz1))
           bandfft_kpt_out(jkpt)%sendcount_fft=bandfft_kpt_in(jkpt)%sendcount_fft
           sz1=size(bandfft_kpt_in(jkpt)%senddisp_fft)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%senddisp_fft,(sz1))
           bandfft_kpt_out(jkpt)%senddisp_fft=bandfft_kpt_in(jkpt)%senddisp_fft
           sz1=size(bandfft_kpt_in(jkpt)%recvcount_fft)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%recvcount_fft,(sz1))
           bandfft_kpt_out(jkpt)%recvcount_fft=bandfft_kpt_in(jkpt)%recvcount_fft
           sz1=size(bandfft_kpt_in(jkpt)%recvdisp_fft)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%recvdisp_fft,(sz1))
           bandfft_kpt_out(jkpt)%recvdisp_fft=bandfft_kpt_in(jkpt)%recvdisp_fft
           sz1=size(bandfft_kpt_in(jkpt)%kg_k_fft,1)
           sz2=size(bandfft_kpt_in(jkpt)%kg_k_fft,2)
           ABI_ALLOCATE(bandfft_kpt_out(jkpt)%kg_k_fft,(sz1,sz2))
           bandfft_kpt_out(jkpt)%kg_k_fft=bandfft_kpt_in(jkpt)%kg_k_fft
         end if
       end do
     end do
   end if
 end if


end subroutine copy_bandfft_kpt
!!***

END MODULE m_bandfft_kpt
!!***
