LCOV - code coverage report
Current view: top level - src/66_wfs - m_wfd.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 65.2 % 1837 1198
Test Date: 2026-09-19 15:24:51 Functions: 62.0 % 79 49

            Line data    Source code
       1              : !****m* ABINIT/m_wfd
       2              : !! NAME
       3              : !!  m_wfd
       4              : !!
       5              : !! FUNCTION
       6              : !!  This module contains the declaration of the wfd_t object.
       7              : !!  The wfd_t is a container of Bloch states (wave_t).
       8              : !!  It provides a high-level API to perform FFT transforms G --> R, compute PAW projections, etc.
       9              : !!
      10              : !! COPYRIGHT
      11              : !! Copyright (C) 2008-2026 ABINIT group (MG)
      12              : !! This file is distributed under the terms of the
      13              : !! GNU General Public License, see ~abinit/COPYING
      14              : !! or http://www.gnu.org/copyleft/gpl.txt .
      15              : !!
      16              : !! SOURCE
      17              : 
      18              : #if defined HAVE_CONFIG_H
      19              : #include "config.h"
      20              : #endif
      21              : 
      22              : #include "abi_common.h"
      23              : 
      24              : module m_wfd
      25              : 
      26              :  use, intrinsic :: iso_c_binding
      27              :  use defs_basis
      28              :  use m_abicore
      29              :  use m_xmpi
      30              :  use m_copy
      31              :  use m_errors
      32              :  use m_crystal
      33              :  use m_wfk
      34              :  use m_hdr
      35              :  use m_cgtools
      36              :  use m_ebands
      37              : 
      38              :  use defs_datatypes,   only : pseudopotential_type
      39              :  use defs_abitypes,    only : mpi_type
      40              :  use m_gwdefs,         only : one_gw
      41              :  use m_time,           only : cwtime, cwtime_report, timab
      42              :  use m_fstrings,       only : toupper, firstchar, int2char10, sjoin, itoa, strcat, itoa, yesno, ltoa, ktoa, ftoa
      43              :  use m_io_tools,       only : get_unit, iomode_from_fname, iomode2str, open_file
      44              :  use m_numeric_tools,  only : imin_loc, list2blocks, bool2index
      45              :  use m_hide_blas,      only : xcopy, xdotc
      46              :  use m_pptools,        only : printxsf
      47              :  use m_cgtk,           only : cgtk_change_gsphere, cgtk_rotate
      48              :  use m_fftcore,        only : print_ngfft, kgindex, sphereboundary, ngfft_seq
      49              :  use m_fft_mesh,       only : rotate_fft_mesh, calc_ceikr, check_rot_fft
      50              :  use m_fft,            only : fft_ug
      51              :  use m_kg,             only : getph, ph1d3d, mkkpg
      52              :  use m_gsphere,        only : kg_map, make_istwfk_table
      53              :  use m_fftcore,        only : kpgsph, get_kg
      54              :  use m_mpinfo,         only : nullify_mpi_enreg, destroy_mpi_enreg, copy_mpi_enreg, initmpi_seq
      55              :  use m_bz_mesh,        only : kmesh_t
      56              :  use m_pawrad,         only : pawrad_type
      57              :  use m_pawtab,         only : pawtab_type, pawtab_get_lsize
      58              :  use m_pawfgrtab,      only : pawfgrtab_type, pawfgrtab_init, pawfgrtab_free, pawfgrtab_print
      59              :  use m_pawcprj,        only : pawcprj_type, pawcprj_alloc, pawcprj_free, pawcprj_copy, paw_overlap
      60              :  use m_paw_pwaves_lmn, only : paw_pwaves_lmn_t, paw_pwaves_lmn_init, paw_pwaves_lmn_free
      61              :  use m_pawrhoij,       only : pawrhoij_type, pawrhoij_mpisum_unpacked, pawrhoij_print_rhoij
      62              :  use m_paw_nhat,       only : nhatgrid
      63              :  use m_paw_occupancies,only : pawaccrhoij
      64              :  use m_iterators,      only : iter2_t, iter_yield, iter_len, iter_free, iter_push, iter_alloc
      65              :  use m_spacepar,       only : symrhg, irrzg
      66              :  use m_initylmg,       only : initylmg
      67              :  use m_mkffnl,         only : mkffnl
      68              :  use m_cgprj,          only : getcprj
      69              :  use m_hamiltonian,    only : gs_hamiltonian_type
      70              :  use m_nonlop,         only : nonlop
      71              :  use m_pstat,          only : pstat_proc
      72              : 
      73              :  implicit none
      74              : 
      75              :  private
      76              : !!***
      77              : 
      78              :  ! Flags giving the status of the local %ug, %ur %cprj buffers.
      79              :  ! Use 1-byte int to save memory as much as possible.
      80              :  integer(c_int8_t),public,parameter :: WFD_NOWAVE    = 0
      81              :  integer(c_int8_t),public,parameter :: WFD_ALLOCATED = 1
      82              :  integer(c_int8_t),public,parameter :: WFD_STORED    = 2
      83              : 
      84              :  integer(c_int8_t),public,parameter :: CPR_RANDOM    = 1
      85              :  integer(c_int8_t),public,parameter :: CPR_SORTED    = 2
      86              : 
      87              : !----------------------------------------------------------------------
      88              : 
      89              : !!****t* m_wfd/kdata_t
      90              : !! NAME
      91              : !! kdata_t
      92              : !!
      93              : !! FUNCTION
      94              : !! Datatype storing k-dependent quantities and tables needed
      95              : !! for performing the zero-padded FFT of wavefunctions.
      96              : !!
      97              : !! SOURCE
      98              : 
      99              :  type,public :: kdata_t
     100              : 
     101              :    logical :: use_fnl_dir0der0 = .False.
     102              :    ! Decide if we need to use fnl_dir0der0.
     103              : 
     104              :    integer :: istwfk = -1
     105              :    ! Storage mode for this k point.
     106              : 
     107              :    integer :: npw = -1
     108              :    ! Number of plane-waves for this k-point.
     109              : 
     110              :    integer :: useylm = -1
     111              :    ! 1 if nonlocal part is applied using real spherical Harmonics. 0 for Legendre polynomial.
     112              : 
     113              :    integer :: has_ylm = -1
     114              :    ! 0 if ylm is not used.
     115              :    ! 1 if ylm is allocated.
     116              :    ! 2 if ylm is already computed.
     117              : 
     118              :    integer,allocatable :: kg_k(:,:)
     119              :    ! kg_k(3,npw)
     120              :    ! G vector coordinates in reduced coordinates.
     121              : 
     122              :    integer,allocatable :: gbound(:,:)
     123              :    ! gbound(2*mgfft+8,2))
     124              :    ! The boundary of the basis sphere of G vectors at a given k point.
     125              :    ! for use in improved zero padding of FFTs in 3 dimensions.
     126              : 
     127              :    real(dp),allocatable :: ph3d(:,:,:)
     128              :    ! ph3d(2, npw, natom)
     129              :    ! 3-dim structure factors, for each atom and each plane wave.
     130              :    ! Available only for PAW or use_fnl_dir0der0 is true.
     131              : 
     132              :    real(dp),allocatable :: phkxred(:,:)
     133              :    ! phkxred(2,natom))
     134              :    ! e^{ik.Ra} for each atom. Packed according to the atom type (atindx).
     135              : 
     136              :    real(dp),allocatable :: fnl_dir0der0(:,:,:,:)
     137              :    ! fnl_dir0der0(npw, 1, lmnmax,ntypat)
     138              :    ! nonlocal form factors. Computed only if usepaw == 1 or use_fnl_dir0der0 is true.
     139              :    ! fnl(k+G).ylm(k+G) if PAW
     140              :    ! f_ln(k+G)/|k+G|^l if NC
     141              : 
     142              :    real(dp),allocatable :: ylm(:,:)
     143              :    ! ylm(npw, mpsang**2*useylm)
     144              :    ! Real spherical harmonics for each k+G
     145              : 
     146              :  contains
     147              : 
     148              :    procedure :: init => kdata_init
     149              :    ! Init object
     150              : 
     151              :    procedure :: free => kdata_free_0D
     152              :    ! Free memory
     153              : 
     154              :  end type kdata_t
     155              : 
     156              :  interface kdata_free
     157              :    module procedure kdata_free_0D
     158              :    module procedure kdata_free_1D
     159              :  end interface kdata_free
     160              : 
     161              :  public :: kdata_copy
     162              : 
     163              :  interface kdata_copy
     164              :    module procedure copy_kdata_0D
     165              :    module procedure copy_kdata_1D
     166              :  end interface kdata_copy
     167              : !!***
     168              : 
     169              : !----------------------------------------------------------------------
     170              : 
     171              : !!****t* m_wfd/wave_t
     172              : !! NAME
     173              : !! wave_t
     174              : !!
     175              : !! FUNCTION
     176              : !!  Object storing a single wavefunction in G-space and, optionally, its r-space representation.
     177              : !!
     178              : !! SOURCE
     179              : 
     180              :  type, public :: wave_t
     181              : 
     182              :   !! integer :: cplex
     183              :   ! 1 for real wavefunctions u(r)
     184              :   ! 2 for complex wavefunctions u(r).
     185              :   ! At gamma we always have real u(r) provided that time-reversal can be used.
     186              :   ! In systems with both time-reversal and spatial inversion, wavefunctions can be chosen to be real.
     187              :   ! One might use this to reduce memory in wave_t.
     188              : 
     189              :   integer(c_int8_t) :: has_ug = WFD_NOWAVE
     190              :   ! Flag giving the status of ug.
     191              : 
     192              :   integer(c_int8_t) :: has_ur = WFD_NOWAVE
     193              :   ! Flag giving the status of ur.
     194              : 
     195              :   integer(c_int8_t) :: has_cprj = WFD_NOWAVE
     196              :   ! Flag giving the status of cprj.
     197              : 
     198              :   integer(c_int8_t) :: cprj_order = CPR_RANDOM
     199              :   ! Flag defining whether cprj are sorted by atom type or ordered according
     200              :   ! to the typat variable used in the input file.
     201              : 
     202              :   complex(gwp),allocatable :: ug(:)
     203              :   ! ug(npw_k*nspinor)
     204              :   ! The periodic part of the Bloch wavefunction in G-space.
     205              : 
     206              :   complex(gwp),allocatable :: ur(:)
     207              :   ! ur(nfft*nspinor)
     208              :   ! The periodic part of the Bloch wavefunction in real space.
     209              : 
     210              :   type(pawcprj_type),allocatable :: Cprj(:,:)
     211              :   ! Cprj(natom,nspinor)
     212              :   ! PAW projected wave function <Proj_i|Cnk> with all NL projectors.
     213              : 
     214              :   contains
     215              : 
     216              :   procedure :: free => wave_free
     217              :   ! Free memory
     218              : 
     219              :   procedure :: copy => wave_copy
     220              :   ! Copy object.
     221              : 
     222              :  end type wave_t
     223              : 
     224              :  public :: wave_init
     225              : !!***
     226              : 
     227              : !----------------------------------------------------------------------
     228              : 
     229              : !!****t* m_wfd/kpt_store_t
     230              : !! NAME
     231              : !!  kpt_store_t
     232              : !!
     233              : !! FUNCTION
     234              : !!  Used to build ragged arrays of wave_t in compact form.
     235              : !!
     236              : !! SOURCE
     237              : 
     238              :  type :: kpt_store_t
     239              :    type(wave_t),allocatable :: b(:)
     240              :  end type kpt_store_t
     241              : !!***
     242              : 
     243              : !----------------------------------------------------------------------
     244              : 
     245              : !!****t* m_wfd/spin_store_t
     246              : !! NAME
     247              : !!  spin_store_t
     248              : !!
     249              : !! FUNCTION
     250              : !!  Used to build ragged arrays of wave_t in compact form.
     251              : !!
     252              : !! SOURCE
     253              : 
     254              :  type :: spin_store_t
     255              :    type(kpt_store_t),allocatable :: k(:)
     256              :  end type spin_store_t
     257              : !!***
     258              : 
     259              : !----------------------------------------------------------------------
     260              : 
     261              : !!****t* m_wfd/wfd_t
     262              : !! NAME
     263              : !! wfd_t
     264              : !!
     265              : !! FUNCTION
     266              : !! Container gathering information on the set of wavefunctions treated by this node
     267              : !! This is a base class without the bks_tab that is used in the GW/BSE code.
     268              : !!
     269              : !! SOURCE
     270              : 
     271              :  type, public :: wfd_t
     272              : 
     273              :   integer :: debug_level = 0    ! Internal flag defining the debug level.
     274              :   integer :: lmnmax
     275              :   integer :: mband              ! MAX(nband)
     276              :   integer :: mgfft              ! Maximum size of 1D FFTs i.e. MAXVAL(ngfft(1:3)), used to dimension some arrays.
     277              :   integer :: natom
     278              :   integer :: nfft               ! Number of FFT points treated by this processor
     279              :   integer :: nfftot             ! Total number of points in the FFT grid
     280              :   integer :: nkibz              ! Number of irreducible k-points
     281              :   integer :: nspden             ! Number of independent spin-density components
     282              :   integer :: nspinor            ! Number of spinor components
     283              :   integer :: nsppol             ! Number of independent spin polarizations
     284              :   integer :: ntypat             ! Number of type of atoms.
     285              :   integer :: paral_kgb          ! Option for kgb parallelism
     286              :   integer :: usepaw             ! 1 if PAW is used, 0 otherwise.
     287              :   integer :: prtvol             ! Verbosity level.
     288              :   integer :: pawprtvol          ! Verbosity level for PAW.
     289              :   integer :: usewvl             ! 1 if BigDFT is used, 0 otherwise.
     290              :   integer :: comm               ! The MPI communicator for this pool of processors.
     291              :   integer :: master             ! The rank of master node in comm.
     292              :   integer :: my_rank            ! The rank of my processor inside the MPI communicator comm.
     293              :   integer :: nproc              ! The number of processors in MPI comm.
     294              :   integer :: my_nspins          ! Number of spins treated by this MPI proc
     295              : 
     296              :   integer,allocatable :: my_nkspin(:)
     297              :   ! (%nsppol))
     298              :   ! Number of k-points treated by this MPI proc.
     299              : 
     300              :   logical :: rfft_is_symok      ! .TRUE. if the real space FFT mesh is compatible with the rotational
     301              :                                 ! part of the space group.
     302              : 
     303              :   logical :: use_fnl_dir0der0   ! .TRUE. if the the Wfd must store fnl dir0der0.
     304              : 
     305              :   real(dp) :: dilatmx
     306              : 
     307              :   real(dp) :: ecut
     308              :    ! Cutoff for plane wave basis set.
     309              : 
     310              :   real(dp) :: ecutsm
     311              :    ! smearing energy for plane wave kinetic energy (Ha)
     312              :    ! Cutoff for plane wave basis set.
     313              : 
     314              :   integer :: ngfft(18)
     315              :    ! Information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
     316              : 
     317              :   integer :: nloalg(3)
     318              :    ! Governs the choice of the algorithm for nonlocal operator. See doc.
     319              : 
     320              :   integer,allocatable :: comm_spin(:)
     321              :    ! (nsppol)
     322              :    ! MPI communicator for collinear spin.
     323              : 
     324              :   integer,allocatable :: irottb(:,:)
     325              :    ! (nfftot, nsym)
     326              :    ! Index of $R^{-1}(r-\tau)$ in the FFT box.
     327              : 
     328              :   integer,allocatable :: istwfk(:)
     329              :    ! (nkibz)
     330              :    ! Storage mode for this k-point.
     331              : 
     332              :   integer,allocatable :: nband(:,:)
     333              :    ! (nkibz,nsppol)
     334              :    ! Number of bands at each k-point and spin.
     335              : 
     336              :   integer,allocatable :: indlmn(:,:,:)
     337              :    ! (6, lmnmax, ntypat)
     338              :    ! array giving l,m,n,lm,ln,spin for i=ln  (if useylm=0)
     339              :    !                                or i=lmn (if useylm=1)
     340              : 
     341              :   integer,allocatable :: nlmn_atm(:)
     342              :    ! (natom)
     343              :    ! Number of (n,l,m) channels for each atom. Only for PAW
     344              : 
     345              :   integer,allocatable :: nlmn_sort(:)
     346              :    ! (natom)
     347              :    ! Number of (n,l,m) channels for each atom (sorted by atom type). Only for PAW
     348              : 
     349              :   integer,allocatable :: nlmn_type(:)
     350              :    ! (ntypat)
     351              :    ! Number of (n,l,m) channels for each type of atom. Only for PAW.
     352              : 
     353              :   integer,allocatable :: npwarr(:)
     354              :    ! (nkibz)
     355              :    ! Number of plane waves for this k-point.
     356              : 
     357              :   integer, allocatable :: bks2wfd(:,:,:,:)
     358              :    ! (3, mband, nkibz, nsppol)
     359              :    ! Maps global (band, ik_ibz, spin) to index in the wave store.
     360              :    ! Set to 0 if the (b, k, s) state is not in the store.
     361              : 
     362              :   real(dp),allocatable :: kibz(:,:)
     363              :    ! (3, nkibz)
     364              :    ! Reduced coordinates of the k-points in the IBZ.
     365              : 
     366              :   real(dp),allocatable :: ph1d(:,:)
     367              :    ! (2,3*(2*mgfft+1)*natom)
     368              :    ! 1-dim structure factor phase information.
     369              : 
     370              :   logical,private, allocatable :: keep_ur(:,:,:)
     371              :    ! TODO: To be removed
     372              :    ! keep(mband,nkibz,nsppol)
     373              :    ! Storage strategy: keep or not keep calculated u(r) in memory.
     374              : 
     375              :   type(kdata_t),allocatable :: kdata(:)
     376              :    ! (nkibz)
     377              :    ! datatype storing k-dependent quantities.
     378              : 
     379              :   type(spin_store_t),allocatable :: s(:)
     380              :    ! (my_nsppol)
     381              :    ! wfd%s(is)%k(ik)%b(ib)
     382              : 
     383              :   type(MPI_type) :: MPI_enreg
     384              :    ! The MPI_type structured datatype gather different information about the MPI parallelisation:
     385              :    ! number of processors, the index of my processor, the different groups of processors, etc ...
     386              : 
     387              :   !type(pseudopotential_type), pointer :: psps
     388              :   !type(pawtab_type), pointer :: pawtab(:)
     389              : 
     390              :  contains
     391              : 
     392              :    procedure :: free => wfd_free
     393              :    ! Free memory.
     394              : 
     395              :    procedure :: norm2 => wfd_norm2
     396              :    ! Compute <u(g)|u(g)> for the same k-point and spin.
     397              : 
     398              :    procedure :: xdotc => wfd_xdotc
     399              :    ! Compute <u_{b1ks}|u_{b2ks}> in G-space.
     400              : 
     401              :    procedure :: get_gvec_gbound => wfd_get_gvec_gbound
     402              :    ! Return the g-sphere centered on kk and gbound_kk,
     403              :    ! mainly used when looping over wavevectors in the full BZ
     404              : 
     405              :    procedure :: reset_ur_cprj => wfd_reset_ur_cprj
     406              :    ! Reinitialize memory storage of u(r) and <p_i|psi>
     407              : 
     408              :    procedure :: get_many_ur => wfd_get_many_ur
     409              :    ! Get many wavefunctions in real space from its (bands(:),k,s) indices.
     410              : 
     411              :    procedure :: copy_cg => wfd_copy_cg
     412              :    ! Return a copy of u(g) in a real(2,npw_k)) array (Abinit convention)
     413              : 
     414              :    procedure :: get_ur => wfd_get_ur
     415              :    ! Get one wavefunction in real space from its (b,k,s) indices.
     416              : 
     417              :    procedure :: get_cprj => wfd_get_cprj
     418              :    ! Get one PAW projection <Proj_i|Cnk> with all NL projectors from its (b,k,s) indices.
     419              : 
     420              :    procedure :: change_ngfft => wfd_change_ngfft
     421              :    ! Reinitialize internal FFT tables.
     422              : 
     423              :    procedure :: print => wfd_print
     424              :    ! Printout of basic info.
     425              : 
     426              :    procedure :: ug2cprj => wfd_ug2cprj
     427              :    ! Get PAW cprj from its (b,k,s) indices.
     428              : 
     429              :    procedure :: wave_free => wfd_wave_free
     430              :    ! Free internal buffers used to store the wavefunctions.
     431              : 
     432              :    procedure :: get_wave_ptr => wfd_get_wave_ptr
     433              :    ! Return pointer to wave_t from its (b,k,s) indices
     434              : 
     435              :    procedure :: push_ug => wfd_push_ug
     436              :    ! Modify the value of u(g)_ks stored in the object.
     437              : 
     438              :    procedure :: extract_cgblock => wfd_extract_cgblock
     439              :    ! Extract a block of wavefunctions for a given spin and k-points (uses the cg storage mode)
     440              : 
     441              :    procedure :: ihave_ug => wfd_ihave_ug
     442              :    ! True if the node has this ug with the specified status.
     443              : 
     444              :    procedure :: mybands => wfd_mybands
     445              :    ! Returns the list of band indices of the u(g) owned by this node at given (k,s).
     446              : 
     447              :    procedure :: test_ortho => wfd_test_ortho
     448              :    ! Test the orthonormalization of the wavefunctions.
     449              : 
     450              :    procedure :: sym_ur => wfd_sym_ur
     451              :    ! Symmetrize a wave function in real space
     452              :    ! This routine is deprecated, see wfd_sym_ug_kg for algo in G-space.
     453              : 
     454              :    procedure :: rotate_cg => wfd_rotate_cg
     455              :    ! Symmetrize a set of wave functions in G-space
     456              : 
     457              :    procedure :: sym_ug_kg => wfd_sym_ug_kg
     458              :    ! Symmetrize a wave function in G-space
     459              :    ! Used in phgamma only, use wfd_rotate_cg for a more efficient version (see m_sigmaph for usage)
     460              :    ! This routine is deprecated and should be replaced by sym_ug_kg_npw in order to call getgh1c with ndat > 1, i
     461              : 
     462              :    procedure :: sym_ug_kg_npw => wfd_sym_ug_kg_npw
     463              :    ! Symmetrize a wave function in G-space
     464              : 
     465              :    procedure :: paw_get_aeur => wfd_paw_get_aeur
     466              :    ! Compute the AE PAW wavefunction in real space.
     467              : 
     468              :    procedure :: read_wfk => wfd_read_wfk
     469              :    ! Read u(g) from the WFK file completing the initialization of the object.
     470              : 
     471              :    procedure :: dump_errinfo => wfd_dump_errinfo
     472              : 
     473              :    procedure :: init => wfd_init                ! Main creation method.
     474              : 
     475              :  end type wfd_t
     476              : 
     477              :  !public :: wfd_init                ! Main creation method.
     478              : 
     479              :  !public :: wfd_get_socpert
     480              :  public :: test_charge
     481              : !!***
     482              : 
     483              : !----------------------------------------------------------------------
     484              : 
     485              : !!****t* m_wfd/wfdgw_t
     486              : !! NAME
     487              : !! wfdgw_t
     488              : !!
     489              : !! FUNCTION
     490              : !!  This is a subclass class with the bks_tab used to parallelize the GW/BSE code.
     491              : !!  Unfortunately, the size of the bks_tab increases with the number of procs
     492              : !!  This design facilated the implementation of the MPI-algorithms but it leads to a big
     493              : !!  scalability issue when nprocs/nband/nkibz is large.
     494              : !!  New algorithms implemented outside of the GW/BSE code should use wfd_t.
     495              : !!  wfdgw_t is kept to avoid breaking the GW/BSE code.
     496              : !!
     497              : !! SOURCE
     498              : 
     499              :  type, extends (wfd_t), public :: wfdgw_t
     500              : 
     501              :    integer(c_int8_t), private, allocatable :: bks_tab(:,:,:,:)
     502              :     ! bks_tab(mband,nkibz,nsppol,0:nproc-1)
     503              :     ! Global table used to keep trace of the distribution of the (b,k,s) states on each node inside Wfd%comm.
     504              :     ! 1 if the node has this state. 0 otherwise.
     505              :     ! A node owns a wavefunction if the corresponding ug is allocated AND computed.
     506              :     ! If a node owns ur but not ug, or ug is just allocated then its entry in the table is zero.
     507              : 
     508              :  contains
     509              : 
     510              :    procedure :: show_bkstab => wfdgw_show_bkstab
     511              :    ! Print a table showing the distribution of the wavefunctions.
     512              : 
     513              :    procedure :: distribute_bands => wfdgw_distribute_bands
     514              :    ! Distribute a set of bands taking into account the distribution of the ug.
     515              : 
     516              :    procedure :: iterator_bks => wfdgw_iterator_bks
     517              :    ! Iterator used to loop over bands, k-points and spin indices
     518              : 
     519              :    procedure :: bks_distrb => wfdgw_bks_distrb
     520              :    ! Distribute bands, k-points and spins
     521              : 
     522              :    procedure :: update_bkstab => wfdgw_update_bkstab
     523              :    ! Update the internal table with info on the distribution of the ugs.
     524              : 
     525              :    procedure :: rotate => wfdgw_rotate
     526              :    ! Linear transformation of the wavefunctions stored in Wfd
     527              : 
     528              :    procedure :: sanity_check => wfdgw_sanity_check
     529              :    ! Debugging tool
     530              : 
     531              :    procedure :: distribute_bbp => wfdgw_distribute_bbp
     532              :    ! Distribute a set of (b,b') indices
     533              : 
     534              :    procedure :: distribute_kb_kpbp => wfdgw_distribute_kb_kpbp
     535              : 
     536              :    procedure :: plot_ur => wfdgw_plot_ur
     537              :    ! Write u(r) to an external file in XSF format.
     538              : 
     539              :    procedure :: mkrho => wfdgw_mkrho
     540              :    ! Calculate the charge density on the fine FFT grid in real space.
     541              : 
     542              :    procedure :: pawrhoij => wfdgw_pawrhoij
     543              : 
     544              :    procedure :: get_nl_me => wfdgw_get_nl_me
     545              : 
     546              :    procedure :: rank_has_ug => wfdgw_rank_has_ug
     547              : 
     548              :    procedure :: bands_of_rank => wfdgw_bands_of_rank
     549              : 
     550              :    procedure :: write_wfk => wfdgw_write_wfk
     551              :    ! Write u(g) to a WFK file.
     552              : 
     553              :  end type wfdgw_t
     554              : 
     555              :  public :: wfdgw_copy
     556              : !!***
     557              : 
     558              :  type, public :: u0_cache_t
     559              :    integer :: prev_npw_k = -1, prev_nband_k = - 1, prev_istwf_k = -1
     560              :    real(dp) :: prev_kpt(3) = -1
     561              :    logical :: use_cache = .False.
     562              :    integer :: ngfft(18)
     563              :    integer, allocatable :: prev_kg_k(:,:)
     564              :    real(dp),allocatable :: prev_cg_k(:,:,:)
     565              :     ! (2, prev_npw_k*nspinor, prev_nband_k))
     566              :  contains
     567              :    procedure :: init => u0_cache_init
     568              :    procedure :: store_kpt => u0_cache_store_kpt
     569              :    procedure :: get_kpt => u0_cache_get_kpt
     570              :    procedure :: free => u0_cache_free
     571              :  end type u0_cache_t
     572              : 
     573              :  type, public :: u1_cache_t
     574              :    integer :: prev_npw_kq = -1, prev_bstart_ks = -1, prev_nbcalc_ks = - 1
     575              :    integer :: hits = 0, miss = 0
     576              :    real(dp) :: prev_qpt(3)
     577              :    integer, allocatable :: prev_kg_kq(:,:)
     578              :    real(dp),allocatable :: prev_cg1s_kq(:,:,:,:)
     579              :     ! (2, npw_kq*nspinor, natom3, nbcalc_ks))
     580              :  contains
     581              :    procedure :: store => u1_cache_store
     582              :    procedure :: find_band => u1_cache_find_band
     583              :    procedure :: free => u1_cache_free
     584              :  end type u1_cache_t
     585              : 
     586              : contains
     587              : 
     588              : !!****f* m_wfd/kdata_init
     589              : !! NAME
     590              : !!  kdata_init
     591              : !!
     592              : !! FUNCTION
     593              : !!  Main creation method for the kdata_t datatype.
     594              : !!
     595              : !! SOURCE
     596              : 
     597         9481 : subroutine kdata_init(Kdata, Cryst, Psps, kpoint, istwfk, ngfft, MPI_enreg, ecut, kg_k)
     598              : 
     599              : !Arguments ------------------------------------
     600              : !scalars
     601              :  class(kdata_t),intent(inout) :: Kdata
     602              :  integer,intent(in) :: istwfk
     603              :  real(dp),optional,intent(in) :: ecut
     604              :  type(crystal_t),intent(in) :: Cryst
     605              :  type(pseudopotential_type),intent(in) :: Psps
     606              :  type(MPI_type),intent(in) :: MPI_enreg
     607              : !arrays
     608              :  integer,optional,target,intent(in) :: kg_k(:,:)
     609              :  integer,intent(in) :: ngfft(18)
     610              :  real(dp),intent(in) :: kpoint(3)
     611              : 
     612              : !Local variables ------------------------------
     613              : !scalars
     614              :  integer,parameter :: ider0 = 0, idir0 = 0
     615              :  integer :: mpw_, npw_k, dimffnl, useylmgr, nkpg, iatom, mkmem_, nkpt_, optder, mgfft, iatm, matblk
     616              :  real(dp) :: arg
     617              : !arrays
     618              :  integer :: nband_(1), npwarr_(1)
     619         9481 :  real(dp),allocatable :: ylmgr_k(:,:,:),kpg_k(:,:),ph1d(:,:)
     620              : !************************************************************************
     621              : 
     622              :  !@kdata_t
     623         9481 :  Kdata%istwfk = istwfk
     624         9481 :  Kdata%useylm = Psps%useylm
     625              : 
     626         9481 :  if (present(ecut)) then
     627              :   ! Calculate G-sphere from input ecut.
     628         4536 :   ABI_CHECK(.not.allocated(Kdata%kg_k), "Kdata%kg_k is allocated!")
     629         4536 :   call get_kg(kpoint,istwfk,ecut,Cryst%gmet,npw_k,Kdata%kg_k)
     630              : 
     631         4945 :  else if (present(kg_k)) then
     632              :    ! Use input g-vectors.
     633         4945 :    npw_k = SIZE(kg_k,DIM=2)
     634        14835 :    ABI_MALLOC(Kdata%kg_k,(3,npw_k))
     635      6063170 :    Kdata%kg_k = kg_k
     636              :  else
     637            0 :    ABI_ERROR("Either ecut or kg_k must be present")
     638              :  end if
     639         9481 :  Kdata%npw = npw_k
     640              : 
     641        37924 :  mgfft = MAXVAL(ngfft(1:3))
     642              : 
     643              :  ! Finds the boundary of the basis sphere of G vectors (for this k point)
     644              :  ! for use in improved zero padding of ffts in 3 dimensions.
     645        37924 :  ABI_MALLOC(Kdata%gbound,(2*mgfft+8, 2))
     646         9481 :  call sphereboundary(Kdata%gbound, istwfk, Kdata%kg_k, mgfft, npw_k)
     647              : 
     648              :  ! Compute e^{ik.Ra} for each atom. Packed according to the atom type (atindx).
     649        28443 :  ABI_MALLOC(Kdata%phkxred,(2, Cryst%natom))
     650        29148 :  do iatom=1,Cryst%natom
     651        19667 :    iatm=Cryst%atindx(iatom)
     652        78668 :    arg=two_pi*(DOT_PRODUCT(kpoint,Cryst%xred(:,iatom)))
     653        19667 :    Kdata%phkxred(1,iatm)=DCOS(arg)
     654        29148 :    Kdata%phkxred(2,iatm)=DSIN(arg)
     655              :  end do
     656              : 
     657              :  ! TODO: Should avoid storing all this stuff in memory (risky if lots of k-points)
     658              :  ! Write method to prepare kdata inside loop
     659              : 
     660              :  ! Calculate 1-dim structure factor phase information.
     661        37924 :  mgfft = MAXVAL(ngfft(1:3))
     662        28443 :  ABI_MALLOC(ph1d,(2, 3*(2*mgfft+1)*Cryst%natom))
     663         9481 :  call getph(Cryst%atindx,Cryst%natom,ngfft(1),ngfft(2),ngfft(3),ph1d,Cryst%xred)
     664              : 
     665              :  ! Calculate 3-dim structure factor phase information.
     666         9481 :  matblk = 0
     667         9481 :  if(psps%usepaw == 1 .or. Kdata%use_fnl_dir0der0) then
     668          321 :    matblk=Cryst%natom
     669              :  end if
     670        37924 :  ABI_MALLOC(Kdata%ph3d,(2, npw_k, matblk))
     671         9481 :  if(psps%usepaw == 1 .or. Kdata%use_fnl_dir0der0) then
     672              :    call ph1d3d(1,Cryst%natom,Kdata%kg_k,matblk,Cryst%natom,npw_k,ngfft(1),ngfft(2),&
     673          321 :    &ngfft(3),Kdata%phkxred,ph1d,Kdata%ph3d)
     674              :  end if
     675         9481 :  ABI_FREE(ph1d)
     676              : 
     677              :  ! Compute spherical harmonics.
     678         9481 :  Kdata%has_ylm = 1
     679        37924 :  ABI_MALLOC(Kdata%ylm, (npw_k, Psps%mpsang**2*Psps%useylm))
     680         9481 :  useylmgr=0
     681        18962 :  ABI_MALLOC(ylmgr_k,(npw_k, 3, Psps%mpsang**2*useylmgr))
     682              : 
     683         9481 :  if (Kdata%useylm == 1) then
     684          269 :    mkmem_=1; mpw_=npw_k; nband_=0; nkpt_=1; npwarr_(1)=npw_k
     685          269 :    optder=0 ! only Ylm(K) are computed.
     686              : 
     687              :    call initylmg(Cryst%gprimd, Kdata%kg_k, kpoint, mkmem_, MPI_enreg, Psps%mpsang, mpw_, nband_, nkpt_,&
     688          269 :    npwarr_, 1, optder, Cryst%rprimd, Kdata%ylm, ylmgr_k)
     689              : 
     690          269 :    Kdata%has_ylm = 2
     691              :  end if
     692              : 
     693              :  ! Compute (k+G) vectors.
     694         9481 :  nkpg = 0
     695        18962 :  ABI_MALLOC(kpg_k,(npw_k, nkpg))
     696              :  if (nkpg>0) call mkkpg(Kdata%kg_k, kpg_k, kpoint, nkpg, npw_k)
     697              : 
     698              :  ! Compute nonlocal form factors fnl_dir0der0 for all (k+G).
     699         9481 :  dimffnl = 0
     700         9481 :  if(psps%usepaw == 1 .or. Kdata%use_fnl_dir0der0) then
     701          321 :    dimffnl = 1+3*ider0
     702              :  end if
     703        56886 :  ABI_MALLOC(Kdata%fnl_dir0der0,(npw_k, dimffnl, Psps%lmnmax, Cryst%ntypat))
     704              : 
     705         9481 :  if (dimffnl /=0 ) then
     706              :    call mkffnl(Psps%dimekb,dimffnl,Psps%ekb,Kdata%fnl_dir0der0,Psps%ffspl,&
     707              :      Cryst%gmet,Cryst%gprimd,ider0,idir0,Psps%indlmn,Kdata%kg_k,kpg_k,kpoint,Psps%lmnmax,&
     708              :      Psps%lnmax,Psps%mpsang,Psps%mqgrid_ff,nkpg,npw_k,Cryst%ntypat,&
     709          321 :      Psps%pspso,Psps%qgrid_ff,Cryst%rmet,Psps%usepaw,Psps%useylm,Kdata%ylm,ylmgr_k)
     710              :  end if
     711              : 
     712         9481 :  ABI_FREE(kpg_k)
     713         9481 :  ABI_FREE(ylmgr_k)
     714              : 
     715         9481 : end subroutine kdata_init
     716              : !!***
     717              : 
     718              : !----------------------------------------------------------------------
     719              : 
     720              : !!****f* m_wfd/kdata_free_0D
     721              : !! NAME
     722              : !!  kdata_free_0D
     723              : !!
     724              : !! FUNCTION
     725              : !!  Deallocate memory
     726              : !!
     727              : !! SOURCE
     728              : 
     729        13089 : subroutine kdata_free_0D(Kdata)
     730              : 
     731              : !Arguments ------------------------------------
     732              :  class(kdata_t),intent(inout) :: Kdata
     733              : !************************************************************************
     734              : 
     735        13089 :  ABI_SFREE(Kdata%kg_k)
     736        13089 :  ABI_SFREE(Kdata%gbound)
     737              : 
     738        13089 :  ABI_SFREE(Kdata%ph3d)
     739        13089 :  ABI_SFREE(Kdata%phkxred)
     740        13089 :  ABI_SFREE(Kdata%fnl_dir0der0)
     741        13089 :  ABI_SFREE(Kdata%ylm)
     742              : 
     743        13089 : end subroutine kdata_free_0D
     744              : !!***
     745              : 
     746              : !----------------------------------------------------------------------
     747              : 
     748              : !!****f* m_wfd/kdata_free_1D
     749              : !! NAME
     750              : !!  kdata_free_1D
     751              : !!
     752              : !! FUNCTION
     753              : !!   Deallocate memory.
     754              : !!
     755              : !! SOURCE
     756              : 
     757          484 : subroutine kdata_free_1D(Kdata)
     758              : 
     759              : !Arguments ------------------------------------
     760              : !scalars
     761              :  type(kdata_t),intent(inout) :: Kdata(:)
     762              : 
     763              : !Local variables ------------------------------
     764              : !scalars
     765              :  integer :: ik
     766              : !************************************************************************
     767              : 
     768         9112 :  do ik=LBOUND(Kdata,DIM=1),UBOUND(Kdata,DIM=1)
     769         8628 :    call kdata_free_0D(Kdata(ik))
     770              :  end do
     771              : 
     772          484 : end subroutine kdata_free_1D
     773              : !!***
     774              : 
     775              : !----------------------------------------------------------------------
     776              : 
     777              : !!****f* m_wfd/copy_kdata_0D
     778              : !! NAME
     779              : !!  copy_kdata_0D
     780              : !!
     781              : !! FUNCTION
     782              : !!  Copy object
     783              : !!
     784              : !! SOURCE
     785              : 
     786            0 : subroutine copy_kdata_0D(Kdata_in, Kdata_out)
     787              : 
     788              : !Arguments ------------------------------------
     789              :  class(kdata_t),intent(in) :: Kdata_in
     790              :  class(kdata_t),intent(inout) :: Kdata_out
     791              : !************************************************************************
     792              : 
     793              :  !@kdata_t
     794            0 :  Kdata_out%istwfk  = Kdata_in%istwfk
     795            0 :  Kdata_out%npw     = Kdata_in%npw
     796            0 :  Kdata_out%useylm  = Kdata_in%useylm
     797            0 :  Kdata_out%has_ylm = Kdata_in%has_ylm
     798              : 
     799            0 :  call alloc_copy(Kdata_in%kg_k, Kdata_out%kg_k)
     800            0 :  call alloc_copy(Kdata_in%gbound, Kdata_out%gbound)
     801              : 
     802            0 :  call alloc_copy(Kdata_in%ph3d,Kdata_out%ph3d)
     803            0 :  call alloc_copy(Kdata_in%phkxred,Kdata_out%phkxred)
     804            0 :  call alloc_copy(Kdata_in%fnl_dir0der0,Kdata_out%fnl_dir0der0)
     805            0 :  call alloc_copy(Kdata_in%ylm,Kdata_out%ylm)
     806              : 
     807            0 : end subroutine copy_kdata_0D
     808              : !!***
     809              : 
     810              : !----------------------------------------------------------------------
     811              : 
     812              : !!****f* m_wfd/copy_kdata_1D
     813              : !! NAME
     814              : !!  copy_kdata_1D
     815              : !!
     816              : !! FUNCTION
     817              : !!   Deallocate memory.
     818              : !!
     819              : !! SOURCE
     820              : 
     821            0 : subroutine copy_kdata_1D(Kdata_in, Kdata_out)
     822              : 
     823              : !Arguments ------------------------------------
     824              : !scalars
     825              :  type(kdata_t),intent(in) :: Kdata_in(:)
     826              :  type(kdata_t),intent(inout) :: Kdata_out(:)
     827              : 
     828              : !Local variables ------------------------------
     829              : !scalars
     830              :  integer :: ik
     831              : !************************************************************************
     832              : 
     833            0 :  if (size(Kdata_in,DIM=1) /= size(Kdata_out,DIM=1)) then
     834            0 :    ABI_ERROR("copy_kdata_1D: wrong sizes !")
     835              :  end if
     836              : 
     837            0 :  do ik=LBOUND(Kdata_in,DIM=1),UBOUND(Kdata_in,DIM=1)
     838            0 :    call copy_kdata_0d(Kdata_in(ik), Kdata_out(ik))
     839              :  end do
     840              : 
     841            0 : end subroutine copy_kdata_1D
     842              : !!***
     843              : 
     844              : !----------------------------------------------------------------------
     845              : 
     846              : !!****f* m_wfd/wfd_init
     847              : !! NAME
     848              : !! wfd_init
     849              : !!
     850              : !! FUNCTION
     851              : !!  Initialize the object.
     852              : !!
     853              : !! INPUTS
     854              : !!  Cryst<crystal_t>=Object defining the unit cell and its symmetries.
     855              : !!  Pawtab(ntypat*usepaw)<type(pawtab_type)>=PAW tabulated starting data.
     856              : !!  Psps<Pseudopotential_type>=datatype storing data on the pseudopotentials.
     857              : !!  ngfft(18)=All needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
     858              : !!  nkibz=Number of irreducible k-points.
     859              : !!  nsppol=Number of independent spin polarizations.
     860              : !!  nspden=Number of density components.
     861              : !!  nspinor=Number of spinorial components.
     862              : !!  ecut=Cutoff energy in Hartree
     863              : !!  ecutsm=Smearing for kinetic energy
     864              : !!  dilatmx
     865              : !!  mband
     866              : !!  nband(nkibz,nsppol)
     867              : !!  keep_ur(mband,nkibz,nsppol)=Option for memory storage of u(r).
     868              : !!  istwfk(nkibz)=Storage mode.
     869              : !!  kibz(3,nkibz)=Reduced coordinates of the k-points.
     870              : !!  nloalg(3)=Governs the choice of the algorithm for nonlocal operator. See doc.
     871              : !!  prtvol=Verbosity level.
     872              : !!  comm=MPI communicator.
     873              : !!
     874              : !! OUTPUT
     875              : !!  Initialize the object with basic dimensions, allocate also memory for u(g) and u(r) according to keep_ur
     876              : !!    %ug in G-space are always allocated.
     877              : !!    %ur in r-space only if keep_ur.
     878              : !!
     879              : !! SOURCE
     880              : 
     881          484 : subroutine wfd_init(Wfd,Cryst,Pawtab,Psps,keep_ur,mband,nband,nkibz,nsppol,bks_mask,&
     882          484 :                     nspden,nspinor,ecut,ecutsm,dilatmx,istwfk,kibz,ngfft,nloalg,prtvol,pawprtvol,comm,&
     883              :                     use_fnl_dir0der0) ! optional
     884              : 
     885              : !Arguments ------------------------------------
     886              : !scalars
     887              :  class(wfd_t),intent(inout) :: Wfd
     888              :  integer,intent(in) :: mband,comm,prtvol,pawprtvol,nkibz,nsppol,nspden,nspinor
     889              :  real(dp),intent(in) :: ecut,ecutsm,dilatmx
     890              :  type(crystal_t),intent(in) :: Cryst
     891              :  type(pseudopotential_type),intent(in) :: Psps
     892              : !array
     893              :  integer,intent(in) :: ngfft(18),istwfk(nkibz),nband(nkibz,nsppol),nloalg(3)
     894              :  real(dp),intent(in) :: kibz(3,nkibz)
     895              :  logical,intent(in) :: bks_mask(mband,nkibz,nsppol), keep_ur(mband,nkibz,nsppol)
     896              :  logical,intent(in),optional :: use_fnl_dir0der0
     897              :  type(Pawtab_type),intent(in) :: Pawtab(Cryst%ntypat*Psps%usepaw)
     898              : 
     899              : !Local variables ------------------------------
     900              : !scalars
     901              :  integer,parameter :: nfft0=0,mpw0=0,ikg0=0
     902              :  integer :: ik_ibz,spin,band,mpw,exchn2n3d,istwf_k,npw_k,iatom,itypat,iat,cnt_b, cnt_k, cnt_s, ierr, color
     903              :  real(dp) :: ug_size,ur_size,cprj_size, bks_size,cpu, wall, gflops
     904              :  logical :: iscompatibleFFT
     905              :  character(len=500) :: msg
     906              : !arrays
     907              :  integer :: dum_kg(3,0)
     908              :  real(dp) :: kpoint(3)
     909              : !************************************************************************
     910              : 
     911          484 :  call cwtime(cpu, wall, gflops, "start")
     912              : 
     913              :  ! MPI info
     914          484 :  Wfd%comm    = comm
     915          484 :  Wfd%my_rank = xmpi_comm_rank(Wfd%comm)
     916          484 :  Wfd%nproc   = xmpi_comm_size(Wfd%comm)
     917          484 :  Wfd%master  = 0
     918              : 
     919              :  ! Sequential MPI datatype to be passed to abinit routines.
     920          484 :  call initmpi_seq(Wfd%MPI_enreg)
     921          484 :  call Wfd%MPI_enreg%distribfft%init('c',Wfd%MPI_enreg%nproc_fft,ngfft(2),ngfft(3))
     922              : 
     923              :  ! TODO: To simply high-level API.
     924              :  !wfd%cryst => cryst
     925              :  !wfd%psps => psps
     926              :  !wfd%pawtab => pawtab
     927              : 
     928              :  ! Basic dimensions
     929          484 :  Wfd%nkibz     = nkibz
     930          484 :  Wfd%nsppol    = nsppol
     931          484 :  Wfd%nspden    = nspden
     932          484 :  Wfd%nspinor   = nspinor
     933          484 :  Wfd%paral_kgb = 0
     934         1936 :  Wfd%nloalg    = nloalg
     935              : 
     936          484 :  Wfd%usepaw = Psps%usepaw
     937          484 :  Wfd%usewvl = 0 ! wavelets are not supported.
     938          484 :  Wfd%use_fnl_dir0der0 = .false.
     939          484 :  if(present(use_fnl_dir0der0)) Wfd%use_fnl_dir0der0 = use_fnl_dir0der0
     940          484 :  Wfd%natom  = Cryst%natom
     941          484 :  Wfd%ntypat = Cryst%ntypat
     942          484 :  Wfd%lmnmax = Psps%lmnmax
     943          484 :  Wfd%prtvol = prtvol
     944          484 :  Wfd%pawprtvol = pawprtvol
     945              : 
     946          484 :  Wfd%ecutsm  = ecutsm
     947          484 :  Wfd%dilatmx = dilatmx
     948              : 
     949         1936 :  ABI_MALLOC(Wfd%indlmn,(6, Wfd%lmnmax, Wfd%ntypat))
     950        16457 :  Wfd%indlmn = Psps%indlmn
     951              : 
     952          484 :  if (Wfd%usepaw==1) then
     953           36 :    ABI_MALLOC(Wfd%nlmn_atm, (Cryst%natom))
     954           36 :    ABI_MALLOC(Wfd%nlmn_type, (Cryst%ntypat))
     955           78 :    do iatom=1,Cryst%natom
     956           78 :      Wfd%nlmn_atm(iatom) = Pawtab(Cryst%typat(iatom))%lmn_size
     957              :    end do
     958              : 
     959           32 :    do itypat=1,Cryst%ntypat
     960           32 :      Wfd%nlmn_type(itypat)=Pawtab(itypat)%lmn_size
     961              :    end do
     962              : 
     963           24 :    ABI_MALLOC(Wfd%nlmn_sort,(Cryst%natom))
     964           12 :    iat=0 ! nlmn dims sorted by atom type.
     965           32 :    do itypat=1,Cryst%ntypat
     966           86 :      Wfd%nlmn_sort(iat+1:iat+Cryst%nattyp(itypat))=Pawtab(itypat)%lmn_size
     967           32 :      iat=iat+Cryst%nattyp(itypat)
     968              :    end do
     969              :  end if
     970              : 
     971         2420 :  ABI_MALLOC(Wfd%keep_ur, (mband, nkibz, nsppol))
     972       118602 :  Wfd%keep_ur = keep_ur
     973              : 
     974              :  ! Setup of the FFT mesh
     975         9196 :  Wfd%ngfft  = ngfft
     976         1936 :  Wfd%mgfft  = MAXVAL (Wfd%ngfft(1:3))
     977         1936 :  Wfd%nfftot = PRODUCT(Wfd%ngfft(1:3))
     978          484 :  Wfd%nfft   = Wfd%nfftot ! At present no FFT parallelism.
     979          484 :  Wfd%ecut = ecut
     980              : 
     981              :  ! Precalculate the FFT index of $ R^{-1} (r-\tau) $ used to symmetrize u_Rk.
     982         1936 :  ABI_MALLOC(Wfd%irottb,(Wfd%nfftot, Cryst%nsym))
     983          484 :  call rotate_FFT_mesh(Cryst%nsym,Cryst%symrel,Cryst%tnons,Wfd%ngfft,Wfd%irottb,iscompatibleFFT)
     984              : 
     985          484 :  if (.not. iscompatibleFFT) then
     986            7 :    msg = "FFT mesh is not compatible with symmetries. Wavefunction symmetrization might be affected by large errors!"
     987            7 :    ABI_WARNING(msg)
     988              :  end if
     989              : 
     990              :  ! Is the real space mesh compatible with the rotational part?
     991          484 :  Wfd%rfft_is_symok = check_rot_fft(Cryst%nsym,Cryst%symrel,Wfd%ngfft(1),Wfd%ngfft(2),Wfd%ngfft(3))
     992              : 
     993         1452 :  ABI_MALLOC(Wfd%kibz, (3, Wfd%nkibz))
     994        33544 :  Wfd%kibz = kibz
     995         1452 :  ABI_MALLOC(Wfd%istwfk, (Wfd%nkibz))
     996         9112 :  Wfd%istwfk = istwfk
     997              : 
     998              :  ! Get the number of planewaves npw_k
     999              :  ! TODO Here we should use ecut_eff instead of ecut
    1000         9596 :  ABI_ICALLOC(Wfd%npwarr, (Wfd%nkibz))
    1001          484 :  exchn2n3d = 0
    1002         8628 :  do ik_ibz=1,Wfd%nkibz
    1003         8144 :    if (mod(ik_ibz, wfd%nproc) /= wfd%my_rank) cycle ! MPI parallelism.
    1004         7480 :    istwf_k = Wfd%istwfk(ik_ibz)
    1005        29920 :    kpoint  = Wfd%kibz(:,ik_ibz)
    1006         7480 :    call kpgsph(Wfd%ecut,exchn2n3d,Cryst%gmet,ikg0,ik_ibz,istwf_k,dum_kg,kpoint,0,Wfd%MPI_enreg,mpw0,npw_k)
    1007         8628 :    Wfd%npwarr(ik_ibz)= npw_k
    1008              :  end do
    1009          484 :  call xmpi_sum(wfd%npwarr, wfd%comm, ierr)
    1010              : 
    1011         8628 :  mpw = maxval(Wfd%npwarr)
    1012              : 
    1013         1936 :  ABI_MALLOC(Wfd%nband, (nkibz,nsppol))
    1014         9623 :  Wfd%nband = nband; Wfd%mband = mband
    1015         9139 :  ABI_CHECK_IEQ(maxval(Wfd%nband), mband, "Wrong mband")
    1016              : 
    1017              :  ! Allocate u(g) and, if required, also u(r)
    1018       118118 :  ug_size = one*nspinor*mpw*COUNT(bks_mask)
    1019          484 :  write(msg,'(a,f8.1,a)')' Memory needed for Fourier components u(G): ',two*gwp*ug_size*b2Mb, ' [Mb] <<< MEM'
    1020          484 :  call wrtout(std_out, msg)
    1021              : #ifdef HAVE_GW_DPC
    1022          484 :  call wrtout(std_out, ' Storing wavefunctions in double precision as `enable_gw_dpc="no"`')
    1023          484 :  call wrtout(std_out, ' Recompile the code with `enable_gw_dpc="no"` to halve memory requirements for the WFs')
    1024              : #else
    1025              :  call wrtout(std_out, ' Storing wavefunctions in single precision as `enable_gw_dpc="no"`')
    1026              : #endif
    1027              : 
    1028          484 :  if (Wfd%usepaw==1) then
    1029         1770 :    cprj_size = one * nspinor*SUM(Wfd%nlmn_atm)*COUNT(bks_mask)
    1030           12 :    write(msg,'(a,f8.1,a)')' Memory needed for PAW projections cprj: ',dp*cprj_size*b2Mb,' [Mb] <<< MEM'
    1031           12 :    call wrtout(std_out, msg)
    1032              :  end if
    1033              : 
    1034       118118 :  ur_size = one*nspinor*Wfd%nfft*COUNT(Wfd%keep_ur)
    1035          484 :  write(msg,'(a,f8.1,a)')' Memory needed for real-space u(r): ',two*gwp*ur_size*b2Mb,' [Mb] <<< MEM'
    1036          484 :  call wrtout(std_out, msg)
    1037              : 
    1038              :  ! Count the number of spins treated by this proc.
    1039          484 :  wfd%my_nspins = 0
    1040          975 :  do spin=1,wfd%nsppol
    1041        12270 :    if (any(bks_mask(:,:,spin))) wfd%my_nspins = wfd%my_nspins + 1
    1042              :  end do
    1043              :  !write(std_out, *)"my_nspins", wfd%my_nspins
    1044         1943 :  ABI_MALLOC(wfd%s, (wfd%my_nspins))
    1045              : 
    1046              :  ! Count the number of kpts in the IBZ treated by this proc. may be spin-dependent.
    1047         1943 :  ABI_ICALLOC(wfd%my_nkspin, (wfd%nsppol))
    1048          484 :  cnt_s = 0
    1049          975 :  do spin=1,wfd%nsppol
    1050         8655 :    do ik_ibz=1,wfd%nkibz
    1051        39867 :      if (any(bks_mask(:,ik_ibz,spin))) wfd%my_nkspin(spin) = wfd%my_nkspin(spin) + 1
    1052              :    end do
    1053          975 :    if (wfd%my_nkspin(spin) > 0) then
    1054          491 :      cnt_s = cnt_s + 1
    1055         6029 :      ABI_MALLOC(wfd%s(cnt_s)%k, (wfd%my_nkspin(spin)))
    1056              :    end if
    1057              :  end do
    1058              : 
    1059              :  ! Allocate bands in packed form and use bks2wfd to go from global (b,k,s) index to local index.
    1060       446991 :  ABI_ICALLOC(wfd%bks2wfd, (3, wfd%mband, wfd%nkibz, wfd%nsppol))
    1061          484 :  cnt_s = 0
    1062          975 :  do spin=1,wfd%nsppol
    1063          491 :    if (wfd%my_nkspin(spin) == 0) cycle
    1064          491 :    cnt_s = cnt_s + 1
    1065          491 :    cnt_k = 0
    1066         9139 :    do ik_ibz=1,wfd%nkibz
    1067       117143 :      cnt_b = count(bks_mask(:, ik_ibz, spin))
    1068         8164 :      if (cnt_b == 0) cycle
    1069         4556 :      cnt_k = cnt_k + 1
    1070        84951 :      ABI_MALLOC(wfd%s(cnt_s)%k(cnt_k)%b, (cnt_b))
    1071         4556 :      cnt_b = 0
    1072         4556 :      npw_k = Wfd%npwarr(ik_ibz)
    1073        83917 :      do band=1,Wfd%nband(ik_ibz, spin)
    1074        87034 :        if (bks_mask(band, ik_ibz, spin)) then
    1075        71283 :          cnt_b = cnt_b + 1
    1076              :          call wave_init(wfd%s(cnt_s)%k(cnt_k)%b(cnt_b), &
    1077        71283 :                         Wfd%usepaw, npw_k, nfft0, Wfd%nspinor, Wfd%natom, Wfd%nlmn_atm, CPR_RANDOM)
    1078       285132 :          wfd%bks2wfd(:, band, ik_ibz, spin) = [cnt_b, cnt_k, cnt_s]
    1079              :        end if
    1080              :      end do
    1081              :    end do
    1082              :  end do
    1083              : 
    1084              :  ! ===================================================
    1085              :  ! ==== Precalculate nonlocal form factors for PAW ====
    1086              :  ! ===================================================
    1087              :  !
    1088              :  ! Calculate 1-dim structure factor phase information.
    1089         1452 :  ABI_MALLOC(Wfd%ph1d, (2, 3*(2*Wfd%mgfft+1)*Wfd%natom))
    1090          484 :  call getph(Cryst%atindx, Wfd%natom, Wfd%ngfft(1), Wfd%ngfft(2), Wfd%ngfft(3), Wfd%ph1d, Cryst%xred)
    1091              : 
    1092              :  ! TODO: This one will require some memory if nkibz is large.
    1093         9596 :  ABI_MALLOC(Wfd%Kdata, (Wfd%nkibz))
    1094         8628 :  Wfd%Kdata%use_fnl_dir0der0 = Wfd%use_fnl_dir0der0
    1095              : 
    1096         8628 :  do ik_ibz=1,Wfd%nkibz
    1097        32576 :    kpoint  = Wfd%kibz(:,ik_ibz)
    1098         8144 :    istwf_k = Wfd%istwfk(ik_ibz)
    1099         8144 :    npw_k   = Wfd%npwarr(ik_ibz)
    1100        43448 :    if (any(wfd%bks2wfd(1, :, ik_ibz, :) /= 0)) then
    1101         4536 :      call Wfd%Kdata(ik_ibz)%init(Cryst, Psps, kpoint, istwf_k, ngfft, Wfd%MPI_enreg, ecut=Wfd%ecut)
    1102              :    end if
    1103              :  end do
    1104              : 
    1105              :  select type (wfd)
    1106              :  class is (wfdgw_t)
    1107              :     ! Allocate the global table used to keep track of the bks distribution, including possible duplication.
    1108          387 :     bks_size = one * wfd%mband * wfd%nkibz * wfd%nsppol * wfd%nproc
    1109          387 :     write(msg,'(a,f8.1,a)')' Memory needed for bks_tab: ',one * bks_size * b2Mb,' [Mb] <<< MEM'
    1110          387 :     call wrtout(std_out, msg)
    1111              : 
    1112              :     !ABI_MALLOC(wfd%bks_ranks, (wfd%mband, nkibz, nsppol))
    1113              : 
    1114         2322 :     ABI_MALLOC(Wfd%bks_tab, (Wfd%mband, nkibz, nsppol, 0:Wfd%nproc-1))
    1115       102861 :     Wfd%bks_tab = WFD_NOWAVE
    1116              : 
    1117              :     ! Update the kbs table storing the distribution of the ug.
    1118          387 :     call wfd%update_bkstab(show=-std_out)
    1119              :  end select
    1120              : 
    1121              :  ! Build MPI communicator for collinear spin
    1122         1452 :  ABI_MALLOC(wfd%comm_spin, (nsppol))
    1123          975 :  do spin=1,nsppol
    1124        11786 :    color = merge(0, 1, any(bks_mask(:,:,spin)))
    1125          975 :    call xmpi_comm_split(wfd%comm, color, wfd%my_rank, wfd%comm_spin(spin), ierr)
    1126              :  end do
    1127              : 
    1128          484 :  call cwtime_report(" wfd_init", cpu, wall, gflops)
    1129              : 
    1130         1452 : end subroutine wfd_init
    1131              : !!***
    1132              : 
    1133              : !----------------------------------------------------------------------
    1134              : 
    1135              : !!****f* m_wfd/wfd_free
    1136              : !! NAME
    1137              : !!  wfd_free
    1138              : !!
    1139              : !! FUNCTION
    1140              : !!  Free the memory allocated in the wfd_t data type.
    1141              : !!
    1142              : !! SOURCE
    1143              : 
    1144          491 : subroutine wfd_free(Wfd)
    1145              : 
    1146              : !Arguments ------------------------------------
    1147              :  class(wfd_t),intent(inout) :: Wfd
    1148              : 
    1149              : !Local variables ------------------------------
    1150              :  integer :: ib, ik, is
    1151              : !************************************************************************
    1152              : 
    1153              :  ! integer.
    1154          491 :  ABI_SFREE(Wfd%irottb)
    1155          491 :  ABI_SFREE(Wfd%istwfk)
    1156          491 :  ABI_SFREE(Wfd%nband)
    1157          491 :  ABI_SFREE(Wfd%indlmn)
    1158          491 :  ABI_SFREE(Wfd%nlmn_atm)
    1159          491 :  ABI_SFREE(Wfd%nlmn_sort)
    1160          491 :  ABI_SFREE(Wfd%nlmn_type)
    1161          491 :  ABI_SFREE(Wfd%npwarr)
    1162              : 
    1163              :  select type (wfd)
    1164              :  class is (wfdgw_t)
    1165          387 :     ABI_SFREE(Wfd%bks_tab)
    1166              :  end select
    1167              : 
    1168          491 :  if (allocated(wfd%s)) then
    1169          975 :    do is=1,size(wfd%s)
    1170         5047 :      do ik=1,size(wfd%s(is)%k)
    1171        75839 :        do ib=1,size(wfd%s(is)%k(ik)%b)
    1172        75839 :          call wfd%s(is)%k(ik)%b(ib)%free()
    1173              :        end do
    1174        76330 :        ABI_FREE(wfd%s(is)%k(ik)%b)
    1175              :      end do
    1176         5531 :      ABI_FREE(wfd%s(is)%k)
    1177              :    end do
    1178          975 :    ABI_FREE(wfd%s)
    1179              :  end if
    1180              : 
    1181          491 :  ABI_SFREE(wfd%my_nkspin)
    1182          491 :  ABI_SFREE(wfd%bks2wfd)
    1183              : 
    1184              :  ! real arrays.
    1185          491 :  ABI_SFREE(Wfd%kibz)
    1186          491 :  ABI_SFREE(Wfd%ph1d)
    1187              : 
    1188              :  ! logical arrays.
    1189          491 :  ABI_SFREE(Wfd%keep_ur)
    1190              : 
    1191              :  ! datatypes.
    1192          491 :  if (allocated(Wfd%Kdata)) then
    1193          484 :    call kdata_free(Wfd%Kdata)
    1194         8628 :    ABI_FREE(Wfd%Kdata)
    1195              :  end if
    1196              : 
    1197          491 :  call destroy_mpi_enreg(Wfd%MPI_enreg)
    1198              : 
    1199              :  ! FIXME: I don't why but this causes a SIGSEV on the test farm.
    1200              :  !do is=1,wfd%nsppol
    1201              :  !  call xmpi_comm_free(wfd%comm_spin(is))
    1202              :  !end do
    1203          491 :  ABI_SFREE(wfd%comm_spin)
    1204              : 
    1205          491 : end subroutine wfd_free
    1206              : !!***
    1207              : 
    1208              : !----------------------------------------------------------------------
    1209              : 
    1210              : !!****f* m_wfd/wfdgw_copy
    1211              : !! NAME
    1212              : !!  wfdgw_copy
    1213              : !!
    1214              : !! FUNCTION
    1215              : !!  Copy a wfd_t data type.
    1216              : !!
    1217              : !! SOURCE
    1218              : 
    1219            0 : subroutine wfdgw_copy(Wfd_in, Wfd_out)
    1220              : 
    1221              : !Arguments ------------------------------------
    1222              :  class(wfdgw_t),intent(inout) :: Wfd_in,Wfd_out
    1223              : 
    1224              : !Local variables ------------------------------
    1225              : !scalars
    1226              :  integer :: band, ik_ibz, spin, cnt_s, cnt_b, ib, ik, is
    1227              : !************************************************************************
    1228              : 
    1229              :  !@wfd_t
    1230            0 :  call deep_copy(Wfd_in%debug_level    ,Wfd_out%debug_level)
    1231            0 :  call deep_copy(Wfd_in%lmnmax         ,Wfd_out%lmnmax)
    1232            0 :  call deep_copy(Wfd_in%mband          ,Wfd_out%mband)
    1233            0 :  call deep_copy(Wfd_in%mgfft          ,Wfd_out%mgfft)
    1234            0 :  call deep_copy(Wfd_in%natom          ,Wfd_out%natom)
    1235            0 :  call deep_copy(Wfd_in%nfft           ,Wfd_out%nfft)
    1236            0 :  call deep_copy(Wfd_in%nfftot         ,Wfd_out%nfftot)
    1237            0 :  call deep_copy(Wfd_in%nkibz          ,Wfd_out%nkibz)
    1238            0 :  call deep_copy(Wfd_in%nspden         ,Wfd_out%nspden)
    1239            0 :  call deep_copy(Wfd_in%nspinor        ,Wfd_out%nspinor)
    1240            0 :  call deep_copy(Wfd_in%nsppol         ,Wfd_out%nsppol)
    1241            0 :  call deep_copy(Wfd_in%ntypat         ,Wfd_out%ntypat)
    1242            0 :  call deep_copy(Wfd_in%paral_kgb      ,Wfd_out%paral_kgb)
    1243            0 :  call deep_copy(Wfd_in%usepaw         ,Wfd_out%usepaw)
    1244            0 :  call deep_copy(Wfd_in%prtvol         ,Wfd_out%prtvol)
    1245            0 :  call deep_copy(Wfd_in%pawprtvol      ,Wfd_out%pawprtvol)
    1246            0 :  call deep_copy(Wfd_in%usewvl         ,Wfd_out%usewvl)
    1247            0 :  call deep_copy(Wfd_in%comm           ,Wfd_out%comm)
    1248            0 :  call deep_copy(Wfd_in%master         ,Wfd_out%master)
    1249            0 :  call deep_copy(Wfd_in%my_rank        ,Wfd_out%my_rank)
    1250            0 :  call deep_copy(Wfd_in%nproc          ,Wfd_out%nproc)
    1251            0 :  call deep_copy(Wfd_in%my_nspins      ,Wfd_out%my_nspins)
    1252            0 :  call deep_copy(Wfd_in%rfft_is_symok  ,Wfd_out%rfft_is_symok)
    1253            0 :  call deep_copy(Wfd_in%dilatmx        ,Wfd_out%dilatmx)
    1254            0 :  call deep_copy(Wfd_in%ecut           ,Wfd_out%ecut)
    1255            0 :  call deep_copy(Wfd_in%ecutsm         ,Wfd_out%ecutsm)
    1256              : 
    1257              : !arrays
    1258            0 :  Wfd_out%ngfft =Wfd_in%ngfft
    1259            0 :  Wfd_out%nloalg=Wfd_in%nloalg
    1260              : 
    1261            0 :  call alloc_copy(Wfd_in%my_nkspin     ,Wfd_out%my_nkspin)
    1262            0 :  call alloc_copy(Wfd_in%irottb        ,Wfd_out%irottb)
    1263            0 :  call alloc_copy(Wfd_in%istwfk        ,Wfd_out%istwfk)
    1264            0 :  call alloc_copy(Wfd_in%nband         ,Wfd_out%nband)
    1265            0 :  call alloc_copy(Wfd_in%indlmn        ,Wfd_out%indlmn)
    1266            0 :  call alloc_copy(Wfd_in%nlmn_atm      ,Wfd_out%nlmn_atm)
    1267            0 :  call alloc_copy(Wfd_in%nlmn_sort     ,Wfd_out%nlmn_sort)
    1268            0 :  call alloc_copy(Wfd_in%nlmn_type     ,Wfd_out%nlmn_type)
    1269            0 :  call alloc_copy(Wfd_in%npwarr        ,Wfd_out%npwarr)
    1270            0 :  call alloc_copy(Wfd_in%kibz          ,Wfd_out%kibz)
    1271            0 :  call alloc_copy(Wfd_in%bks2wfd       ,Wfd_out%bks2wfd)
    1272            0 :  call alloc_copy(Wfd_in%bks_tab       ,Wfd_out%bks_tab)
    1273            0 :  call alloc_copy(Wfd_in%ph1d          ,Wfd_out%ph1d)
    1274            0 :  call alloc_copy(Wfd_in%keep_ur       ,Wfd_out%keep_ur)
    1275              : 
    1276              :  ! types
    1277            0 :  if (size(Wfd_in%Kdata,DIM=1) /= size(Wfd_out%Kdata,DIM=1)) then
    1278            0 :    ABI_REMALLOC(Wfd_out%Kdata, (Wfd_out%nkibz))
    1279              :  end if
    1280              : 
    1281            0 :  call kdata_copy(Wfd_in%Kdata, Wfd_out%Kdata)
    1282              : 
    1283              :  ! Allocate ragged array.
    1284            0 :  ABI_MALLOC(wfd_out%s, (wfd_out%my_nspins))
    1285            0 :  cnt_s = 0
    1286            0 :  do spin=1,wfd_out%nsppol
    1287            0 :    if (wfd_out%my_nkspin(spin) > 0) then
    1288            0 :      cnt_s = cnt_s + 1
    1289            0 :      ABI_MALLOC(wfd_out%s(cnt_s)%k, (wfd_out%my_nkspin(spin)))
    1290            0 :      do ik=1,wfd_out%my_nkspin(spin)
    1291            0 :         cnt_b = size(wfd_out%s(cnt_s)%k(ik)%b)
    1292            0 :         ABI_MALLOC(wfd_out%s(cnt_s)%k(ik)%b, (cnt_b))
    1293              :      end do
    1294              :    end if
    1295              :  end do
    1296              : 
    1297              :  ! Copy waves
    1298            0 :  do spin=1,wfd_in%nsppol
    1299            0 :    do ik_ibz=1,wfd_in%nkibz
    1300            0 :      do band=1,wfd_in%nband(ik_ibz, spin)
    1301            0 :        ib = wfd_in%bks2wfd(1, band, ik_ibz, spin)
    1302            0 :        ik = wfd_in%bks2wfd(2, band, ik_ibz, spin)
    1303            0 :        is = wfd_in%bks2wfd(3, band, ik_ibz, spin)
    1304            0 :        if (ib /= 0) wfd_out%s(is)%k(ik)%b(ib) = wfd_in%s(is)%k(ik)%b(ib)%copy()
    1305              :      end do
    1306              :    end do
    1307              :  end do
    1308              : 
    1309            0 :  call copy_mpi_enreg(Wfd_in%MPI_enreg, Wfd_out%MPI_enreg)
    1310              : 
    1311            0 : end subroutine wfdgw_copy
    1312              : !!***
    1313              : 
    1314              : !----------------------------------------------------------------------
    1315              : 
    1316              : !!****f* m_wfd/wfd_norm2
    1317              : !! NAME
    1318              : !!  wfd_norm2
    1319              : !!
    1320              : !! FUNCTION
    1321              : !!   Compute <u_{bks}|u_{bks}> in G-space
    1322              : !!
    1323              : !! INPUTS
    1324              : !!  Wfd<wfd_t>=the wavefunction descriptor.
    1325              : !!  Cryst<crystal_t>=Structure describing the crystal structure and its symmetries.
    1326              : !!  Pawtab(ntypat*usepaw)<type(pawtab_type)>=PAW tabulated starting data.
    1327              : !!  band=Band index.
    1328              : !!  ik_bz=Index of the k-point in the BZ.
    1329              : !!  spin=Spin index
    1330              : !!
    1331              : !! SOURCE
    1332              : 
    1333            0 : function wfd_norm2(Wfd,Cryst,Pawtab,band,ik_ibz,spin) result(norm2)
    1334              : 
    1335              : !Arguments ------------------------------------
    1336              : !scalars
    1337              :  integer,intent(in) :: band,ik_ibz,spin
    1338              :  real(dp) :: norm2
    1339              :  type(crystal_t),intent(in) :: Cryst
    1340              :  class(wfd_t),target,intent(inout) :: Wfd
    1341              :  type(Pawtab_type),intent(in) :: Pawtab(Cryst%ntypat*Wfd%usepaw)
    1342              : 
    1343              : !Local variables ------------------------------
    1344              : !scalars
    1345              :  integer :: npw_k,istwf_k
    1346              :  complex(dp) :: cdum
    1347              :  type(wave_t),pointer :: wave
    1348              :  character(len=500) :: msg
    1349              : !arrays
    1350              :  real(dp) :: pawovlp(2)
    1351            0 :  complex(gwp),contiguous, pointer :: ug1(:)
    1352            0 :  type(pawcprj_type),allocatable :: Cp1(:,:)
    1353              : !************************************************************************
    1354              : 
    1355              :  ! Planewave part.
    1356            0 :  npw_k   = Wfd%npwarr(ik_ibz)
    1357            0 :  istwf_k = Wfd%istwfk(ik_ibz)
    1358              : 
    1359            0 :  ABI_CHECK(wfd%get_wave_ptr(band, ik_ibz, spin, wave, msg) == 0, msg)
    1360              : 
    1361            0 :  ug1 => wave%ug
    1362            0 :  cdum = xdotc(Wfd%nspinor*npw_k,ug1,1,ug1,1)
    1363              : 
    1364            0 :  if (istwf_k>1) then
    1365            0 :    cdum=two*DBLE(cdum)
    1366            0 :    if (istwf_k==2) cdum=cdum-CONJG(ug1(1))*ug1(1)
    1367              :  end if
    1368              : 
    1369              :  ! Paw on-site term.
    1370            0 :  if (Wfd%usepaw==1) then
    1371              : 
    1372              :    ! Avoid the computation if Cprj are already in memory with the correct order.
    1373            0 :    if (wave%has_cprj == WFD_STORED .and. wave%cprj_order == CPR_RANDOM) then
    1374            0 :        pawovlp = paw_overlap(wave%Cprj, wave%Cprj, Cryst%typat, Pawtab)
    1375            0 :        cdum = cdum + CMPLX(pawovlp(1),pawovlp(2), kind=dp)
    1376              :    else
    1377              :      ! Compute Cproj
    1378            0 :      ABI_MALLOC(Cp1,(Wfd%natom,Wfd%nspinor))
    1379            0 :      call pawcprj_alloc(Cp1,0,Wfd%nlmn_atm)
    1380            0 :      call wfd%get_cprj(band,ik_ibz,spin,Cryst,Cp1,sorted=.FALSE.)
    1381            0 :      pawovlp = paw_overlap(Cp1,Cp1,Cryst%typat,Pawtab)
    1382            0 :      cdum = cdum + CMPLX(pawovlp(1),pawovlp(2), kind=dp)
    1383            0 :      call pawcprj_free(Cp1)
    1384            0 :      ABI_FREE(Cp1)
    1385              :    end if
    1386              :  end if
    1387              : 
    1388            0 :  norm2 = DBLE(cdum)
    1389              : 
    1390            0 : end function wfd_norm2
    1391              : !!***
    1392              : 
    1393              : !----------------------------------------------------------------------
    1394              : 
    1395              : !!****f* m_wfd/wfd_xdotc
    1396              : !! NAME
    1397              : !!  wfd_xdotc
    1398              : !!
    1399              : !! FUNCTION
    1400              : !!   Compute <u_{b1ks}|u_{b2ks}> in G-space
    1401              : !!
    1402              : !! INPUTS
    1403              : !!  Wfd<wfd_t>=the wavefunction descriptor.
    1404              : !!  Cryst<crystal_t>=Structure describing the crystal structure and its symmetries.
    1405              : !!  Pawtab(ntypat*usepaw)<type(pawtab_type)>=PAW tabulated starting data.
    1406              : !!  band1, band2=Band indices.
    1407              : !!  ik_bz=Index of the k-point in the BZ.
    1408              : !!  spin=Spin index
    1409              : !!
    1410              : !! SOURCE
    1411              : 
    1412            0 : function wfd_xdotc(Wfd,Cryst,Pawtab,band1,band2,ik_ibz,spin)
    1413              : 
    1414              : !Arguments ------------------------------------
    1415              : !scalars
    1416              :  integer,intent(in) :: band1,band2,ik_ibz,spin
    1417              :  complex(gwp) :: wfd_xdotc
    1418              :  class(wfd_t),target,intent(inout) :: Wfd
    1419              :  type(crystal_t),intent(in) :: Cryst
    1420              : !arrays
    1421              :  type(Pawtab_type),intent(in) :: Pawtab(Cryst%ntypat*Wfd%usepaw)
    1422              : 
    1423              : !Local variables ------------------------------
    1424              : !scalars
    1425              :  integer :: npw_k,istwf_k
    1426              :  type(wave_t),pointer :: wave1, wave2
    1427              :  character(len=500) :: msg
    1428              : !arrays
    1429              :  real(dp) :: pawovlp(2)
    1430            0 :  complex(gwp),contiguous, pointer :: ug1(:),ug2(:)
    1431            0 :  type(pawcprj_type),allocatable :: Cp1(:,:),Cp2(:,:)
    1432              : !************************************************************************
    1433              : 
    1434              :  ! Planewave part.
    1435            0 :  npw_k   = Wfd%npwarr(ik_ibz)
    1436            0 :  istwf_k = Wfd%istwfk(ik_ibz)
    1437              : 
    1438            0 :  ABI_CHECK(wfd%get_wave_ptr(band1, ik_ibz, spin, wave1, msg) == 0, msg)
    1439            0 :  ABI_CHECK(wfd%get_wave_ptr(band2, ik_ibz, spin, wave2, msg) == 0, msg)
    1440            0 :  ug1 => wave1%ug
    1441            0 :  ug2 => wave2%ug
    1442              : 
    1443            0 :  wfd_xdotc = xdotc(npw_k*Wfd%nspinor,ug1,1,ug2,1)
    1444            0 :  if (istwf_k>1) then
    1445            0 :    wfd_xdotc=two*DBLE(wfd_xdotc)
    1446            0 :    if (istwf_k==2) wfd_xdotc = wfd_xdotc-CONJG(ug1(1))*ug2(1)
    1447              :  end if
    1448              : 
    1449              :  ! Paw on-site term.
    1450            0 :  if (Wfd%usepaw==1) then
    1451              :    ! Avoid the computation if Cprj are already in memory with the correct order.
    1452              :    if (wave1%has_cprj == WFD_STORED .and. wave1%cprj_order == CPR_RANDOM .and. &
    1453            0 :        wave2%has_cprj == WFD_STORED .and. wave2%cprj_order == CPR_RANDOM) then
    1454              : 
    1455              :        pawovlp = paw_overlap(wave1%Cprj, wave2%Cprj,&
    1456            0 :                              Cryst%typat,Pawtab,spinor_comm=Wfd%MPI_enreg%comm_spinor)
    1457            0 :        wfd_xdotc = wfd_xdotc + CMPLX(pawovlp(1),pawovlp(2), kind=gwp)
    1458              :    else
    1459              :      ! Compute Cprj
    1460            0 :      ABI_MALLOC(Cp1,(Wfd%natom,Wfd%nspinor))
    1461            0 :      call pawcprj_alloc(Cp1,0,Wfd%nlmn_atm)
    1462            0 :      ABI_MALLOC(Cp2,(Wfd%natom,Wfd%nspinor))
    1463            0 :      call pawcprj_alloc(Cp2,0,Wfd%nlmn_atm)
    1464              : 
    1465            0 :      call wfd%get_cprj(band1,ik_ibz,spin,Cryst,Cp1,sorted=.FALSE.)
    1466            0 :      call wfd%get_cprj(band2,ik_ibz,spin,Cryst,Cp2,sorted=.FALSE.)
    1467              : 
    1468            0 :      pawovlp = paw_overlap(Cp1,Cp2,Cryst%typat,Pawtab,spinor_comm=Wfd%MPI_enreg%comm_spinor)
    1469            0 :      wfd_xdotc = wfd_xdotc + CMPLX(pawovlp(1),pawovlp(2), kind=gwp)
    1470              : 
    1471            0 :      call pawcprj_free(Cp1)
    1472            0 :      ABI_FREE(Cp1)
    1473            0 :      call pawcprj_free(Cp2)
    1474            0 :      ABI_FREE(Cp2)
    1475              :    end if
    1476              :  end if
    1477              : 
    1478            0 : end function wfd_xdotc
    1479              : !!***
    1480              : 
    1481              : !----------------------------------------------------------------------
    1482              : 
    1483              : !!****f* m_wfd/wfd_get_gvec_gbound
    1484              : !! NAME
    1485              : !! wfd_get_gvec_gbound
    1486              : !!
    1487              : !! FUNCTION
    1488              : !! Return the g-sphere centered on kq and gbound_kq,
    1489              : !! mainly used when looping over wavevectors in the full BZ.
    1490              : !!
    1491              : !! INPUTS
    1492              : !!
    1493              : !! OUTPUT
    1494              : !!
    1495              : !! SOURCE
    1496              : 
    1497         5491 : subroutine wfd_get_gvec_gbound(wfd, gmet, ecut, kq, ikq_ibz, isirr_kq, nloalg, &    ! in
    1498         5491 :                                istwf_kq, npw_kq, kg_kq, nkpg_kq, kpg_kq, gbound_kq) ! out
    1499              : 
    1500              : !Arguments -------------------------------
    1501              :  class(wfd_t),intent(in) :: wfd
    1502              :  real(dp),intent(in) :: gmet(3,3), ecut, kq(3)
    1503              :  integer,intent(in) :: ikq_ibz, nloalg(3)
    1504              :  logical,intent(in) :: isirr_kq
    1505              :  integer,intent(out) :: istwf_kq, npw_kq, kg_kq(:,:), nkpg_kq, gbound_kq(2*wfd%mgfft+8,2)
    1506              :  real(dp),allocatable,intent(out) :: kpg_kq(:,:)
    1507              : 
    1508              : !Local variables ------------------------------
    1509              :  integer :: mpw
    1510         5491 :  integer,allocatable :: gtmp(:,:)
    1511              : ! *********************************************************************
    1512              : 
    1513         5491 :  mpw = size(kg_kq, dim=2)
    1514              : 
    1515         5491 :  if (isirr_kq) then
    1516              :    ! Copy data
    1517         1228 :    istwf_kq = wfd%istwfk(ikq_ibz); npw_kq = wfd%npwarr(ikq_ibz)
    1518         1228 :    ABI_CHECK_IGEQ(mpw, npw_kq, sjoin("mpw should be => npw_kq for kq:", ktoa(kq)))
    1519      4686408 :    kg_kq(:,1:npw_kq) = wfd%kdata(ikq_ibz)%kg_k
    1520              :  else
    1521              :    ! Build new g-sphere centered on k+q without TR
    1522         4263 :    istwf_kq = 1
    1523         4263 :    call get_kg(kq, istwf_kq, ecut, gmet, npw_kq, gtmp)
    1524         4263 :    ABI_CHECK_IGEQ(mpw, npw_kq, sjoin("mpw should be => npw_kq for kq:", ktoa(kq)))
    1525     11770399 :    kg_kq(:,1:npw_kq) = gtmp(:,:npw_kq)
    1526         4263 :    ABI_FREE(gtmp)
    1527              :  end if
    1528              : 
    1529         5491 :  call sphereboundary(gbound_kq, istwf_kq, kg_kq, wfd%mgfft, npw_kq)
    1530              : 
    1531         5491 :  nkpg_kq = 3*nloalg(3)
    1532        21964 :  ABI_MALLOC(kpg_kq, (npw_kq, nkpg_kq))
    1533         5491 :  if (nkpg_kq > 0) call mkkpg(kg_kq, kpg_kq, kq, nkpg_kq, npw_kq)
    1534              : 
    1535         5491 : end subroutine wfd_get_gvec_gbound
    1536              : !!***
    1537              : 
    1538              : !----------------------------------------------------------------------
    1539              : 
    1540              : !!****f* m_wfd/wfd_reset_ur_cprj
    1541              : !! NAME
    1542              : !!  wfd_reset_ur_cprj
    1543              : !!
    1544              : !! FUNCTION
    1545              : !!  Reinitialize the storage mode of the ur treated by this node.
    1546              : !!
    1547              : !! SOURCE
    1548              : 
    1549           76 : subroutine wfd_reset_ur_cprj(Wfd)
    1550              : 
    1551              : !Arguments ------------------------------------
    1552              :  class(wfd_t),intent(inout) :: Wfd
    1553              : 
    1554              : !Local variables ------------------------------
    1555              :  integer :: ib, ik, is
    1556              : !************************************************************************
    1557              : 
    1558          154 :  do is=1,size(wfd%s)
    1559          607 :    do ik=1,size(wfd%s(is)%k)
    1560         5771 :      do ib=1,size(wfd%s(is)%k(ik)%b)
    1561         5240 :        if (wfd%s(is)%k(ik)%b(ib)%has_ur == WFD_STORED) wfd%s(is)%k(ik)%b(ib)%has_ur = WFD_ALLOCATED
    1562         5693 :        if (wfd%usepaw == 1) then
    1563            0 :          if (wfd%s(is)%k(ik)%b(ib)%has_cprj == WFD_STORED) wfd%s(is)%k(ik)%b(ib)%has_cprj = WFD_ALLOCATED
    1564              :        end if
    1565              :      end do
    1566              :    end do
    1567              :  end do
    1568              : 
    1569           76 : end subroutine wfd_reset_ur_cprj
    1570              : !!***
    1571              : 
    1572              : !----------------------------------------------------------------------
    1573              : 
    1574              : !!****f* m_wfd/wfd_get_many_ur
    1575              : !! NAME
    1576              : !!  wfd_get_many_ur
    1577              : !!
    1578              : !! FUNCTION
    1579              : !!  Get many wave functions in real space, either by doing a G-->R FFT
    1580              : !!  or by just retrieving the data already stored in Wfd.
    1581              : !!
    1582              : !! INPUTS
    1583              : !!  Wfd<wfd_t>=the wavefunction descriptor.
    1584              : !!  ndat=Number of wavefunctions required
    1585              : !!  bands(:)=Band indices.
    1586              : !!  ik_ibz=Index of the k-point in the IBZ.
    1587              : !!  spin=Spin index
    1588              : !!
    1589              : !! OUTPUT
    1590              : !!  ur(Wfd%nfft*Wfd%nspinor*SIZE(bands))=The wavefunction in real space.
    1591              : !!
    1592              : !! SOURCE
    1593              : 
    1594         1124 : subroutine wfd_get_many_ur(Wfd, bands, ik_ibz, spin, ur)
    1595              : 
    1596              : !Arguments ------------------------------------
    1597              : !scalars
    1598              :  integer,intent(in) :: ik_ibz,spin
    1599              :  class(wfd_t),intent(inout) :: Wfd
    1600              : !arrays
    1601              :  integer,intent(in) :: bands(:)
    1602              :  complex(gwp),intent(out) :: ur(Wfd%nfft*Wfd%nspinor*SIZE(bands))
    1603              : 
    1604              : !Local variables ------------------------------
    1605              :  integer :: dat,ptr,band
    1606              : !************************************************************************
    1607              : 
    1608         9924 :  do dat=1,SIZE(bands)
    1609         8800 :    band = bands(dat)
    1610         8800 :    ptr = 1 + (dat-1)*Wfd%nfft*Wfd%nspinor
    1611         9924 :    call wfd%get_ur(band,ik_ibz,spin,ur(ptr))
    1612              :  end do
    1613              : 
    1614         1124 : end subroutine wfd_get_many_ur
    1615              : !!***
    1616              : 
    1617              : !----------------------------------------------------------------------
    1618              : 
    1619              : !!****f* m_wfd/wfd_copy_cg
    1620              : !! NAME
    1621              : !!  wfd_copy_cg
    1622              : !!
    1623              : !! FUNCTION
    1624              : !!  Return a copy u(g) in a real(dp) array. Useful if we have to interface
    1625              : !!  the wavefunction descriptor with Abinit code expecting cg(2,npw_k*nspinor) arrays
    1626              : !!  The routine takes also into account the fact that the ug in wfs could be stored in single-precision.
    1627              : !!
    1628              : !! INPUTS
    1629              : !!  wfd<wfd_t>=the wavefunction descriptor.
    1630              : !!  band=Band index.
    1631              : !!  ik_ibz=Index of the k-point in the IBZ.
    1632              : !!  spin=Spin index
    1633              : !!
    1634              : !! OUTPUT
    1635              : !!  cg(npw_k*nspinor)=The wavefunction in real space in the Abinit cg convention.
    1636              : !!
    1637              : !! SOURCE
    1638              : 
    1639       397347 : subroutine wfd_copy_cg(wfd, band, ik_ibz, spin, cg)
    1640              : 
    1641              : !Arguments ------------------------------------
    1642              : !scalars
    1643              :  integer,intent(in) :: band,ik_ibz,spin
    1644              :  class(wfd_t),intent(in) :: wfd
    1645              : !arrays
    1646              :  real(dp),intent(out) :: cg(2,*) ! npw_k*wfd%nspinor)
    1647              : 
    1648              : !Local variables ------------------------------
    1649              : !scalars
    1650              :  integer :: csiz
    1651              :  type(wave_t),pointer :: wave
    1652              :  character(len=500) :: msg
    1653              : !************************************************************************
    1654              : 
    1655       397347 :  ABI_CHECK(wfd%get_wave_ptr(band, ik_ibz, spin, wave, msg) == 0, msg)
    1656              : 
    1657       397347 :  if (.not. wave%has_ug == WFD_STORED) then
    1658            0 :    write(msg,'(a,3(i0,1x),a)')" ug for (band, ik_ibz, spin): ",band, ik_ibz, spin," is not stored in memory!"
    1659            0 :    ABI_ERROR(msg)
    1660              :  end if
    1661              : 
    1662       397347 :  csiz = wfd%npwarr(ik_ibz) * wfd%nspinor
    1663              : #ifdef HAVE_GW_DPC
    1664       397347 :  call zcopy(csiz, wave%ug, 1, cg, 1)
    1665              : #else
    1666              :  cg(1,1:csiz) = dble(wave%ug)
    1667              :  cg(2,1:csiz) = aimag(wave%ug)
    1668              : #endif
    1669              : 
    1670       397347 : end subroutine wfd_copy_cg
    1671              : !!***
    1672              : 
    1673              : !----------------------------------------------------------------------
    1674              : 
    1675              : !!****f* m_wfd/wfd_get_ur
    1676              : !! NAME
    1677              : !!  wfd_get_ur
    1678              : !!
    1679              : !! FUNCTION
    1680              : !!  Get a wave function in real space, either by doing a G-->R FFT
    1681              : !!  or by just retrieving the data already stored in Wfd.
    1682              : !!
    1683              : !! INPUTS
    1684              : !!  Wfd<wfd_t>=the wavefunction descriptor.
    1685              : !!  band=Band index.
    1686              : !!  ik_ibz=Index of the k-point in the IBZ.
    1687              : !!  spin=Spin index
    1688              : !!
    1689              : !! OUTPUT
    1690              : !!  ur(Wfd%nfft*Wfd%nspinor)=The wavefunction in real space.
    1691              : !!
    1692              : !! SOURCE
    1693              : 
    1694      2413007 : subroutine wfd_get_ur(Wfd, band, ik_ibz, spin, ur)
    1695              : 
    1696              : !Arguments ------------------------------------
    1697              : !scalars
    1698              :  integer,intent(in) :: band,ik_ibz,spin
    1699              :  class(wfd_t),target,intent(inout) :: Wfd
    1700              : !arrays
    1701              :  complex(gwp),intent(out) :: ur(Wfd%nfft*Wfd%nspinor)
    1702              : 
    1703              : !Local variables ------------------------------
    1704              : !scalars
    1705              :  integer,parameter :: npw0=0,ndat1=1
    1706              :  integer :: npw_k, nfft, nspinor
    1707              :  character(len=500) :: msg
    1708              :  type(wave_t),pointer :: wave
    1709              : !arrays
    1710      2413007 :  integer,contiguous, pointer :: kg_k(:,:),gbound(:,:)
    1711      2413007 :  complex(gwp),contiguous, pointer :: ug(:)
    1712              : !************************************************************************
    1713              : 
    1714      2413007 :  npw_k  = Wfd%npwarr(ik_ibz)
    1715      2413007 :  nfft   = Wfd%nfft
    1716      2413007 :  nspinor= Wfd%nspinor
    1717              : 
    1718      2413007 :  ABI_CHECK(wfd%get_wave_ptr(band, ik_ibz, spin, wave, msg) == 0, msg)
    1719              : 
    1720      2525311 :  select case (wave%has_ur)
    1721              : 
    1722              :  case (WFD_NOWAVE, WFD_ALLOCATED)
    1723              :    ! FFT is required.
    1724       112304 :    if (.not. wave%has_ug == WFD_STORED) then
    1725            0 :      write(msg,'(a,3(i0,1x),a)')" ug for (band, ik_ibz, spin): ",band,ik_ibz,spin," is not stored in memory!"
    1726            0 :      ABI_ERROR(msg)
    1727              :    end if
    1728              : 
    1729       112304 :    ug => wave%ug
    1730       112304 :    kg_k    => Wfd%Kdata(ik_ibz)%kg_k
    1731       112304 :    gbound  => Wfd%Kdata(ik_ibz)%gbound(:,:)
    1732              : 
    1733       112304 :    call fft_ug(npw_k,nfft,nspinor,ndat1,Wfd%mgfft,Wfd%ngfft,Wfd%istwfk(ik_ibz),kg_k,gbound,ug,ur)
    1734              : 
    1735       112304 :    if (Wfd%keep_ur(band,ik_ibz,spin)) then
    1736              :      ! Store results
    1737        66966 :      if (wave%has_ur == WFD_NOWAVE) then
    1738              :        ! Alloc buffer for ur.
    1739        62826 :        call wave_init(wave, Wfd%usepaw,npw0,nfft,nspinor,Wfd%natom,Wfd%nlmn_atm,CPR_RANDOM)
    1740              :      end if
    1741        66966 :      call xcopy(nfft*nspinor, ur, 1, wave%ur, 1)
    1742        66966 :      wave%has_ur = WFD_STORED
    1743              :    end if
    1744              : 
    1745              :  case (WFD_STORED)
    1746              :    ! copy it back.
    1747      2300703 :    call xcopy(nfft*nspinor, wave%ur, 1, ur, 1)
    1748              : 
    1749              :  case default
    1750      2413007 :    ABI_BUG(sjoin("Wrong has_ur:", itoa(wave%has_ur)))
    1751              :  end select
    1752              : 
    1753      2413007 : end subroutine wfd_get_ur
    1754              : !!***
    1755              : 
    1756              : !----------------------------------------------------------------------
    1757              : 
    1758              : !!****f* m_wfd/wfd_print
    1759              : !! NAME
    1760              : !! wfd_print
    1761              : !!
    1762              : !! FUNCTION
    1763              : !!  Print the content of a wfd_t datatype
    1764              : !!
    1765              : !! INPUTS
    1766              : !!  units=Unit numbers for output
    1767              : !!  [header]=String to be printed as header for additional info.
    1768              : !!  [prtvol]=Verbosity level
    1769              : !!
    1770              : !! OUTPUT
    1771              : !!  Only printing
    1772              : !!
    1773              : !! SOURCE
    1774              : 
    1775          938 : subroutine wfd_print(Wfd, units, header, prtvol)
    1776              : 
    1777              : !Arguments ------------------------------------
    1778              :  class(wfd_t),intent(in) :: Wfd
    1779              :  integer,intent(in) :: units(:)
    1780              :  integer,optional,intent(in) :: prtvol
    1781              :  character(len=*),optional,intent(in) :: header
    1782              : 
    1783              : !Local variables-------------------------------
    1784              : !scalars
    1785              :  integer :: my_prtvol, mpw, ib, ik, is, ug_cnt, ur_cnt, cprj_cnt, spin, ik_ibz, band
    1786              :  real(dp) :: ug_size, ur_size, cprj_size !,kdata_bsize
    1787              :  character(len=500) :: msg
    1788              : ! *************************************************************************
    1789              : 
    1790          469 :  my_prtvol=0      ; if (present(prtvol    )) my_prtvol=prtvol
    1791              : 
    1792          469 :  msg = ' ==== Info on the wfd% object ==== '
    1793          469 :  if (present(header)) msg=' ==== '//TRIM(ADJUSTL(header))//' ==== '
    1794          469 :  call wrtout(units, msg)
    1795              : 
    1796              :  write(msg,'(3(a,i0,a),a,i0,2a,f5.1)')&
    1797          469 :    '  Number of irreducible k-points ........ ',Wfd%nkibz,ch10,&
    1798          469 :    '  Number of spinorial components ........ ',Wfd%nspinor,ch10,&
    1799          469 :    '  Number of spin-density components ..... ',Wfd%nspden,ch10,&
    1800          469 :    '  Number of spin polarizations .......... ',Wfd%nsppol,ch10,&
    1801          938 :    '  Plane wave cutoff energy .............. ',Wfd%ecut
    1802          469 :  call wrtout(units, msg)
    1803              : 
    1804         8236 :  mpw = maxval(Wfd%npwarr)
    1805              :  write(msg,'(3(a,i0,a))')&
    1806          469 :    '  Max number of G-vectors ............... ',mpw,ch10,&
    1807          469 :    '  Total number of FFT points ............ ',Wfd%nfftot,ch10,&
    1808          938 :    '-  Number of FFT points treated by me .... ',Wfd%nfft,ch10
    1809          469 :  call wrtout(units, msg)
    1810              : 
    1811          469 :  call print_ngfft(units, Wfd%ngfft, 'FFT mesh for wavefunctions', prtvol=my_prtvol)
    1812              : 
    1813          469 :  ug_cnt = 0; ur_cnt = 0; cprj_cnt = 0
    1814          945 :  do spin=1,Wfd%nsppol
    1815         8732 :    do ik_ibz=1,Wfd%nkibz
    1816       113254 :      do band=1,Wfd%nband(ik_ibz,spin)
    1817       104991 :        ib = wfd%bks2wfd(1, band, ik_ibz, spin)
    1818       104991 :        if (ib  == 0) cycle
    1819        67295 :        ik = wfd%bks2wfd(2, band, ik_ibz, spin)
    1820        67295 :        is = wfd%bks2wfd(3, band, ik_ibz, spin)
    1821        67295 :        if (wfd%s(is)%k(ik)%b(ib)%has_ug >= WFD_ALLOCATED) ug_cnt = ug_cnt + 1
    1822        67295 :        if (wfd%s(is)%k(ik)%b(ib)%has_ur >= WFD_ALLOCATED) ur_cnt = ur_cnt + 1
    1823        75082 :        if (wfd%s(is)%k(ik)%b(ib)%has_cprj >= WFD_ALLOCATED) cprj_cnt = cprj_cnt + 1
    1824              :      end do
    1825              :    end do
    1826              :  end do
    1827              : 
    1828              :  ! Info on memory needed for u(g), u(r) and PAW cprj
    1829          469 :  write(msg, '(a,i0)')'P Total number of (b,k,s) states stored by this rank: ', ug_cnt
    1830          469 :  call wrtout(units, msg, pre_newlines=1)
    1831              : 
    1832          469 :  ug_size = one * Wfd%nspinor * mpw * ug_cnt
    1833          469 :  write(msg,'(a,f8.1,a)')'P Memory allocated for Fourier components u(G): ',two*gwp*ug_size*b2Mb,' [Mb] <<< MEM'
    1834          469 :  call wrtout(units, msg)
    1835              : 
    1836        51745 :  if (any(wfd%keep_ur)) then
    1837          349 :    ur_size = one * Wfd%nspinor * Wfd%nfft * ur_cnt
    1838          349 :    write(msg,'(a,f8.1,a)')'P Memory allocated for real-space u(r): ',two*gwp*ur_size*b2Mb,' [Mb] <<< MEM'
    1839          349 :    call wrtout(units, msg)
    1840              :  end if
    1841              : 
    1842          469 :  if (wfd%usepaw==1) then
    1843           78 :    cprj_size = one * Wfd%nspinor * sum(Wfd%nlmn_atm) * cprj_cnt
    1844           12 :    write(msg,'(a,f8.1,a)')'P Memory allocated for PAW projections cprj: ',dp*cprj_size*b2Mb,' [Mb] <<< MEM'
    1845           12 :    call wrtout(units, msg)
    1846              :  end if
    1847              : 
    1848          938 :  write(msg,'(a,f8.1,a)')'P Memory needed for wfd%s datastructure: ',ABI_MEM_MB(wfd%s),' [Mb] <<< MEM'
    1849          469 :  call wrtout(units, msg)
    1850          938 :  write(msg,'(a,f8.1,a)')'P Memory needed for wfd%s(0)%k datastructure: ',ABI_MEM_MB(wfd%s(1)%k),' [Mb] <<< MEM'
    1851          469 :  call wrtout(units, msg)
    1852          938 :  write(msg,'(a,f8.1,a)')'P Memory allocated for Kdata array: ',ABI_MEM_MB(wfd%kdata),' [Mb] <<< MEM'
    1853          469 :  call wrtout(units, msg, newlines=1)
    1854              : 
    1855          469 : end subroutine wfd_print
    1856              : !!***
    1857              : 
    1858              : !----------------------------------------------------------------------
    1859              : 
    1860              : !!****f* m_wfd/wfd_ug2cprj
    1861              : !! NAME
    1862              : !! wfd_ug2cprj
    1863              : !!
    1864              : !! FUNCTION
    1865              : !!  Calculate the projected wave function <Proj_i|Cnk> with all NL projectors for a single
    1866              : !!  k-point, band and spin.
    1867              : !!
    1868              : !! INPUTS
    1869              : !!  Wfd<wfd_t>=Structure containing the wave functions for the GW.
    1870              : !!  ik_ibz=Index of the required k-point
    1871              : !!  spin=Required spin index.
    1872              : !!  choice=chooses possible output:
    1873              : !!    In addition to projected wave function:
    1874              : !!    choice=1 => nothing else
    1875              : !!          =2 => 1st gradients with respect to atomic position(s)
    1876              : !!          =3 => 1st gradients with respect to strain(s)
    1877              : !!          =23=> 1st gradients with respect to atm. pos. and strain(s)
    1878              : !!          =4 => 2nd derivatives with respect to atomic pos.
    1879              : !!          =24=> 1st and 2nd derivatives with respect to atomic pos.
    1880              : !!          =5 => 1st gradients with respect to k wavevector
    1881              : !!          =6 => 2nd derivatives with respect to strain and atm. pos.
    1882              : !!  idir=direction of the derivative, i.e. dir. of - atom to be moved  in the case choice=2
    1883              : !!                                                 - strain component  in the case choice=3
    1884              : !!                                                 - k point direction in the case choice=5
    1885              : !!       Compatible only with choice=2,3,5; if idir=0, all derivatives are computed
    1886              : !!  natom
    1887              : !!  Cryst
    1888              : !!  [sorted]=Logical flags defining if the output Cprj has to be sorted by atom type or not.
    1889              : !!    By default, Cprj matrix elements are unsorted.
    1890              : !!
    1891              : !! OUTPUT
    1892              : !!  cwaveprj
    1893              : !!
    1894              : !! SOURCE
    1895              : 
    1896         1599 : subroutine wfd_ug2cprj(Wfd,band,ik_ibz,spin,choice,idir,natom,Cryst,cwaveprj,sorted)
    1897              : 
    1898              : !Arguments -------------------------------
    1899              : !scalars
    1900              :  integer,intent(in) :: choice,idir,natom,band,ik_ibz,spin
    1901              :  logical,optional,intent(in) :: sorted
    1902              :  class(wfd_t),target,intent(inout) :: Wfd
    1903              :  type(crystal_t),intent(in) :: Cryst
    1904              : !arrays
    1905              :  type(pawcprj_type),intent(inout) :: cwaveprj(natom,Wfd%nspinor)
    1906              : 
    1907              : !Local variables-------------------------------
    1908              : !scalars
    1909              :  integer :: cpopt,istwf_k,npw_k,nkpg
    1910              :  integer :: ia,iatm,dimffnl,itypat,iatom,isp
    1911              :  character(len=500) :: msg
    1912              :  type(wave_t),pointer :: wave
    1913              :  logical :: want_sorted
    1914              : !arrays
    1915         1599 :  integer,contiguous, pointer :: kg_k(:,:)
    1916         1599 :  integer,allocatable :: dimcprj_srt(:)
    1917              :  real(dp) :: kpoint(3)
    1918         1599 :  real(dp),contiguous, pointer :: phkxred(:,:)
    1919         1599 :  real(dp),allocatable :: cwavef(:,:), kpg(:,:)
    1920              :  !real(dp),allocatable :: ph1d(2,3*(2*mgfft+1)*natom)
    1921         1599 :  real(dp),contiguous, pointer :: ph3d(:,:,:)    ! ph3d(2,npw_k,matblk)
    1922         1599 :  real(dp),contiguous, pointer :: ffnl(:,:,:,:)  ! ffnl(npw_k,dimffnl,lmnmax,ntypat)
    1923         1599 :  type(pawcprj_type),allocatable :: Cprj_srt(:,:)
    1924              : ! *********************************************************************
    1925              : 
    1926              :  ! Different form factors have to be calculated and stored in Kdata.
    1927            0 :  ABI_CHECK_IEQ(choice, 1, "choice/=1 not coded")
    1928              : 
    1929         1599 :  dimffnl = 1
    1930         1599 :  npw_k   = Wfd%npwarr(ik_ibz)
    1931         1599 :  istwf_k = Wfd%istwfk(ik_ibz)
    1932         6396 :  kpoint  = Wfd%kibz(:,ik_ibz)
    1933              : 
    1934         1599 :  kg_k    => Wfd%Kdata(ik_ibz)%kg_k
    1935         1599 :  ph3d    => Wfd%Kdata(ik_ibz)%ph3d
    1936         1599 :  ffnl    => Wfd%Kdata(ik_ibz)%fnl_dir0der0
    1937         1599 :  phkxred => Wfd%Kdata(ik_ibz)%phkxred
    1938              : 
    1939              :  ! Compute (k+G) vectors
    1940         1599 :  nkpg=0
    1941              :  !% if (choice==3.or.choice==2.or.choice==23) nkpg=3*Wfd%nloalg(3)
    1942              :  !% if (choice==4.or.choice==24) nkpg=9*Wfd%nloalg(3)
    1943         3198 :  ABI_MALLOC(kpg,(npw_k,nkpg))
    1944              :  if (nkpg>0) call mkkpg(kg_k,kpg,kpoint,nkpg,npw_k)
    1945              : 
    1946              :  ! Copy wavefunction in G-space
    1947         4797 :  ABI_MALLOC(cwavef, (2,npw_k*Wfd%nspinor))
    1948         1599 :  ABI_CHECK(wfd%get_wave_ptr(band, ik_ibz, spin, wave, msg) == 0, msg)
    1949       973832 :  cwavef(1,:) = DBLE (wave%ug)
    1950       973832 :  cwavef(2,:) = AIMAG(wave%ug)
    1951              : 
    1952         1599 :  cpopt = 0 ! Nothing is already calculated.
    1953              : 
    1954         1599 :  want_sorted=.FALSE.; if (present(sorted)) want_sorted=sorted
    1955              : 
    1956         1599 :  if (want_sorted) then
    1957              :    ! Output cprj are sorted.
    1958              :    call getcprj(choice,cpopt,cwavef,cwaveprj,ffnl,&
    1959              :      idir,Wfd%indlmn,istwf_k,kg_k,kpg,kpoint,Wfd%lmnmax,Wfd%mgfft,Wfd%MPI_enreg,1,&
    1960              :      Cryst%natom,Cryst%nattyp,Wfd%ngfft,Wfd%nloalg,npw_k,Wfd%nspinor,Cryst%ntypat,&
    1961            0 :      phkxred,Wfd%ph1d,ph3d,Cryst%ucvol,1)
    1962              : 
    1963              :  else
    1964              :    ! Output cprj are unsorted.
    1965         4797 :    ABI_MALLOC(dimcprj_srt,(Cryst%natom))
    1966         1599 :    ia=0
    1967         3534 :    do itypat=1,Cryst%ntypat
    1968         6309 :      dimcprj_srt(ia+1:ia+Cryst%nattyp(itypat))=Wfd%nlmn_type(itypat)
    1969         3534 :      ia=ia+Cryst%nattyp(itypat)
    1970              :    end do
    1971              : 
    1972        12369 :    ABI_MALLOC(Cprj_srt,(natom,Wfd%nspinor))
    1973         1599 :    call pawcprj_alloc(Cprj_srt,0,dimcprj_srt)
    1974         1599 :    ABI_FREE(dimcprj_srt)
    1975              : 
    1976              :    ! Calculate sorted cprj.
    1977              :    call getcprj(choice,cpopt,cwavef,Cprj_srt,ffnl,&
    1978              :     idir,Wfd%indlmn,istwf_k,kg_k,kpg,kpoint,Wfd%lmnmax,Wfd%mgfft,Wfd%MPI_enreg,1,&
    1979              :     Cryst%natom,Cryst%nattyp,Wfd%ngfft,Wfd%nloalg,npw_k,Wfd%nspinor,Cryst%ntypat,&
    1980         1599 :     phkxred,Wfd%ph1d,ph3d,Cryst%ucvol,1)
    1981              : 
    1982              :    ! Reorder cprj (sorted --> unsorted)
    1983         5973 :    do iatom=1,Cryst%natom
    1984         4374 :      iatm=Cryst%atindx(iatom)
    1985        10347 :      do isp=1,Wfd%nspinor
    1986       124146 :        cwaveprj(iatom,isp)%cp=Cprj_srt(iatm,isp)%cp
    1987              :      end do
    1988              :    end do
    1989              : 
    1990         1599 :    call pawcprj_free(Cprj_srt)
    1991         5973 :    ABI_FREE(Cprj_srt)
    1992              :  end if
    1993              : 
    1994         1599 :  ABI_FREE(cwavef)
    1995         1599 :  ABI_FREE(kpg)
    1996              : 
    1997         3198 : end subroutine wfd_ug2cprj
    1998              : !!***
    1999              : 
    2000              : !----------------------------------------------------------------------
    2001              : 
    2002              : !!****f* m_wfd/wave_init
    2003              : !! NAME
    2004              : !!  wave_init
    2005              : !!
    2006              : !! FUNCTION
    2007              : !!   Main creation method for the wave_t data type
    2008              : !!
    2009              : !! INPUTS
    2010              : !!  usepaw=1 if PAW is used.
    2011              : !!  npw =Number of plane-waves for ug
    2012              : !!  nfft=Number of FFT points for the real space wavefunction.
    2013              : !!  nspinor=Number of spinor components.
    2014              : !!  natom=Number of atoms in cprj matrix elements.
    2015              : !!  nlmn_size(natom)=Number of (n,l,m) channel for each atom. Ordering of atoms depends on cprj_order
    2016              : !!  cprj_order=Flag defining the ordering of the atoms in the cprj matrix elements (CPR_RANDOM|CPR_SORTED).
    2017              : !!    Use to know if we have to reorder the matrix elements when wfd_get_cprj is called.
    2018              : !!
    2019              : !! OUTPUT
    2020              : !!  Wave<wave_t>=The structure fully initialized.
    2021              : !!
    2022              : !! SOURCE
    2023              : 
    2024       134109 : subroutine wave_init(Wave, usepaw, npw, nfft, nspinor, natom, nlmn_size, cprj_order)
    2025              : 
    2026              : !Arguments ------------------------------------
    2027              : !scalars
    2028              :  integer,intent(in) :: npw,nfft,nspinor,usepaw,natom
    2029              :  integer(c_int8_t),intent(in) :: cprj_order
    2030              :  type(wave_t),intent(inout) :: Wave
    2031              : !arrays
    2032              :  integer,intent(in) :: nlmn_size(:)
    2033              : 
    2034              : !Local variables ------------------------------
    2035              :  integer,parameter :: ncpgr0=0  ! For the time being, no derivatives
    2036              : !************************************************************************
    2037              : 
    2038              :  !@wave_t
    2039       134109 :  if (npw >0) then
    2040       213849 :    ABI_MALLOC(Wave%ug, (npw*nspinor))
    2041        71283 :    Wave%has_ug = WFD_ALLOCATED
    2042     32172485 :    Wave%ug = huge(one_gw)
    2043        71283 :    if (usepaw == 1) then
    2044        12418 :      ABI_MALLOC(Wave%Cprj, (natom,nspinor))
    2045         1606 :      call pawcprj_alloc(Wave%Cprj,ncpgr0,nlmn_size)
    2046         1606 :      Wave%has_cprj = WFD_ALLOCATED
    2047         1606 :      Wave%cprj_order = cprj_order
    2048              :    end if
    2049              :  end if
    2050              : 
    2051       134109 :  if (nfft > 0) then
    2052       188478 :    ABI_MALLOC(Wave%ur, (nfft*nspinor))
    2053    418007039 :    Wave%ur = huge(one_gw)
    2054        62826 :    Wave%has_ur = WFD_ALLOCATED
    2055              :  end if
    2056              : 
    2057       134109 : end subroutine wave_init
    2058              : !!***
    2059              : 
    2060              : !----------------------------------------------------------------------
    2061              : 
    2062              : !!****f* m_wfd/wave_free
    2063              : !! NAME
    2064              : !!  wave_free
    2065              : !!
    2066              : !! FUNCTION
    2067              : !!  Main destruction method for the wave_t datatype.
    2068              : !!
    2069              : !! INPUTS
    2070              : !!  [what]=String defining what has to be freed.
    2071              : !!     "A" =Both ug and ur and Cprj. Default.
    2072              : !!     "G" =Only ug.
    2073              : !!     "R" =Only ur
    2074              : !!     "C" =Only PAW Cprj.
    2075              : !!
    2076              : !! SIDE EFFECTS
    2077              : !!  Memory in Wave is deallocated depending on what
    2078              : !!
    2079              : !! SOURCE
    2080              : 
    2081       163978 : subroutine wave_free(Wave, what)
    2082              : 
    2083              : !Arguments ------------------------------------
    2084              : !scalars
    2085              :  class(wave_t),intent(inout) :: Wave
    2086              :  character(len=*),optional,intent(in) :: what
    2087              : 
    2088              : !Local variables ------------------------------
    2089              :  character(len=10) :: my_what
    2090              : !************************************************************************
    2091              : 
    2092       163978 :  my_what="ALL"; if (present(what)) my_what=toupper(what)
    2093              : 
    2094       819890 :  if (.not.firstchar(my_what, ["A", "G", "R", "C"] )) then
    2095            0 :    ABI_ERROR(sjoin("Unknown what:", what))
    2096              :  end if
    2097              : 
    2098       491934 :  if (firstchar(my_what, ["A", "G"])) then
    2099        79891 :    ABI_SFREE(Wave%ug)
    2100        79891 :    Wave%has_ug = WFD_NOWAVE
    2101              :  end if
    2102              : 
    2103       491934 :  if (firstchar(my_what, ["A", "R"])) then
    2104       163978 :    ABI_SFREE(Wave%ur)
    2105       163978 :    Wave%has_ur = WFD_NOWAVE
    2106              :  end if
    2107              : 
    2108       491934 :  if (firstchar(my_what, ["A", "C"])) then
    2109        79891 :    if (allocated(Wave%Cprj)) then
    2110         1606 :      call pawcprj_free(Wave%Cprj)
    2111         5994 :      ABI_FREE(Wave%Cprj)
    2112              :    end if
    2113        79891 :    Wave%has_cprj = WFD_NOWAVE
    2114              :  end if
    2115              : 
    2116       163978 : end subroutine wave_free
    2117              : !!***
    2118              : 
    2119              : !----------------------------------------------------------------------
    2120              : 
    2121              : !!****f* m_wfd/wave_copy
    2122              : !! NAME
    2123              : !!  wave_copy
    2124              : !!
    2125              : !! FUNCTION
    2126              : !!  Copy method for the wave_t datatype.
    2127              : !!
    2128              : !! SOURCE
    2129              : 
    2130            0 : type(wave_t) function wave_copy(Wave_in) result(Wave_out)
    2131              : 
    2132              : !Arguments ------------------------------------
    2133              : !scalars
    2134              :  class(wave_t),intent(in) :: Wave_in
    2135              : 
    2136              : !Local variables ------------------------------
    2137              :  integer :: natom,nspinor,iatom,ispinor
    2138              : !************************************************************************
    2139              : 
    2140            0 :  Wave_out%has_ug = Wave_in%has_ug
    2141            0 :  Wave_out%has_ur = Wave_in%has_ur
    2142            0 :  Wave_out%has_cprj = Wave_in%has_cprj
    2143            0 :  Wave_out%cprj_order = Wave_in%cprj_order
    2144              : 
    2145            0 :  ABI_MALLOC(Wave_out%ug, (SIZE(Wave_in%ug)))
    2146            0 :  Wave_out%ug = Wave_in%ug
    2147            0 :  ABI_MALLOC(Wave_out%ur, (SIZE(Wave_in%ur)))
    2148            0 :  Wave_out%ur = Wave_in%ur
    2149              : 
    2150            0 :  natom   = size(Wave_in%Cprj,dim=1)
    2151            0 :  nspinor = size(Wave_in%Cprj,dim=2)
    2152            0 :  if ((size(Wave_out%Cprj,dim=1) .ne. natom) .or. (size(Wave_out%Cprj,dim=2) .ne. nspinor)) then
    2153              :    if (allocated(Wave_out%Cprj))  then
    2154              :      ABI_FREE(Wave_out%Cprj)
    2155              :    end if
    2156            0 :    ABI_MALLOC(Wave_out%Cprj,(natom,nspinor))
    2157              :  end if
    2158              : 
    2159            0 :  do ispinor=1,nspinor
    2160            0 :    do iatom=1,natom
    2161            0 :     Wave_out%Cprj(iatom,ispinor)%ncpgr=Wave_in%Cprj(iatom,ispinor)%ncpgr
    2162            0 :     Wave_out%Cprj(iatom,ispinor)%nlmn=Wave_in%Cprj(iatom,ispinor)%nlmn
    2163            0 :     call alloc_copy(Wave_in%Cprj(iatom,ispinor)%cp,Wave_out%Cprj(iatom,ispinor)%cp)
    2164            0 :     call alloc_copy(Wave_in%Cprj(iatom,ispinor)%dcp,Wave_out%Cprj(iatom,ispinor)%dcp)
    2165              :    end do
    2166              :  end do
    2167              : 
    2168            0 : end function wave_copy
    2169              : !!***
    2170              : 
    2171              : !----------------------------------------------------------------------
    2172              : 
    2173              : !!****f* m_wfd/wfd_get_wave_prt
    2174              : !! NAME
    2175              : !!  wfd_get_wave_prt
    2176              : !!
    2177              : !! FUNCTION
    2178              : !!  Return pointer to the wave object corresponding to the given (band, ik_ibz, spin) indices.
    2179              : !!  If the state is not treated ...
    2180              : !!
    2181              : !! INPUTS
    2182              : !!   band=Band index.
    2183              : !!   ik_ibz=k-point index
    2184              : !!   spin=Spin index.
    2185              : !!
    2186              : !! SOURCE
    2187              : 
    2188    467394330 : integer function wfd_get_wave_ptr(wfd, band, ik_ibz, spin, wave_ptr, msg) result(ierr)
    2189              : 
    2190              : !Arguments ------------------------------------
    2191              : !scalars
    2192              :  integer,intent(in) :: ik_ibz, spin, band
    2193              :  class(wfd_t),target,intent(in) :: wfd
    2194              :  type(wave_t),pointer :: wave_ptr
    2195              :  character(len=*),intent(out) :: msg
    2196              : 
    2197              : !Local variables ------------------------------
    2198              :  integer :: ib, ik, is
    2199              : !************************************************************************
    2200              : 
    2201    467394330 :  ierr = 1
    2202   1869577320 :  if (any(wfd%bks2wfd(:, band, ik_ibz, spin) == 0)) then
    2203            0 :    write(msg,'(a,i0,a,3(i0,1x))')" MPI rank ",Wfd%my_rank," does not have wavefunction coefficients (ug) for (band, ik_ibz, spin): ",band,ik_ibz,spin
    2204            0 :    wave_ptr => null(); return
    2205              :  end if
    2206              : 
    2207    467394330 :  ib = wfd%bks2wfd(1, band, ik_ibz, spin)
    2208    467394330 :  ik = wfd%bks2wfd(2, band, ik_ibz, spin)
    2209    467394330 :  is = wfd%bks2wfd(3, band, ik_ibz, spin)
    2210    467394330 :  wave_ptr => wfd%s(is)%k(ik)%b(ib)
    2211              :  !if (wave_ptr%has_ug /= WFD_STORED)
    2212              : 
    2213    467394330 :  ierr = 0
    2214              : 
    2215    467394330 : end function wfd_get_wave_ptr
    2216              : !!***
    2217              : 
    2218              : !----------------------------------------------------------------------
    2219              : 
    2220              : !!****f* m_wfd/wfd_push_ug
    2221              : !! NAME
    2222              : !!  wfd_push_ug
    2223              : !!
    2224              : !! FUNCTION
    2225              : !!  This routine changes the status of the object by saving the wavefunction in the correct
    2226              : !!  slot inside Wfd%Wave. It also set the corresponding has_ug flag to WFD_STORED.
    2227              : !!  If the status of the corresponding ur is (WFD_STORED|WFD_ALLOCATED), then an G->R FFT transform
    2228              : !!  is done (see also update_ur)
    2229              : !!
    2230              : !! INPUTS
    2231              : !!   band=Band index.
    2232              : !!   ik_ibz=k-point index
    2233              : !!   spin=Spin index.
    2234              : !!   Cryst<crystal_t>=Object defining the unit cell and its symmetries.
    2235              : !!   ug(npw_k*Wfd%nspinor)=The ug to be saved.
    2236              : !!   [update_ur]=If .FALSE.: no G-->R transform is done even if ur is (WFD_STORED|WFD_ALLOCATED) so be careful.
    2237              : !!               Defaults to .TRUE.
    2238              : !!   [update_cprj]=If .FALSE.: <C|p_i> matrix elements are not recalculatedd even
    2239              : !!     if cprj is (WFD_STORED|WFD_ALLOCATED) so be careful. Defaults to .TRUE.
    2240              : !!
    2241              : !! SIDE EFFECTS
    2242              : !!   Wfd<wfd_t>=See above.
    2243              : !!
    2244              : !! SOURCE
    2245              : 
    2246         7108 : subroutine wfd_push_ug(Wfd, band, ik_ibz, spin, Cryst, ug, update_ur, update_cprj)
    2247              : 
    2248              : !Arguments ------------------------------------
    2249              : !scalars
    2250              :  integer,intent(in) :: ik_ibz,spin,band
    2251              :  logical,optional,intent(in) :: update_ur,update_cprj
    2252              :  class(wfd_t),target,intent(inout) :: Wfd
    2253              :  type(crystal_t),intent(in) :: Cryst
    2254              : !arrays
    2255              :  complex(gwp),intent(inout) :: ug(:)
    2256              : 
    2257              : !Local variables ------------------------------
    2258              : !scalars
    2259              :  integer,parameter :: choice1=1,idir0=0,tim_fourdp=5,ndat1=1
    2260              :  integer :: npw_k, ib, ik, is
    2261              :  logical :: do_update_ur,do_update_cprj,want_sorted
    2262              :  character(len=500) :: msg
    2263              :  type(wave_t),pointer :: wave
    2264              : !************************************************************************
    2265              : 
    2266         7108 :  if (size(ug) /= Wfd%npwarr(ik_ibz) * Wfd%nspinor) then
    2267            0 :    ABI_ERROR("Wrong size in assumed shape array")
    2268              :  end if
    2269              : 
    2270        28432 :  if (any(wfd%bks2wfd(:, band, ik_ibz, spin) == 0)) then
    2271            0 :    write(msg,'(a,i0,a,3(i0,1x))')" MPI rank ",Wfd%my_rank," doesn't have ug for (band, ik_ibz, spin): ",band,ik_ibz,spin
    2272            0 :    ABI_ERROR(msg)
    2273              :  end if
    2274              : 
    2275         7108 :  ib = wfd%bks2wfd(1, band, ik_ibz, spin)
    2276         7108 :  ik = wfd%bks2wfd(2, band, ik_ibz, spin)
    2277         7108 :  is = wfd%bks2wfd(3, band, ik_ibz, spin)
    2278              : 
    2279         7108 :  wave => wfd%s(is)%k(ik)%b(ib)
    2280      1770410 :  wave%ug = ug
    2281         7108 :  wave%has_ug = WFD_STORED
    2282              : 
    2283         7108 :  if (Wfd%debug_level>0) then
    2284              :    if (wave%has_ug == WFD_NOWAVE) then
    2285              :      write(msg,'(a,i0,a,3(i0,1x))')" MPI rank ",Wfd%my_rank," doesn't have ug for (band, ik_ibz, spin): ",band,ik_ibz,spin
    2286              :      ABI_ERROR(msg)
    2287              :    end if
    2288              :  end if
    2289              : 
    2290         7108 :  if (Wfd%usepaw==1) then
    2291              :    ! Update the corresponding cprj if required.
    2292            0 :    do_update_cprj=.TRUE.; if (present(update_cprj)) do_update_cprj=update_cprj
    2293            0 :    if (do_update_cprj) then
    2294            0 :      want_sorted = (wave%cprj_order == CPR_SORTED)
    2295            0 :      call wfd%ug2cprj(band, ik_ibz, spin, choice1, idir0, wfd%natom, cryst, wave%cprj, sorted=want_sorted)
    2296            0 :      wave%has_cprj = WFD_STORED
    2297              :    else
    2298            0 :      wave%has_cprj = WFD_ALLOCATED
    2299              :    end if
    2300              :  end if
    2301              : 
    2302         7108 :  if (any(wave%has_ur == [WFD_STORED, WFD_ALLOCATED])) then
    2303              :    ! Update the corresponding ur if required.
    2304         2532 :    do_update_ur=.TRUE.; if (present(update_ur)) do_update_ur=update_ur
    2305              : 
    2306            0 :    if (do_update_ur) then
    2307         2532 :      npw_k = Wfd%npwarr(ik_ibz)
    2308              :      call fft_ug(npw_k,Wfd%nfft,Wfd%nspinor,ndat1,Wfd%mgfft,Wfd%ngfft,Wfd%istwfk(ik_ibz),&
    2309         2532 :        Wfd%Kdata(ik_ibz)%kg_k,Wfd%Kdata(ik_ibz)%gbound,ug,wave%ur)
    2310         2532 :      wave%has_ur = WFD_STORED
    2311              :    else
    2312            0 :      wave%has_ur = WFD_ALLOCATED
    2313              :    end if
    2314              :  end if
    2315              : 
    2316         7108 : end subroutine wfd_push_ug
    2317              : !!***
    2318              : 
    2319              : !----------------------------------------------------------------------
    2320              : 
    2321              : !!****f* m_wfd/wfd_extract_cgblock
    2322              : !! NAME
    2323              : !!  wfd_extract_cgblock
    2324              : !!
    2325              : !! FUNCTION
    2326              : !!  This routine extract a block of wavefunctions for a given spin and k-points.
    2327              : !!  The wavefunctions are stored in a real(dp) array with the same convention
    2328              : !!  as the one used in the GS part of Abinit, i.e cg_block(2,nspinor*npw_k*num_bands)
    2329              : !!
    2330              : !! INPUTS
    2331              : !!   Wfd<wfd_t>=Wavefunction descriptor.
    2332              : !!   band_list(:)=List of bands to extract
    2333              : !!   ik_ibz=k-point index
    2334              : !!   spin=Spin index.
    2335              : !!
    2336              : !! OUTPUT
    2337              : !!   cgblock(nspinor*npw_k*num_bands)=A contiguous block of memory with the set of u(g)
    2338              : !!
    2339              : !! SOURCE
    2340              : 
    2341           30 : subroutine wfd_extract_cgblock(Wfd,band_list,ik_ibz,spin,cgblock)
    2342              : 
    2343              : !Arguments ------------------------------------
    2344              : !scalars
    2345              :  integer,intent(in) :: ik_ibz,spin
    2346              :  class(wfd_t),intent(in) :: Wfd
    2347              : !arrays
    2348              :  integer,intent(in) :: band_list(:)
    2349              :  real(dp),intent(out) :: cgblock(:,:)
    2350              : 
    2351              : !Local variables ------------------------------
    2352              : !scalars
    2353              :  integer :: ii,band,start,istop,npw_k
    2354              :  character(len=500) :: msg
    2355              :  type(wave_t),pointer :: wave
    2356              : !************************************************************************
    2357              : 
    2358           30 :  npw_k = Wfd%npwarr(ik_ibz)
    2359              : 
    2360           30 :  if (size(cgblock, dim=1) /= 2) then
    2361            0 :    ABI_ERROR("Wrong size(1) in assumed shape array")
    2362              :  end if
    2363              : 
    2364           30 :  if (size(cgblock, dim=2) /= Wfd%nspinor* npw_k * size(band_list)) then
    2365            0 :    ABI_ERROR("Wrong size in assumed shape array")
    2366              :  end if
    2367              : 
    2368           30 :  start = 1
    2369          270 :  do ii=1,size(band_list)
    2370          240 :    band = band_list(ii)
    2371          240 :    ABI_CHECK(wfd%get_wave_ptr(band, ik_ibz, spin, wave, msg) == 0, msg)
    2372          240 :    if (wave%has_ug /= WFD_STORED) then
    2373            0 :      write(msg,"(3(a,i0),a)")"u(g) for band: ",band,", ik_ibz: ",ik_ibz,", spin: ",spin," is not stored!"
    2374            0 :      ABI_ERROR(msg)
    2375              :    end if
    2376          240 :    istop = start + Wfd%nspinor*npw_k - 1
    2377        32656 :    cgblock(1,start:istop) = REAL(wave%ug)
    2378        32656 :    cgblock(2,start:istop) = AIMAG(wave%ug)
    2379          270 :    start = start + Wfd%nspinor * npw_k
    2380              :  end do
    2381              : 
    2382           30 : end subroutine wfd_extract_cgblock
    2383              : !!***
    2384              : 
    2385              : !----------------------------------------------------------------------
    2386              : 
    2387              : !!****f* m_wfd/wfdgw_rank_has_ug
    2388              : !! NAME
    2389              : !!  wfdgw_rank_has_ug
    2390              : !!
    2391              : !! FUNCTION
    2392              : !!  This function is used to ask a particular processor whether it has a particular ug and with which status.
    2393              : !!
    2394              : !! INPUTS
    2395              : !!   rank=The MPI rank of the processor.
    2396              : !!   band=Band index.
    2397              : !!   ik_ibz=k-point index
    2398              : !!   spin=Spin index.
    2399              : !!
    2400              : !! NOTES
    2401              : !!   A zero index can be used to inquire the status of a bunch of states.
    2402              : !!   Thus (band,ik_ibz,spin) = (0,1,1) means: Do you have at least one band for the first k-point and the first spin.
    2403              : !!
    2404              : !! SOURCE
    2405              : 
    2406      2525180 : function wfdgw_rank_has_ug(Wfd,rank,band,ik_ibz,spin)
    2407              : 
    2408              : !Arguments ------------------------------------
    2409              : !scalars
    2410              :  integer,intent(in) :: band,ik_ibz,spin,rank
    2411              :  logical :: wfdgw_rank_has_ug
    2412              :  class(wfdgw_t),intent(in) :: Wfd
    2413              : 
    2414              : !Local variables ------------------------------
    2415              : !scalars
    2416              :  integer :: nzeros
    2417              :  integer(c_int8_t) :: bks_flag
    2418              : !arrays
    2419              :  integer :: indices(3)
    2420              : !************************************************************************
    2421              : 
    2422     10100720 :  indices = [band,ik_ibz,spin]
    2423      2525180 :  bks_flag = WFD_STORED
    2424              : 
    2425     10100720 :  if (ALL(indices/= [0,0,0])) then
    2426      2525180 :    wfdgw_rank_has_ug = (Wfd%bks_tab(band,ik_ibz,spin,rank) == bks_flag); RETURN
    2427              :  else
    2428            0 :    nzeros = COUNT(indices==0)
    2429            0 :    if (nzeros==3) ABI_ERROR("All indices are zero!")
    2430              : 
    2431            0 :    if (band==0) then
    2432            0 :      if (nzeros==1) wfdgw_rank_has_ug = ANY( Wfd%bks_tab(:,ik_ibz,spin,rank)==bks_flag)
    2433            0 :      if (ik_ibz==0) wfdgw_rank_has_ug = ANY( Wfd%bks_tab(:,:,spin,rank)     ==bks_flag)
    2434            0 :      if (spin  ==0) wfdgw_rank_has_ug = ANY( Wfd%bks_tab(:,ik_ibz,:,rank)   ==bks_flag)
    2435              : 
    2436            0 :    else if (ik_ibz==0) then
    2437            0 :      if (nzeros==1) wfdgw_rank_has_ug = ANY( Wfd%bks_tab(band,:,spin,rank)==bks_flag)
    2438              :      if (band  ==0) wfdgw_rank_has_ug = ANY( Wfd%bks_tab(:,:,spin,rank)   ==bks_flag)
    2439            0 :      if (spin  ==0) wfdgw_rank_has_ug = ANY( Wfd%bks_tab(band,:,:,rank)   ==bks_flag)
    2440              : 
    2441              :    else
    2442            0 :      if (nzeros==1) wfdgw_rank_has_ug = ANY( Wfd%bks_tab(band,ik_ibz,:,rank)==bks_flag)
    2443              :      if (ik_ibz==0) wfdgw_rank_has_ug = ANY( Wfd%bks_tab(band,:,:,rank)     ==bks_flag)
    2444              :      if (band  ==0) wfdgw_rank_has_ug = ANY( Wfd%bks_tab(:,ik_ibz,:,rank)   ==bks_flag)
    2445              :    end if
    2446              :  end if
    2447              : 
    2448              : end function wfdgw_rank_has_ug
    2449              : !!***
    2450              : 
    2451              : !----------------------------------------------------------------------
    2452              : 
    2453              : !!****f* m_wfd/wfd_ihave_ug
    2454              : !! NAME
    2455              : !!  wfd_ihave_ug
    2456              : !!
    2457              : !! FUNCTION
    2458              : !!  This function is used to ask the processor whether it has a particular ug and with which status.
    2459              : !!
    2460              : !! INPUTS
    2461              : !!   band=Band index.
    2462              : !!   ik_ibz=k-point index
    2463              : !!   spin=Spin index.
    2464              : !!   [how]=string defining which status is checked.
    2465              : !!     Possible mutually exclusive values: "Allocated", "Stored".
    2466              : !!     Only the first character is checked (no case-sensitive)
    2467              : !!     By default the function returns .TRUE. if the wave is either WFD_ALLOCATED or WFD_STORED.
    2468              : !!
    2469              : !! NOTES
    2470              : !!   A zero index can be used to inquire the status of a bunch of states.
    2471              : !!   Thus (band,ik_ibz,spin) = (0,1,1) means: Do you have at least one band for the first k-point and the first spin.
    2472              : !!
    2473              : !! SOURCE
    2474              : 
    2475       184001 : pure function wfd_ihave_ug(Wfd, band, ik_ibz, spin, how)
    2476              : 
    2477              : !Arguments ------------------------------------
    2478              : !scalars
    2479              :  integer,intent(in) :: band,ik_ibz,spin
    2480              :  logical :: wfd_ihave_ug
    2481              :  character(len=*),optional,intent(in) :: how
    2482              :  class(wfd_t),intent(in) :: Wfd
    2483              : 
    2484              : !Local variables ------------------------------
    2485              : !scalars
    2486              :  integer :: ib, ik, is
    2487              :  integer(c_int8_t) :: check2(2)
    2488              : !************************************************************************
    2489              : 
    2490       184001 :  check2 = [WFD_ALLOCATED, WFD_STORED]
    2491       184001 :  if (present(how)) then
    2492       204585 :    if (firstchar(how, ["A", "a"])) check2 = [WFD_ALLOCATED, WFD_ALLOCATED]
    2493       204585 :    if (firstchar(how, ["S", "s"])) check2 = [WFD_STORED, WFD_STORED]
    2494              :  end if
    2495       184001 :  ib = wfd%bks2wfd(1, band, ik_ibz, spin)
    2496       184001 :  ik = wfd%bks2wfd(2, band, ik_ibz, spin)
    2497       184001 :  is = wfd%bks2wfd(3, band, ik_ibz, spin)
    2498       184001 :  wfd_ihave_ug = .False.
    2499       328696 :  if (ib /= 0) wfd_ihave_ug = any(wfd%s(is)%k(ik)%b(ib)%has_ug == check2)
    2500              : 
    2501       184001 : end function wfd_ihave_ug
    2502              : !!***
    2503              : 
    2504              : !----------------------------------------------------------------------
    2505              : 
    2506              : !!****f* m_wfd/wfd_mybands
    2507              : !! NAME
    2508              : !!  wfd_mybands
    2509              : !!
    2510              : !! FUNCTION
    2511              : !!  Return the list of band indices of the ug owned by this node at given (k,s).
    2512              : !!
    2513              : !! INPUTS
    2514              : !!  ik_ibz=Index of the k-point in the IBZ
    2515              : !!  spin=spin index
    2516              : !!  [how]=string defining which status is checked.
    2517              : !!    Possible mutually exclusive values: "Allocated", "Stored".
    2518              : !!    Only the first character is checked (no case-sensitive)
    2519              : !!    By default the list of bands whose status is either WFD_ALLOCATED or WFD_STORED is returned.
    2520              : !!
    2521              : !! OUTPUT
    2522              : !!  how_manyb=The number of bands owned by this node
    2523              : !!  my_band_list(Wfd%mband)=The first how_manyb values are the bands treated by this node.
    2524              : !!
    2525              : !! SOURCE
    2526              : 
    2527           30 : subroutine wfd_mybands(Wfd, ik_ibz, spin, how_manyb, my_band_list, how)
    2528              : 
    2529              : !Arguments ------------------------------------
    2530              : !scalars
    2531              :  integer,intent(in) :: ik_ibz,spin
    2532              :  integer,intent(out) :: how_manyb
    2533              :  character(len=*),optional,intent(in) :: how
    2534              :  class(wfd_t),intent(in) :: Wfd
    2535              : !arrays
    2536              :  integer,intent(out) :: my_band_list(Wfd%mband)
    2537              : 
    2538              : !Local variables ------------------------------
    2539              :  integer :: band
    2540              :  logical :: do_have
    2541              : !************************************************************************
    2542              : 
    2543          270 :  how_manyb=0; my_band_list=-1
    2544          270 :  do band=1,Wfd%nband(ik_ibz,spin)
    2545          240 :    if (present(how)) then
    2546          240 :      do_have = wfd%ihave_ug(band, ik_ibz, spin, how=how)
    2547              :    else
    2548            0 :      do_have = wfd%ihave_ug(band, ik_ibz, spin)
    2549              :    end if
    2550          270 :    if (do_have) then
    2551          240 :      how_manyb = how_manyb + 1
    2552          240 :      my_band_list(how_manyb) = band
    2553              :    end if
    2554              :  end do
    2555              : 
    2556           30 : end subroutine wfd_mybands
    2557              : !!***
    2558              : 
    2559              : !----------------------------------------------------------------------
    2560              : 
    2561              : !!****f* m_wfd/wfdgw_show_bkstab
    2562              : !! NAME
    2563              : !!  wfdgw_show_bkstab
    2564              : !!
    2565              : !! FUNCTION
    2566              : !!  Print a table showing the distribution of the wavefunctions.
    2567              : !!
    2568              : !! SOURCE
    2569              : 
    2570            0 : subroutine wfdgw_show_bkstab(Wfd, unit)
    2571              : 
    2572              : !Arguments ------------------------------------
    2573              : !scalars
    2574              :  integer,intent(in) :: unit
    2575              :  class(wfdgw_t),intent(in) :: Wfd
    2576              : 
    2577              : !Local variables ------------------------------
    2578              : !scalars
    2579              :  integer :: ik_ibz,spin,band,nband_k,width
    2580            0 :  character(len=1) :: chlist(0:Wfd%nproc-1)
    2581              :  character(len=500) :: fmt
    2582              : !************************************************************************
    2583              : 
    2584            0 :  width = max(80, Wfd%nproc)
    2585              : 
    2586            0 :  write(fmt,"(a,i0,a)")"(i5,3x,",Wfd%nproc,"(a))"
    2587              : 
    2588            0 :  do spin=1,Wfd%nsppol
    2589            0 :    do ik_ibz=1,Wfd%nkibz
    2590            0 :      write(unit,"(a)")repeat("=",width)
    2591            0 :      write(unit,"(2(a,i0))")"Spin: ",spin,", ik_ibz: ",ik_ibz
    2592            0 :      write(unit,"(a)")"MPI rank ----> (A=allocated, S=Stored, N=NoWave)."
    2593            0 :      nband_k = Wfd%nband(ik_ibz, spin)
    2594            0 :      do band=1,nband_k
    2595            0 :        where (Wfd%bks_tab(band, ik_ibz, spin,:) == WFD_NOWAVE)
    2596              :          chlist = "N"
    2597              :        elsewhere (Wfd%bks_tab(band, ik_ibz, spin,:) == WFD_ALLOCATED)
    2598              :          chlist = "A"
    2599              :        elsewhere (Wfd%bks_tab(band, ik_ibz, spin,:) == WFD_STORED)
    2600              :          chlist = "S"
    2601              :        end where
    2602            0 :        write(unit,fmt)band,chlist(:)
    2603              :      end do
    2604            0 :      write(unit,"(a)")repeat("=",width)
    2605              :    end do
    2606              :  end do
    2607              : 
    2608            0 : end subroutine wfdgw_show_bkstab
    2609              : !!***
    2610              : 
    2611              : !----------------------------------------------------------------------
    2612              : 
    2613              : !!****f* m_wfd/wfdgw_bands_of_rank
    2614              : !! NAME
    2615              : !!  wfdgw_bands_of_rank
    2616              : !!
    2617              : !! FUNCTION
    2618              : !!  Return the list of band index of the ug owned by a given processor at given (k,s).
    2619              : !!
    2620              : !! INPUTS
    2621              : !!  Wfd
    2622              : !!  rank=The MPI rank of the processor.
    2623              : !!  ik_ibz=Index of the k-point in the IBZ
    2624              : !!  spin=spin index
    2625              : !!
    2626              : !! OUTPUT
    2627              : !!  how_manyb=The number of bands owned by this node
    2628              : !!  rank_band_list(Wfd%mband)=The first how_manyb values are the bands treated by the node.
    2629              : !!
    2630              : !! SOURCE
    2631              : 
    2632       176074 : subroutine wfdgw_bands_of_rank(Wfd,rank,ik_ibz,spin,how_manyb,rank_band_list)
    2633              : 
    2634              : !Arguments ------------------------------------
    2635              : !scalars
    2636              :  integer,intent(in) :: ik_ibz,spin,rank
    2637              :  integer,intent(out) :: how_manyb
    2638              :  class(wfdgw_t),intent(in) :: Wfd
    2639              : !arrays
    2640              :  integer,intent(out) :: rank_band_list(Wfd%mband)
    2641              : 
    2642              : !Local variables ------------------------------
    2643              :  integer :: band
    2644              :  logical :: it_has
    2645              : !************************************************************************
    2646              : 
    2647      2701254 :  how_manyb=0; rank_band_list=-1
    2648      2701254 :  do band=1,Wfd%nband(ik_ibz,spin)
    2649      2525180 :    it_has = Wfd%rank_has_ug(rank, band, ik_ibz, spin)
    2650      2701254 :    if (it_has) then
    2651      2260020 :      how_manyb = how_manyb +1
    2652      2260020 :      rank_band_list(how_manyb)=band
    2653              :    end if
    2654              :  end do
    2655              : 
    2656       176074 : end subroutine wfdgw_bands_of_rank
    2657              : !!***
    2658              : 
    2659              : !----------------------------------------------------------------------
    2660              : 
    2661              : !!****f* m_wfd/wfd_get_ug
    2662              : !! NAME
    2663              : !!  wfd_get_ug
    2664              : !!
    2665              : !! FUNCTION
    2666              : !!  Get a **copy** of a wave function in G-space.
    2667              : !!
    2668              : !! INPUTS
    2669              : !!  Wfd<wfd_t>=the data type
    2670              : !!  band=the index of the band.
    2671              : !!  ik_ibz=Index of the k-point in the IBZ
    2672              : !!  spin=spin index
    2673              : !!
    2674              : !! OUTPUT
    2675              : !!  ug(npw_k*Wfd%nspinor)=The required wavefunction in G-space
    2676              : !!
    2677              : !! SOURCE
    2678              : 
    2679              : subroutine wfd_get_ug(Wfd, band, ik_ibz, spin, ug)
    2680              : 
    2681              : !Arguments ------------------------------------
    2682              : !scalars
    2683              :  integer,intent(in) :: band,ik_ibz,spin
    2684              :  class(wfd_t),intent(inout) :: Wfd
    2685              : !arrays
    2686              :  complex(gwp),intent(out) :: ug(Wfd%npwarr(ik_ibz)*Wfd%nspinor)
    2687              : 
    2688              : !Local variables ------------------------------
    2689              : !scalars
    2690              :  integer :: npw_k
    2691              :  character(len=500) :: msg
    2692              :  type(wave_t),pointer :: wave
    2693              : !************************************************************************
    2694              : 
    2695              :  ABI_CHECK(wfd%get_wave_ptr(band, ik_ibz, spin, wave, msg) == 0, msg)
    2696              : 
    2697              :  if (.not. wave%has_ug == WFD_STORED) then
    2698              :    write(msg,'(a,i0,a,3i0)')" Node ",Wfd%my_rank," doesn't have (band,ik_ibz,spin): ",band,ik_ibz,spin
    2699              :    ABI_BUG(msg)
    2700              :  end if
    2701              : 
    2702              :  npw_k = Wfd%npwarr(ik_ibz)
    2703              :  call xcopy(npw_k*Wfd%nspinor, wave%ug, 1, ug, 1)
    2704              : 
    2705              : end subroutine wfd_get_ug
    2706              : !!***
    2707              : 
    2708              : !----------------------------------------------------------------------
    2709              : 
    2710              : !!****f* m_wfd/wfd_wave_free
    2711              : !! NAME
    2712              : !!  wfd_wave_free
    2713              : !!
    2714              : !! FUNCTION
    2715              : !!  Collection procedure that frees the set of waves specified by mask.
    2716              : !!
    2717              : !! INPUTS
    2718              : !!  mask(Wfd%mband,Wfd%nkibz,Wfd%nsppol)=.TRUE. if the memory allocated for
    2719              : !!    this state has to be freed
    2720              : !!  [what]=String specifying which array have to be deallocated.
    2721              : !!    Possible values (no case-sensitive).
    2722              : !!      "All"= To free both ug and ur and PAW Cprj, if any. Default
    2723              : !!      "G"  = Only ug
    2724              : !!      "R"  = Only ur.
    2725              : !!      "C"  = Only PAW Cprj.
    2726              : !!
    2727              : !! SIDE EFFECTS
    2728              : !!  Wfd<wfd_t>=See above.
    2729              : !!
    2730              : !! SOURCE
    2731              : 
    2732           58 : subroutine wfd_wave_free(Wfd, what, bks_mask)
    2733              : 
    2734              : !Arguments ------------------------------------
    2735              : !scalars
    2736              :  class(wfd_t),target,intent(inout) :: Wfd
    2737              :  character(len=*),optional,intent(in) :: what
    2738              : !arrays
    2739              :  logical,optional,intent(in) :: bks_mask(Wfd%mband,Wfd%nkibz,Wfd%nsppol)
    2740              : 
    2741              : !Local variables ------------------------------
    2742              : !scalars
    2743              :  integer :: ik_ibz, spin, band, ib, ik, is
    2744              :  logical :: do_free
    2745              :  type(wave_t),pointer :: wave
    2746              :  !character(len=500) :: msg
    2747              :  character(len=10) :: my_what
    2748              : !************************************************************************
    2749              : 
    2750           85 :  my_what="ALL"; if (present(what)) my_what=toupper(what)
    2751              : 
    2752          172 :  do spin=1,Wfd%nsppol
    2753         3110 :    do ik_ibz=1,Wfd%nkibz
    2754        22872 :      do band=1,Wfd%nband(ik_ibz,spin)
    2755        19847 :         do_free=.TRUE.; if (present(bks_mask)) do_free=bks_mask(band,ik_ibz,spin)
    2756        14884 :         if (do_free) then
    2757        14837 :           ib = wfd%bks2wfd(1, band, ik_ibz, spin)
    2758        14837 :           ik = wfd%bks2wfd(2, band, ik_ibz, spin)
    2759        14837 :           is = wfd%bks2wfd(3, band, ik_ibz, spin)
    2760        14837 :           if (ib /= 0) then
    2761        14581 :             wave => wfd%s(is)%k(ik)%b(ib)
    2762        14581 :             call wave%free(what=my_what)
    2763              :           end if
    2764              :           select type (wfd)
    2765              :           class is (wfdgw_t)
    2766              :             ! Update the associated flags if we release the G-space.
    2767        44511 :             if ( firstchar(my_what, ["A", "G"])) Wfd%bks_tab(band, ik_ibz, spin, Wfd%my_rank) = WFD_NOWAVE
    2768              :           end select
    2769              :         end if
    2770              :      end do
    2771              :    end do
    2772              :  end do
    2773              : 
    2774           85 : end subroutine wfd_wave_free
    2775              : !!***
    2776              : 
    2777              : !----------------------------------------------------------------------
    2778              : 
    2779              : !!****f* m_wfd/wfdgw_who_has_ug
    2780              : !! NAME
    2781              : !!  wfdgw_who_has_ug
    2782              : !!
    2783              : !! FUNCTION
    2784              : !!  Return the number of processors having a particular (b,k,s) state as well as their MPI rank.
    2785              : !!  Warning: Wfd%bks_tab is supposed to be up-to-date (see wfdgw_update_bkstab).
    2786              : !!
    2787              : !! INPUTS
    2788              : !!  band=the index of the band.
    2789              : !!  ik_ibz=Index of the k-point in the IBZ
    2790              : !!  spin=spin index
    2791              : !!
    2792              : !! OUTPUT
    2793              : !!  how_many=The number of nodes owing this ug state.
    2794              : !!  proc_ranks(1:how_many)=Gives the MPI rank of the nodes owing the state.
    2795              : !!
    2796              : !! SOURCE
    2797              : 
    2798       410262 : subroutine wfdgw_who_has_ug(Wfd,band,ik_ibz,spin,how_many,proc_ranks)
    2799              : 
    2800              : !Arguments ------------------------------------
    2801              : !scalars
    2802              :  integer,intent(in) :: band,ik_ibz,spin
    2803              :  integer,intent(out) :: how_many
    2804              :  class(wfdgw_t),intent(in) :: Wfd
    2805              : !arrays
    2806              :  integer,intent(out) :: proc_ranks(Wfd%nproc)
    2807              : 
    2808              : !Local variables ------------------------------
    2809              : !scalars
    2810              :  integer :: irank
    2811              :  logical :: bks_select,spin_select,kpt_select
    2812              :  character(len=500) :: msg
    2813              : !************************************************************************
    2814              : 
    2815       410262 :  bks_select  = (band/=0.and.ik_ibz/=0.and.spin/=0)
    2816       410262 :  spin_select = (band==0.and.ik_ibz==0.and.spin/=0)
    2817       410262 :  kpt_select = (band==0.and.ik_ibz/=0.and.spin/=0)
    2818              : 
    2819      1147564 :  how_many=0; proc_ranks=-1
    2820              : 
    2821       410262 :  if (bks_select) then
    2822              :    ! List the proc owining this (b,k,s) state.
    2823      1147564 :    do irank=0,Wfd%nproc-1
    2824      1147564 :      if (Wfd%bks_tab(band, ik_ibz, spin, irank) == WFD_STORED) then
    2825       713824 :        how_many = how_many +1
    2826       713824 :        proc_ranks(how_many)=irank
    2827              :      end if
    2828              :    end do
    2829              : 
    2830            0 :  else if (spin_select) then
    2831              :    ! List the proc owining at least one state with this spin.
    2832            0 :    do irank=0,Wfd%nproc-1
    2833            0 :      if ( ANY(Wfd%bks_tab(:,:,spin,irank)==WFD_STORED) ) then
    2834            0 :        how_many = how_many +1
    2835            0 :        proc_ranks(how_many)=irank
    2836              :      end if
    2837              :    end do
    2838              : 
    2839            0 :  else if (kpt_select) then
    2840              :    ! List the proc owining at least one state with this (k-point, spin).
    2841            0 :    do irank=0,Wfd%nproc-1
    2842            0 :      if ( ANY(Wfd%bks_tab(:,ik_ibz,spin,irank)==WFD_STORED) ) then
    2843            0 :        how_many = how_many +1
    2844            0 :        proc_ranks(how_many)=irank
    2845              :      end if
    2846              :    end do
    2847              : 
    2848              :  else
    2849            0 :    write(msg,'(a,3(i0,1x))')" Wrong value for (b,k,s): ",band,ik_ibz,spin
    2850            0 :    ABI_ERROR(msg)
    2851              :  end if
    2852              : 
    2853       410262 : end subroutine wfdgw_who_has_ug
    2854              : !!***
    2855              : 
    2856              : !----------------------------------------------------------------------
    2857              : 
    2858              : !!****f* m_wfd/wfdgw_update_bkstab
    2859              : !! NAME
    2860              : !!  wfdgw_update_bkstab
    2861              : !!
    2862              : !! FUNCTION
    2863              : !!  This routine should be called by all the nodes before any MPI operation involving the object.
    2864              : !!  It updates the bks_tab storing information on the distribution of ug.
    2865              : !!
    2866              : !! INPUT
    2867              : !!  [show]=If present and > 0, print tabs to unit show.
    2868              : !!
    2869              : !! SIDE EFFECTS
    2870              : !!  Wfd%bks_tab
    2871              : !!
    2872              : !! SOURCE
    2873              : 
    2874         2460 : subroutine wfdgw_update_bkstab(Wfd, show)
    2875              : 
    2876              : !Arguments ------------------------------------
    2877              : !scalars
    2878              :  class(wfdgw_t),intent(inout) :: Wfd
    2879              :  integer,optional,intent(in) :: show
    2880              : 
    2881              : !Local variables ------------------------------
    2882              : !scalars
    2883              :  integer :: ierr, nelem, spin, ik_ibz, band, is, ik, ib
    2884         2460 :  integer(c_int8_t),allocatable :: my_vtab(:),gather_vtabs(:)
    2885              :  !logical,allocatable :: tab_ranks(:)
    2886              : !************************************************************************
    2887              : 
    2888              :  ! Fill my slice of the global table.
    2889         4959 :  do spin=1,wfd%nsppol
    2890        23282 :    do ik_ibz=1,wfd%nkibz
    2891       340127 :      do band=1,Wfd%nband(ik_ibz, spin)
    2892       319305 :        ib = wfd%bks2wfd(1, band, ik_ibz, spin)
    2893       319305 :        ik = wfd%bks2wfd(2, band, ik_ibz, spin)
    2894       319305 :        is = wfd%bks2wfd(3, band, ik_ibz, spin)
    2895       337628 :        if (ib /= 0) then
    2896       297789 :          Wfd%bks_tab(band, ik_ibz, spin, Wfd%my_rank) = wfd%s(is)%k(ik)%b(ib)%has_ug
    2897              :        else
    2898        21516 :          Wfd%bks_tab(band, ik_ibz, spin, Wfd%my_rank) = WFD_NOWAVE
    2899              :        end if
    2900              :      end do
    2901              :    end do
    2902              :  end do
    2903              : 
    2904              :  ! Gather flags on each node.
    2905         2460 :  nelem = Wfd%mband*Wfd%nkibz*Wfd%nsppol
    2906         7380 :  ABI_MALLOC(my_vtab, (nelem))
    2907         4920 :  my_vtab(:) = reshape(Wfd%bks_tab(:,:,:,Wfd%my_rank), [nelem])
    2908              : 
    2909         7380 :  ABI_MALLOC(gather_vtabs, (nelem*Wfd%nproc))
    2910              : 
    2911         2460 :  call xmpi_allgather(my_vtab,nelem,gather_vtabs,Wfd%comm,ierr)
    2912              : 
    2913       563641 :  Wfd%bks_tab(:,:,:,:) = reshape(gather_vtabs, [Wfd%mband, Wfd%nkibz, Wfd%nsppol, Wfd%nproc])
    2914         2460 :  ABI_FREE(my_vtab)
    2915         2460 :  ABI_FREE(gather_vtabs)
    2916              : 
    2917              : #if 0
    2918              :  ! This is gonna be slow but if lot of k-points as I cannot assume bands or k-points have been filtered
    2919              :  ! Need to introduce global_filter_ikibz_spin in wfd_init ...
    2920              :  ABI_MALLOC(tab_ranks, (wfd%nproc))
    2921              :  do spin=1,Wfd%nsppol
    2922              :    do ik_ibz=1,Wfd%nkibz
    2923              :      !if wfd%global_filter_ikibz_spin(ik_ibz, spin) cycle
    2924              :      do band=1,Wfd%nband(ik_ibz, spin)
    2925              :        tab_ranks = .False.
    2926              :        if (len(wfd%bks_ranks(band, ik_ibz, spin) > 0) then
    2927              :          if (any(wfd%my_rank == wfd%bks_ranks(band, ik_ibz, spin)) tab_ranks(wfd%my_rank) = .True.
    2928              :        end if
    2929              :        call xmpi_lor(tab_ranks, wfd%comm)
    2930              :        call bool2index(tab_ranks, wfd%bks_ranks(band, ik_ibz, spin))
    2931              :      end do
    2932              :    end do
    2933              :  end do
    2934              :  ABI_FREE(tab_ranks)
    2935              : #endif
    2936              : 
    2937         2460 :  if (present(show)) then
    2938          387 :    if (show >= 0) call wfd%show_bkstab(unit=show)
    2939              :  end if
    2940              : 
    2941         4920 : end subroutine wfdgw_update_bkstab
    2942              : !!***
    2943              : 
    2944              : !----------------------------------------------------------------------
    2945              : 
    2946              : !!****f* m_wfd/wfdgw_distribute_bands
    2947              : !! NAME
    2948              : !!  wfdgw_distribute_bands
    2949              : !!
    2950              : !! FUNCTION
    2951              : !!  Distribute a set of bands taking into account the distribution of the ug.
    2952              : !!
    2953              : !! INPUTS
    2954              : !!  band=the index of the band.
    2955              : !!  ik_ibz=Index of the k-point in the IBZ
    2956              : !!  spin=spin index
    2957              : !!  [got(Wfd%nproc)]=The number of tasks already assigned to the nodes.
    2958              : !!  [bmask(Wfd%mband)]=The routine will raise an error if one band index
    2959              : !!    is not treated by any processor. bmask can be used to select the subset of
    2960              : !!    indices that are expected to be available.
    2961              : !!
    2962              : !! OUTPUT
    2963              : !!   my_nband=The number of bands that will be treated by this node.
    2964              : !!   my_band_list(1:my_nband)=The band indices for this node
    2965              : !!
    2966              : !! SOURCE
    2967              : 
    2968        47788 : subroutine wfdgw_distribute_bands(Wfd,ik_ibz,spin,my_nband,my_band_list,got,bmask)
    2969              : 
    2970              : !Arguments ------------------------------------
    2971              : !scalars
    2972              :  integer,intent(in) :: ik_ibz,spin
    2973              :  integer,intent(out) :: my_nband
    2974              :  class(wfdgw_t),intent(in) :: Wfd
    2975              : !arrays
    2976              :  integer,intent(out) :: my_band_list(Wfd%mband)
    2977              :  integer,optional,intent(inout) :: got(Wfd%nproc)
    2978              :  logical,optional,intent(in) :: bmask(Wfd%mband)
    2979              : 
    2980              : !Local variables ------------------------------
    2981              : !scalars
    2982              :  integer :: band,how_many,idle
    2983              :  character(len=500) :: msg
    2984              : !arrays
    2985       103344 :  integer :: proc_ranks(Wfd%nproc),get_more(Wfd%nproc)
    2986       103344 :  logical :: rank_mask(Wfd%nproc)
    2987              : !************************************************************************
    2988              : 
    2989       766539 :  my_nband=0; my_band_list=0
    2990       241488 :  get_more=0; if (present(got)) get_more = got
    2991              : 
    2992       766539 :  do band=1,Wfd%nband(ik_ibz,spin)
    2993       714867 :    if (present(bmask)) then
    2994       710691 :      if (.not.bmask(band)) CYCLE
    2995              :    end if
    2996              : 
    2997       409830 :    call wfdgw_who_has_ug(Wfd, band, ik_ibz, spin, how_many, proc_ranks)
    2998              : 
    2999       461502 :    if (how_many == 1) then
    3000              :      ! I am the only one owing this band. Add it to list.
    3001       279732 :      if (proc_ranks(1) == Wfd%my_rank) then
    3002       273024 :        my_nband=my_nband + 1
    3003       273024 :        my_band_list(my_nband) = band
    3004              :      end if
    3005       130098 :    else if (how_many > 1) then
    3006              :      ! This band is duplicated. Assign it trying to obtain a good load distribution.
    3007      1431078 :      rank_mask=.FALSE.; rank_mask(proc_ranks(1:how_many)+1)=.TRUE.
    3008       130098 :      idle = imin_loc(get_more, mask=rank_mask)
    3009       130098 :      get_more(idle) = get_more(idle) + 1
    3010       130098 :      if (Wfd%my_rank==idle-1) then
    3011        43366 :        my_nband=my_nband + 1
    3012        43366 :        my_band_list(my_nband) = band
    3013              :      end if
    3014              :    else
    3015            0 :      write(msg,'(a,3(i0,1x))')" No processor has (band, ik_ibz, spin): ",band,ik_ibz,spin
    3016            0 :      ABI_ERROR(msg)
    3017              :    end if
    3018              :  end do
    3019              : 
    3020       143224 :  if (present(got)) got = get_more
    3021              : 
    3022        51672 : end subroutine wfdgw_distribute_bands
    3023              : !!***
    3024              : 
    3025              : !----------------------------------------------------------------------
    3026              : 
    3027              : !!****f* m_wfd/wfdgw_rotate
    3028              : !! NAME
    3029              : !! wfdgw_rotate
    3030              : !!
    3031              : !! FUNCTION
    3032              : !!  This routine performs a linear transformation of the wavefunctions stored in Wfd
    3033              : !!  taking into account memory distribution. The transformation is done in G-space
    3034              : !!  therefore all the ug should be available. Wavefunctions in real space are then
    3035              : !!  obtained via FFT. The implementation assumes that the matrix associated to the
    3036              : !!  linear transformation is sparse (No BLAS-3 calls here).
    3037              : !!
    3038              : !! INPUTS
    3039              : !!  Cryst<crystal_t>=Object defining the unit cell and its symmetries.
    3040              : !!  m_ks_to_qp(mband,mband,nkibz,nsppol)= expansion of the QP amplitudes in terms of KS wavefunctions.
    3041              : !!  [bmask(mband,nkibz,nsppol)]=The routine will raise an error if one band index
    3042              : !!    is not treated by any processor. bmask can be used to select the subset of
    3043              : !!    indices that are expected to be available.
    3044              : !!
    3045              : !! SIDE EFFECTS
    3046              : !!   Wfd<wfd_t>=See above.
    3047              : !!
    3048              : !! SOURCE
    3049              : !!
    3050              : 
    3051            5 : subroutine wfdgw_rotate(Wfd, Cryst, m_ks_to_qp, bmask)
    3052              : 
    3053              : !Arguments ------------------------------------
    3054              : !scalars
    3055              :  class(wfdgw_t),intent(inout) :: Wfd
    3056              :  type(crystal_t),intent(in) :: Cryst
    3057              : !arrays
    3058              :  complex(dp),target,intent(in) :: m_ks_to_qp(Wfd%mband,Wfd%mband,Wfd%nkibz,Wfd%nsppol)
    3059              :  logical,optional,intent(in) :: bmask(Wfd%mband,Wfd%nkibz,Wfd%nsppol)
    3060              : 
    3061              : !Local variables-------------------------------
    3062              : !scalars
    3063              :  integer :: band,ik_ibz,spin,ierr,icol,nnew,inew,my_nband,ib,npw_k,istwf_k
    3064              :  character(len=500) :: msg
    3065              :  type(wave_t),pointer :: wave
    3066              : !arrays
    3067          214 :  integer :: new_list(Wfd%mband),my_band_list(Wfd%mband)
    3068          107 :  complex(dp),contiguous, pointer :: umat_sk(:,:)
    3069          214 :  complex(gwp) :: mcol(Wfd%mband)
    3070          107 :  complex(gwp),allocatable :: new_ug(:,:) !, new_ur(:)
    3071              : !************************************************************************
    3072              : 
    3073              :  ! Update the distribution table, first.
    3074          107 :  call wfd%update_bkstab()
    3075              : 
    3076              :  ! Calculate: $\Psi^{QP}_{r,b} = \sum_n \Psi^{KS}_{r,n} M_{n,b}$
    3077          216 :  do spin=1,Wfd%nsppol
    3078          832 :    do ik_ibz=1,Wfd%nkibz
    3079          616 :      npw_k  = Wfd%npwarr(ik_ibz)
    3080          616 :      istwf_k = Wfd%istwfk(ik_ibz)
    3081          616 :      if (istwf_k /= 1) then
    3082            0 :        ABI_WARNING("wfdgw_rotate with istwfk /= 1")
    3083              :      end if
    3084          616 :      umat_sk => m_ks_to_qp(:,:,ik_ibz,spin)
    3085              : 
    3086              :      ! Select only those states that are mixed by the (sparse) m_ks_to_qp.
    3087         7552 :      nnew=0; new_list=0
    3088         7552 :      do icol=1,Wfd%nband(ik_ibz,spin)
    3089        92684 :        mcol = m_ks_to_qp(:,icol,ik_ibz,spin)
    3090         6936 :        mcol(icol) = mcol(icol) - cone
    3091        47077 :        if (ANY(ABS(mcol)>tol12)) then  ! Avoid a simple copy.
    3092         3816 :          nnew=nnew+1
    3093         3816 :          new_list(nnew)=icol
    3094              :        end if
    3095              :      end do
    3096          616 :      if (nnew==0) CYCLE ! Nothing to do.
    3097              : 
    3098              :      ! Retrieve the set of band indices that have to be treated by
    3099              :      ! this node taking into account a possible duplication.
    3100          378 :      if (present(bmask)) then
    3101           30 :        call wfd%distribute_bands(ik_ibz,spin,my_nband,my_band_list,bmask=bmask(:,ik_ibz,spin))
    3102              :      else
    3103          348 :        call wfd%distribute_bands(ik_ibz,spin,my_nband,my_band_list)
    3104              :      end if
    3105              : 
    3106              :      !if (my_nband>0) then
    3107              :      !  write(std_out,*)" At (ik_ibz,spin) ",ik_ibz,spin,&
    3108              :      !  & ", rank ",Wfd%my_rank," will sum ",my_nband," bands, my_band_list: ",my_band_list(1:my_nband)
    3109              :      !end if
    3110         1512 :      ABI_MALLOC(new_ug,(npw_k*Wfd%nspinor,nnew))
    3111      1192860 :      new_ug=czero
    3112         4194 :      do inew=1,nnew
    3113         3816 :        icol = new_list(inew)
    3114        44466 :        do ib=1,my_nband
    3115        40272 :          band = my_band_list(ib)
    3116        44088 :          if (ABS(umat_sk(band,icol))>tol12) then
    3117        36484 :             ABI_CHECK(wfd%get_wave_ptr(band, ik_ibz, spin, wave, msg) == 0, msg)
    3118      7275904 :             new_ug(:,inew) = new_ug(:,inew) + umat_sk(band, icol) * wave%ug
    3119              :          end if
    3120              :        end do
    3121              :      end do
    3122              : 
    3123              :      !if (istwf_k /= 1) then
    3124              :      !  ABI_MALLOC(new_ur, (wfd%nfft * wfd%nspinor * nnew))
    3125              :      !  call fft_ug_dpc(npw_k, wfd%nfft, wfd%nspinor, nnew, wfd%mgfft, wfd%ngfft, istwf_k, &
    3126              :      !                  wfd%kdata(ik_ibz)%kg_k, wfd%kdata(ik_ibz)%gbound, new_ug, new_ur)
    3127              :      !  new_ur = real(new_ur)
    3128              :      !  call fft_ur_dpc(npw_k, wfd%nfft, wfd%nspinor, nnew, wfd%mgfft, wfd%ngfft, istwf_k, &
    3129              :      !                  wfd%kdata(ik_ibz)%kg_k, wfd%kdata(ik_ibz)%gbound, new_ur, new_ug)
    3130              :      !  ABI_FREE(new_ur)
    3131              :      !end if
    3132              : 
    3133          378 :      call xmpi_sum(new_ug,Wfd%comm,ierr)
    3134              : 
    3135              :      ! Update the input wave functions
    3136         4194 :      do inew=1,nnew
    3137         3816 :        band = new_list(inew)
    3138         4194 :        if (wfd%ihave_ug(band, ik_ibz, spin)) call wfd%push_ug(band, ik_ibz, spin, Cryst, new_ug(:,inew))
    3139              :      end do
    3140              : 
    3141         1103 :      ABI_FREE(new_ug)
    3142              :    end do !ik_ibz
    3143              :  end do !spin
    3144              : 
    3145              :  ! Reinit the storage mode of Wfd as ug have been changed.
    3146              :  ! This is needed only if FFTs are not done in wfd_push_ug. Do not know which one is faster.
    3147              :  !call wfd%reset_ur_cprj()
    3148          107 :  call xmpi_barrier(Wfd%comm)
    3149              : 
    3150          219 : end subroutine wfdgw_rotate
    3151              : !!***
    3152              : 
    3153              : !----------------------------------------------------------------------
    3154              : 
    3155              : !!****f* m_wfd/wfdgw_iterator_bks
    3156              : !! NAME
    3157              : !!  wfdgw_iterator_bks
    3158              : !!
    3159              : !! FUNCTION
    3160              : !!  Iterator used to loop over bands, k-points and spin indices
    3161              : !!  taking into account the distribution of the ug.
    3162              : !!
    3163              : !! INPUTS
    3164              : !!  Wfd<wfd_t>=
    3165              : !!  bks_mask(Wfd%mband.Wfd%nkibz,Wfd%nsppol)= mask used to select the (b,k,s) indices.
    3166              : !!
    3167              : !! OUTPUT
    3168              : !!  iter_bks<iter2_t>=Iterator over the bands treated by this node for each k-point and spin.
    3169              : !!
    3170              : !! SOURCE
    3171              : 
    3172          459 : type(iter2_t) function wfdgw_iterator_bks(Wfd, bks_mask) result(iter_bks)
    3173              : 
    3174              : !Arguments ------------------------------------
    3175              : !scalars
    3176              :  class(wfdgw_t),intent(in) :: Wfd
    3177              : !arrays
    3178              :  logical,optional,intent(in) :: bks_mask(Wfd%mband,Wfd%nkibz,Wfd%nsppol)
    3179              : 
    3180              : !Local variables ------------------------------
    3181              : !scalars
    3182              :  integer :: ik_ibz,spin,my_nband
    3183              : !arrays
    3184          918 :  integer :: my_band_list(Wfd%mband)
    3185              : !************************************************************************
    3186              : 
    3187         1377 :  call iter_alloc(iter_bks,(/Wfd%nkibz,Wfd%nsppol/))
    3188              : 
    3189          927 :  do spin=1,Wfd%nsppol
    3190         4402 :    do ik_ibz=1,Wfd%nkibz
    3191         3475 :      if (present(bks_mask)) then
    3192         3475 :        call wfd%distribute_bands(ik_ibz,spin,my_nband,my_band_list,bmask=bks_mask(:,ik_ibz,spin))
    3193              :      else
    3194            0 :        call wfd%distribute_bands(ik_ibz,spin,my_nband,my_band_list)
    3195              :      end if
    3196         3943 :      call iter_push(iter_bks,ik_ibz,spin,my_band_list(1:my_nband))
    3197              :    end do
    3198              :  end do
    3199              : 
    3200          459 : end function wfdgw_iterator_bks
    3201              : !!***
    3202              : 
    3203              : !----------------------------------------------------------------------
    3204              : 
    3205              : !!****f* m_wfd/wfdgw_bks_distrb
    3206              : !! NAME
    3207              : !!  wfdgw_bks_distrb
    3208              : !!
    3209              : !! FUNCTION
    3210              : !!  Build a local logical table indexed by bands, k-points and spin that defines
    3211              : !!  the distribution of the load inside the loops according to the availability of the ug.
    3212              : !!
    3213              : !! INPUTS
    3214              : !!  Wfd<wfd_t>=
    3215              : !!  [bks_mask(Wfd%mband,Wfd%nkibz,Wfd%nsppol)]=Mask used to skip selected (b,k,s) entries.
    3216              : !!  [got(Wfd%nproc)]=The number of tasks already assigned to the nodes.
    3217              : !!
    3218              : !! OUTPUT
    3219              : !!  bks_distrbk(Wfd%mband,Wfd%nkibz,Wfd%nsppol)=Global table with the rank of the node treating (b,k,s)
    3220              : !!
    3221              : !! SOURCE
    3222              : 
    3223            4 : subroutine wfdgw_bks_distrb(Wfd, bks_distrb, got, bks_mask)
    3224              : 
    3225              : !Arguments ------------------------------------
    3226              : !scalars
    3227              :  class(wfdgw_t),intent(in) :: Wfd
    3228              : !arrays
    3229              :  integer,intent(out) :: bks_distrb(Wfd%mband,Wfd%nkibz,Wfd%nsppol)
    3230              :  integer,optional,intent(inout) :: got(Wfd%nproc)
    3231              :  logical,optional,intent(in) :: bks_mask(Wfd%mband,Wfd%nkibz,Wfd%nsppol)
    3232              : 
    3233              : !Local variables ------------------------------
    3234              : !scalars
    3235              :  integer :: ik_ibz,spin,band,how_many,idle
    3236              :  character(len=500) :: msg
    3237              : !arrays
    3238            8 :  integer :: get_more(Wfd%nproc),proc_ranks(Wfd%nproc)
    3239            4 :  logical :: rank_mask(Wfd%nproc)
    3240              : !************************************************************************
    3241              : 
    3242            8 :  get_more=0; if (present(got)) get_more=got
    3243              : 
    3244              :  ! Initialize the table here to avoid problem with the cycle instruction below.
    3245          224 :  bks_distrb = xmpi_undefined_rank
    3246              : 
    3247            8 :  do spin=1,Wfd%nsppol
    3248           32 :    do ik_ibz=1,Wfd%nkibz
    3249          220 :      do band=1,Wfd%nband(ik_ibz,spin)
    3250          192 :        if (present(bks_mask)) then
    3251          192 :          if (.not.bks_mask(band, ik_ibz, spin)) CYCLE
    3252              :        end if
    3253              : 
    3254          192 :        call wfdgw_who_has_ug(Wfd, band, ik_ibz, spin, how_many, proc_ranks)
    3255              : 
    3256          216 :        if (how_many == 1) then
    3257              :          ! I am the only one owing this band. Add it to list.
    3258          192 :          bks_distrb(band, ik_ibz, spin) = proc_ranks(1)
    3259              : 
    3260            0 :        else if (how_many>1) then
    3261              :          ! This band is duplicated. Assign it trying to obtain a good load distribution.
    3262            0 :          rank_mask=.FALSE.; rank_mask(proc_ranks(1:how_many)+1)=.TRUE.
    3263            0 :          idle = imin_loc(get_more,mask=rank_mask)
    3264            0 :          get_more(idle) = get_more(idle) + 1
    3265            0 :          bks_distrb(band,ik_ibz,spin) = proc_ranks(idle)
    3266              : 
    3267              :        else
    3268            0 :          call wfd%dump_errinfo()
    3269            0 :          write(msg,'(a,3(i0,1x))')" Nobody has (band, ik_ibz, spin): ",band,ik_ibz,spin
    3270            0 :          ABI_ERROR(msg)
    3271              :        end if
    3272              : 
    3273              :      end do
    3274              :    end do
    3275              :  end do
    3276              : 
    3277            4 :  if (present(got)) got=get_more
    3278              : 
    3279            4 : end subroutine wfdgw_bks_distrb
    3280              : !!***
    3281              : 
    3282              : !----------------------------------------------------------------------
    3283              : 
    3284              : !!****f* m_wfd/wfdgw_sanity_check
    3285              : !! NAME
    3286              : !!  wfdgw_sanity_check
    3287              : !!
    3288              : !! FUNCTION
    3289              : !!  Debugging tool
    3290              : !!
    3291              : !! INPUTS
    3292              : !!  Wfd<wfd_t>=
    3293              : !!
    3294              : !! OUTPUT
    3295              : !!
    3296              : !! SOURCE
    3297              : 
    3298            0 : subroutine wfdgw_sanity_check(Wfd)
    3299              : 
    3300              : !Arguments ------------------------------------
    3301              : !scalars
    3302              :  class(wfdgw_t),intent(inout) :: Wfd
    3303              : 
    3304              : !Local variables ------------------------------
    3305              : !scalars
    3306              :  integer :: ik_ibz,spin,band,mpi_ierr,ierr,how_manyb,unt_dbg,irank
    3307              :  character(len=500) :: msg
    3308              : !arrays
    3309            0 :  integer :: my_band_list(Wfd%mband)
    3310              : !************************************************************************
    3311              : 
    3312            0 :  call wfd%update_bkstab()
    3313            0 :  ierr=0
    3314              : 
    3315            0 :  do spin=1,Wfd%nsppol
    3316            0 :    do ik_ibz=1,Wfd%nkibz
    3317            0 :       do band=1,Wfd%nband(ik_ibz,spin)
    3318            0 :         if (Wfd%bks_tab(band, ik_ibz, spin, Wfd%my_rank) == WFD_STORED .and. &
    3319            0 :            .not. wfd%ihave_ug(band, ik_ibz, spin, how="Stored") ) then
    3320            0 :           write(msg,'(a,3(i0,1x))')" Found inconsistency in bks_tab for (band, ik_ibz, spin): ",band,ik_ibz,spin
    3321            0 :           call wrtout(std_out, msg)
    3322            0 :           ierr = ierr+1
    3323              :         end if
    3324              :      end do
    3325              :    end do
    3326              :  end do
    3327              : 
    3328            0 :  call xmpi_sum(ierr,Wfd%comm,mpi_ierr)
    3329              : 
    3330            0 :  if (ierr/=0) then
    3331            0 :    if (open_file("__WFD_DEBUG__",msg,newunit=unt_dbg,form="formatted") /= 0) then
    3332            0 :      ABI_ERROR(msg)
    3333              :    end if
    3334              : 
    3335            0 :    do irank=0,Wfd%nproc-1
    3336            0 :      if (irank==Wfd%my_rank) then
    3337            0 :        write(unt_dbg,*)" (k,b,s) states owned by rank: ",Wfd%my_rank
    3338              : 
    3339            0 :        do spin=1,Wfd%nsppol
    3340            0 :          do ik_ibz=1,Wfd%nkibz
    3341            0 :             write(unt_dbg,*)" (spin,ik_ibz) ",spin,ik_ibz
    3342            0 :             call wfd%mybands(ik_ibz, spin, how_manyb, my_band_list, how="Stored")
    3343            0 :             write(unt_dbg,*) (my_band_list(band),band=1,how_manyb)
    3344              :           end do
    3345              :        end do
    3346              : 
    3347              :      end if
    3348              :    end do
    3349            0 :    close(unt_dbg)
    3350            0 :    call xmpi_barrier(Wfd%comm)
    3351            0 :    ABI_ERROR("Sanity check failed. Check WFD_DEBUG")
    3352              :  end if
    3353              : 
    3354            0 : end subroutine wfdgw_sanity_check
    3355              : !!***
    3356              : 
    3357              : !----------------------------------------------------------------------
    3358              : 
    3359              : !!****f* m_wfd/wfd_dump_errinfo
    3360              : !! NAME
    3361              : !!  wfd_dump_errinfo
    3362              : !!
    3363              : !! FUNCTION
    3364              : !!
    3365              : !! INPUTS
    3366              : !!  Wfd<wfd_t>=
    3367              : !!
    3368              : !! OUTPUT
    3369              : !!
    3370              : !! SOURCE
    3371              : 
    3372            0 : subroutine wfd_dump_errinfo(Wfd,onfile)
    3373              : 
    3374              : !Arguments ------------------------------------
    3375              : !scalars
    3376              :  logical,optional,intent(in) :: onfile
    3377              :  class(wfd_t),intent(in) :: Wfd
    3378              : 
    3379              : !Local variables ------------------------------
    3380              : !scalars
    3381              :  integer :: ik_ibz,spin,band,how_manyb,unt_dbg
    3382              :  character(len=10) :: strank
    3383              :  character(len=500) :: msg
    3384              :  character(len=fnlen) :: fname_dbg
    3385              : !arrays
    3386            0 :  integer :: my_band_list(Wfd%mband)
    3387              : !************************************************************************
    3388              : 
    3389            0 :  unt_dbg=std_out
    3390              : 
    3391            0 :  if (present(onfile)) then
    3392            0 :    if (onfile) then
    3393            0 :      call int2char10(Wfd%my_rank,strank)
    3394            0 :      fname_dbg = "WFD_DEBUG_RANK"//TRIM(strank)
    3395            0 :      if (open_file(fname_dbg,msg,newunit=unt_dbg,form="formatted") /= 0) then
    3396            0 :        ABI_ERROR(msg)
    3397              :      end if
    3398              :    end if
    3399              :  end if
    3400              : 
    3401            0 :  write(unt_dbg,*)" (k,b,s) states owned by rank: ",Wfd%my_rank
    3402            0 :  do spin=1,Wfd%nsppol
    3403            0 :    do ik_ibz=1,Wfd%nkibz
    3404            0 :       write(unt_dbg,*)" ug stored at (ik_ibz, spin) ",ik_ibz,spin
    3405            0 :       call wfd%mybands(ik_ibz, spin, how_manyb, my_band_list, how="Stored")
    3406            0 :       write(unt_dbg,*) (my_band_list(band),band=1,how_manyb)
    3407              :     end do
    3408              :  end do
    3409              : 
    3410            0 : end subroutine wfd_dump_errinfo
    3411              : !!***
    3412              : 
    3413              : !----------------------------------------------------------------------
    3414              : 
    3415              : !!****f* m_wfd/wfdgw_distribute_bbp
    3416              : !! NAME
    3417              : !!  wfdgw_distribute_bbp
    3418              : !!
    3419              : !! FUNCTION
    3420              : !!  Distribute a set of (b,b') indices taking into account the MPI distribution of the ug.
    3421              : !!  It is used to calculate matrix elements of the form <b,k,s|O|b',k,s>
    3422              : !!
    3423              : !! INPUTS
    3424              : !!  Wfd<wfd_t>=
    3425              : !!  ik_ibz=The index of the k-point in the IBZ.
    3426              : !!  spin=Spin index.
    3427              : !!  allup=String used to select or not the upper triangle. Possible values:
    3428              : !!    "All"  =Entire (b,b') matrix will be distributed.
    3429              : !!    "Upper"=Only the upper triangle is distributed.
    3430              : !!  [got(%nproc)]=The number of tasks already assigned to the nodes. Used to optimize the work load.
    3431              : !!    Be careful when this routine is called inside several loops since each node should call the routine
    3432              : !!    at each iteration with the same (local) copy of got so that bbp_distrb will assume the same value on each node.
    3433              : !!  [bbp_mask(%mband,%mband)]= mask used to select a subset of (b,b') indices.
    3434              : !!
    3435              : !! OUTPUT
    3436              : !!  my_nbbp=The number of (b,b') indices treated by this node.
    3437              : !!  bbp_distrb(%mband%mband)=The rank of the node that will treat (b,b').
    3438              : !!
    3439              : !! SOURCE
    3440              : 
    3441         2424 : subroutine wfdgw_distribute_bbp(Wfd,ik_ibz,spin,allup,my_nbbp,bbp_distrb,got,bbp_mask)
    3442              : 
    3443              : !Arguments ------------------------------------
    3444              : !scalars
    3445              :  integer,intent(in) :: ik_ibz,spin
    3446              :  integer,intent(out) :: my_nbbp
    3447              :  class(wfdgw_t),intent(in) :: Wfd
    3448              :  character(len=*),intent(in) :: allup
    3449              : !arrays
    3450              :  integer,intent(out) :: bbp_distrb(Wfd%mband,Wfd%mband)
    3451              :  integer,optional,intent(inout) :: got(Wfd%nproc)
    3452              :  logical,optional,intent(in) :: bbp_mask(Wfd%mband,Wfd%mband)
    3453              : 
    3454              : !Local variables ------------------------------
    3455              : !arrays
    3456         9180 :  integer :: loc_got(Wfd%nproc)
    3457              : !************************************************************************
    3458              : 
    3459              :  ! Just a wrapper around wfdgw_distribute_kb_kpbp.
    3460        31300 :  loc_got=0; if (present(got)) loc_got = got
    3461              : 
    3462         9180 :  if (present(bbp_mask)) then
    3463         9180 :    call wfd%distribute_kb_kpbp(ik_ibz,ik_ibz,spin,allup,my_nbbp,bbp_distrb,loc_got,bbp_mask)
    3464              :  else
    3465            0 :    call wfd%distribute_kb_kpbp(ik_ibz,ik_ibz,spin,allup,my_nbbp,bbp_distrb,loc_got)
    3466              :  end if
    3467              : 
    3468         9180 : end subroutine wfdgw_distribute_bbp
    3469              : !!***
    3470              : 
    3471              : !----------------------------------------------------------------------
    3472              : 
    3473              : !!****f* m_wfd/wfdgw_distribute_kb_kpbp
    3474              : !! NAME
    3475              : !!  wfdgw_distribute_kb_kpbp
    3476              : !!
    3477              : !! FUNCTION
    3478              : !!  This routines distributes as set of (b,b') indices taking into account the MPI distribution of the ug.
    3479              : !!  It is used to calculate matrix elements of the form <b,k,s|O|b',k',s>
    3480              : !!
    3481              : !! INPUTS
    3482              : !!  Wfd<wfd_t>=
    3483              : !!  ik_ibz =The index of the k-point k  in the IBZ.
    3484              : !!  ikp_ibz=The index of the k-point k' in the IBZ.
    3485              : !!  spin=Spin index.
    3486              : !!  allup=String used to select the upper triangle of the (b,b') matrix. Possible values:
    3487              : !!    "All"  =Entire (b,b') matrix will be distributed.
    3488              : !!    "Upper"=Only the upper triangle is distributed.
    3489              : !!  [got(%nproc)]=The number of tasks already assigned to the nodes. Used to optimize the distribution of the tasks.
    3490              : !!    Be careful when this routine is called inside several loops since each node should call the routine
    3491              : !!    at each iteration with the same (local) copy of got so that bbp_distrb will assume the same value on each node.
    3492              : !!  [bbp_mask(%mband,%mband)]= mask used to select a subset of (b,b') indices.
    3493              : !!
    3494              : !! OUTPUT
    3495              : !!  my_nbbp=The number of (b,b') indices treated by this node.
    3496              : !!  bbp_distrb(%mband%mband)=The rank of the node that will treat (b,b').
    3497              : !!
    3498              : !! SOURCE
    3499              : 
    3500        85774 : subroutine wfdgw_distribute_kb_kpbp(Wfd, ik_ibz, ikp_ibz, spin, allup, my_nbbp, bbp_distrb, &
    3501        85774 :                                   got, bbp_mask) ! optional
    3502              : 
    3503              : !Arguments ------------------------------------
    3504              : !scalars
    3505              :  integer,intent(in) :: ik_ibz,ikp_ibz,spin
    3506              :  integer,intent(out) :: my_nbbp
    3507              :  class(wfdgw_t),intent(in) :: Wfd
    3508              :  character(len=*),intent(in) :: allup
    3509              : !arrays
    3510              :  integer,intent(out) :: bbp_distrb(Wfd%mband,Wfd%mband)
    3511              :  integer,optional,intent(inout) :: got(Wfd%nproc)
    3512              :  logical,optional,intent(in) :: bbp_mask(Wfd%mband,Wfd%mband)
    3513              : 
    3514              : !Local variables ------------------------------
    3515              : !scalars
    3516              :  integer :: my_nband,ib1,ib2,pcb2,pcb1,howmany_b,howmany_bp,workload_min
    3517              :  integer :: rank,ncpus,idle,b1_stop,ierr
    3518              :  character(len=500) :: msg
    3519              : !arrays
    3520        85774 :  integer :: rank_bandlist_k(Wfd%mband),rank_bandlist_kp(Wfd%mband)
    3521        85774 :  integer :: get_more(Wfd%nproc),my_band_list_k(Wfd%mband)
    3522        42887 :  integer,allocatable :: whocan_k(:,:),whocan_kp(:,:)
    3523        85774 :  logical :: b_mask(Wfd%mband)
    3524              : !************************************************************************
    3525              : 
    3526       171548 :  ABI_MALLOC_OR_DIE(whocan_k ,(Wfd%mband,Wfd%nproc), ierr)
    3527       171548 :  ABI_MALLOC_OR_DIE(whocan_kp,(Wfd%mband,Wfd%nproc), ierr)
    3528      1393514 :  whocan_k =0 !  Will be set to 1 if this node can calculate something containing (k,b)
    3529      1393514 :  whocan_kp=0 !  Will be set to 1 if this node can calculate something containing (kp,bp)
    3530              : 
    3531       130924 :  do rank=0,Wfd%nproc-1
    3532              : 
    3533        88037 :    call wfd%bands_of_rank(rank,ik_ibz ,spin,howmany_b, rank_bandlist_k )
    3534      1218047 :    do pcb1=1,howmany_b
    3535      1130010 :      ib1 = rank_bandlist_k(pcb1)
    3536      1218047 :      whocan_k(ib1,rank+1) = 1
    3537              :    end do
    3538              : 
    3539        88037 :    call wfd%bands_of_rank(rank,ikp_ibz,spin,howmany_bp,rank_bandlist_kp)
    3540      1348971 :    do pcb2=1,howmany_bp
    3541      1130010 :      ib2 = rank_bandlist_kp(pcb2)
    3542      1218047 :      whocan_kp(ib2,rank+1) = 1
    3543              :    end do
    3544              : 
    3545              :  end do
    3546              : 
    3547       218961 :  get_more=0; if (present(got)) get_more=got
    3548        42887 :  b1_stop=Wfd%nband(ik_ibz,spin)
    3549              : 
    3550     20659353 :  bbp_distrb = xmpi_undefined_rank
    3551              : 
    3552       713221 :  do ib2=1,Wfd%nband(ikp_ibz,spin)
    3553     40562598 :    b_mask = .TRUE.; if (present(bbp_mask)) b_mask = bbp_mask(:,ib2)
    3554     17916804 :    if (ANY(b_mask)) then
    3555      3755718 :      my_nband=0; my_band_list_k=0
    3556              :      ! Only the upper triangle of the (b1,b2) matrix.
    3557       653211 :      if (firstchar(allup, ["U","u"])) b1_stop = MIN(ib2,Wfd%nband(ik_ibz,spin))
    3558              : 
    3559      3670689 :      do ib1=1,b1_stop
    3560      3670689 :        if (b_mask(ib1)) then
    3561              :          !
    3562              :          ! find which CPUs can do the calculation (k,b)->(kp,bp)
    3563              :          ! find the one which is less busy
    3564      2354185 :          ncpus=0
    3565      2354185 :          workload_min=HUGE(0)
    3566      6445042 :          do rank=0,Wfd%nproc-1
    3567      6445042 :            if( whocan_k(ib1,rank+1)==1 .AND.  whocan_kp(ib2,rank+1)==1 ) then
    3568      3596629 :              ncpus=ncpus+1
    3569      3596629 :              if( get_more(rank+1) < workload_min ) then
    3570      2707613 :                idle=rank+1
    3571      2707613 :                workload_min=get_more(idle)
    3572              :              end if
    3573              : 
    3574              :            end if
    3575              :          end do
    3576              : 
    3577      2354185 :          if(ncpus>0) then
    3578      2354185 :            bbp_distrb(ib1,ib2)=idle-1
    3579      2354185 :            get_more(idle) = get_more(idle) + 1
    3580              : 
    3581              :          else
    3582            0 :            call wfd%dump_errinfo()
    3583            0 :            write(msg,'(a,5(i0,1x))')" Nobody has (band1, ik_ibz) (band2, ikp_ibz) spin: ",ib1,ik_ibz,ib2,ikp_ibz,spin
    3584            0 :            ABI_ERROR(msg)
    3585              :          end if
    3586              : 
    3587              :        end if
    3588              :      end do ! ib1
    3589              :    end if
    3590              :  end do ! ib2
    3591              : 
    3592        42887 :  ABI_FREE(whocan_k)
    3593        42887 :  ABI_FREE(whocan_kp)
    3594              : 
    3595     20659353 :  my_nbbp = COUNT(bbp_distrb==Wfd%my_rank)
    3596       130924 :  if (present(got)) got=get_more
    3597              : 
    3598        85774 : end subroutine wfdgw_distribute_kb_kpbp
    3599              : !!***
    3600              : 
    3601              : !----------------------------------------------------------------------
    3602              : 
    3603              : !!****f* m_wfd/wfd_get_cprj
    3604              : !! NAME
    3605              : !!  wfd_get_cprj
    3606              : !!
    3607              : !! FUNCTION
    3608              : !!  Return a copy of Cprj either by calculating it on-the-fly or by just retrieving the data already stored in the data type.
    3609              : !!
    3610              : !! INPUTS
    3611              : !!  Wfd<wfd_t>=the wavefunction descriptor.
    3612              : !!  band=Band index.
    3613              : !!  ik_ibz=Index of the k-point in the IBZ.
    3614              : !!  spin=Spin index
    3615              : !!  sorted=.TRUE. if the output cprj matrix elements have to be sorted by atom type.
    3616              : !!
    3617              : !! OUTPUT
    3618              : !!  Cprj_out(Wfd%natom,Wfd%nspinor) <type(pawcprj_type)>=Unsorted matrix elements.
    3619              : !!
    3620              : !! SOURCE
    3621              : 
    3622       130075 : subroutine wfd_get_cprj(Wfd, band, ik_ibz, spin, Cryst, Cprj_out, sorted)
    3623              : 
    3624              : !Arguments ------------------------------------
    3625              : !scalars
    3626              :  integer,intent(in) :: band,ik_ibz,spin
    3627              :  logical,intent(in) :: sorted
    3628              :  class(wfd_t),intent(inout) :: Wfd
    3629              :  type(crystal_t),intent(in) :: Cryst
    3630              : !arrays
    3631              :  type(pawcprj_type),intent(inout) :: Cprj_out(Wfd%natom,Wfd%nspinor)
    3632              : 
    3633              : !Local variables ------------------------------
    3634              : !scalars
    3635              :  integer,parameter :: choice1=1,idir0=0
    3636              :  integer :: want_order,iatom,sidx
    3637              :  character(len=500) :: msg
    3638              :  type(wave_t),pointer :: wave
    3639              : !************************************************************************
    3640              : 
    3641       130075 :  want_order=CPR_RANDOM; if (sorted) want_order=CPR_SORTED
    3642              : 
    3643       130075 :  ABI_CHECK(wfd%get_wave_ptr(band, ik_ibz, spin, wave, msg) == 0, msg)
    3644              : 
    3645       131674 :  select case (wave%has_cprj)
    3646              : 
    3647              :  case (WFD_NOWAVE, WFD_ALLOCATED)
    3648              :    ! Have to calculate it!
    3649         1599 :    if (.not. wave%has_ug == WFD_STORED) then
    3650            0 :      write(msg,'(a,3(i0,1x),a)')" ug for (band, ik_ibz, spin): ",band,ik_ibz,spin," is not stored in memory!"
    3651            0 :      ABI_ERROR(msg)
    3652              :    end if
    3653              :    ! Get cprj.
    3654         1599 :    call wfd%ug2cprj(band,ik_ibz,spin,choice1,idir0,Wfd%natom,Cryst,Cprj_out,sorted=sorted)
    3655              : 
    3656         1599 :    if (wave%has_cprj == WFD_ALLOCATED) then
    3657              :      ! Store it.
    3658         1599 :      if (want_order == wave%cprj_order) then
    3659         1599 :        call pawcprj_copy(Cprj_out, wave%Cprj)
    3660         1599 :        wave%has_cprj = WFD_STORED
    3661              : 
    3662              :      else
    3663              :        ! Have to reorder cprj_out
    3664            0 :        select case (want_order)
    3665              :        case (CPR_SORTED)
    3666            0 :          do iatom=1,Cryst%natom
    3667            0 :            sidx = Cryst%atindx(iatom) ! random --> sorted table.
    3668            0 :            call pawcprj_copy(Cprj_out(sidx:sidx,:), wave%Cprj(iatom:iatom,:))
    3669              :          end do
    3670              :        case (CPR_RANDOM)
    3671            0 :          do sidx=1,Cryst%natom
    3672            0 :            iatom = Cryst%atindx1(sidx) ! sorted --> random table.
    3673            0 :            call pawcprj_copy(Cprj_out(iatom:iatom,:), wave%Cprj(sidx:sidx,:))
    3674              :          end do
    3675              :        case default
    3676            0 :          ABI_ERROR(sjoin("Wrong value for want_order:", itoa(want_order)))
    3677              :        end select
    3678              :      end if
    3679              :    end if
    3680              : 
    3681              :  case (WFD_STORED)
    3682              :    ! copy it back.
    3683       128476 :    if (want_order == wave%cprj_order) then
    3684       128476 :      call pawcprj_copy(wave%Cprj,Cprj_out)
    3685              : 
    3686              :    else
    3687            0 :      select case (want_order)
    3688              :      case (CPR_SORTED)
    3689            0 :        do iatom=1,Cryst%natom
    3690            0 :          sidx = Cryst%atindx(iatom) ! random --> sorted table.
    3691            0 :          call pawcprj_copy(wave%Cprj(iatom:iatom,:),Cprj_out(sidx:sidx,:))
    3692              :        end do
    3693              :      case (CPR_RANDOM)
    3694            0 :        do sidx=1,Cryst%natom
    3695            0 :          iatom = Cryst%atindx1(sidx) ! sorted --> random table.
    3696            0 :          call pawcprj_copy(wave%Cprj(sidx:sidx,:),Cprj_out(iatom:iatom,:))
    3697              :        end do
    3698              :      case default
    3699            0 :        ABI_ERROR(sjoin("Wrong value for want_order:", itoa(want_order)))
    3700              :      end select
    3701              :    end if
    3702              : 
    3703              :  case default
    3704       130075 :    ABI_BUG(sjoin("Wrong has_cprj: ", itoa(wave%has_cprj)))
    3705              :  end select
    3706              : 
    3707       130075 : end subroutine wfd_get_cprj
    3708              : !!***
    3709              : 
    3710              : !----------------------------------------------------------------------
    3711              : 
    3712              : !!****f* m_wfd/wfd_change_ngfft
    3713              : !! NAME
    3714              : !!  wfd_change_ngfft
    3715              : !!
    3716              : !! FUNCTION
    3717              : !!   Reallocate and reinitialize internal tables for performing FFTs of wavefunctions.
    3718              : !!
    3719              : !! INPUTS
    3720              : !!  Cryst<crystal_t>=Info on unit cell.
    3721              : !!  Psps<pseudopotential_type>=Pseudopotential info.
    3722              : !!  new_ngfft(18)=FFT descriptor for the new FFT mesh.
    3723              : !!
    3724              : !! SOURCE
    3725              : 
    3726          645 : subroutine wfd_change_ngfft(Wfd, Cryst, Psps, new_ngfft)
    3727              : 
    3728              : !Arguments ------------------------------------
    3729              : !scalars
    3730              :  integer,intent(in) :: new_ngfft(18)
    3731              :  type(crystal_t),intent(in) :: Cryst
    3732              :  type(pseudopotential_type),intent(in) :: Psps
    3733              :  class(wfd_t),intent(inout) :: Wfd
    3734              : 
    3735              : !Local variables ------------------------------
    3736              : !scalars
    3737              :  integer,parameter :: npw0=0
    3738              :  integer :: npw_k, ik_ibz, istwf_k, is, ik, ib
    3739              :  logical :: iscompatibleFFT
    3740              :  !character(len=500) :: msg
    3741              : !arrays
    3742          645 :  integer,allocatable :: kg_k(:,:)
    3743              : !************************************************************************
    3744              : 
    3745          654 :  if (all(Wfd%ngfft(1:3) == new_ngfft(1:3)) ) RETURN ! Nothing to do.
    3746              : 
    3747          642 :  if (Wfd%prtvol > 0) then
    3748           89 :    call wrtout(std_out, sjoin(" Changing FFT mesh for wavefunctions: ",ltoa(Wfd%ngfft(1:3)), " ==> ", ltoa(new_ngfft(1:3))))
    3749              :  end if
    3750              : 
    3751              :  ! Change FFT dimensions.
    3752        12198 :  Wfd%ngfft  = new_ngfft
    3753         2568 :  Wfd%mgfft  = MAXVAL(new_ngfft(1:3))
    3754         2568 :  Wfd%nfftot = PRODUCT(new_ngfft(1:3))
    3755          642 :  Wfd%nfft   = Wfd%nfftot ! No FFT parallelism.
    3756              : 
    3757              :  ! Re-initialize fft distribution
    3758          642 :  call Wfd%MPI_enreg%distribfft%free()
    3759          642 :  call Wfd%MPI_enreg%distribfft%init('c',Wfd%MPI_enreg%nproc_fft,new_ngfft(2),new_ngfft(3))
    3760              : 
    3761         1926 :  ABI_REMALLOC(Wfd%ph1d,(2,3*(2*Wfd%mgfft+1)*Cryst%natom))
    3762          642 :  call getph(Cryst%atindx,Cryst%natom,Wfd%ngfft(1),Wfd%ngfft(2),Wfd%ngfft(3),Wfd%ph1d,Cryst%xred)
    3763              : 
    3764              :  ! Recalculate FFT tables.
    3765              :  ! Calculate the FFT index of $ R^{-1} (r-\tau) $ used to symmetrize u_Rk.
    3766              : #ifdef FC_LLVM
    3767              :  ! LLVM 16 doesn't recognize this macro here
    3768              :  ABI_REMALLOC(Wfd%irottb, (Wfd%nfftot,Cryst%nsym) )
    3769              : #else
    3770         2568 :  ABI_REMALLOC(Wfd%irottb, (Wfd%nfftot,Cryst%nsym))
    3771              : #endif
    3772          642 :  call rotate_FFT_mesh(Cryst%nsym,Cryst%symrel,Cryst%tnons,Wfd%ngfft,Wfd%irottb,iscompatibleFFT)
    3773              : 
    3774          642 :  if (.not. iscompatibleFFT) then
    3775          120 :    ABI_WARNING("FFT mesh not compatible with symmetries. Wavefunction symmetrization should not be done in r-space!")
    3776              :  end if
    3777              : 
    3778              :  ! Is the new real space FFT mesh compatible with the rotational part?
    3779          642 :  Wfd%rfft_is_symok = check_rot_fft(Cryst%nsym,Cryst%symrel,Wfd%ngfft(1),Wfd%ngfft(2),Wfd%ngfft(3))
    3780              : 
    3781              :  ! Reallocate ur buffers with correct dimensions.
    3782         1296 :  do is=1,size(wfd%s)
    3783         6279 :    do ik=1,size(wfd%s(is)%k)
    3784        83751 :      do ib=1,size(wfd%s(is)%k(ik)%b)
    3785        83097 :        call wfd%s(is)%k(ik)%b(ib)%free(what="R")
    3786              :      end do
    3787              :    end do
    3788              :  end do
    3789              : 
    3790              :  ! Reinit Kdata_t
    3791         5587 :  do ik_ibz=1,Wfd%nkibz
    3792         5921 :    if (any(wfd%bks2wfd(1, :, ik_ibz, :) /= 0)) then
    3793         4945 :      istwf_k = Wfd%istwfk(ik_ibz)
    3794         4945 :      npw_k   = Wfd%Kdata(ik_ibz)%npw
    3795        14835 :      ABI_MALLOC(kg_k, (3,npw_k))
    3796      6063170 :      kg_k = Wfd%Kdata(ik_ibz)%kg_k
    3797         4945 :      call Wfd%Kdata(ik_ibz)%free()
    3798         4945 :      call Wfd%Kdata(ik_ibz)%init(Cryst,Psps,Wfd%kibz(:,ik_ibz),istwf_k,new_ngfft,Wfd%MPI_enreg,kg_k=kg_k)
    3799         4945 :      ABI_FREE(kg_k)
    3800              :    end if
    3801              :  end do
    3802              : 
    3803          642 : end subroutine wfd_change_ngfft
    3804              : !!***
    3805              : 
    3806              : !----------------------------------------------------------------------
    3807              : 
    3808              : !!****f* m_wfd/wfd_test_ortho
    3809              : !! NAME
    3810              : !! wfd_test_ortho
    3811              : !!
    3812              : !! FUNCTION
    3813              : !!  Test the orthonormalization of the wavefunctions stored in Wfd.
    3814              : !!
    3815              : !! INPUTS
    3816              : !!  Cryst<crystal_t>=Object defining the unit cell and its symmetries.
    3817              : !!  Pawtab(ntypat*usepaw)<type(pawtab_type)>=PAW tabulated starting data.
    3818              : !!
    3819              : !! OUTPUT
    3820              : !!   Only writing.
    3821              : !!
    3822              : !! SOURCE
    3823              : 
    3824            0 : subroutine wfd_test_ortho(Wfd,Cryst,Pawtab,unit,mode_paral)
    3825              : 
    3826              : !Arguments ------------------------------------
    3827              : !scalars
    3828              :  integer,intent(in),optional :: unit
    3829              :  character(len=4),optional,intent(in) :: mode_paral
    3830              :  type(crystal_t),intent(in) :: Cryst
    3831              :  class(wfd_t),target,intent(inout) :: Wfd
    3832              : !array
    3833              :  type(Pawtab_type),intent(in) :: Pawtab(Cryst%ntypat*Wfd%usepaw)
    3834              : 
    3835              : !Local variables ------------------------------
    3836              : !scalars
    3837              :  integer :: ik_ibz,spin,band,band1,band2,ib,ib1,ib2,ierr,how_manyb,my_unt,npw_k,istwf_k
    3838              :  real(dp) :: glob_cinf,my_cinf,glob_csup,my_csup,glob_einf,min_norm2,glob_esup,max_norm2
    3839              :  complex(dp) :: cdum
    3840              :  logical :: bands_are_spread
    3841              :  character(len=4) :: my_mode
    3842              :  character(len=500) :: msg
    3843              :  type(wave_t),pointer :: wave1, wave2
    3844              : !arrays
    3845            0 :  integer :: my_bandlist(Wfd%mband)
    3846              :  real(dp) :: pawovlp(2)
    3847            0 :  complex(gwp),contiguous, pointer :: ug1(:),ug2(:)
    3848              :  !complex(gwp) :: ur(Wfd%nfft*Wfd%nspinor)
    3849              :  character(len=6) :: tag_spin(2)
    3850            0 :  type(pawcprj_type),allocatable :: Cp1(:,:),Cp2(:,:)
    3851              : !************************************************************************
    3852              : 
    3853            0 :  tag_spin(:)=(/'      ','      '/); if (Wfd%nsppol==2) tag_spin(:)=(/' UP   ',' DOWN '/)
    3854              : 
    3855            0 :  my_unt   =std_out; if (present(unit      )) my_unt   =unit
    3856              :  my_mode  ='COLL' ; if (present(mode_paral)) my_mode  =mode_paral
    3857              : 
    3858            0 :  if (Wfd%usepaw==1) then
    3859            0 :    ABI_MALLOC(Cp1,(Wfd%natom,Wfd%nspinor))
    3860            0 :    call pawcprj_alloc(Cp1,0,Wfd%nlmn_atm)
    3861            0 :    ABI_MALLOC(Cp2,(Wfd%natom,Wfd%nspinor))
    3862            0 :    call pawcprj_alloc(Cp2,0,Wfd%nlmn_atm)
    3863              :  end if
    3864              : 
    3865            0 :  bands_are_spread = .FALSE.
    3866              : 
    3867            0 :  do spin=1,Wfd%nsppol
    3868            0 :    min_norm2=greatest_real; max_norm2=-greatest_real
    3869            0 :    my_cinf=greatest_real;  my_csup=-greatest_real
    3870            0 :    do ik_ibz=1,Wfd%nkibz
    3871            0 :      npw_k = Wfd%npwarr(ik_ibz); istwf_k = Wfd%istwfk(ik_ibz)
    3872              : 
    3873              :      ! Select my band indices.
    3874            0 :      call wfd%mybands(ik_ibz,spin,how_manyb,my_bandlist, how="Stored")
    3875            0 :      if (how_manyb/=Wfd%nband(ik_ibz,spin)) bands_are_spread = .TRUE.
    3876              : 
    3877              :      ! 1) Normalization.
    3878            0 :      do ib=1,how_manyb
    3879            0 :        band = my_bandlist(ib)
    3880            0 :        ABI_CHECK(wfd%get_wave_ptr(band, ik_ibz, spin, wave1, msg) == 0, msg)
    3881            0 :        ug1 => wave1%ug
    3882            0 :        cdum = xdotc(npw_k*Wfd%nspinor,ug1,1,ug1,1)
    3883            0 :        if (istwf_k > 1) then
    3884            0 :          cdum=two*DBLE(cdum)
    3885            0 :          if (istwf_k == 2) cdum=cdum-CONJG(ug1(1))*ug1(1)
    3886              :        end if
    3887            0 :        if (Wfd%usepaw==1) then
    3888            0 :          call wfd%get_cprj(band,ik_ibz,spin,Cryst,Cp1,sorted=.FALSE.)
    3889            0 :          pawovlp = paw_overlap(Cp1,Cp1,Cryst%typat,Pawtab,spinor_comm=Wfd%MPI_enreg%comm_spinor)
    3890            0 :          cdum = cdum + CMPLX(pawovlp(1),pawovlp(2), kind=dp)
    3891              :        end if
    3892              :        !write(std_out,*)"ik_ibz, band, spin, cdum: ",ik_ibz,band,spin,cdum
    3893            0 :        if (REAL(cdum)<min_norm2) min_norm2=REAL(cdum)
    3894            0 :        if (REAL(cdum)>max_norm2) max_norm2=REAL(cdum)
    3895              :      end do
    3896              : 
    3897              :      ! TODO should use the communicator for this spin
    3898            0 :      call xmpi_min(min_norm2,glob_einf,Wfd%comm,ierr)
    3899            0 :      call xmpi_max(max_norm2,glob_esup,Wfd%comm,ierr)
    3900              : 
    3901              :      ! 2) Orthogonality of wavefunctions.
    3902            0 :      do ib1=1,how_manyb
    3903            0 :        band1 = my_bandlist(ib1)
    3904            0 :        ABI_CHECK(wfd%get_wave_ptr(band1, ik_ibz, spin, wave1, msg) == 0, msg)
    3905            0 :        ug1 => wave1%ug
    3906            0 :        if (Wfd%usepaw==1) call wfd%get_cprj(band1,ik_ibz,spin,Cryst,Cp1,sorted=.FALSE.)
    3907              : 
    3908            0 :        do ib2=ib1+1,how_manyb
    3909            0 :          band2 = my_bandlist(ib2)
    3910            0 :          ABI_CHECK(wfd%get_wave_ptr(band2, ik_ibz, spin, wave2, msg) == 0, msg)
    3911            0 :          ug2 => wave2%ug
    3912            0 :          if (Wfd%usepaw==1) call wfd%get_cprj(band2,ik_ibz,spin,Cryst,Cp2,sorted=.FALSE.)
    3913              : 
    3914            0 :          cdum = xdotc(npw_k*Wfd%nspinor,ug1,1,ug2,1)
    3915            0 :          if (istwf_k>1) then
    3916            0 :            cdum=two*DBLE(cdum)
    3917            0 :            if (istwf_k==2) cdum=cdum-CONJG(ug1(1))*ug2(1)
    3918              :          end if
    3919            0 :          if (Wfd%usepaw==1) then
    3920            0 :            pawovlp = paw_overlap(Cp1,Cp2,Cryst%typat,Pawtab,spinor_comm=Wfd%MPI_enreg%comm_spinor)
    3921            0 :            cdum = cdum + CMPLX(pawovlp(1),pawovlp(2), kind=dp)
    3922              :          end if
    3923              : 
    3924            0 :          if (ABS(cdum)<my_cinf) my_cinf=ABS(cdum)
    3925            0 :          if (ABS(cdum)>my_csup) my_csup=ABS(cdum)
    3926              :          !if (ABS(cdum) > 0.1) write(std_out,*)" ib1,ib2,ABS_dotprod: ",ib1,ib2,ABS(cdum)
    3927              :        end do !ib2
    3928              :      end do !ib
    3929              : 
    3930              :      ! TODO should use the communicator for this spin
    3931            0 :      call xmpi_min(my_cinf,glob_cinf,Wfd%comm,ierr)
    3932            0 :      call xmpi_max(my_csup,glob_csup,Wfd%comm,ierr)
    3933              :    end do ! ik_ibz
    3934              : 
    3935              :    ! Output results for this spin
    3936            0 :    write(msg,'(2a)')ch10,' test on the normalization of the wavefunctions'
    3937            0 :    if (Wfd%nsppol==2) write(msg,'(3a)')ch10,' test on the normalization of the wavefunctions with spin ',tag_spin(spin)
    3938            0 :    call wrtout(my_unt,msg,mode_paral)
    3939              :    write(msg,'(a,f9.6,a,a,f9.6)')&
    3940            0 :      ' min sum_G |a(n,k,G)| = ',glob_einf,ch10,&
    3941            0 :      ' max sum_G |a(n,k,G)| = ',glob_esup
    3942            0 :    call wrtout(my_unt,msg,mode_paral)
    3943              : 
    3944            0 :    write(msg,'(a)')' test on the orthogonalization of the wavefunctions (NB: this is not invariant for degenerate states)'
    3945            0 :    if (Wfd%nsppol==2) write(msg,'(2a)')' test on the orthogonalization of the wavefunctions with spin ',tag_spin(spin)
    3946            0 :    call wrtout(my_unt,msg,mode_paral)
    3947              :    write(msg,'(a,f9.6,a,a,f9.6,a)')&
    3948            0 :      '- min sum_G a(n,k,G)a(n",k,G) = ',glob_cinf,ch10,&
    3949            0 :      '- max sum_G a(n,k,G)a(n",k,G) = ',glob_csup,ch10
    3950            0 :    call wrtout(my_unt,msg,mode_paral)
    3951              : 
    3952              :  end do ! spin
    3953              : 
    3954            0 :  if (bands_are_spread) then
    3955              :    write(msg,'(3a)')&
    3956            0 :      'Note that the test on the orthogonalization is not complete ',ch10,&
    3957            0 :      'since bands are spread among different processors'
    3958            0 :    call wrtout(my_unt,msg,mode_paral)
    3959              :  end if
    3960              : 
    3961            0 :  if (Wfd%usepaw==1) then
    3962            0 :    call pawcprj_free(Cp1)
    3963            0 :    ABI_FREE(Cp1)
    3964            0 :    call pawcprj_free(Cp2)
    3965            0 :    ABI_FREE(Cp2)
    3966              :  end if
    3967              : 
    3968            0 : end subroutine wfd_test_ortho
    3969              : !!***
    3970              : 
    3971              : !----------------------------------------------------------------------
    3972              : 
    3973              : !!****f* m_wfd/wfd_sym_ur
    3974              : !! NAME
    3975              : !!  wfd_sym_ur
    3976              : !!
    3977              : !! FUNCTION
    3978              : !!  Symmetrize a wave function in real space
    3979              : !!
    3980              : !! INPUTS
    3981              : !!  Wfd<wfd_t>=the wavefunction descriptor.
    3982              : !!  Cryst<crystal_t>=Structure describing the crystal structure and its symmetries.
    3983              : !!  Kmesh<kmesh_t>=Structure describing the BZ sampling
    3984              : !!  band=Band index.
    3985              : !!  ik_bz=Index of the k-point in the BZ.
    3986              : !!  spin=Spin index
    3987              : !!  [trans] = "N" if only the symmetried wavefunction is needed, "C" if the complex conjugate is required.
    3988              : !!            Default is "N"
    3989              : !!  [with_umklp] = Optional flag. If .True. (Default) the umklapp G0 vector in the relation kbz = Sk + G0
    3990              : !!                 is taken into account when constructing u_kbz.
    3991              : !!
    3992              : !! NOTES
    3993              : !!  This method is deprecated. See wfd_sym_ug_kg and wfd_sym_ug_kg_npw for symmetrization in G-space
    3994              : !!
    3995              : !! OUTPUT
    3996              : !!  ur_kbz(Wfd%nfft*Wfd%nspinor)=The symmetrized wavefunction in real space.
    3997              : !!  [ur_kibz(Wfd%nfft*Wfd%nspinor)]= Optional output: u(r) in the IBZ.
    3998              : !!
    3999              : !! SOURCE
    4000              : 
    4001        51200 : subroutine wfd_sym_ur(Wfd,Cryst,Kmesh,band,ik_bz,spin,ur_kbz,trans,with_umklp,ur_kibz)
    4002              : 
    4003              : !Arguments ------------------------------------
    4004              : !scalars
    4005              :  integer,intent(in) :: band,ik_bz,spin
    4006              :  character(len=*),optional,intent(in) :: trans
    4007              :  logical,optional,intent(in) :: with_umklp
    4008              :  type(crystal_t),intent(in) :: Cryst
    4009              :  type(kmesh_t),intent(in) :: Kmesh
    4010              :  class(wfd_t),intent(inout) :: Wfd
    4011              : !arrays
    4012              :  complex(gwp),intent(out) :: ur_kbz(Wfd%nfft*Wfd%nspinor)
    4013              :  complex(gwp),optional,intent(out) :: ur_kibz(Wfd%nfft*Wfd%nspinor)
    4014              : 
    4015              : !Local variables ------------------------------
    4016              : !scalars
    4017              :  integer :: ik_ibz,isym_k,itim_k,nr,ispinor,spad,ir,ir2
    4018              :  integer :: fft_idx,ix,iy,iz,nx,ny,nz,irot
    4019              :  real(dp) :: gdotr
    4020              :  complex(dp) :: ph_mkt,u2b,u2a
    4021              :  complex(gwp) :: gwpc_ph_mkt
    4022              :  logical :: isirred,my_with_umklp
    4023              :  character(len=1) :: my_trans
    4024              :  !character(len=500) :: msg
    4025              : !arrays
    4026              :  integer :: umklp(3)
    4027              :  real(dp) :: kbz(3),spinrot_k(4)
    4028              :  complex(dp) :: spinrot_mat(2,2)
    4029        51200 :  complex(gwp),allocatable :: ur(:)
    4030              : !************************************************************************
    4031              : 
    4032        51200 :  my_trans = "N"; if (present(trans)) my_trans = toupper(trans(1:1))
    4033        51200 :  my_with_umklp = .TRUE.; if (present(with_umklp)) my_with_umklp = with_umklp
    4034              : 
    4035              :  ! k_bz =  S k - G0 ==> u_{k_bz} =  e^{iG0.r} u_{Sk}
    4036              :  ! k_bz = -S k - G0 ==> u_{k_bz} =  e^{iG0.r} u_{Sk}^*
    4037              : 
    4038              :  ! u(r,b,kbz)=e^{-2i\pi kibz.(R^{-1}t} u (R{^-1}(r-t),b,kibz)
    4039              :  !           =e^{+2i\pi kibz.(R^{-1}t} u*({R^-1}(r-t),b,kibz) for time-reversal
    4040              :  !
    4041              :  ! Get ik_ibz, non-symmorphic phase, ph_mkt, and symmetries from ik_bz.
    4042        51200 :  call Kmesh%get_BZ_item(ik_bz,kbz,ik_ibz,isym_k,itim_k,ph_mkt,umklp,isirred)
    4043        51200 :  gwpc_ph_mkt = ph_mkt
    4044              : 
    4045        51200 :  if (isirred) then
    4046              :    ! Avoid symmetrization if this point is irreducible.
    4047        51200 :    call wfd%get_ur(band,ik_ibz,spin,ur_kbz)
    4048        51200 :    if (present(ur_kibz)) call xcopy(Wfd%nfft*Wfd%nspinor,ur_kbz,1,ur_kibz,1)
    4049        51200 :    if (my_trans=="C") ur_kbz = GWPC_CONJG(ur_kbz)
    4050              :    RETURN
    4051              :  end if
    4052              : 
    4053              :  ! Reconstruct ur in the BZ from the corresponding wavefunction in IBZ.
    4054            0 :  ABI_MALLOC(ur, (Wfd%nfft*Wfd%nspinor))
    4055              : 
    4056            0 :  call wfd%get_ur(band,ik_ibz,spin,ur)
    4057            0 :  if (present(ur_kibz)) call xcopy(Wfd%nfft*Wfd%nspinor,ur,1,ur_kibz,1)
    4058              : 
    4059              :  ! Wfd%irottb(:,isym_k) is the table for rotated FFT points
    4060            0 :  SELECT CASE (Wfd%nspinor)
    4061              : 
    4062              :  CASE (1)
    4063              :    ! Rotation in real space
    4064            0 :    do ir=1,Wfd%nfft
    4065            0 :      irot = Wfd%irottb(ir,isym_k)
    4066            0 :      ur_kbz(ir) = ur(irot) * gwpc_ph_mkt
    4067              :    end do
    4068              : 
    4069              :    ! Apply time-reversal symmetry if needed.
    4070            0 :    if (itim_k==2) ur_kbz = GWPC_CONJG(ur_kbz)
    4071              : 
    4072              :    ! Take into account a possible umklapp.
    4073            0 :    if (ANY(umklp/=0).and. my_with_umklp) then
    4074              :      ! Compute ur_kbz = ur_kbz*eig0r
    4075            0 :      nx = Wfd%ngfft(1); ny = Wfd%ngfft(2); nz = Wfd%ngfft(3)
    4076            0 :      fft_idx=0
    4077            0 :      do iz=0,nz-1
    4078            0 :        do iy=0,ny-1
    4079            0 :          do ix=0,nx-1
    4080              :            gdotr= two_pi*( umklp(1)*(ix/DBLE(nx)) &
    4081              :                           +umklp(2)*(iy/DBLE(ny)) &
    4082            0 :                           +umklp(3)*(iz/DBLE(nz)) )
    4083            0 :            fft_idx = fft_idx+1
    4084            0 :            ur_kbz(fft_idx) = ur_kbz(fft_idx) * DCMPLX(DCOS(gdotr),DSIN(gdotr))
    4085              :          end do
    4086              :        end do
    4087              :      end do
    4088              :    end if
    4089              : 
    4090            0 :    if (my_trans=="C") ur_kbz = GWPC_CONJG(ur_kbz)
    4091              : 
    4092              :  CASE (2)
    4093            0 :    ABI_ERROR("Implementation has to be tested")
    4094              : 
    4095            0 :    nr = Wfd%nfft
    4096            0 :    spinrot_k = Cryst%spinrot(:,isym_k)
    4097              :    !
    4098              :    ! ==== Apply Time-reversal if required ====
    4099              :    ! \psi_{-k}^1 =  (\psi_k^2)^*
    4100              :    ! \psi_{-k}^2 = -(\psi_k^1)^*
    4101            0 :    if (itim_k==1) then
    4102            0 :      ur_kbz = ur
    4103            0 :    else if (itim_k==2) then
    4104            0 :      ur_kbz(1:nr)     = GWPC_CONJG(ur(nr+1:2*nr))
    4105            0 :      ur_kbz(nr+1:2*nr)=-GWPC_CONJG(ur(1:nr))
    4106              :    else
    4107            0 :      ABI_ERROR('Wrong i2 in spinor')
    4108              :    end if
    4109              :    !
    4110              :    ! Rotate wavefunctions in real space.
    4111            0 :    do ispinor=1,Wfd%nspinor
    4112            0 :      spad=(ispinor-1)*nr
    4113            0 :      do ir=1,nr
    4114            0 :        ir2 = Wfd%irottb(ir,isym_k)
    4115            0 :        ur_kbz(ir+spad) = ur_kbz(ir2+spad) * gwpc_ph_mkt
    4116              :      end do
    4117              :    end do
    4118              :    !
    4119              :    ! Rotation in spinor space.
    4120            0 :    spinrot_mat(1,1)= spinrot_k(1) + j_dpc*spinrot_k(4)
    4121            0 :    spinrot_mat(1,2)= spinrot_k(3) + j_dpc*spinrot_k(2)
    4122            0 :    spinrot_mat(2,1)=-spinrot_k(3) + j_dpc*spinrot_k(2)
    4123            0 :    spinrot_mat(2,2)= spinrot_k(1) - j_dpc*spinrot_k(4)
    4124              : 
    4125            0 :    do ir=1,nr
    4126            0 :      u2a=ur_kbz(ir)
    4127            0 :      u2b=ur_kbz(ir+nr)
    4128            0 :      ur_kbz(ir)   =spinrot_mat(1,1)*u2a+spinrot_mat(1,2)*u2b
    4129            0 :      ur_kbz(ir+nr)=spinrot_mat(2,1)*u2a+spinrot_mat(2,2)*u2b
    4130              :    end do
    4131              : 
    4132            0 :    if (ANY(umklp /=0)) then
    4133              :      !ur_kbz(1:Wfd%nfft)  = ur_kbz(1:Wfd%nfft) *eig0r
    4134              :      !ur_kbz(Wfd%nfft+1:) = ur_kbz(Wfd%nfft+1:)*eig0r
    4135              :    end if
    4136              : 
    4137              :  CASE DEFAULT
    4138            0 :    ABI_ERROR(sjoin("Wrong value for nspinor: ", itoa(Wfd%nspinor)))
    4139              :  END SELECT
    4140              : 
    4141            0 :  ABI_FREE(ur)
    4142              : 
    4143              : end subroutine wfd_sym_ur
    4144              : !!***
    4145              : 
    4146              : !!****f* m_wfd/wfd_rotate_cg
    4147              : !! NAME
    4148              : !!  wfd_rotate_cg
    4149              : !!
    4150              : !! FUNCTION
    4151              : !!  Use crystalline symmetries and time reversal to reconstruct wavefunctions at kk_bz from the IBZ image
    4152              : !!  Return the periodic part in G-space and, optionally, the real-space term.
    4153              : !!
    4154              : !! INPUTS
    4155              : !!  kk_ibz: Symmetrical image of kk_bz in the IBZ.
    4156              : !!  band: Initial band index
    4157              : !!  ndat: Number of bands to symmetrize.
    4158              : !!  spin: Spin index
    4159              : !!  npw_kbz: Number of G-vectors in kk_bz G-sphere
    4160              : !!  kg_kbz: G-vectors in reduced coordinates.
    4161              : !!  istwf_kbz: Time-reversal flag associated to output wavefunctions
    4162              : !!  cryst: Crystalline structure and symmetries
    4163              : !!  indkk: Symmetry map kk_bz -> kk_ibz as computed by listkk with the SYMREL convention.
    4164              : !!  gbound_kbz: The boundary of the basis sphere of G vectors centered on the kk in BZ (not on kk_ibz!)
    4165              : !!  work_ngfft: Define the size of the workspace array work
    4166              : !!  work: Workspace array used to symmetrize wavefunctions
    4167              : !!
    4168              : !! OUTPUT
    4169              : !!  cgs_kbz: Periodic part of wavefunctions at kk_bz
    4170              : !!  [urs_kbz]: wavefunctions at kk_bz in real space.
    4171              : !!
    4172              : !! SOURCE
    4173              : 
    4174       304478 : subroutine wfd_rotate_cg(wfd, band, ndat, spin, kk_ibz, npw_kbz, kg_kbz, istwf_kbz, &
    4175        15352 :                          cryst, indkk, gbound_kbz, work_ngfft, work, cgs_kbz, urs_kbz)
    4176              : 
    4177              : !Arguments ------------------------------------
    4178              : !scalars
    4179              :  class(wfd_t),intent(inout) :: wfd
    4180              :  integer,intent(in) :: band, ndat, spin, npw_kbz, istwf_kbz
    4181              :  type(crystal_t),intent(in) :: cryst
    4182              : !arrays
    4183              :  integer,intent(in) :: work_ngfft(18)
    4184              :  integer,intent(in) :: indkk(6)
    4185              :  integer,intent(in) :: gbound_kbz(2*wfd%mgfft+8, 2)
    4186              :  integer,intent(in) :: kg_kbz(3, npw_kbz)
    4187              :  real(dp),intent(in) :: kk_ibz(3)
    4188              :  real(dp),intent(out) :: work(2, work_ngfft(4), work_ngfft(5), work_ngfft(6))
    4189              :  real(dp),target,intent(out) :: cgs_kbz(2, npw_kbz*wfd%nspinor, ndat)
    4190              :  complex(gwp),optional,intent(out) :: urs_kbz(wfd%nfft*wfd%nspinor, ndat)
    4191              : 
    4192              : !Local variables ------------------------------
    4193              : !scalars
    4194              :  integer,parameter :: ndat1 = 1
    4195              :  integer :: ik_ibz, isym_k, trev_k, idat, istwf_kirr, npw_kirr, ib
    4196              :  logical :: isirr_k
    4197              :  !real(dp) :: norm
    4198              : !arrays
    4199              :  integer :: g0_k(3)
    4200       152239 :  real(dp),allocatable :: cg_kirr(:,:)
    4201              :  complex(gwp),allocatable :: cwork_sp(:,:)
    4202              : #ifdef HAVE_GW_DPC
    4203       152239 :  complex(gwp),pointer :: ugs_dp_ptr(:,:)
    4204              : #endif
    4205              : !************************************************************************
    4206              : 
    4207              :  ! As reported by listkk with the symrel convention
    4208       608956 :  ik_ibz = indkk(1); isym_k = indkk(2); trev_k = indkk(6); g0_k = indkk(3:5)
    4209       459244 :  isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
    4210              : 
    4211              :  if (isirr_k) then
    4212        77340 :    do idat=1,ndat
    4213              :      ! Copy u_k(G)
    4214        38670 :      ib = band + idat - 1
    4215        38670 :      call wfd%copy_cg(ib, ik_ibz, spin, cgs_kbz(:,:,idat))
    4216        77340 :      if (present(urs_kbz)) call wfd%get_ur(ib, ik_ibz, spin, urs_kbz(:,idat))
    4217              :    end do
    4218              : 
    4219              :  else
    4220              :    ! Reconstruct u_k(G) from the IBZ image. Use cg_kirr as workspace array, results stored in cgs_kbz.
    4221       113569 :    istwf_kirr = wfd%istwfk(ik_ibz); npw_kirr = wfd%npwarr(ik_ibz)
    4222       340707 :    ABI_MALLOC(cg_kirr, (2, npw_kirr*wfd%nspinor))
    4223              : 
    4224       227138 :    do idat=1,ndat
    4225       113569 :      ib = band + idat - 1
    4226       113569 :      call wfd%copy_cg(ib, ik_ibz, spin, cg_kirr)
    4227              :      call cgtk_rotate(cryst, kk_ibz, isym_k, trev_k, g0_k, wfd%nspinor, ndat1, &
    4228              :                       wfd%npwarr(ik_ibz), wfd%kdata(ik_ibz)%kg_k, &
    4229       227138 :                       npw_kbz, kg_kbz, wfd%istwfk(ik_ibz), istwf_kbz, cg_kirr, cgs_kbz(:,:,idat), work_ngfft, work)
    4230              :    end do
    4231       113569 :    ABI_FREE(cg_kirr)
    4232              : 
    4233       113569 :    if (present(urs_kbz)) then
    4234              : #ifdef HAVE_GW_DPC
    4235              :      ! we are using double precision -> cast dp cgs_kbz to dp complex pointer.
    4236        37686 :      call c_f_pointer(c_loc(cgs_kbz), ugs_dp_ptr, [npw_kbz*wfd%nspinor, ndat])
    4237              :      call fft_ug(npw_kbz, wfd%nfft, wfd%nspinor, ndat, wfd%mgfft, wfd%ngfft, istwf_kbz, kg_kbz, gbound_kbz, &
    4238        12562 :                  ugs_dp_ptr(:,1), urs_kbz(:,1))
    4239              : #else
    4240              :      ! Transfer cgs_kbz from dp to sp and perform FFT in single precision.
    4241              :      ABI_MALLOC(cwork_sp, (npw_kbz*wfd%nspinor, ndat))
    4242              :      cwork_sp(:,:) = cgs_kbz(1,:,:) + j_sp * cgs_kbz(2,:,:)
    4243              :      call fft_ug(npw_kbz, wfd%nfft, wfd%nspinor, ndat, wfd%mgfft, wfd%ngfft, istwf_kbz, kg_kbz, gbound_kbz, &
    4244              :                  cwork_sp(:,1), urs_kbz(:,1))
    4245              :      ABI_FREE(cwork_sp)
    4246              : #endif
    4247              :    end if
    4248              :  end if
    4249              : 
    4250              :  ! Debug section
    4251              :  !do idat=1,ndat
    4252              :  !  norm = sqrt(cg_dznrm2(npw_kbz*wfd%nspinor, cgs_kbz(:, :, idat)))
    4253              :  !  if (abs(norm - one) > tol12) then
    4254              :  !    ABI_ERROR(sjoin("norm:", ftoa(norm)))
    4255              :  !  end if
    4256              :  !end do
    4257              : 
    4258       167591 : end subroutine wfd_rotate_cg
    4259              : !!***
    4260              : 
    4261              : !----------------------------------------------------------------------
    4262              : 
    4263              : !!****f* m_wfd/wfd_sym_ug_kg
    4264              : !! NAME
    4265              : !!  wfd_sym_ug_kg
    4266              : !!
    4267              : !! FUNCTION
    4268              : !!  Use crystalline symmetries and time reversal to reconstruct wavefunctions at kk_bz from the IBZ image kk_ibz.
    4269              : !!  Return periodic part in G-space as well as list of G-vectors belonging to the G-sphere centered on kk_bz
    4270              : !!
    4271              : !! INPUTS
    4272              : !!  ecut: Cutoff energy for planewave basis set.
    4273              : !!  kk_bz: k-point in the BZ for output wavefunctions and G-vectors.
    4274              : !!  kk_ibz: Symmetrical image of kk_bz in the IBZ.
    4275              : !!  bstart: Initial band index
    4276              : !!  nband: Number of bands to symmetrize.
    4277              : !!  spin: Spin index
    4278              : !!  mpw: MAXIMUM number of planewaves used to dimension arrays.
    4279              : !!  indkk: Symmetry map kk_bz -> kk_ibz as computed by listkk with the symrel convention.
    4280              : !!  cryst: Crystalline structure and symmetries
    4281              : !!  work_ngfft: Define the size of the workspace array work
    4282              : !!  work: Workspace array used to symmetrize wavefunctions
    4283              : !!  force_rotate: optional, use cgtk_rotate for kpoint even if it is in the IBZ.
    4284              : !!
    4285              : !! OUTPUT
    4286              : !!  istwf_kbz: Time-reversal flag associated to output wavefunctions.
    4287              : !!  npw_kbz: Number of G-vectors in kk_bz G-sphere.
    4288              : !!  kg_kbz: G-vectors in reduced coordinates.
    4289              : !!  cgs_kbz: Periodic part of wavefunctions at kk_bz.
    4290              : !!
    4291              : !! NOTES
    4292              : !!  This routine is deprecated and should be replaced by sym_ug_kg_npw.
    4293              : !!  In order to call getgh1c with ndat > 1, indeed, one should return an array dimensioned
    4294              : !!  as (2, npw_kbz*wfd%nspinor, nband) instead of (2, mpw*wfd%nspinor, nband)
    4295              : !!
    4296              : !! SOURCE
    4297              : 
    4298          304 : subroutine wfd_sym_ug_kg(wfd, ecut, kk_bz, kk_ibz, bstart, nband, spin, mpw, indkk, cryst, &
    4299          304 :                          work_ngfft, work, istwf_kbz, npw_kbz, kg_kbz, cgs_kbz, &
    4300              :                          force_rotate) ! optional
    4301              : 
    4302              : !Arguments ------------------------------------
    4303              : !scalars
    4304              :  class(wfd_t),intent(in) :: wfd
    4305              :  integer,intent(in) :: bstart, nband, spin, mpw
    4306              :  type(crystal_t),intent(in) :: cryst
    4307              :  integer,intent(out) :: istwf_kbz, npw_kbz
    4308              :  real(dp),intent(in) :: ecut
    4309              : !arrays
    4310              :  integer :: work_ngfft(18)
    4311              :  integer,intent(in) :: indkk(6)
    4312              :  integer,intent(out) :: kg_kbz(3, mpw)
    4313              :  real(dp),intent(in) :: kk_bz(3), kk_ibz(3)
    4314              :  real(dp),intent(out) :: cgs_kbz(2, mpw*wfd%nspinor, nband)
    4315              :  real(dp),intent(out) :: work(2, work_ngfft(4), work_ngfft(5), work_ngfft(6))
    4316              :  logical ,optional, intent(in) :: force_rotate
    4317              : 
    4318              : !Local variables ------------------------------
    4319              : !scalars
    4320              :  integer,parameter :: ndat1 = 1
    4321              :  integer :: ik_ibz, isym_k, trev_k, ib, band, istwf_kirr, npw_kirr
    4322              :  logical :: isirr_k, rotate
    4323              : !arrays
    4324              :  integer :: g0_k(3)
    4325          304 :  integer,allocatable :: gtmp(:,:)
    4326          304 :  real(dp),allocatable :: cg_kirr(:,:)
    4327              : !************************************************************************
    4328              : 
    4329              :  ! As reported by listkk via symrel
    4330         1216 :  ik_ibz = indkk(1); isym_k = indkk(2); trev_k = indkk(6); g0_k = indkk(3:5)
    4331         1040 :  isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
    4332              : 
    4333          304 :  rotate= .not. isirr_k
    4334          304 :  if (present(force_rotate)) then
    4335          304 :    if (force_rotate) rotate=.True.
    4336              :  endif
    4337              : 
    4338              :  ! Get npw_kbz, kg_kbz and symmetrize wavefunctions from IBZ (if needed).
    4339              :  ! Be careful with time-reversal symmetry.
    4340            0 :  if (.not. rotate) then
    4341              :    ! Copy u_k(G)
    4342            0 :    istwf_kbz = wfd%istwfk(ik_ibz); npw_kbz = wfd%npwarr(ik_ibz)
    4343            0 :    ABI_CHECK_ILEQ(npw_kbz, mpw, "npw_kbz > mpw!")
    4344            0 :    kg_kbz(:,1:npw_kbz) = wfd%kdata(ik_ibz)%kg_k
    4345              : 
    4346            0 :    do ib=1,nband
    4347            0 :      band = ib + bstart - 1
    4348            0 :      call wfd%copy_cg(band, ik_ibz, spin, cgs_kbz(1,1,ib))
    4349              :    end do
    4350              : 
    4351              :  else
    4352              :    ! Reconstruct u_k(G) from the IBZ image.
    4353          304 :    istwf_kbz = 1
    4354          304 :    call get_kg(kk_bz, istwf_kbz, ecut, cryst%gmet, npw_kbz, gtmp)
    4355          304 :    ABI_CHECK_ILEQ(npw_kbz, mpw, "npw_kbz > mpw!")
    4356       278060 :    kg_kbz(:,1:npw_kbz) = gtmp(:,:npw_kbz)
    4357          304 :    ABI_FREE(gtmp)
    4358              : 
    4359              :    ! Use cg_kirr as workspace array, results stored in cgs_kbz.
    4360          304 :    istwf_kirr = wfd%istwfk(ik_ibz); npw_kirr = wfd%npwarr(ik_ibz)
    4361          912 :    ABI_MALLOC(cg_kirr, (2, npw_kirr*wfd%nspinor))
    4362         3632 :    do ib=1,nband
    4363         3328 :      band = ib + bstart - 1
    4364         3328 :      call wfd%copy_cg(band, ik_ibz, spin, cg_kirr)
    4365              :      call cgtk_rotate(cryst, kk_ibz, isym_k, trev_k, g0_k, wfd%nspinor, ndat1, &
    4366              :                       npw_kirr, wfd%kdata(ik_ibz)%kg_k, &
    4367         3632 :                       npw_kbz, kg_kbz, istwf_kirr, istwf_kbz, cg_kirr, cgs_kbz(:,:,ib), work_ngfft, work)
    4368              :    end do
    4369          304 :    ABI_FREE(cg_kirr)
    4370              :  end if
    4371              : 
    4372          304 : end subroutine wfd_sym_ug_kg
    4373              : !!***
    4374              : 
    4375              : !----------------------------------------------------------------------
    4376              : 
    4377              : !!****f* m_wfd/wfd_sym_ug_kg_npw
    4378              : !! NAME
    4379              : !!  wfd_sym_ug_kg_npw
    4380              : !!
    4381              : !! FUNCTION
    4382              : !!  Use crystalline symmetries and time reversal to reconstruct wavefunctions at kk_bz from the IBZ image kk_ibz.
    4383              : !!  Return periodic part in G-space as well as list of G-vectors belonging to the G-sphere centered on kk_bz
    4384              : !!
    4385              : !! INPUTS
    4386              : !!  ecut: Cutoff energy for planewave basis set.
    4387              : !!  kk_bz: k-point in the BZ for output wavefunctions and G-vectors.
    4388              : !!  kk_ibz: Symmetrical image of kk_bz in the IBZ.
    4389              : !!  bstart: Initial band index
    4390              : !!  nband: Number of bands to symmetrize.
    4391              : !!  spin: Spin index
    4392              : !!  mpw: MAXIMUM number of planewaves used to dimension arrays.
    4393              : !!  indkk: Symmetry map kk_bz -> kk_ibz as computed by listkk with the symrel convention.
    4394              : !!  cryst: Crystalline structure and symmetries
    4395              : !!  work_ngfft: Define the size of the workspace array work
    4396              : !!  work: Workspace array used to symmetrize wavefunctions
    4397              : !!  force_rotate: optional, use cgtk_rotate for kpoint even if it is in the IBZ.
    4398              : !!
    4399              : !! OUTPUT
    4400              : !!  istwf_kbz: Time-reversal flag associated to output wavefunctions.
    4401              : !!  npw_kbz: Number of G-vectors in kk_bz G-sphere.
    4402              : !!  kg_kbz: G-vectors in reduced coordinates.
    4403              : !!  cgs_kbz: Periodic part of wavefunctions at kk_bz.
    4404              : !!
    4405              : !! NOTES
    4406              : !!
    4407              : !! SOURCE
    4408              : 
    4409       152910 : subroutine wfd_sym_ug_kg_npw(wfd, ecut, kk_bz, kk_ibz, bstart, nband, spin, indkk, cryst, &
    4410       152910 :                              work_ngfft, work, istwf_kbz, npw_kbz, kg_kbz, cgs_kbz, &
    4411              :                              force_rotate) ! optional
    4412              : 
    4413              : !Arguments ------------------------------------
    4414              : !scalars
    4415              :  class(wfd_t),intent(in) :: wfd
    4416              :  integer,intent(in) :: bstart, nband, spin
    4417              :  type(crystal_t),intent(in) :: cryst
    4418              :  integer,intent(out) :: istwf_kbz, npw_kbz
    4419              :  real(dp),intent(in) :: ecut
    4420              : !arrays
    4421              :  integer :: work_ngfft(18)
    4422              :  integer,intent(in) :: indkk(6)
    4423              :  integer,intent(out) :: kg_kbz(:,:) ! (3, mpw)
    4424              :  real(dp),intent(in) :: kk_bz(3), kk_ibz(3)
    4425              :  real(dp),allocatable,intent(out) :: cgs_kbz(:,:,:) ! (2, npw_kbz*wfd%nspinor, nband)
    4426              :  real(dp),intent(out) :: work(2, work_ngfft(4), work_ngfft(5), work_ngfft(6))
    4427              :  logical ,optional, intent(in) :: force_rotate
    4428              : 
    4429              : !Local variables ------------------------------
    4430              : !scalars
    4431              :  integer,parameter :: ndat1 = 1
    4432              :  integer :: ik_ibz, isym_k, trev_k, ib, band, istwf_kirr, npw_kirr, mpw
    4433              :  logical :: isirr_k, rotate
    4434              : !arrays
    4435              :  integer :: g0_k(3)
    4436       152910 :  integer,allocatable :: gtmp(:,:)
    4437       152910 :  real(dp),allocatable :: cg_kirr(:,:)
    4438              : !************************************************************************
    4439              : 
    4440       152910 :  mpw = size(kg_kbz, dim=2)
    4441              : 
    4442              :  ! As reported by listkk via symrel
    4443       611640 :  ik_ibz = indkk(1); isym_k = indkk(2); trev_k = indkk(6); g0_k = indkk(3:5)
    4444       558889 :  isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
    4445              : 
    4446       152910 :  rotate= .not. isirr_k
    4447       152910 :  if (present(force_rotate)) then
    4448            0 :    if (force_rotate) rotate=.True.
    4449              :  endif
    4450              : 
    4451              :  ! Get npw_kbz, kg_kbz and symmetrize wavefunctions from IBZ (if needed).
    4452              :  ! Be careful with time-reversal symmetry.
    4453       152910 :  if (.not. rotate) then
    4454              :    ! Copy u_k(G)
    4455        10306 :    istwf_kbz = wfd%istwfk(ik_ibz); npw_kbz = wfd%npwarr(ik_ibz)
    4456        10306 :    ABI_CHECK_ILEQ(npw_kbz, mpw, "npw_kbz > mpw!")
    4457     36430678 :    kg_kbz(:,1:npw_kbz) = wfd%kdata(ik_ibz)%kg_k
    4458              : 
    4459        41224 :    ABI_MALLOC(cgs_kbz, (2, npw_kbz*wfd%nspinor, nband))
    4460        26576 :    do ib=1,nband
    4461        16270 :      band = ib + bstart - 1
    4462        26576 :      call wfd%copy_cg(band, ik_ibz, spin, cgs_kbz(1,1,ib))
    4463              :    end do
    4464              : 
    4465              :  else
    4466              :    ! Reconstruct u_k(G) from the IBZ image.
    4467       142604 :    istwf_kbz = 1
    4468       142604 :    call get_kg(kk_bz, istwf_kbz, ecut, cryst%gmet, npw_kbz, gtmp)
    4469       142604 :    ABI_CHECK_ILEQ(npw_kbz, mpw, "npw_kbz > mpw!")
    4470    491066936 :    kg_kbz(:,1:npw_kbz) = gtmp(:,:npw_kbz)
    4471       142604 :    ABI_FREE(gtmp)
    4472              : 
    4473       570416 :    ABI_MALLOC(cgs_kbz, (2, npw_kbz*wfd%nspinor, nband))
    4474              : 
    4475              :    ! Use cg_kirr as workspace array, results stored in cgs_kbz.
    4476       142604 :    istwf_kirr = wfd%istwfk(ik_ibz); npw_kirr = wfd%npwarr(ik_ibz)
    4477       427812 :    ABI_MALLOC(cg_kirr, (2, npw_kirr*wfd%nspinor))
    4478       361220 :    do ib=1,nband
    4479       218616 :      band = ib + bstart - 1
    4480       218616 :      call wfd%copy_cg(band, ik_ibz, spin, cg_kirr)
    4481              :      call cgtk_rotate(cryst, kk_ibz, isym_k, trev_k, g0_k, wfd%nspinor, ndat1, &
    4482              :                       npw_kirr, wfd%kdata(ik_ibz)%kg_k, &
    4483       361220 :                       npw_kbz, kg_kbz, istwf_kirr, istwf_kbz, cg_kirr, cgs_kbz(:,:,ib), work_ngfft, work)
    4484              :    end do
    4485       142604 :    ABI_FREE(cg_kirr)
    4486              :  end if
    4487              : 
    4488       152910 : end subroutine wfd_sym_ug_kg_npw
    4489              : !!***
    4490              : 
    4491              : !----------------------------------------------------------------------
    4492              : 
    4493              : !!****f* m_wfd/wfdgw_write_wfk
    4494              : !! NAME
    4495              : !! wfdgw_write_wfk
    4496              : !!
    4497              : !! FUNCTION
    4498              : !!  This routine writes the wavefunctions to the specified WFK file
    4499              : !!  All the wavefunction are stored on each node, only the spin is distributed.
    4500              : !!
    4501              : !! INPUTS
    4502              : !!  Wfd<wfd_t>=Initialized wavefunction descriptor.
    4503              : !!  wfk_fname=Name of the WFK file.
    4504              : !!
    4505              : !! OUTPUT
    4506              : !!  Only writing
    4507              : !!
    4508              : !! SOURCE
    4509              : 
    4510            5 : subroutine wfdgw_write_wfk(Wfd, Hdr, ebands, wfk_fname, wfknocheck)
    4511              : 
    4512              : !Arguments ------------------------------------
    4513              : !scalars
    4514              :  character(len=*),intent(in) :: wfk_fname
    4515              :  class(wfdgw_t),intent(in) :: Wfd
    4516              :  type(Hdr_type),intent(in) :: Hdr
    4517              :  type(ebands_t),intent(in) :: ebands
    4518              :  logical,intent(in),optional :: wfknocheck
    4519              : 
    4520              : !Local variables ------------------------------
    4521              : !scalars
    4522              :  integer,parameter :: formeig0=0,master=0
    4523              :  integer :: nprocs,my_rank,iomode,cgsize,npw_k,ik_ibz,spin,nband_k,band,ii
    4524              :  integer :: blk,nblocks,how_many,ierr,how_manyb
    4525              :  real(dp) :: cpu,wall,gflops
    4526              :  logical :: iam_master,nocheck ! MRM
    4527              :  character(len=500) :: msg
    4528           20 :  type(wfk_t) :: Wfkfile
    4529              : !arrays
    4530           10 :  integer :: band_block(2),proc_ranks(Wfd%nproc),my_band_list(Wfd%mband)
    4531            5 :  integer,allocatable :: blocks(:,:) !
    4532            5 :  real(dp),allocatable :: cg_k(:,:)
    4533              : !************************************************************************
    4534              : 
    4535            5 :  nocheck=.false.
    4536            5 :  if(present(wfknocheck)) nocheck=wfknocheck
    4537              : 
    4538            5 :  nprocs = xmpi_comm_size(Wfd%comm); my_rank = xmpi_comm_rank(Wfd%comm)
    4539            5 :  iam_master = (my_rank == master)
    4540              : 
    4541              :  ! Select the IO library from the file extension.
    4542            5 :  iomode = iomode_from_fname(wfk_fname)
    4543            5 :  call wrtout(std_out, sjoin('Writing GS WFK file: ',wfk_fname,", with iomode ",iomode2str(iomode)))
    4544              : 
    4545            5 :  if (nprocs > 1 .and. iomode /= IO_MODE_MPI) then
    4546            0 :    ABI_ERROR("You need MPI-IO to write wavefunctions in parallel")
    4547              :  end if
    4548              :  !
    4549              :  ! Check consistency between Wfd and Header!
    4550              :  ! The ideal approach would be to generate the header from the Wfd but a lot of info are missing
    4551            5 :  ABI_CHECK(Wfd%nkibz == Hdr%nkpt,"Different number of k-points")
    4552            5 :  ABI_CHECK(Wfd%nsppol == Hdr%nsppol,"Different number of spins")
    4553            5 :  ABI_CHECK(Wfd%nspinor == Hdr%nspinor,"Different number of spinors")
    4554              : 
    4555              :  !if (any(Wfd%nband /= reshape(Hdr%nband, [Wfd%nkibz, Wfd%nsppol]))) then
    4556              :  !  ABI_ERROR("Wfd%nband /= Hdr%nband")
    4557              :  !end if
    4558              : 
    4559              :  !endif
    4560              :  ! Use bks_tab to decide who will write the data. Remember
    4561              :  ! integer,allocatable :: bks_tab(:,:,:,:)
    4562              :  ! Wfd%bks_tab(mband,nkibz,nsppol,0:nproc-1)
    4563              :  ! Global table used to keep trace of the distribution of the (b,k,s) states on each node inside Wfd%comm.
    4564              :  ! 1 if the node has this state. 0 otherwise.
    4565              :  ! A node owns a wavefunction if the corresponding ug is allocated AND computed.
    4566              :  ! If a node owns ur but not ug, or ug is just allocated then its entry in the table is zero.
    4567              :  ! The main difficulties here are:
    4568              :  !
    4569              :  ! 1) FFT parallelism (not coded, indeed)
    4570              :  ! 2) Wavefunctions that are replicated, i.e. the same (b,k,s) is treated by more than one node.
    4571              : 
    4572            5 :  ierr = 0
    4573           10 :  do spin=1,Wfd%nsppol
    4574           40 :    do ik_ibz=1,Wfd%nkibz
    4575          275 :      do band=1,Wfd%nband(ik_ibz,spin)
    4576          240 :        call wfdgw_who_has_ug(Wfd,band,ik_ibz,spin,how_many,proc_ranks)
    4577          270 :        if (how_many /= 1) then
    4578            0 :          ierr = ierr + 1
    4579            0 :          write(msg,'(a,3(i0,1x))')" Found replicated state (b,k,s) ",band,ik_ibz,spin
    4580            0 :          ABI_WARNING(msg)
    4581              :        end if
    4582              :      end do
    4583              :    end do
    4584              :  end do
    4585              : 
    4586            5 :  if (ierr /= 0) then
    4587            0 :    ABI_ERROR("Cannot write WFK file when wavefunctions are replicated")
    4588              :  end if
    4589              : 
    4590            5 :  call cwtime(cpu,wall,gflops,"start")
    4591              : 
    4592              :  ! Master node opens the file and writes the Abinit header.
    4593            5 :  if (iam_master) then
    4594           35 :    do ik_ibz=1,Wfd%nkibz
    4595           35 :      if (size(Wfd%Kdata(ik_ibz)%kg_k,dim=2)<Hdr%npwarr(ik_ibz)) then
    4596            0 :        ABI_ERROR("Impossible to continue when the npw in the Hdr is diff. to the npw in the Wfd")
    4597              :      end if
    4598              :    end do
    4599            5 :    call wfkfile%open_write(Hdr,wfk_fname,formeig0,iomode,get_unit(),xmpi_comm_self,write_hdr=.TRUE.,write_frm=.TRUE.)
    4600              :  end if
    4601              : 
    4602              :  ! Other nodes wait here before opening the same file.
    4603            5 :  call xmpi_barrier(Wfd%comm)
    4604            5 :  if (.not.iam_master) then
    4605            0 :    call wfkfile%open_write(Hdr,wfk_fname,formeig0,iomode,get_unit(),xmpi_comm_self,write_hdr=.FALSE.,write_frm=.FALSE.)
    4606              :  end if
    4607              : 
    4608           10 :  do spin=1,Wfd%nsppol
    4609           40 :    do ik_ibz=1,Wfd%nkibz
    4610              :    ! MRM: Well, we do not check because nocheck is used when Wfd is stored only on the master. So it works for this case!
    4611           30 :      if(.not.nocheck) then
    4612            0 :        if (.not. wfd%ihave_ug(band, ik_ibz, spin, how="Stored")) cycle
    4613              :      endif
    4614              : 
    4615           30 :      nband_k = Wfd%nband(ik_ibz,spin)
    4616           30 :      npw_k   = Wfd%npwarr(ik_ibz)
    4617              : 
    4618              :      ! Compute my block of bands for this k-point and spin.
    4619           30 :      call wfd%mybands(ik_ibz, spin, how_manyb, my_band_list, how="Stored")
    4620           30 :      call list2blocks(my_band_list(1:how_manyb), nblocks, blocks)
    4621              : 
    4622              :      !if (proc_distrb_cycle(mpi_enreg%proc_distrb,ik_ibz,1,nband_k,spin,my_rank)) CYCLE
    4623              :      !call mask2blocks(mpi_enreg%proc_distrb(ik_ibz,:,spin)==my_rank, nblocks,blocks)
    4624              : 
    4625           30 :      ABI_CHECK(nblocks==1,"nblocks !=1")
    4626           30 :      write(msg,"(a,3(i0,2x))")" Will write (ik_ibz, spin, nblocks) ",ik_ibz,spin,nblocks
    4627           30 :      call wrtout(std_out, msg)
    4628              : 
    4629              :      ! Extract the block of wavefunctions from Wfd.
    4630              :      ! Try to allocate all u(g) first,
    4631              :      ! TODO: If not enough memory fallback to a blocked algorithm.
    4632           30 :      cgsize = Wfd%nspinor * npw_k * how_manyb
    4633           90 :      ABI_MALLOC_OR_DIE(cg_k, (2,cgsize), ierr)
    4634              : 
    4635           30 :      if (size(Wfd%Kdata(ik_ibz)%kg_k,dim=2)<wfkfile%Hdr%npwarr(ik_ibz)) then
    4636            0 :        ABI_ERROR("Wrong number of npw before printing")
    4637              :      end if
    4638              :      ! Extract the set of u(g) for this (kpoint,spin)
    4639              :      ! This works only if all the bands are on the same node.
    4640              :      !band_block = [1, nband_k]
    4641              :      !call wfd_extract_cgblock(Wfd,[(ii, ii=1,nband_k)],ik_ibz,spin,cg_k)
    4642           60 :      do blk=1,nblocks
    4643           90 :        band_block = blocks(:,blk)
    4644          510 :        call wfd_extract_cgblock(Wfd,[(ii, ii=band_block(1),band_block(2))],ik_ibz,spin,cg_k) ! cg_k extracted from Wfd!
    4645              : 
    4646           60 :        if (band_block(1)==1) then
    4647              :          ! Write also kg_k, eig_k and occ_k
    4648              :          call wfkfile%write_band_block(band_block,ik_ibz,spin,xmpio_single,&
    4649              :             kg_k=Wfd%Kdata(ik_ibz)%kg_k,cg_k=cg_k, &
    4650           30 :             eig_k=ebands%eig(:,ik_ibz,spin),occ_k=ebands%occ(:,ik_ibz,spin))     ! occs extracted from Bands (i.e. QP_BSt)
    4651              :                                                                                  ! kg_k obtained from Wfd so OK! It is
    4652              :                                                                                  ! how Gs are ordered.
    4653              :        else
    4654            0 :          ABI_ERROR("band_block(1)>1 should not happen in the present version!")
    4655              :          !call wfkfile%write_band_block(band_block,ik_ibz,spin,xmpio_single,cg_k=cg_k(:,1+icg:))
    4656              :        end if
    4657              :      end do
    4658              : 
    4659           30 :      ABI_FREE(cg_k)
    4660           35 :      ABI_FREE(blocks)
    4661              :    end do  ! k-points
    4662              :  end do  ! spin
    4663              : 
    4664            5 :  call xmpi_barrier(Wfd%comm)
    4665              : 
    4666              :  ! Close the file.
    4667            5 :  call wfkfile%close()
    4668              : 
    4669            5 :  call cwtime_report(" write all cg" , cpu, wall, gflops)
    4670              : 
    4671            5 : end subroutine wfdgw_write_wfk
    4672              : !!***
    4673              : 
    4674              : !----------------------------------------------------------------------
    4675              : 
    4676              : !!****f* m_wfd/wfd_read_wfk
    4677              : !! NAME
    4678              : !! wfd_read_wfk
    4679              : !!
    4680              : !! FUNCTION
    4681              : !!  This routine reads the WFK file completing the initialization of the wavefunction descriptor
    4682              : !!
    4683              : !! INPUTS
    4684              : !!  wfk_fname=Name of the WFK file.
    4685              : !!  iomode=Option specifying the fileformat as well as the IO mode to be used.
    4686              : !!
    4687              : !! OUTPUT
    4688              : !!  [out_hdr]=Header of the WFK file.
    4689              : !!
    4690              : !! SIDE EFFECTS
    4691              : !!  Wfd<wfd_t>=All the states owned by this node whose status is (STORED|ALLOCATED) read.
    4692              : !!
    4693              : !! SOURCE
    4694              : 
    4695          479 : subroutine wfd_read_wfk(Wfd, wfk_fname, iomode, out_hdr)
    4696              : 
    4697              : !Arguments ------------------------------------
    4698              : !scalars
    4699              :  integer,intent(in) :: iomode
    4700              :  character(len=*),intent(in) :: wfk_fname
    4701              :  class(wfd_t),target,intent(inout) :: Wfd
    4702              :  type(Hdr_type),optional,intent(inout) :: out_hdr ! ifort and others are buggy for optional intent(out) structured types
    4703              : 
    4704              : !Local variables ------------------------------
    4705              : !scalars
    4706              :  integer,parameter :: formeig0 = 0, optkg1 = 1, method = 2
    4707              :  integer :: wfk_unt,npw_disk,nmiss,ig,sc_mode,ii
    4708              :  integer :: io_comm,master,my_rank,spin,ik_ibz,fform,ierr ! ,igp
    4709              :  integer :: mcg,nband_wfd,nband_disk,band,mband_disk,bcount,istwfk_disk
    4710              :  integer :: spinor,cg_spad,gw_spad,icg,igw,cg_bpad, allcg_bpad, ib, ik, is
    4711              :  integer :: my_bmin, my_bmax, bmin, bmax
    4712              :  logical :: change_gsphere, master_only, iread
    4713              :  real(dp) :: cpu, wall, gflops, cpu_ks, wall_ks, gflops_ks
    4714              :  character(len=500) :: msg
    4715         1916 :  type(Wfk_t) :: Wfk
    4716          479 :  type(Hdr_type) :: Hdr
    4717              :  type(wave_t),pointer :: wave
    4718              : !arrays
    4719          479 :  integer,allocatable :: gf2wfd(:), kg_k(:,:), all_countks(:,:)
    4720              :  integer :: work_ngfft(18),gmax_wfd(3),gmax_disk(3),gmax(3)
    4721              :  real(dp) :: tsec(2)
    4722          958 :  real(dp),allocatable :: eig_k(:), cg_k(:,:), out_cg(:,:), work(:,:,:,:), allcg_k(:,:)
    4723          479 :  logical,allocatable :: my_readmask(:,:,:)
    4724              :  character(len=6) :: tag_spin(2)
    4725              : !************************************************************************
    4726              : 
    4727              :  ! Keep track of time spent in wfd_read_wfk
    4728          479 :  call timab(300, 1, tsec)
    4729              : 
    4730          479 :  if (any(iomode == [IO_MODE_NETCDF, IO_MODE_FORTRAN_MASTER])) then
    4731            0 :    ABI_ERROR(sjoin("Unsupported value for iomode: ", itoa(iomode)))
    4732              :  end if
    4733              : 
    4734              :  ! IO_MODE_FORTRAN --> only master reads and broadcasts data.
    4735              :  ! IO_MODE_MPI --> all procs read with collective operations.
    4736          479 :  my_rank = Wfd%my_rank; master = Wfd%master
    4737          479 :  io_comm = wfd%comm; sc_mode = xmpio_collective; master_only = .False.; iread = .True.
    4738              :  !if (iomode == IO_MODE_FORTRAN) then
    4739          479 :    io_comm = xmpi_comm_self; sc_mode = xmpio_single; master_only = .True.; iread = my_rank == wfd%master
    4740              :  !end if
    4741              : 
    4742              :  call wrtout(std_out, sjoin( &
    4743              :    " wfd_read_wfk: Reading file:", wfk_fname, &
    4744          479 :    " with iomode:", iomode2str(iomode),", master_only:", yesno(master_only)), pre_newlines=2)
    4745          479 :  if (iomode == IO_MODE_MPI) then
    4746              :    call wrtout(std_out, sjoin( &
    4747              :      " If MPI-IO is too slow, use the command line option `abinit --enforce-fortran-io ...`", ch10, &
    4748            0 :      " to make the master proc read data with Fortran-IO and then broadcast (requires more memory)"), do_flush=.True.)
    4749              :  end if
    4750              : 
    4751          479 :  if (iread) then
    4752          419 :    wfk_unt = get_unit()
    4753          419 :    call wfk%open_read(wfk_fname, formeig0, iomode, wfk_unt, io_comm, Hdr_out=Hdr)
    4754              :  end if
    4755              : 
    4756          479 :  if (master_only) call hdr%bcast(wfd%master, wfd%my_rank, wfd%comm)
    4757          479 :  if (present(out_hdr)) call hdr%copy(out_hdr)
    4758              : 
    4759              :  ! TODO: Perform more consistency check btw Hdr and Wfd.
    4760              :  ! Output the header of the GS wavefunction file.
    4761          479 :  fform = 0
    4762          479 :  if (wfd%prtvol /= 0 .and. wfd%my_rank == 0) call hdr%echo(fform, 4, unit=std_out)
    4763              : 
    4764         8339 :  mband_disk = MAXVAL(Hdr%nband)
    4765          479 :  ABI_CHECK_ILEQ(Wfd%mband, mband_disk, "Not enough bands stored on WFK file")
    4766              : 
    4767              :  ! Make sure wfd%kibz agrees the k-points reported in the hdr.
    4768          479 :  ABI_CHECK_IEQ(wfd%nkibz, hdr%nkpt, "wfd%nkibz != hdr%nkpt")
    4769          479 :  ierr = 0
    4770         8319 :  do ik_ibz=1,wfd%nkibz
    4771        31839 :    if (any(abs(wfd%kibz(:, ik_ibz) - hdr%kptns(:, ik_ibz)) > tol12)) then
    4772            0 :      ierr = ierr + 1
    4773              :      call wrtout(std_out, &
    4774            0 :        sjoin("For ik_ibz: ", itoa(ik_ibz), "wfd kpt:", ktoa(wfd%kibz(:, ik_ibz)), " /= ", ktoa(hdr%kptns(:,ik_ibz))))
    4775              :    end if
    4776              :  end do
    4777          479 :  ABI_CHECK_IEQ(ierr, 0, "kpoints in wfd% and WFK file do not agree. See messages above")
    4778              : 
    4779              :  ! Each node will read the waves whose status if (WFD_ALLOCATED|WFD_STORED).
    4780              :  ! all_countks is a global array used to skip (ik_ibz, spin) if all MPI procs do not need bands for this (k, s)
    4781         2395 :  ABI_MALLOC(my_readmask, (mband_disk, Wfd%nkibz, Wfd%nsppol))
    4782       170764 :  my_readmask = .False.
    4783          479 :  my_bmin = huge(1); my_bmax = -huge(1)
    4784        10262 :  ABI_ICALLOC(all_countks, (wfd%nkibz, wfd%nsppol))
    4785              : 
    4786          965 :  do spin=1,Wfd%nsppol
    4787         8825 :    do ik_ibz=1,Wfd%nkibz
    4788       113997 :      do band=1,Wfd%nband(ik_ibz,spin)
    4789       113511 :        if (wfd%ihave_ug(band, ik_ibz, spin)) then
    4790        67955 :          my_bmin = min(my_bmin, band)
    4791        67955 :          my_bmax = max(my_bmax, band)
    4792        67955 :          my_readmask(band, ik_ibz, spin) = .True.
    4793        67955 :          all_countks(ik_ibz, spin) = 1
    4794        67955 :          if (wfd%ihave_ug(band, ik_ibz, spin, how="Stored")) then
    4795            0 :            ABI_ERROR("Wavefunction is already stored!")
    4796              :          end if
    4797              :        end if
    4798              :      end do
    4799              :    end do
    4800              :  end do
    4801              : 
    4802              :  ! All procs must agree when skipping (k, s) states
    4803              :  ! We also need bmin/bmax for master_only option.
    4804          479 :  call xmpi_sum(all_countks, wfd%comm, ierr)
    4805          479 :  call xmpi_min(my_bmin, bmin, wfd%comm, ierr)
    4806          479 :  call xmpi_max(my_bmax, bmax, wfd%comm, ierr)
    4807              : 
    4808       170764 :  call wrtout(std_out, sjoin(" About to read: ",itoa(count(my_readmask)), " (b, k, s) states in total."))
    4809          965 :  do spin=1,wfd%nsppol
    4810              :    call wrtout(std_out, sjoin(" For spin:", itoa(spin), &
    4811         8825 :               ", will read:", itoa(count(any(my_readmask(:,:,spin), dim=1))), " k-points out of:", itoa(wfd%nkibz)))
    4812              :  end do
    4813         1451 :  tag_spin(: )= ['      ','      ']; if (Wfd%nsppol==2) tag_spin(:)= [' UP   ',' DOWN ']
    4814          479 :  if (wfd%prtvol > 0) call wrtout(std_out,' k       eigenvalues [eV]')
    4815              : 
    4816          479 :  call cwtime(cpu, wall, gflops, "start")
    4817              : 
    4818              :  if (method == 1) then
    4819              :   do spin=1,wfd%nsppol
    4820              :     do ik_ibz=1,Wfd%nkibz
    4821              :       if (all_countks(ik_ibz, spin) == 0) cycle
    4822              :       npw_disk   = Hdr%npwarr(ik_ibz)
    4823              :       nband_disk = Hdr%nband(ik_ibz+(spin-1)*Hdr%nkpt)
    4824              :       istwfk_disk = hdr%istwfk(ik_ibz)
    4825              :       change_gsphere = istwfk_disk /= wfd%istwfk(ik_ibz)
    4826              :       ABI_CHECK(.not. change_gsphere, "different istwfk values are not coded")
    4827              : 
    4828              :       nband_wfd  = Wfd%nband(ik_ibz,spin)
    4829              :       if (nband_wfd > nband_disk) then
    4830              :         write(msg,'(a,2(i0,1x))')" nband_wfd to be read cannot be greater than nband_disk while: ",nband_wfd, nband_disk
    4831              :         ABI_ERROR(msg)
    4832              :       end if
    4833              : 
    4834              :       mcg = npw_disk*Wfd%nspinor*nband_wfd
    4835              : 
    4836              :       ABI_MALLOC(eig_k,((2*Wfk%mband)**formeig0*Wfk%mband))
    4837              :       ABI_MALLOC(kg_k,(3,optkg1*npw_disk))
    4838              :       ABI_MALLOC_OR_DIE(cg_k,(2,mcg), ierr)
    4839              : 
    4840              :       call wfk%read_band_block([1, nband_wfd], ik_ibz, spin, sc_mode, kg_k=kg_k, cg_k=cg_k, eig_k=eig_k)
    4841              : 
    4842              :       if (wfd%prtvol > 0 .and. Wfd%my_rank==Wfd%master) then
    4843              :         if (Wfd%nsppol==2) then
    4844              :           write(std_out,'(i3,a,10f7.2/50(10x,10f7.2/))') ik_ibz,tag_spin(spin),(eig_k(ib)*Ha_eV,ib=1,nband_wfd)
    4845              :         else
    4846              :           write(std_out,'(i3,7x,10f7.2/50(10x,10f7.2/))')ik_ibz,(eig_k(ib)*Ha_eV,ib=1,nband_wfd)
    4847              :         end if
    4848              :       end if
    4849              : 
    4850              :       ! Table with the correspondence btw the k-centered sphere of the WFK file
    4851              :       ! and the one used in Wfd (possibly smaller due to ecutwfn).
    4852              :       ABI_MALLOC(gf2wfd, (npw_disk))
    4853              :       if (any(my_readmask(:,ik_ibz,spin))) then
    4854              :         call kg_map(wfd%npwarr(ik_ibz), wfd%kdata(ik_ibz)%kg_k, npw_disk, kg_k, gf2wfd, nmiss)
    4855              :       end if
    4856              :       !if (nmiss/=0) then
    4857              :       !  write(msg,'(a,2(1x,i0),a,i0)')" For (k,s) ",ik_ibz,spin," the number of missing G is ",nmiss
    4858              :       !  ABI_WARNING(msg)
    4859              :       !end if
    4860              : 
    4861              :       ! Conversion of the basis set.
    4862              :       do band=1,Wfd%nband(ik_ibz,spin)
    4863              :         if (my_readmask(band, ik_ibz, spin)) then
    4864              : 
    4865              :           ABI_CHECK(all(wfd%bks2wfd(:, band, ik_ibz, spin) /= 0), "state in not allocated")
    4866              :           ib = wfd%bks2wfd(1, band, ik_ibz, spin)
    4867              :           ik = wfd%bks2wfd(2, band, ik_ibz, spin)
    4868              :           is = wfd%bks2wfd(3, band, ik_ibz, spin)
    4869              :           wave => wfd%s(is)%k(ik)%b(ib)
    4870              :           wave%ug = czero
    4871              : 
    4872              :           cg_bpad=npw_disk*Wfd%nspinor*(band-1)
    4873              :           do spinor=1,Wfd%nspinor
    4874              :             cg_spad=(spinor-1)*npw_disk
    4875              :             gw_spad=(spinor-1)*Wfd%npwarr(ik_ibz)
    4876              :             do ig=1,npw_disk
    4877              :               icg = ig+cg_spad+cg_bpad
    4878              :               igw = gf2wfd(ig)+gw_spad
    4879              :               if (gf2wfd(ig) /= 0) wave%ug(igw) = CMPLX(cg_k(1,icg), cg_k(2,icg), kind=gwp)
    4880              :             end do
    4881              :           end do
    4882              :           wave%has_ug = WFD_STORED
    4883              : 
    4884              :         end if
    4885              :       end do
    4886              : 
    4887              :       ABI_FREE(eig_k)
    4888              :       ABI_FREE(kg_k)
    4889              :       ABI_FREE(cg_k)
    4890              :       ABI_FREE(gf2wfd)
    4891              :     end do !ik_ibz
    4892              :   end do !spin
    4893              : 
    4894              :  else if (method==2) then
    4895              :   ! DEFAULT ALGO: This seems to be the most efficient one.
    4896              : 
    4897          965 :   do spin=1,Wfd%nsppol
    4898         8825 :     do ik_ibz=1,Wfd%nkibz
    4899         7860 :       if (all_countks(ik_ibz, spin) == 0) cycle
    4900         4252 :       call cwtime(cpu_ks, wall_ks, gflops_ks, "start")
    4901              :       !write(std_out,*)" About to read ik_ibz: ",ik_ibz,", spin: ",spin
    4902              : 
    4903         4252 :       npw_disk   = Hdr%npwarr(ik_ibz)
    4904         4252 :       nband_disk = Hdr%nband(ik_ibz+(spin-1)*Hdr%nkpt)
    4905         4252 :       istwfk_disk = hdr%istwfk(ik_ibz)
    4906         4252 :       change_gsphere = istwfk_disk /= wfd%istwfk(ik_ibz)
    4907         4252 :       nband_wfd  = Wfd%nband(ik_ibz, spin)
    4908              : 
    4909         4252 :       if (nband_wfd > nband_disk) then
    4910            0 :         write(msg,'(2(a, i0))')"nband_wfd to be read: ", nband_wfd,", cannot be greater than nband_disk: ",nband_disk
    4911            0 :         ABI_ERROR(msg)
    4912              :       end if
    4913              : 
    4914              :       ! Allocate full array for eigenvalues and G-vectors.
    4915              :       !print *, "nband_disk, npw_disk", nband_disk, npw_disk
    4916        12756 :       ABI_MALLOC(eig_k, ((2*nband_disk)**formeig0*nband_disk))
    4917        12756 :       ABI_MALLOC(kg_k, (3,optkg1*npw_disk))
    4918              : 
    4919              :       ! Allocate array to store my wavefunctions and read data
    4920       136034 :       mcg = npw_disk * wfd%nspinor * count(my_readmask(:, ik_ibz, spin))
    4921              :       !print *, "mcg", mcg
    4922        12756 :       ABI_MALLOC_OR_DIE(cg_k, (2, mcg), ierr)
    4923              : 
    4924              :       if (.not. master_only) then
    4925              :         ! All procs read.
    4926              :         call wfk%read_bmask(my_readmask(:,ik_ibz, spin), ik_ibz, spin, sc_mode, kg_k=kg_k, cg_k=cg_k, eig_k=eig_k)
    4927              : 
    4928              :       else
    4929              :         ! Master reads full set of bands and broadcasts data, then each proc extract its own set of wavefunctions.
    4930              :         ! TODO: Should read in blocks to reduce memory footprint
    4931              :         ! See for instance gwr_read_ugb_from_wfk for blocked algorithm.
    4932              : 
    4933        12756 :         ABI_MALLOC_OR_DIE(allcg_k, (2, npw_disk*wfd%nspinor*(bmax-bmin+1)), ierr)
    4934              :         !call pstat_proc%print(_PSTAT_ARGS_)
    4935              : 
    4936         4252 :         if (my_rank == master) then
    4937        10764 :           call wfk%read_band_block([bmin, bmax], ik_ibz, spin, xmpio_single, kg_k=kg_k, cg_k=allcg_k, eig_k=eig_k)
    4938              :         end if
    4939              : 
    4940         4252 :         call xmpi_bcast(kg_k, wfd%master, wfd%comm, ierr)
    4941         4252 :         call xmpi_bcast(eig_k, wfd%master, wfd%comm, ierr)
    4942         4252 :         call xmpi_bcast(allcg_k, wfd%master, wfd%comm, ierr)
    4943              : 
    4944         4252 :         bcount = 0
    4945        77427 :         do band=bmin,bmax
    4946        77427 :           if (my_readmask(band, ik_ibz, spin)) then
    4947        67955 :             bcount = bcount + 1
    4948        67955 :             cg_bpad    = npw_disk * wfd%nspinor * (bcount-1)
    4949        67955 :             allcg_bpad = npw_disk * wfd%nspinor * (band - bmin)
    4950        67955 :             call cg_zcopy(npw_disk * wfd%nspinor, allcg_k(:, allcg_bpad+1), cg_k(:, cg_bpad+1))
    4951              :           end if
    4952              :         end do
    4953         8504 :         ABI_FREE(allcg_k)
    4954              :       end if
    4955              : 
    4956         4252 :       if (Wfd%my_rank == Wfd%master .and. wfd%prtvol > 0) then
    4957          658 :         if (Wfd%nsppol==2) then
    4958          672 :           write(std_out,'(i3,a,10f7.2/50(10x,10f7.2/))') ik_ibz,tag_spin(spin),(eig_k(ib)*Ha_eV,ib=1,nband_wfd)
    4959              :         else
    4960        12408 :           write(std_out,'(i3,7x,10f7.2/50(10x,10f7.2/))')ik_ibz,(eig_k(ib)*Ha_eV,ib=1,nband_wfd)
    4961              :         end if
    4962              :       end if
    4963              : 
    4964              :       !print *, "Before change_gpshere-1", npw_disk
    4965              : 
    4966              :       ! Table with the correspondence btw the k-centered sphere of the WFK file
    4967              :       ! and the one used in Wfd (possibly smaller due to ecutwfn).
    4968              :       ! TODO: Here I should treat the case in which istwfk in wfd differs from the one on disk.
    4969        12756 :       ABI_MALLOC(gf2wfd, (npw_disk))
    4970         5355 :       if (any(my_readmask(:,ik_ibz,spin))) then
    4971              : #if defined FC_NVHPC
    4972              :       !write(std_out, *)"NVHPC with netcdf gives crazy values for kg_k"
    4973              :       !write(std_out,*)  "wfd%kdata(ik_ibz)%kg_k(:,1)", wfd%kdata(ik_ibz)%kg_k(:,1)
    4974              :       !write(std_out,*)  "kg_k(:,1):", kg_k(:,1)
    4975              : #endif
    4976         4252 :         call kg_map(wfd%npwarr(ik_ibz), wfd%kdata(ik_ibz)%kg_k, npw_disk, kg_k, gf2wfd, nmiss)
    4977              :       end if
    4978              :       !if (nmiss/=0) then
    4979              :       !  write(msg,'(a,2(1x,i0),a,i0)')" For (k,s) ",ik_ibz,spin," the number of missing G is ",nmiss
    4980              :       !  ABI_WARNING(msg)
    4981              :       !end if
    4982              :       !print *, "Before change_gpshere0"
    4983              : 
    4984         5355 :       if (change_gsphere .and. any(my_readmask(:,ik_ibz,spin))) then
    4985              :         ! Prepare call to ctgk_change_sphere
    4986              :         ! FFT box must enclose the two spheres (wfd(k), wfk(k))
    4987       780012 :         gmax_wfd = maxval(abs(wfd%kdata(ik_ibz)%kg_k), dim=2)
    4988       390196 :         gmax_disk = maxval(abs(kg_k), dim=2)
    4989          688 :         do ii=1,3
    4990          688 :           gmax(ii) = max(gmax_wfd(ii), gmax_disk(ii))
    4991              :         end do
    4992          688 :         gmax = 2*gmax + 1
    4993          172 :         call ngfft_seq(work_ngfft, gmax)
    4994          860 :         ABI_MALLOC(work, (2, work_ngfft(4),work_ngfft(5),work_ngfft(6)))
    4995          516 :         ABI_MALLOC(out_cg, (2, wfd%npwarr(ik_ibz) * wfd%nspinor))
    4996              :      end if
    4997              : 
    4998              :       ! Conversion of the basis set.
    4999         4252 :       bcount = 0
    5000        79794 :       do band=1,Wfd%nband(ik_ibz,spin)
    5001        79794 :         if (my_readmask(band, ik_ibz, spin)) then
    5002              : 
    5003        67955 :           ib = wfd%bks2wfd(1, band, ik_ibz, spin)
    5004        67955 :           ik = wfd%bks2wfd(2, band, ik_ibz, spin)
    5005        67955 :           is = wfd%bks2wfd(3, band, ik_ibz, spin)
    5006       271820 :           ABI_CHECK(all(wfd%bks2wfd(:, band, ik_ibz, spin) /= 0), "state in not allocated")
    5007              : 
    5008        67955 :           wave => wfd%s(is)%k(ik)%b(ib)
    5009     31432681 :           wave%ug = czero
    5010              : 
    5011        67955 :           bcount = bcount + 1
    5012        67955 :           cg_bpad = npw_disk*Wfd%nspinor*(bcount-1)
    5013              :           !print *, "Before change_gpshere"
    5014              : 
    5015        67955 :           if (change_gsphere) then
    5016              :             ! Different istwfk storage.
    5017              :             call cgtk_change_gsphere(wfd%nspinor, &
    5018              :                npw_disk, istwfk_disk, kg_k, cg_k(:, cg_bpad+1:), &
    5019         3166 :                wfd%npwarr(ik_ibz), wfd%istwfk(ik_ibz), wfd%kdata(ik_ibz)%kg_k, out_cg, work_ngfft, work)
    5020              : 
    5021      3535667 :             wave%ug(:) = CMPLX(out_cg(1, :), out_cg(2, :), kind=gwp)
    5022              :             !call wfd%push_ug(band, ik_ibz, spin, cryst, out_cg)
    5023              :           else
    5024       130506 :             do spinor=1,Wfd%nspinor
    5025        65717 :               cg_spad=(spinor-1)*npw_disk
    5026        65717 :               gw_spad=(spinor-1)*Wfd%npwarr(ik_ibz)
    5027     27919228 :               do ig=1,npw_disk
    5028     27788722 :                 icg = ig+cg_spad+cg_bpad
    5029     27788722 :                 igw = gf2wfd(ig)+gw_spad
    5030     27854439 :                 if (gf2wfd(ig) /= 0) then
    5031     27242402 :                   wave%ug(igw) = CMPLX(cg_k(1,icg),cg_k(2,icg), kind=gwp)
    5032              :                 end if
    5033              :               end do
    5034              :               !call wfd%push_ug(band, ik_ibz, spin, cryst, out_cg)
    5035              :             end do
    5036              :           end if
    5037              : 
    5038        67955 :           wave%has_ug = WFD_STORED
    5039              :         end if
    5040              :       end do
    5041              : 
    5042         4252 :       ABI_FREE(eig_k)
    5043         4252 :       ABI_FREE(kg_k)
    5044         4252 :       ABI_FREE(cg_k)
    5045         4252 :       ABI_FREE(gf2wfd)
    5046         4252 :       ABI_SFREE(work)
    5047         4252 :       ABI_SFREE(out_cg)
    5048              : 
    5049         8990 :       if (ik_ibz <= 10 .or. mod(ik_ibz, 200) == 0) then
    5050         2744 :         write(msg,'(4x,4(a,i0),a)') "Reading kpt [", ik_ibz, "/", wfd%nkibz, "] spin [", spin, "/", wfd%nsppol, "]"
    5051         2744 :         call cwtime_report(msg, cpu_ks, wall_ks, gflops_ks)
    5052              :       end if
    5053              :     end do ! ik_ibz
    5054              :   end do ! spin
    5055              : 
    5056              :  else
    5057              :    ABI_ERROR(sjoin("Wrong method: ", itoa(method)))
    5058              :  end if
    5059              : 
    5060          479 :  call wfk%close(); call Hdr%free()
    5061              : 
    5062          479 :  ABI_FREE(my_readmask)
    5063          479 :  ABI_FREE(all_countks)
    5064              : 
    5065              :  ! Update the kbs table storing the distribution of the ug and set the MPI communicators.
    5066              :  select type (wfd)
    5067              :  class is (wfdgw_t)
    5068          387 :    call wfd%update_bkstab()
    5069              :  end select
    5070              : 
    5071          479 :  call cwtime_report(" WFK IO", cpu, wall, gflops, end_str=ch10)
    5072          479 :  call timab(300, 2, tsec)
    5073              : 
    5074         1916 : end subroutine wfd_read_wfk
    5075              : !!***
    5076              : 
    5077              : !----------------------------------------------------------------------
    5078              : 
    5079              : !!****f* m_wfd/wfd_paw_get_aeur
    5080              : !! NAME
    5081              : !! wfd_paw_get_aeur
    5082              : !!
    5083              : !! FUNCTION
    5084              : !!   Compute the AE PAW wavefunction in real space.
    5085              : !!
    5086              : !! INPUTS
    5087              : !!   band,ik_ibz,spin=indices specifying the band, the k-point and the spin.
    5088              : !!   Psps<pseudopotential_type>=variables related to pseudopotentials
    5089              : !!   Cryst<crystal_t>= data type gathering info on symmetries and unit cell.
    5090              : !!   Wfd<wfd_t>=wavefunction descriptor.
    5091              : !!   Pawtab(ntypat*usepaw)<type(pawtab_type)>=paw tabulated starting data.
    5092              : !!   Pawfgrtab(natom)<pawfgrtab_type>= atomic data given on fine rectangular grid.
    5093              : !!     NB: rpaw should be used in nhatgrid to initialize the datatype (optcut=1 option) instead of the radius for the
    5094              : !!     shape functions (rpaw /= rshp).
    5095              : !!   Paw_onsite(natom)<paw_pwaves_lmn_t>=3D PAW partial waves in real space for each FFT point in the PAW spheres.
    5096              : !!
    5097              : !! OUTPUT
    5098              : !! ur_ae(Wfd%nfft*Wfd%nspinor)=AE PAW wavefunction in real space.
    5099              : !! [ur_ae_onsite(Wfd%nfft*Wfd%nspinor)]
    5100              : !! [ur_ps_onsite(Wfd%nfft*Wfd%nspinor)]
    5101              : !!
    5102              : !! NOTES
    5103              : !!  (1) The true wavefunction integrates in real space to the unit cell volume.
    5104              : !!      The definition of the cprj matrix elements includes the term 1/SQRT(ucvol) that comes
    5105              : !!      from the use of a normalized planewave e^(iG.r)/SQRT(omega) in the FFT transform G-->R (see e.g. opernla_ylm)
    5106              : !!      On the contrary, the convention for the G-->R transform employed in the FFT routines used in abinit is
    5107              : !!      u(r) = sum_G u(G) e^(iG.r); u(G) = one/omega \int u(r) e^(-iG.r)dr.
    5108              : !!      Hence we have to multiply the onsite part by SQRT(uvol) before adding the smooth FFT part in real space.
    5109              : !!
    5110              : !!  (2) Care has to be taken in the calculation of the onsite contribution when the FFT point belongs to the PAW
    5111              : !!      sphere of a periodically repeated atom. In this case one evaluates the onsite term associated to the
    5112              : !!      atom in the first unit cell then the contribution has to be multiplied by a k- dependent
    5113              : !!      phase factor to account for the wrapping of the real-space point in the first unit cell.
    5114              : !!
    5115              : !! SOURCE
    5116              : 
    5117            0 : subroutine wfd_paw_get_aeur(Wfd,band,ik_ibz,spin,Cryst,Paw_onsite,Psps,Pawtab,Pawfgrtab,ur_ae,ur_ae_onsite,ur_ps_onsite)
    5118              : 
    5119              : !Arguments ------------------------------------
    5120              : !scalars
    5121              :  integer,intent(in) :: band,ik_ibz,spin
    5122              :  type(pseudopotential_type),intent(in) :: Psps
    5123              :  type(crystal_t),intent(in) :: Cryst
    5124              :  class(wfd_t),intent(inout) :: Wfd
    5125              : !arrays
    5126              :  type(pawtab_type),intent(in) :: Pawtab(Cryst%ntypat)
    5127              :  type(pawfgrtab_type),intent(in) :: Pawfgrtab(Cryst%natom)
    5128              :  type(paw_pwaves_lmn_t),intent(in) :: Paw_onsite(Cryst%natom)
    5129              :  complex(gwp),intent(out) :: ur_ae(Wfd%nfft*Wfd%nspinor)
    5130              :  complex(gwp),optional,intent(out) :: ur_ae_onsite(Wfd%nfft*Wfd%nspinor)
    5131              :  complex(gwp),optional,intent(out) :: ur_ps_onsite(Wfd%nfft*Wfd%nspinor)
    5132              : 
    5133              : !Local variables-------------------------------
    5134              : !scalars
    5135              :  integer :: itypat,ln_size,lmn_size,iatom,spinor
    5136              :  integer :: nfgd,ifgd,jlmn,jl,jm,ifftsph
    5137              :  real(dp) :: phj,tphj,arg,re_cp,im_cp
    5138              :  complex(dp) :: cp,cnorm
    5139              : !arrays
    5140              :  real(dp) :: kpoint(3)
    5141            0 :  complex(dp),allocatable :: ceikr(:),phk_atm(:)
    5142              :  type(pawcprj_type),allocatable :: Cp1(:,:)
    5143              : ! *************************************************************************
    5144              : 
    5145              :  ! TODO ngfft should be included in pawfgrtab_type
    5146              :  !% if (ANY(Wfd%ngfft(1:3)/=Pawfgrtab%ngfft(1:3)) then
    5147              :  !!  ABI_ERROR("Wfd%ngfft(1:3)/=Pawfgrtab%ngfft(1:3)")
    5148              :  !% end if
    5149              : 
    5150            0 :  call wfd%get_ur(band,ik_ibz,spin,ur_ae)
    5151              : 
    5152            0 :  kpoint = Wfd%kibz(:,ik_ibz)
    5153            0 :  ABI_MALLOC(ceikr, (Wfd%nfftot * wfd%nspinor))
    5154              : 
    5155            0 :  call calc_ceikr(kpoint, wfd%ngfft, Wfd%nfftot, wfd%nspinor, ceikr)
    5156            0 :  ur_ae = ur_ae * ceikr
    5157              : 
    5158            0 :  ABI_MALLOC(Cp1,(Wfd%natom,Wfd%nspinor))
    5159            0 :  call pawcprj_alloc(Cp1,0,Wfd%nlmn_atm)
    5160              : 
    5161            0 :  call wfd%get_cprj(band,ik_ibz,spin,Cryst,Cp1,sorted=.FALSE.)
    5162              : 
    5163              :  ! Add onsite term on the augmented FFT mesh.
    5164            0 :  if (present(ur_ae_onsite)) ur_ae_onsite = czero
    5165            0 :  if (present(ur_ps_onsite)) ur_ps_onsite = czero
    5166              : 
    5167            0 :  ABI_CHECK(Wfd%nspinor==1,"nspinor==1 not coded")
    5168              : 
    5169            0 :  do iatom=1,Cryst%natom
    5170            0 :    itypat  =Cryst%typat(iatom)
    5171            0 :    lmn_size=Pawtab(itypat)%lmn_size
    5172            0 :    ln_size =Pawtab(itypat)%basis_size   ! no. of nl elements in PAW basis.
    5173            0 :    nfgd    =Pawfgrtab(iatom)%nfgd       ! no. of points in the fine grid for this PAW sphere.
    5174              : 
    5175            0 :    ABI_MALLOC(phk_atm,(nfgd))
    5176            0 :    do ifgd=1,nfgd
    5177            0 :      arg = -two_pi* DOT_PRODUCT(Paw_onsite(iatom)%r0shift(:,ifgd),kpoint)
    5178            0 :      phk_atm(ifgd) = DCMPLX(COS(arg),SIN(arg))
    5179              :    end do
    5180              : 
    5181            0 :    do spinor=1,Wfd%nspinor
    5182            0 :      do jlmn=1,lmn_size
    5183            0 :        jl=Psps%indlmn(1,jlmn,itypat)
    5184            0 :        jm=Psps%indlmn(2,jlmn,itypat)
    5185            0 :        re_cp = Cp1(iatom,spinor)%cp(1,jlmn)
    5186            0 :        im_cp = Cp1(iatom,spinor)%cp(2,jlmn)
    5187            0 :        cp = DCMPLX(re_cp, im_cp) * SQRT(Cryst%ucvol) ! Pay attention here. see (1).
    5188              : 
    5189            0 :        do ifgd=1,nfgd ! loop over fine grid points in current PAW sphere.
    5190            0 :          ifftsph = Pawfgrtab(iatom)%ifftsph(ifgd) ! index of the point on the grid
    5191            0 :          phj  = Paw_onsite(iatom)% phi(ifgd,jlmn)
    5192            0 :          tphj = Paw_onsite(iatom)%tphi(ifgd,jlmn)
    5193            0 :          ur_ae(ifftsph)           = ur_ae(ifftsph) + cp * (phj-tphj) * phk_atm(ifgd)
    5194            0 :          if (present(ur_ae_onsite)) ur_ae_onsite(ifftsph) = ur_ae_onsite(ifftsph) + cp *  phj * phk_atm(ifgd)
    5195            0 :          if (present(ur_ps_onsite)) ur_ps_onsite(ifftsph) = ur_ps_onsite(ifftsph) + cp * tphj * phk_atm(ifgd)
    5196              :        end do
    5197              :      end do !jlmn
    5198              :    end do !spinor
    5199              : 
    5200            0 :    ABI_FREE(phk_atm)
    5201              :  end do !iatom
    5202              : 
    5203              :  ! Remove the phase e^{ikr}, u(r) is returned.
    5204            0 :  ur_ae = ur_ae * CONJG(ceikr)
    5205            0 :  cnorm = xdotc(Wfd%nfft*Wfd%nspinor,ur_ae,1,ur_ae,1)/Wfd%nfft
    5206              :  !write(std_out,*)" AE PAW norm: (b,k,s)",band,ik_ibz,spin,REAL(cnorm)
    5207              : 
    5208            0 :  if (present(ur_ae_onsite)) ur_ae_onsite = ur_ae_onsite * CONJG(ceikr)
    5209            0 :  if (present(ur_ps_onsite)) ur_ps_onsite = ur_ps_onsite * CONJG(ceikr)
    5210              : 
    5211            0 :  call pawcprj_free(Cp1)
    5212            0 :  ABI_FREE(Cp1)
    5213            0 :  ABI_FREE(ceikr)
    5214              : 
    5215            0 : end subroutine wfd_paw_get_aeur
    5216              : !!***
    5217              : 
    5218              : !----------------------------------------------------------------------
    5219              : 
    5220              : !!****f* m_wfd/wfdgw_plot_ur
    5221              : !! NAME
    5222              : !! wfdgw_plot_ur
    5223              : !!
    5224              : !! FUNCTION
    5225              : !!  This routine writes the squared modulus of the wavefunctions in real space
    5226              : !!  to an external files, one for each (k,b,s). File are written in the XSF format (Xcrysden).
    5227              : !!  A subset of (b,k,s) states can be specified via the bks_mask. The routine is MPI parallelized.
    5228              : !!
    5229              : !! INPUTS
    5230              : !!  Wfd<wfd_t>=Wavefunction descriptor.
    5231              : !!  Cryst<crystal_t>= Information on symmetries and unit cell.
    5232              : !!  Psps<pseudopotential_type>=Pseudopotential info.
    5233              : !!  Pawtab(ntypat*usepaw)<type(pawtab_type)>=PAW tabulated starting data.
    5234              : !!  Pawrad(ntypat*usepaw)<type(pawrad_type)>=paw radial mesh and related data.
    5235              : !!  ngfftf(18)=The FFT mesh used for plotting |wfr|**2, it can differ from the one internally used in Wfd.
    5236              : !!    For example, PAW wavefunctions should be plotted on a much finer FFT mesh.
    5237              : !!  bks_mask(mband,nkibz,nsppol)=logical mask used to select the states to be plotted.
    5238              : !!
    5239              : !! OUTPUT
    5240              : !!  Output is written on file.
    5241              : !!
    5242              : !! SOURCE
    5243              : 
    5244            0 : subroutine wfdgw_plot_ur(Wfd,Cryst,Psps,Pawtab,Pawrad,ngfftf,bks_mask)
    5245              : 
    5246              : !Arguments ------------------------------------
    5247              : !scalars
    5248              :  type(crystal_t),intent(in) :: Cryst
    5249              :  type(Pseudopotential_type),intent(in) :: Psps
    5250              :  class(wfdgw_t),intent(inout) :: Wfd
    5251              : !arrays
    5252              :  integer,intent(in) :: ngfftf(18)
    5253              :  logical,target,intent(in) :: bks_mask(Wfd%mband,Wfd%nkibz,Wfd%nsppol)
    5254              :  type(Pawtab_type),intent(in) :: Pawtab(Cryst%ntypat*Wfd%usepaw)
    5255              :  type(Pawrad_type),intent(in) :: Pawrad(Cryst%ntypat*Wfd%usepaw)
    5256              : 
    5257              : !Local variables ------------------------------
    5258              : !scalars
    5259              :  integer :: spin,band,ik_ibz,optcut,optgr0,optgr1,optgr2,optrad
    5260              :  integer :: n1,n2,n3,my_nplots,plot,funt,my_nband,cplex
    5261              :  character(len=500) :: msg
    5262              :  character(len=fnlen) :: xsf_fname
    5263              : !arrays
    5264            0 :  integer :: got(Wfd%nproc)
    5265            0 :  integer,allocatable :: l_size_atm(:),my_plot_list(:,:)
    5266            0 :  integer :: my_band_list(Wfd%mband)
    5267            0 :  real(dp),allocatable :: data_plot(:)
    5268            0 :  logical,contiguous, pointer :: bmask(:)
    5269            0 :  complex(gwp),allocatable :: ur_ae(:),nc_ur(:)
    5270            0 :  type(Pawfgrtab_type),allocatable :: Pawfgrtab(:)
    5271            0 :  type(paw_pwaves_lmn_t),allocatable :: Paw_onsite(:)
    5272              : !************************************************************************
    5273              : 
    5274            0 :  if (ALL(.not.bks_mask)) RETURN
    5275              : 
    5276            0 :  call wrtout(std_out," Plotting |wfs|^2 ...")
    5277              :  !
    5278              :  ! Change the FFT mesh if needed because we want u(r) on the ngfftf mesh (pawecutd for PAW).
    5279            0 :  call wfd%change_ngfft(Cryst,Psps,ngfftf)
    5280            0 :  n1 = ngfftf(1); n2 = ngfftf(2); n3 = ngfftf(3)
    5281              : 
    5282              :  ! Distribute the plots among the nodes taking into account the distribution of the waves.
    5283              :  ! my_plot_list gives the list of (b,k,s) states plotted by this node.
    5284            0 :  ABI_MALLOC(my_plot_list,(3,Wfd%mband*Wfd%nkibz*Wfd%nsppol))
    5285              : 
    5286            0 :  my_nplots=0; got=0
    5287            0 :  do spin=1,Wfd%nsppol
    5288            0 :    do ik_ibz=1,Wfd%nkibz
    5289            0 :      bmask => bks_mask(:,ik_ibz,spin)
    5290            0 :      call wfd%distribute_bands(ik_ibz,spin,my_nband,my_band_list,got,bmask)
    5291              : 
    5292            0 :      if (my_nband>0) then
    5293            0 :        my_plot_list(1,my_nplots+1:my_nplots+my_nband) = my_band_list(1:my_nband)
    5294            0 :        my_plot_list(2,my_nplots+1:my_nplots+my_nband) = ik_ibz
    5295            0 :        my_plot_list(3,my_nplots+1:my_nplots+my_nband) = spin
    5296              :        my_nplots = my_nplots + my_nband
    5297              :      end if
    5298              :    end do
    5299              :  end do
    5300              : 
    5301            0 :  if (Wfd%usepaw==1) then
    5302            0 :    ABI_WARNING("Testing the calculation of AE PAW wavefunctions.")
    5303              :    ! Use a local pawfgrtab to make sure we use the correction in the paw spheres
    5304              :    ! the usual pawfgrtab uses r_shape which may not be the same as r_paw.
    5305            0 :    cplex=1
    5306            0 :    call pawtab_get_lsize(Pawtab,l_size_atm,Cryst%natom,Cryst%typat)
    5307            0 :    ABI_MALLOC(Pawfgrtab,(Cryst%natom))
    5308            0 :    call pawfgrtab_init(Pawfgrtab,cplex,l_size_atm,Wfd%nspden,Cryst%typat)
    5309            0 :    ABI_FREE(l_size_atm)
    5310              : 
    5311            0 :    optcut=1                     ! use rpaw to construct Pawfgrtab.
    5312            0 :    optgr0=0; optgr1=0; optgr2=0 ! dont need gY terms locally.
    5313            0 :    optrad=1                     ! do store r-R.
    5314              : 
    5315              :    call nhatgrid(Cryst%atindx1,Cryst%gmet,Cryst%natom,Cryst%natom,Cryst%nattyp,ngfftf,Cryst%ntypat,&
    5316            0 :      optcut,optgr0,optgr1,optgr2,optrad,Pawfgrtab,Pawtab,Cryst%rprimd,Cryst%typat,Cryst%ucvol,Cryst%xred)
    5317              : 
    5318              :    !Pawfgrtab is ready to use
    5319              : 
    5320            0 :    if (Wfd%pawprtvol>0) then
    5321              :      call pawfgrtab_print(Pawfgrtab,natom=Cryst%natom,unit=std_out,&
    5322            0 :                           prtvol=Wfd%pawprtvol,mode_paral="COLL")
    5323              :    end if
    5324              : 
    5325            0 :    ABI_MALLOC(Paw_onsite,(Cryst%natom))
    5326              :    call paw_pwaves_lmn_init(Paw_onsite,Cryst%natom,Cryst%natom,Cryst%ntypat,&
    5327            0 :                             Cryst%rprimd,Cryst%xcart,Pawtab,Pawrad,Pawfgrtab)
    5328              : 
    5329            0 :    ABI_MALLOC(ur_ae,(Wfd%nfft*Wfd%nspinor))
    5330            0 :    ABI_MALLOC(data_plot,(Wfd%nfft))
    5331              : 
    5332            0 :    do plot=1,my_nplots
    5333            0 :      band  =my_plot_list(1,plot)
    5334            0 :      ik_ibz=my_plot_list(2,plot)
    5335            0 :      spin  =my_plot_list(3,plot)
    5336              : 
    5337            0 :      call wfd%paw_get_aeur(band,ik_ibz,spin,Cryst,Paw_onsite,Psps,Pawtab,Pawfgrtab,ur_ae)
    5338              : 
    5339            0 :      data_plot = DBLE(ur_ae(1:Wfd%nfft)*CONJG(ur_ae(1:Wfd%nfft)))/Cryst%ucvol
    5340            0 :      if (Wfd%nspinor==2) data_plot = data_plot + DBLE(ur_ae(Wfd%nfft+1:)*CONJG(ur_ae(Wfd%nfft+1:)))/Cryst%ucvol
    5341              : 
    5342            0 :      write(xsf_fname,'(3(a,i0),a)') 'PAW_AE_wfk2_sp',spin,'_kpt',ik_ibz,'_bd',band,'.xsf'
    5343            0 :      if (open_file(xsf_fname,msg,newunit=funt,status='unknown',form='formatted') /= 0) then
    5344            0 :        ABI_ERROR(msg)
    5345              :      end if
    5346              : 
    5347              :      call printxsf(n1,n2,n3,data_plot,Cryst%rprimd,(/zero,zero,zero/),&
    5348            0 :        Cryst%natom,Cryst%ntypat,Cryst%typat,Cryst%xcart,Cryst%znucl,funt,0)
    5349              : 
    5350            0 :      close(funt)
    5351              :    end do
    5352              : 
    5353            0 :    ABI_FREE(ur_ae)
    5354            0 :    ABI_FREE(data_plot)
    5355              : 
    5356            0 :    call pawfgrtab_free(Pawfgrtab)
    5357            0 :    ABI_FREE(Pawfgrtab)
    5358            0 :    call paw_pwaves_lmn_free(Paw_onsite)
    5359            0 :    ABI_FREE(Paw_onsite)
    5360              : 
    5361              :  else
    5362              :    ! NC case. Just a simple FFT G-->R and then dump the results.
    5363            0 :    ABI_MALLOC(nc_ur,(Wfd%nfft*Wfd%nspinor))
    5364            0 :    ABI_MALLOC(data_plot,(Wfd%nfft))
    5365              : 
    5366            0 :    do plot=1,my_nplots
    5367            0 :      band  =my_plot_list(1,plot)
    5368            0 :      ik_ibz=my_plot_list(2,plot)
    5369            0 :      spin  =my_plot_list(3,plot)
    5370              : 
    5371            0 :      call wfd%get_ur(band,ik_ibz,spin,nc_ur)
    5372              : 
    5373            0 :      data_plot = DBLE(nc_ur(1:Wfd%nfft)*CONJG(nc_ur(1:Wfd%nfft)))/Cryst%ucvol
    5374            0 :      if (Wfd%nspinor==2) data_plot = data_plot + DBLE(nc_ur(Wfd%nfft+1:)*CONJG(nc_ur(Wfd%nfft+1:)))/Cryst%ucvol
    5375              : 
    5376            0 :      write(xsf_fname,'(3(a,i0),a)') 'NC_wfk2_sp',spin,'_kpt',ik_ibz,'_bd',band,'.xsf'
    5377            0 :      if (open_file(xsf_fname,msg,newunit=funt,status='unknown',form='formatted') /= 0) then
    5378            0 :        ABI_ERROR(msg)
    5379              :      end if
    5380              :      call printxsf(n1,n2,n3,data_plot,Cryst%rprimd,(/zero,zero,zero/),&
    5381            0 :        Cryst%natom,Cryst%ntypat,Cryst%typat,Cryst%xcart,Cryst%znucl,funt,0)
    5382              : 
    5383            0 :      close(funt)
    5384              :    end do
    5385              : 
    5386            0 :    ABI_FREE(nc_ur)
    5387            0 :    ABI_FREE(data_plot)
    5388              :  end if
    5389              : 
    5390            0 :  ABI_FREE(my_plot_list)
    5391              : 
    5392            0 : end subroutine wfdgw_plot_ur
    5393              : !!***
    5394              : 
    5395              : !----------------------------------------------------------------------
    5396              : 
    5397              : !!****f* m_wfd/wfdgw_get_nl_me
    5398              : !! NAME
    5399              : !! wfdgw_get_nl_me
    5400              : !!
    5401              : !! FUNCTION
    5402              : !!  Compute the non-local potential using the Wfd information.
    5403              : !!
    5404              : !! INPUTS
    5405              : !! cryst<crystal_t>= data type gathering info on symmetries and unit cell
    5406              : !! psps<pseudopotential_type>=variables related to pseudopotentials
    5407              : !! pawtab(psps%ntypat) <type(pawtab_type)>=paw tabulated starting data
    5408              : !! paw_ij(natom)<type(paw_ij_type)>=data structure containing PAW arrays given on (i,j) channels.
    5409              : !!
    5410              : !! OUTPUT
    5411              : !!
    5412              : !! SOURCE
    5413              : 
    5414            4 : subroutine wfdgw_get_nl_me(Wfd, cryst, psps, pawtab, bks_mask, nl_bks)
    5415              : 
    5416              : !Arguments ------------------------------------
    5417              : !scalars
    5418              :  class(wfdgw_t),target,intent(inout) :: Wfd
    5419              :  type(crystal_t),intent(in) :: cryst
    5420              :  type(pseudopotential_type),intent(in) :: psps
    5421              : ! arrays
    5422              :  logical,intent(in) :: bks_mask(Wfd%mband, Wfd%nkibz, Wfd%nsppol)
    5423              :  real(dp),allocatable,intent(out) :: nl_bks(:, :, :)
    5424              :  type(Pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
    5425              : 
    5426              : !Local variables ------------------------------
    5427              : !scalars
    5428              :  integer,parameter :: nspinor1=1,nspden1=1,nsppol1=1,spin1=1
    5429              :  integer,parameter :: ndat1=1,nnlout1=1,tim_nonlop0=0,idir0=0
    5430              :  integer :: natom,ib,ispin,ik_ibz,npw_k,istwf_k,nkpg
    5431              :  integer :: choice,cpopt,paw_opt,signs,ierr
    5432              :  character(len=500) :: msg
    5433            4 :  type(gs_hamiltonian_type) :: ham_k
    5434              :  type(wave_t),pointer :: wave
    5435              : !arrays
    5436            8 :  integer :: bks_distrb(Wfd%mband, Wfd%nkibz, Wfd%nsppol)
    5437            4 :  integer, contiguous, pointer :: kg_k(:,:)
    5438              :  real(dp) :: kpoint(3),enlout(1)
    5439            4 :  real(dp),allocatable :: kpg_k(:,:),vnl_psi(:,:),vectin(:,:)
    5440              :  real(dp) :: opaw_psi(1,1)
    5441            4 :  real(dp),contiguous, pointer :: ffnl_k(:,:,:,:),ph3d_k(:,:,:)
    5442            4 :  complex(gwp),contiguous, pointer :: ug1(:)
    5443            4 :  type(pawcprj_type),allocatable :: cprj(:,:)
    5444              : !************************************************************************
    5445              : 
    5446            0 :  ABI_CHECK(Wfd%paral_kgb == 0, "paral_kgb not coded")
    5447              : 
    5448            4 :  natom = cryst%natom
    5449              : 
    5450            4 :  signs  = 1  ! => get non-local energy in G-space.
    5451            4 :  choice = 1  ! => <G|V_nonlocal|vectin>.
    5452            4 :  cpopt  =-1; paw_opt= 0
    5453            4 :  if (Wfd%usepaw==1) then
    5454            0 :    ABI_ERROR("The construction of the non-local contribution is not tested/implemented for usepaw==1!")
    5455              :  end if
    5456              :  ! Initialize the Hamiltonian on the coarse FFT mesh.
    5457              :  call ham_k%init(psps, pawtab, nspinor1, nsppol1, nspden1, natom, cryst%typat, cryst%xred, &
    5458            4 :     Wfd%nfft, Wfd%mgfft, Wfd%ngfft, cryst%rprimd, Wfd%nloalg)
    5459              : 
    5460              :  ! Continue to prepare the GS Hamiltonian (note spin1)
    5461            4 :  call ham_k%load_spin(spin1, with_nonlocal=.true.)
    5462              : 
    5463              :  ! Distribute (b, k, s) states.
    5464            4 :  call Wfd%bks_distrb(bks_distrb, bks_mask=bks_mask)
    5465              : 
    5466          240 :  ABI_CALLOC(nl_bks, (Wfd%mband, Wfd%nkibz, Wfd%nsppol))
    5467          224 :  nl_bks(:,:,:) = czero
    5468              : 
    5469            4 :  write(std_out,'(a)') " "
    5470          224 :  call wrtout(std_out,sjoin(" Will calculate ",itoa(count(bks_mask))," <b,k,s|Vnl|b,k,s> matrix elements in wfdgw_get_nl_me."))
    5471            8 :  do ispin=1,Wfd%nsppol
    5472            4 :    if (ispin/=1) then
    5473            0 :      ABI_WARNING("In the construction of the non-local contribution, the case nsppol/=1 is not tested.")
    5474              :    end if
    5475           32 :    do ik_ibz=1,Wfd%nkibz
    5476           24 :      if (all(bks_distrb(:, ik_ibz, ispin) /= Wfd%my_rank)) cycle
    5477              : 
    5478           96 :      kpoint = Wfd%kibz(:, ik_ibz)
    5479           24 :      istwf_k = Wfd%istwfk(ik_ibz)
    5480           24 :      npw_k = Wfd%Kdata(ik_ibz)%npw
    5481           24 :      kg_k => Wfd%kdata(ik_ibz)%kg_k
    5482           24 :      ffnl_k => Wfd%Kdata(ik_ibz)%fnl_dir0der0
    5483           24 :      ph3d_k => Wfd%Kdata(ik_ibz)%ph3d
    5484              : 
    5485           72 :      ABI_MALLOC(vectin, (2, npw_k * nspinor1))
    5486           48 :      ABI_MALLOC(vnl_psi, (2, npw_k * nspinor1))
    5487         6975 :      vectin=zero
    5488         6975 :      vnl_psi=zero
    5489              :      ! Compute (k+G) vectors (only if psps%useylm=1)
    5490           24 :      nkpg = 3 *  Wfd%nloalg(3)
    5491           96 :      ABI_MALLOC(kpg_k, (npw_k, nkpg))
    5492           24 :      if (nkpg > 0) then
    5493            0 :        call mkkpg(kg_k, kpg_k, kpoint, nkpg, npw_k)
    5494              :      end if
    5495              : 
    5496              :      ! Load k-dependent part in the Hamiltonian datastructure
    5497              :      call ham_k%load_k(kpt_k=kpoint,istwf_k=istwf_k,npw_k=npw_k,kg_k=kg_k,kpg_k=kpg_k,ffnl_k=ffnl_k,&
    5498           24 :                        ph3d_k=ph3d_k,compute_ph3d=(Wfd%paral_kgb/=1),compute_gbound=(Wfd%paral_kgb/=1))
    5499              : 
    5500              :      ! ========================================================
    5501              :      ! ==== Compute nonlocal form factors ffnl at all (k+G) ====
    5502              :      ! ========================================================
    5503              :      ! Calculate <G|Vnl|psi> for this k-point
    5504          216 :      do ib=1,Wfd%nband(ik_ibz, ispin)
    5505          192 :        if (bks_distrb(ib, ik_ibz, ispin) /= Wfd%my_rank) cycle
    5506              : 
    5507          192 :            ABI_CHECK(Wfd%get_wave_ptr(ib, ik_ibz, ispin, wave, msg) == 0, msg)
    5508          192 :            ug1 => wave%ug
    5509              :            ! Input wavefunction coefficients <G|Cnk>.
    5510              :            ! vectin, (2, npw_k * nspinor1))
    5511        55800 :            vectin(:,:) = zero
    5512          192 :            if (ispin == 1) then
    5513        18728 :              vectin(1, 1:npw_k) = real(ug1)
    5514        18728 :              vectin(2, 1:npw_k) = aimag(ug1)
    5515              :            else
    5516            0 :              vectin(1, npw_k+1:) = real(ug1)
    5517            0 :              vectin(2, npw_k+1:) = aimag(ug1)
    5518              :            end if
    5519              : 
    5520          192 :            if (Wfd%usepaw == 1) then
    5521            0 :               call Wfd%get_cprj(ib, ik_ibz, ispin, cryst, cprj, sorted=.True.)
    5522              :            end if
    5523              : 
    5524              :            ! Compute nonlocal band energy. We could use nonlop to get matrix elements but we only need diagonal contributions.
    5525              :            ! enlout(1) is the band energy
    5526              :            call nonlop(choice, cpopt, cprj, enlout, ham_k, idir0, (/zero/), Wfd%mpi_enreg, ndat1, nnlout1, &
    5527          192 :                        paw_opt, signs, opaw_psi, tim_nonlop0, vectin, vnl_psi)
    5528          216 :            nl_bks(ib, ik_ibz, ispin) = enlout(1)
    5529              :      end do ! ib
    5530              : 
    5531           24 :      ABI_FREE(vectin)
    5532           24 :      ABI_FREE(vnl_psi)
    5533           28 :      ABI_FREE(kpg_k)
    5534              :    end do ! ik_ibz
    5535              :  end do ! ispin
    5536              : 
    5537            4 :  call xmpi_sum(nl_bks, Wfd%comm, ierr)
    5538              : 
    5539            4 :  call ham_k%free()
    5540              : 
    5541           12 : end subroutine wfdgw_get_nl_me
    5542              : !!***
    5543              : 
    5544              : !----------------------------------------------------------------------
    5545              : 
    5546              : !!****f* m_wfd/wfd_get_socpert
    5547              : !! NAME
    5548              : !! wfd_get_socpert
    5549              : !!
    5550              : !! FUNCTION
    5551              : !!
    5552              : !! INPUTS
    5553              : !! cryst<crystal_t>= data type gathering info on symmetries and unit cell
    5554              : !! psps<pseudopotential_type>=variables related to pseudopotentials
    5555              : !! pawtab(psps%ntypat) <type(pawtab_type)>=paw tabulated starting data
    5556              : !! paw_ij(natom)<type(paw_ij_type)>=data structure containing PAW arrays given on (i,j) channels.
    5557              : !!
    5558              : !! OUTPUT
    5559              : !!
    5560              : !! SOURCE
    5561              : 
    5562              : !!!  subroutine wfd_get_socpert(wfd, cryst, psps, pawtab, bks_mask, soc_bks)
    5563              : !!!
    5564              : !!!   !use m_pawcprj
    5565              : !!!   use m_hamiltonian,    only : destroy_hamiltonian, init_hamiltonian, &
    5566              : !!!                                load_spin_hamiltonian,load_k_hamiltonian, gs_hamiltonian_type
    5567              : !!!
    5568              : !!!   implicit none
    5569              : !!!
    5570              : !!!  !Arguments ------------------------------------
    5571              : !!!  !scalars
    5572              : !!!   type(wfd_t),target,intent(inout) :: wfd
    5573              : !!!   type(crystal_t),intent(in) :: cryst
    5574              : !!!   type(pseudopotential_type),intent(in) :: psps
    5575              : !!!  ! arrays
    5576              : !!!   logical,intent(in) :: bks_mask(wfd%mband, wfd%nkibz, wfd%nsppol)
    5577              : !!!   real(dp),allocatable,intent(out) :: osoc_bks(:, :, :)
    5578              : !!!   type(Pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
    5579              : !!!   !type(paw_ij_type),intent(in) :: paw_ij(cryst%natom*psps%usepaw)
    5580              : !!!
    5581              : !!!  !Local variables ------------------------------
    5582              : !!!  !scalars
    5583              : !!!   integer,parameter :: nspinor2=2,nspden4=4,nsppol1=1,spin1=1
    5584              : !!!   integer,parameter :: ndat1=1,nnlout0=0,tim_nonlop0=0,idir0=0 !,ider0=0,
    5585              : !!!   integer :: natom,band,spin,ik_ibz,npw_k,istwf_k,nkpg !,ig,optder,matblk,mkmem_,nkpg,dimffnl,nspinortot
    5586              : !!!   integer :: choice,cpopt,cp_dim,paw_opt,signs,ierr
    5587              : !!!   !character(len=500) :: msg
    5588              : !!!   type(gs_hamiltonian_type) :: ham_k
    5589              : !!!  !arrays
    5590              : !!!   integer :: bks_distrb(wfd%mband, wfd%nkibz, wfd%nsppol)
    5591              : !!!   integer, contiguous, pointer :: kg_k(:,:)
    5592              : !!!   !real(dp) :: kptns_(3,1),ylmgr_dum(1,1,1),shifts(3)
    5593              : !!!   !real(dp),allocatable :: ylm_k(:,:),dum_ylm_gr_k(:,:,:)
    5594              : !!!   !real(dp),pointer :: ffnl_k(:,:,:,:)
    5595              : !!!   real(dp) :: kpoint(3),dum_enlout(0),dummy_lambda(1),soc(2)
    5596              : !!!   real(dp),allocatable :: kpg_k(:,:),vnl_psi(:,:),vectin(:,:) !,s_psi(:,:)
    5597              : !!!   real(dp),allocatable :: opaw_psi(:,:) !2, npw_k*wfd%nspinor*wfd%usepaw) ! <G|1+S|Cnk>
    5598              : !!!   real(dp),contiguous, pointer :: ffnl_k(:,:,:,:),ph3d_k(:,:,:)
    5599              : !!!   type(pawcprj_type),allocatable :: cprj(:,:)
    5600              : !!!  !************************************************************************
    5601              : !!!
    5602              : !!!   ABI_CHECK(wfd%paral_kgb == 0, "paral_kgb not coded")
    5603              : !!!
    5604              : !!!   natom = cryst%natom
    5605              : !!!
    5606              : !!!   signs  = 2  ! => apply the non-local operator to a function in G-space.
    5607              : !!!   choice = 1  ! => <G|V_nonlocal|vectin>.
    5608              : !!!   cpopt  =-1; paw_opt= 0
    5609              : !!!   if (wfd%usepaw==1) then
    5610              : !!!     paw_opt=4 ! both PAW nonlocal part of H (Dij) and overlap matrix (Sij)
    5611              : !!!     cpopt=3   ! <p_lmn|in> are already in memory
    5612              : !!!
    5613              : !!!     cp_dim = ((cpopt+5) / 5)
    5614              : !!!     ABI_MALLOC(cprj, (natom, nspinor2*cp_dim))
    5615              : !!!     call pawcprj_alloc(cprj, 0, wfd%nlmn_sort)
    5616              : !!!   end if
    5617              : !!!
    5618              : !!!   ! Initialize the Hamiltonian on the coarse FFT mesh.
    5619              : !!!   call init_hamiltonian(ham_k, psps, pawtab, nspinor2, nsppol1, nspden4, natom, cryst%typat, cryst%xred, &
    5620              : !!!      wfd%nfft, wfd%mgfft, wfd%ngfft, cryst%rprimd, wfd%nloalg)
    5621              : !!!   !ham_k%ekb(:,:,1) = zero
    5622              : !!!
    5623              : !!!   ! Continue to prepare the GS Hamiltonian (note spin1)
    5624              : !!!   call load_spin_hamiltonian(ham_k, spin1, with_nonlocal=.True.)
    5625              : !!!
    5626              : !!!   ! Distribute (b, k, s) states.
    5627              : !!!   call wfd%bks_distrb(bks_distrb, bks_mask=bks_mask)
    5628              : !!!
    5629              : !!!   ABI_CALLOC(osoc_bks, (wfd%mband, wfd%nkibz, wfd%nsppol))
    5630              : !!!   osoc_bks = zero
    5631              : !!!
    5632              : !!!   do spin=1,wfd%nsppol
    5633              : !!!     do ik_ibz=1,wfd%nkibz
    5634              : !!!       if (all(bks_distrb(:, ik_ibz, spin) /= wfd%my_rank)) cycle
    5635              : !!!
    5636              : !!!       kpoint = wfd%kibz(:, ik_ibz)
    5637              : !!!       npw_k = wfd%Kdata(ik_ibz)%npw; istwf_k = wfd%istwfk(ik_ibz)
    5638              : !!!       ABI_CHECK(istwf_k == 1, "istwf_k must be 1 if SOC term is computed with perturbation theory.")
    5639              : !!!       kg_k => wfd%kdata(ik_ibz)%kg_k
    5640              : !!!       ffnl_k => wfd%Kdata(ik_ibz)%fnl_dir0der0
    5641              : !!!       ph3d_k => wfd%Kdata(ik_ibz)%ph3d
    5642              : !!!
    5643              : !!!       ABI_MALLOC(vectin, (2, npw_k * nspinor2))
    5644              : !!!       ABI_MALLOC(vnl_psi, (2, npw_k * nspinor2))
    5645              : !!!       !ABI_MALLOC(cvnl_psi, (npw_k * nspinor2))
    5646              : !!!       !ABI_MALLOC(s_psi, (2, npw_k * nspinor2 * psps%usepaw))
    5647              : !!!
    5648              : !!!       ! Compute (k+G) vectors (only if psps%useylm=1)
    5649              : !!!       nkpg = 3 * wfd%nloalg(3)
    5650              : !!!       ABI_MALLOC(kpg_k, (npw_k, nkpg))
    5651              : !!!       if (nkpg > 0) then
    5652              : !!!         call mkkpg(kg_k, kpg_k, kpoint, nkpg, npw_k)
    5653              : !!!       end if
    5654              : !!!
    5655              : !!!       ! Load k-dependent part in the Hamiltonian datastructure
    5656              : !!!       !matblk = min(NLO_MINCAT, maxval(ham_k%nattyp)); if (wfd%nloalg(2) > 0) matblk = natom
    5657              : !!!       !ABI_MALLOC(ph3d_k,(2, npw_k, matblk))
    5658              : !!!       call load_k_hamiltonian(ham_k, kpt_k=kpoint, npw_k=npw_k, istwf_k=istwf_k, kg_k=kg_k, &
    5659              : !!!                               kpg_k=kpg_k, ffnl_k=ffnl_k, ph3d_k=ph3d_k, compute_ph3d=(wfd%paral_kgb/=1))
    5660              : !!!
    5661              : !!!       ! THIS PART IS NEEDED FOR THE CALL TO opernl although some quantities won't be used.
    5662              : !!!       ! Now I do things cleanly then we try to pass zero-sized arrays!
    5663              : !!!       !ABI_MALLOC(ylm_k, (npw_k, psps%mpsang**2 * psps%useylm))
    5664              : !!!       !if (psps%useylm == 1) then
    5665              : !!!       !  kptns_(:,1) = k4intp; optder = 0; mkmem_ = 1
    5666              : !!!       !  ABI_MALLOC(dum_ylm_gr_k,(npw_k,3+6*(optder/2),psps%mpsang**2))
    5667              : !!!       !  ! Here mband is not used if paral_compil_kpt=0
    5668              : !!!       !  call initylmg(cryst%gprimd, kg_k, kptns_, mkmem_, wfd%MPI_enreg, psps%mpsang, npw_k, [1], 1,&
    5669              : !!!       !    [npw_k], 1, optder, cryst%rprimd, ylm_k, dum_ylm_gr_k)
    5670              : !!!       !  ABI_FREE(dum_ylm_gr_k)
    5671              : !!!       !end if
    5672              : !!!
    5673              : !!!       ! ========================================================
    5674              : !!!       ! ==== Compute nonlocal form factors ffnl at all (k+G) ====
    5675              : !!!       ! ========================================================
    5676              : !!!       !dimffnl = 1 + ider0 ! Derivatives are not needed.
    5677              : !!!       !ABI_MALLOC(ffnl_k, (npw_k, dimffnl, psps%lmnmax, psps%ntypat))
    5678              : !!!       !! ffnl_k => Kdata%fnl_dir0der0
    5679              : !!!       !call mkffnl(psps%dimekb, dimffnl, psps%ekb, ffnl_k, psps%ffspl, cryst%gmet, cryst%gprimd, ider0, idir0, psps%indlmn,&
    5680              : !!!       !   kg_k, kpg_k, k4intp, psps%lmnmax, psps%lnmax, psps%mpsang, psps%mqgrid_ff, nkpg, npw_k, &
    5681              : !!!       !   psps%ntypat, psps%pspso, psps%qgrid_ff, cryst%rmet, psps%usepaw, psps%useylm, ylm_k, ylmgr_dum)
    5682              : !!!       !ABI_FREE(ylm_k)
    5683              : !!!
    5684              : !!!       ! Calculate <G|Vnl|psi> for this k-point
    5685              : !!!       do band=1,wfd%nband(ik_ibz, spin)
    5686              : !!!         if (bks_distrb(band, ik_ibz, spin) /= wfd%my_rank) cycle
    5687              : !!!
    5688              : !!!         ! Input wavefunction coefficients <G|Cnk>.
    5689              : !!!         ! vectin, (2, npw_k * nspinor2))
    5690              : !!!         if (spin == 1) then
    5691              : !!!           vectin(1, 1:npw_k) = dble(wfd%wave(band, ik_ibz, spin)%ug)
    5692              : !!!           vectin(2, 1:npw_k) = aimag(wfd%wave(band, ik_ibz, spin)%ug)
    5693              : !!!           vectin(:, npw_k+1:) = zero
    5694              : !!!         else
    5695              : !!!           vectin(:, 1:npw_k) = zero
    5696              : !!!           vectin(1, npw_k+1:) = dble(wfd%wave(band, ik_ibz, spin)%ug)
    5697              : !!!           vectin(2, npw_k+1:) = aimag(wfd%wave(band, ik_ibz, spin)%ug)
    5698              : !!!         end if
    5699              : !!!
    5700              : !!!         if (wfd%usepaw == 1) call wfd%get_cprj(band, ik_ibz, spin, cryst, cprj, sorted=.True.)
    5701              : !!!
    5702              : !!!         ! TODO: consistency check for only_SO
    5703              : !!!         call nonlop(choice, cpopt, cprj, dum_enlout, ham_k, idir0, dummy_lambda, wfd%mpi_enreg, ndat1, nnlout0, &
    5704              : !!!                     paw_opt, signs, opaw_psi, tim_nonlop0, vectin, vnl_psi, only_SO=1)
    5705              : !!!
    5706              : !!!         soc = cg_zdotc(npw_k * nspinor2, vectin, vnl_psi)
    5707              : !!!         write(std_out,*)soc * Ha_eV, "for (b, k, s)",band, ik_ibz, spin
    5708              : !!!         osoc_bks(band, ik_ibz, spin) = soc(1)
    5709              : !!!       end do ! band
    5710              : !!!
    5711              : !!!       !ABI_FREE(ffnl_k)
    5712              : !!!       !ABI_FREE(ph3d_k)
    5713              : !!!       ABI_FREE(vectin)
    5714              : !!!       ABI_FREE(vnl_psi)
    5715              : !!!       ABI_FREE(kpg_k)
    5716              : !!!       !ABI_FREE(cvnl_psi)
    5717              : !!!       !ABI_FREE(s_psi)
    5718              : !!!     end do ! ik_ibz
    5719              : !!!   end do ! spin
    5720              : !!!
    5721              : !!!   call xmpi_sum(osoc_bks, wfd%comm, ierr)
    5722              : !!!
    5723              : !!!   call destroy_hamiltonian(ham_k)
    5724              : !!!
    5725              : !!!   if (wfd%usepaw == 1) then
    5726              : !!!     call pawcprj_free(cprj)
    5727              : !!!     ABI_FREE(cprj)
    5728              : !!!   end if
    5729              : !!!
    5730              : !!!  end subroutine wfd_get_socpert
    5731              : !!***
    5732              : 
    5733              : !!****f* m_wfd/wfdgw_mkrho
    5734              : !! NAME
    5735              : !! wfdgw_mkrho
    5736              : !!
    5737              : !! FUNCTION
    5738              : !! Calculate the charge density on the fine FFT grid in real space.
    5739              : !!
    5740              : !! INPUTS
    5741              : !!  Wfd<wfd_t)=datatype gathering info on the wavefunctions.
    5742              : !!  ngfftf(18)=array containing all the information for the "fine" FFT.
    5743              : !!  Cryst<crystal_t> Info on the crystalline structure
    5744              : !!  optcalc=option for calculation. If =0 (default value) perform calculation
    5745              : !!    of electronic density. If =1, perform calculation of kinetic energy density.
    5746              : !!    In both cases, the result is returned in rhor.
    5747              : !!  Psps<type(pseudopotential_type)>=variables related to pseudopotentials
    5748              : !!  nfftf=Total number of points on the fine FFT grid (for this processor)
    5749              : !! [optcalc]=Optional option used to calculate the kinetic energy density. Defaults to 0.
    5750              : !!
    5751              : !! OUTPUT
    5752              : !!  rhor(nfftf,nspden)=The density in the real space on the fine FFT grid.
    5753              : !!   If nsppol==2, total charge in first half, spin-up component in second half.
    5754              : !!   (for non-collinear magnetism, first element: total density, 3 next ones: mx,my,mz in units of hbar/2)
    5755              : !!   If optcalc==1 (optional argument, default value is 0), then rhor will actually
    5756              : !!   contains kinetic energy density (taur) instead of electronic density.
    5757              : !!
    5758              : !! NOTES
    5759              : !! In the case of PAW calculations:
    5760              : !!    All computations are done on the fine FFT grid.
    5761              : !!    All variables (nfftf,ngfftf,mgfftf) refer to this fine FFT grid.
    5762              : !!    All arrays (densities/potentials...) are computed on this fine FFT grid.
    5763              : !!    Developers have to be careful when introducing others arrays:
    5764              : !!      they have to be stored on the fine FFT grid.
    5765              : !! In the case of norm-conserving calculations:
    5766              : !!    The mesh is the usual augmented FFT grid to treat correctly the convolution.
    5767              : !!
    5768              : !! SOURCE
    5769              : 
    5770          459 : subroutine wfdgw_mkrho(wfd, cryst, psps, ebands, ngfftf, nfftf, rhor, &
    5771              :                       optcalc) ! optional arguments
    5772              : 
    5773              : !Arguments ------------------------------------
    5774              : !scalars
    5775              :  integer,intent(in) :: nfftf
    5776              :  integer,intent(in),optional :: optcalc
    5777              :  type(ebands_t),intent(in) :: ebands
    5778              :  type(crystal_t),intent(in) :: cryst
    5779              :  type(Pseudopotential_type),intent(in) :: psps
    5780              :  class(wfdgw_t),intent(inout) :: wfd
    5781              : !arrays
    5782              :  integer,intent(in) :: ngfftf(18)
    5783              :  real(dp),intent(out) :: rhor(nfftf, Wfd%nspden)
    5784              : 
    5785              : !Local variables ------------------------------
    5786              : !scalars
    5787              :  integer,parameter :: ndat1=1
    5788              :  integer :: cplex,ib,ib_iter,ierr,ik,ir,is,n1,n2,n3,nfftotf
    5789              :  integer :: alpha,nalpha,ipw,myoptcalc
    5790              :  real(dp) :: kpt_cart,kg_k_cart,gp2pi1,gp2pi2,gp2pi3,cwftmp,bks_weight
    5791              :  character(len=500) :: msg
    5792              :  type(wave_t),pointer :: wave
    5793              : !arrays
    5794          459 :  integer,allocatable :: irrzon(:,:,:)
    5795          459 :  real(dp),allocatable :: phnons(:,:,:),rhog(:,:),rhor_down(:),rhor_mx(:),rhor_my(:),cwavef(:,:)
    5796          459 :  complex(dp),allocatable :: wfr_x(:),wfr_y(:)
    5797          459 :  complex(gwp),allocatable :: gradug(:),work(:)
    5798          459 :  complex(gwp),allocatable,target :: wfr(:)
    5799          459 :  complex(gwp), contiguous, pointer :: cwavef1(:),cwavef2(:)
    5800          459 :  type(iter2_t) :: Iter_bks
    5801              : !*************************************************************************
    5802              : 
    5803              :  ! Consistency check.
    5804            0 :  ABI_CHECK(Wfd%nsppol == ebands%nsppol, "Mismatch in nsppol")
    5805              : 
    5806          888 :  if (ANY(ngfftf(1:3) /= Wfd%ngfft(1:3))) call wfd%change_ngfft(Cryst,Psps,ngfftf)
    5807              : 
    5808              :  ! Calculate IBZ contribution to the charge density.
    5809         1377 :  ABI_MALLOC(wfr, (nfftf*Wfd%nspinor))
    5810              : 
    5811          459 :  if (wfd%nspden == 4) then
    5812           18 :    ABI_MALLOC(wfr_x, (nfftf))
    5813           12 :    ABI_MALLOC(wfr_y, (nfftf))
    5814           18 :    ABI_MALLOC(rhor_down, (nfftf))
    5815           12 :    ABI_MALLOC(rhor_mx, (nfftf))
    5816           12 :    ABI_MALLOC(rhor_my, (nfftf))
    5817       144006 :    rhor_down = zero; rhor_mx = zero; rhor_my = zero
    5818              :  end if
    5819              : 
    5820              :  ! Update the (b,k,s) distribution table.
    5821          459 :  call wfd%update_bkstab()
    5822              : 
    5823              :  ! Calculate the unsymmetrized density.
    5824      8194854 :  rhor=zero
    5825          459 :  myoptcalc=0; if (present(optcalc)) myoptcalc=optcalc
    5826          459 :  nalpha=1; if (myoptcalc==1) nalpha=3
    5827          459 :  if (myoptcalc == 1 .and. wfd%nspinor == 2) then
    5828            0 :    ABI_ERROR("kinetic energy density with nspinor == 2 not implemented")
    5829              :  end if
    5830              : 
    5831              :  ! Build the iterator that will distribute the states in an automated way.
    5832        67329 :  Iter_bks = wfd%iterator_bks(bks_mask=ABS(ebands%occ)>=tol8)
    5833              : 
    5834          918 :  do alpha=1,nalpha
    5835         1386 :    do is=1,Wfd%nsppol
    5836         4402 :      do ik=1,Wfd%nkibz
    5837        16380 :        do ib_iter=1,iter_len(Iter_bks,ik,is)
    5838        12437 :          ib = iter_yield(Iter_bks,ib_iter,ik,is)
    5839        12437 :          bks_weight = ebands%occ(ib,ik,is) * ebands%wtk(ik) / Cryst%ucvol
    5840              : 
    5841        12437 :          call wfd%get_ur(ib,ik,is,wfr)
    5842              : 
    5843        12437 :          cwavef1 => wfr(1:nfftf)
    5844        12437 :          if (myoptcalc == 1) then
    5845            0 :            ABI_MALLOC(gradug,(Wfd%Kdata(ik)%npw))
    5846            0 :            ABI_MALLOC(cwavef,(2,Wfd%Kdata(ik)%npw))
    5847            0 :            ABI_MALLOC(work,(nfftf))
    5848              : 
    5849            0 :            ABI_CHECK(wfd%get_wave_ptr(ib, ik, is, wave, msg) == 0, msg)
    5850            0 :            cwavef(1,:)= REAL(wave%ug(:))
    5851            0 :            cwavef(2,:)=AIMAG(wave%ug(:))
    5852              : 
    5853              :            ! Multiplication by 2pi i (k+G)_alpha
    5854            0 :            gp2pi1=Cryst%gprimd(alpha,1)*two_pi
    5855            0 :            gp2pi2=Cryst%gprimd(alpha,2)*two_pi
    5856            0 :            gp2pi3=Cryst%gprimd(alpha,3)*two_pi
    5857            0 :            kpt_cart=gp2pi1*Wfd%kibz(1,ik)+gp2pi2*Wfd%kibz(2,ik)+gp2pi3*Wfd%kibz(3,ik)
    5858            0 :            do ipw=1,Wfd%Kdata(ik)%npw
    5859              :              kg_k_cart= gp2pi1*Wfd%Kdata(ik)%kg_k(1,ipw) + &
    5860              :                         gp2pi2*Wfd%Kdata(ik)%kg_k(2,ipw) + &
    5861            0 :                         gp2pi3*Wfd%Kdata(ik)%kg_k(3,ipw)+kpt_cart
    5862              :              !ipwsp=ipw!+(ispinor-1)*Wfd%Kdata(ik)%npw
    5863            0 :              cwftmp=-cwavef(2,ipw)*kg_k_cart
    5864            0 :              cwavef(2,ipw)=cwavef(1,ipw)*kg_k_cart
    5865            0 :              cwavef(1,ipw)=cwftmp
    5866              :            end do
    5867            0 :            gradug(:)=CMPLX(cwavef(1,:),cwavef(2,:),gwp)
    5868              :            call fft_ug(Wfd%npwarr(ik),nfftf,Wfd%nspinor,ndat1,Wfd%mgfft,Wfd%ngfft,&
    5869            0 :              Wfd%istwfk(ik),Wfd%Kdata(ik)%kg_k,Wfd%Kdata(ik)%gbound,gradug,work)
    5870            0 :            cwavef1(:)=work(:)
    5871            0 :            ABI_FREE(work)
    5872            0 :            ABI_FREE(cwavef)
    5873            0 :            ABI_FREE(gradug)
    5874              :          end if
    5875              : 
    5876              :          !$OMP PARALLEL DO
    5877    117544637 :          do ir=1,nfftf
    5878    117544637 :            rhor(ir,is) = rhor(ir,is) + CONJG(cwavef1(ir)) * cwavef1(ir) * bks_weight
    5879              :          end do
    5880              :          !call cplx_addtorho(n1,n2,n3,n4,n5,n6,ndat,weight_r,ur,rho)
    5881              : 
    5882        12437 :          if (wfd%nspinor == 2 .and. wfd%nspden == 1) then
    5883          112 :            cwavef2 => wfr(1+nfftf:2*nfftf)
    5884      1175664 :            do ir=1,nfftf
    5885      1175664 :              rhor(ir, 1) = rhor(ir, 1) + CONJG(cwavef2(ir)) * cwavef2(ir) * bks_weight
    5886              :            end do
    5887              :          end if
    5888              : 
    5889        15912 :          if (wfd%nspinor == 2 .and. wfd%nspden == 4) then
    5890          184 :            cwavef2 => wfr(1+nfftf:2*nfftf)
    5891      1472184 :            wfr_x(:) = cwavef1(:) + cwavef2(:)       ! $(\Psi^{1}+\Psi^{2})$
    5892      1472184 :            wfr_y(:) = cwavef1(:) -j_dpc*cwavef2(:)  ! $(\Psi^{1}-i\Psi^{2})$
    5893              :            !$OMP PARALLEL DO
    5894      1472184 :            do ir=1,nfftf
    5895      1472000 :              rhor_down(ir) = rhor_down(ir) + CONJG(cwavef2(ir)) * cwavef2(ir) * bks_weight
    5896      1472000 :              rhor_mx(ir) = rhor_mx(ir) + CONJG(wfr_x(ir)) * wfr_x(ir) * bks_weight
    5897      1472184 :              rhor_my(ir) = rhor_my(ir) + CONJG(wfr_y(ir)) * wfr_y(ir) * bks_weight
    5898              :            end do
    5899              :          end if
    5900              : 
    5901              :        end do
    5902              :      end do
    5903              :    end do
    5904              : 
    5905              :  end do ! enddo alpha
    5906              : 
    5907          459 :  call iter_free(Iter_bks)
    5908              : 
    5909          459 :  select case (myoptcalc)
    5910              :  case (0)
    5911              :    ! density
    5912          459 :    if (wfd%nspden == 4) then
    5913        48006 :      rhor(:, 2) = rhor_mx
    5914        48006 :      rhor(:, 3) = rhor_my
    5915        48006 :      rhor(:, 4) = rhor_down
    5916              :    end if
    5917              :  case (1)
    5918              :    ! convention for taur = 1/2 Sum_i |grad phi_i|^2
    5919            0 :    rhor(:,:)=half*rhor(:,:)
    5920              : 
    5921              :  case default
    5922          459 :    ABI_ERROR(sjoin("Wrong myoptcalc:", itoa(myoptcalc)))
    5923              :  end select
    5924              : 
    5925          459 :  call xmpi_sum(rhor,Wfd%comm,ierr)
    5926              : 
    5927              :  ! Symmetrization in G-space implementing also the AFM case
    5928          459 :  n1=ngfftf(1); n2=ngfftf(2); n3=ngfftf(3); nfftotf=n1*n2*n3
    5929              : 
    5930         1836 :  ABI_MALLOC(irrzon,(nfftotf**(1-1/Cryst%nsym),2,(Wfd%nspden/Wfd%nsppol)-3*(Wfd%nspden/4)))
    5931         1836 :  ABI_MALLOC(phnons,(2,nfftotf,(Wfd%nspden/Wfd%nsppol)-3*(Wfd%nspden/4)))
    5932              : 
    5933          459 :  if (Cryst%nsym/=1) then
    5934          459 :    call irrzg(irrzon,Wfd%nspden,Wfd%nsppol,Cryst%nsym,n1,n2,n3,phnons,Cryst%symafm,Cryst%symrel,Cryst%tnons)
    5935              :  end if
    5936              : 
    5937              :  ! Symmetrize rho(r), and pack nspden components following abinit conventions.
    5938          459 :  cplex=1
    5939         1377 :  ABI_MALLOC(rhog,(2,cplex*nfftf))
    5940              : 
    5941              :  call symrhg(cplex,Cryst%gprimd,irrzon,Wfd%MPI_enreg,nfftf,nfftotf,ngfftf,Wfd%nspden,Wfd%nsppol,&
    5942          459 :              Cryst%nsym,phnons,rhog,rhor,Cryst%rprimd,Cryst%symafm,Cryst%symrel,Cryst%tnons)
    5943              : 
    5944          459 :  ABI_FREE(rhog)
    5945          459 :  ABI_FREE(phnons)
    5946          459 :  ABI_FREE(irrzon)
    5947              : 
    5948              :  ! Find and print minimum and maximum total electron density
    5949              :  ! (or total kinetic energy density, or total element of kinetic energy density tensor) and locations
    5950              :  !call wrtout(std_out,'mkrho: echo density (plane-wave part only)','COLL')
    5951              :  !call prtrhomxmn(std_out,wfd%mpi_enreg,nfftf,ngfftf,wfd%nspden,1,rhor,optrhor=optcalc,ucvol=crystl%ucvol)
    5952              : 
    5953      7726606 :  write(msg,'(a,f9.4)')' planewave contribution to nelect: ',SUM(rhor(:,1))*Cryst%ucvol/nfftf
    5954          459 :  call wrtout(std_out, msg)
    5955              : 
    5956          459 :  if (Wfd%nspden==4) then
    5957              :    write(msg,'(a,3f9.4)')&
    5958       144006 :      ' mx, my, mz: ',SUM(rhor(:,2))*Cryst%ucvol/nfftf,SUM(rhor(:,3))*Cryst%ucvol/nfftf,SUM(rhor(:,4))*Cryst%ucvol/nfftf
    5959            6 :    call wrtout(std_out, msg)
    5960              :  end if
    5961              : 
    5962          459 :  ABI_FREE(wfr)
    5963              : 
    5964          459 :  if (Wfd%nspden == 4) then
    5965            6 :    ABI_FREE(wfr_x)
    5966            6 :    ABI_FREE(wfr_y)
    5967            6 :    ABI_FREE(rhor_down)
    5968            6 :    ABI_FREE(rhor_mx)
    5969            6 :    ABI_FREE(rhor_my)
    5970              :  end if
    5971              : 
    5972          918 : end subroutine wfdgw_mkrho
    5973              : !!***
    5974              : 
    5975              : !----------------------------------------------------------------------
    5976              : 
    5977              : !!****f* m_wfd/test_charge
    5978              : !! NAME
    5979              : !! test_charge
    5980              : !!
    5981              : !! FUNCTION
    5982              : !!  Reports info on the electronic charge as well as Drude plasma frequency.
    5983              : !!  Mainly used in the GW part.
    5984              : !!
    5985              : !! INPUTS
    5986              : !!  nelectron_exp=Expected total number of electrons (used to normalize the charge)
    5987              : !!
    5988              : !! OUTPUT
    5989              : !!
    5990              : !! SOURCE
    5991              : 
    5992          454 : subroutine test_charge(nfftf,nelectron_exp,nspden,rhor,ucvol,&
    5993              :                        usepaw,usexcnhat,usefinegrid,compch_sph,compch_fft,omegaplasma)
    5994              : 
    5995              : !Arguments ------------------------------------
    5996              : !scalars
    5997              :  integer,intent(in) :: nfftf,nspden,usefinegrid,usepaw,usexcnhat
    5998              :  real(dp),intent(in) :: compch_fft,compch_sph,ucvol,nelectron_exp
    5999              :  real(dp),intent(out) :: omegaplasma
    6000              : !arrays
    6001              :  real(dp),intent(inout) :: rhor(nfftf,nspden)
    6002              : 
    6003              : !Local variables ------------------------------
    6004              : !scalars
    6005              :  real(dp) :: nelectron_tot,nelectron_fft
    6006              :  real(dp) :: nelectron_pw,nelectron_sph,rhoav,rs,nratio
    6007              :  character(len=500) :: msg
    6008              : !*************************************************************************
    6009              : 
    6010              : ! ABI_UNUSED(usexcnhat)
    6011              :  if (usexcnhat==0)then
    6012              :  end if
    6013              : 
    6014              :  ! === For PAW output of compensation charges ===
    6015          454 :  if (usepaw==1) then
    6016              :  !if (usepaw==1.and.usexcnhat>0) then ! TODO I still dont understand this if!
    6017           12 :    write(msg,'(4a)')ch10,' PAW TEST:',ch10,' ==== Compensation charge inside spheres ============'
    6018           12 :    if (compch_sph<greatest_real.and.compch_fft<greatest_real) &
    6019           12 :      write(msg,'(3a)')TRIM(msg),ch10,' The following values must be close...'
    6020           12 :    if (compch_sph<greatest_real) &
    6021           12 :      write(msg,'(3a,f22.15)')TRIM(msg),ch10,' Compensation charge over spherical meshes = ',compch_sph
    6022           12 :    if (compch_fft<greatest_real) then
    6023           12 :      if (usefinegrid==1) then
    6024            6 :        write(msg,'(3a,f22.15)')TRIM(msg),ch10,' Compensation charge over fine fft grid    = ',compch_fft
    6025              :      else
    6026            6 :        write(msg,'(3a,f22.15)')TRIM(msg),ch10,' Compensation charge over fft grid         = ',compch_fft
    6027              :      end if
    6028              :    end if
    6029           36 :    call wrtout([std_out, ab_out], msg)
    6030           12 :    write(msg,'(a)')ch10
    6031           36 :    call wrtout([std_out, ab_out], msg)
    6032              :  end if !PAW
    6033              : 
    6034      7707601 :  nelectron_pw =SUM(rhor(:,1))*ucvol/nfftf
    6035          454 :  nelectron_tot=nelectron_pw
    6036          454 :  nratio       =nelectron_exp/nelectron_tot
    6037              : 
    6038          454 :  if (usepaw==1) then
    6039           12 :    nelectron_sph=nelectron_pw+compch_sph
    6040           12 :    nelectron_fft=nelectron_pw+compch_fft
    6041           12 :    nelectron_tot=nelectron_sph
    6042           12 :    nratio=(nelectron_exp-nelectron_sph)/nelectron_pw
    6043              :  end if
    6044              : 
    6045          454 :  rhoav=nelectron_tot/ucvol ; rs=(three/(four_pi*rhoav))**third
    6046          454 :  if (usepaw==0) then
    6047              :   write(msg,'(2(a,f9.4))')&
    6048          442 :    ' Number of electrons calculated from density = ',nelectron_tot,'; Expected = ',nelectron_exp
    6049              :  else
    6050              :    write(msg,'(2(a,f9.4),a)')&
    6051           12 :    ' Total number of electrons per unit cell = ',nelectron_sph,' (Spherical mesh), ',nelectron_fft,' (FFT mesh)'
    6052              :  end if
    6053         1362 :  call wrtout([std_out, ab_out], msg)
    6054              : 
    6055              :  !write(msg,'(a,f9.4)')' Renormalizing smooth charge density using nratio = ',nratio
    6056              :  !rhor(:,:)=nratio*rhor(:,:)
    6057              : 
    6058          454 :  write(msg,'(a,f9.6)')' average of density, n = ',rhoav
    6059         1362 :  call wrtout([std_out, ab_out], msg)
    6060          454 :  write(msg,'(a,f9.4)')' r_s = ',rs
    6061         1362 :  call wrtout([std_out, ab_out], msg)
    6062          454 :  omegaplasma=SQRT(four_pi*rhoav)
    6063          454 :  write(msg,'(a,f9.4,2a)')' omega_plasma = ',omegaplasma*Ha_eV,' [eV]',ch10
    6064         1362 :  call wrtout([std_out, ab_out], msg)
    6065              : 
    6066          454 : end subroutine test_charge
    6067              : !!***
    6068              : 
    6069              : !!****f* m_wfd/wfdgw_pawrhoij
    6070              : !! NAME
    6071              : !! wfdgw_pawrhoij
    6072              : !!
    6073              : !! FUNCTION
    6074              : !! Calculate the PAW quantities rhoij (augmentation occupancies)
    6075              : !! Remember:for each atom, rho_ij=Sum_{n,k} {occ(n,k)*<Cnk|p_i><p_j|Cnk>}
    6076              : !!
    6077              : !! INPUTS
    6078              : !!  atindx1(natom)=index table for atoms, inverse of atindx
    6079              : !!  cprj(natom,nspinor*mband*mkmem*nsppol)= wave functions projected with non-local projectors:
    6080              : !!                                   cprj_nk(i)=<p_i|Cnk> where p_i is a non-local projector.
    6081              : !!  istwfk(nkpt)=parameter that describes the storage of wfs
    6082              : !!  kptopt=option for the generation of k points
    6083              : !!  mband=maximum number of bands
    6084              : !!  natom=number of atoms in cell
    6085              : !!  nkpt=number of k points
    6086              : !!  nspinor=number of spinorial components of the wavefunctions
    6087              : !!  nsppol=1 for unpolarized, 2 for spin-polarized
    6088              : !!  occ(mband*nkpt*nsppol)=occupation number for each band for each k
    6089              : !!  pawprtvol=control print volume and debugging output for PAW
    6090              : !!
    6091              : !! SIDE EFFECTS
    6092              : !!  pawrhoij(natom) <type(pawrhoij_type)>= paw rhoij occupancies and related data
    6093              : !!  On input: arrays dimensions
    6094              : !!  On output:
    6095              : !!    pawrhoij(:)%rhoij_(lmn2_size,nspden)=
    6096              : !!          Sum_{n,k} {occ(n,k)*conjugate[cprj_nk(ii)].cprj_nk(jj)} (non symetrized)
    6097              : !!
    6098              : !! SOURCE
    6099              : 
    6100            0 : subroutine wfdgw_pawrhoij(Wfd,Cryst,Bst,kptopt,pawrhoij,pawprtvol)
    6101              : 
    6102              : !Arguments ---------------------------------------------
    6103              : !scalars
    6104              :  integer,intent(in) :: kptopt,pawprtvol
    6105              :  type(crystal_t),intent(in) :: Cryst
    6106              :  class(wfdgw_t),intent(inout) :: Wfd
    6107              :  type(ebands_t),intent(in) :: Bst
    6108              : !arrays
    6109              :  type(pawrhoij_type),intent(inout) :: pawrhoij(Wfd%natom)
    6110              : 
    6111              : !Local variables ---------------------------------------
    6112              : !scalars
    6113              :  integer :: cplex,cplex_rhoij,qphase,iatom,band,ik_ibz
    6114              :  integer :: spin,natinc,nband_k,option,lmn2_size,nspden
    6115              :  logical :: use_timerev,use_zeromag
    6116              :  real(dp) :: occup,wtk_k
    6117              :  character(len=500) :: msg
    6118              : !arrays
    6119              :  !real(dp) :: tsec(2)
    6120              :  character(len=8),parameter :: dspin(6)=(/"up      ","down    ","dens (n)","magn (x)","magn (y)","magn (z)"/)
    6121              :  type(pawcprj_type),allocatable :: cwaveprj(:,:)
    6122            0 :  integer :: bks_distrb(Wfd%mband,Wfd%nkibz,Wfd%nsppol)
    6123            0 :  integer :: got(Wfd%nproc)
    6124            0 :  logical :: bks_mask(Wfd%mband,Wfd%nkibz,Wfd%nsppol)
    6125              : !************************************************************************
    6126              : 
    6127              :  ! Allocate temporary cwaveprj storage (sorted by atom type)
    6128            0 :  ABI_MALLOC(cwaveprj,(Wfd%natom,Wfd%nspinor))
    6129            0 :  call pawcprj_alloc(cwaveprj,0,Wfd%nlmn_sort)
    6130              : 
    6131              :  ! Initialize output quantities if not already done.
    6132            0 :  do iatom=1,Wfd%natom
    6133            0 :    if (pawrhoij(iatom)%use_rhoij_==0) then
    6134            0 :      cplex_rhoij= pawrhoij(iatom)%cplex_rhoij
    6135            0 :      qphase     = pawrhoij(iatom)%qphase
    6136            0 :      lmn2_size  = pawrhoij(iatom)%lmn2_size
    6137            0 :      nspden     = pawrhoij(iatom)%nspden
    6138            0 :      ABI_MALLOC(pawrhoij(iatom)%rhoij_,(cplex_rhoij*qphase*lmn2_size,nspden))
    6139            0 :      pawrhoij(iatom)%use_rhoij_=1
    6140              :    end if
    6141            0 :    pawrhoij(iatom)%rhoij_=zero
    6142              :  end do
    6143              : 
    6144            0 :  option=1
    6145            0 :  use_timerev=(kptopt>0.and.kptopt<3)
    6146            0 :  use_zeromag=.false. ; if (Wfd%natom>0) use_zeromag=(pawrhoij(1)%nspden==4.and.Wfd%nspden==1)
    6147              : 
    6148              :  ! Distribute (b,k,s).
    6149            0 :  where (ABS(Bst%occ)>tol8)
    6150              :    bks_mask=.TRUE.
    6151              :  else where
    6152              :    bks_mask=.FALSE.
    6153              :  end where
    6154            0 :  got = 0
    6155              : 
    6156            0 :  call wfd%bks_distrb(bks_distrb,got,bks_mask)
    6157              : 
    6158            0 :  do spin=1,Wfd%nsppol
    6159            0 :    do ik_ibz=1,Wfd%nkibz
    6160              : 
    6161            0 :      nband_k=Wfd%nband(ik_ibz,spin)
    6162            0 :      wtk_k=Bst%wtk(ik_ibz)
    6163              : 
    6164            0 :      cplex=2; if (Wfd%istwfk(ik_ibz)>1) cplex=1
    6165              : 
    6166            0 :      do band=1,nband_k
    6167              : 
    6168            0 :        if (bks_distrb(band,ik_ibz,spin) == Wfd%my_rank) then
    6169              :          !locc_test = (abs(Bst%occ(band,ik_ibz,spin))>tol8)
    6170            0 :          occup = Bst%occ(band,ik_ibz,spin)
    6171              : 
    6172              :           ! Extract cprj for current band cwaveprj are sorted by atom type.
    6173            0 :           call wfd%get_cprj(band,ik_ibz,spin,Cryst,cwaveprj,sorted=.TRUE.)
    6174              : 
    6175              :           ! Accumulate contribution from (occupied) current band
    6176              :           !if (locc_test) then
    6177              :            call pawaccrhoij(Cryst%atindx,cplex,cwaveprj,cwaveprj ,0,spin,Wfd%natom,Wfd%natom,&
    6178            0 :                             Wfd%nspinor,occup,option,pawrhoij,use_timerev,use_zeromag,wtk_k)
    6179              :           !end if
    6180              :        end if
    6181              :      end do !band
    6182              : 
    6183              :    end do !ik_ibz
    6184              :  end do !spin
    6185              : 
    6186              :  ! Free temporary cwaveprj storage.
    6187            0 :  call pawcprj_free(cwaveprj)
    6188            0 :  ABI_FREE(cwaveprj)
    6189              : 
    6190              :  !==========================================
    6191              :  ! MPI: need to exchange arrays between procs
    6192              :  ! TODO it should be tested.
    6193            0 :  call pawrhoij_mpisum_unpacked(pawrhoij,Wfd%comm)
    6194              : 
    6195              :  ! Print info.
    6196            0 :  if (abs(pawprtvol)>=1) then
    6197            0 :    natinc=1; if(Wfd%natom>1.and.pawprtvol>=0) natinc=Wfd%natom-1
    6198            0 :    write(msg, '(7a)') ch10," PAW TEST:",ch10,' ========= Values of RHOIJ in wfdgw_pawrhoij =========',ch10
    6199            0 :    call wrtout(std_out, msg)
    6200            0 :    do iatom=1,Cryst%natom,natinc
    6201              :      call pawrhoij_print_rhoij(pawrhoij(iatom)%rhoij_,pawrhoij(iatom)%cplex_rhoij,&
    6202            0 :                   pawrhoij(iatom)%qphase,iatom,Cryst%natom, unit=std_out,opt_prtvol=pawprtvol)
    6203              :    end do
    6204              :  end if
    6205              : 
    6206            0 : end subroutine wfdgw_pawrhoij
    6207              : !!***
    6208              : 
    6209            4 : subroutine u0_cache_init(u0c, use_cache, ngfft)
    6210              : 
    6211              : !Arguments ------------------------------------
    6212              :  class(u0_cache_t),intent(out) :: u0c
    6213              :  logical,intent(in) :: use_cache
    6214              :  integer,intent(in) :: ngfft(18)
    6215              : !************************************************************************
    6216              : 
    6217            4 :  u0c%use_cache = use_cache
    6218           76 :  u0c%ngfft = ngfft
    6219              : 
    6220            4 : end subroutine u0_cache_init
    6221              : 
    6222          127 : subroutine u0_cache_store_kpt(u0c, kpt, istwf_k, npw_k, nspinor, nband_k, kg_k, cg_k)
    6223              : 
    6224              : !Arguments ------------------------------------
    6225              :  class(u0_cache_t),intent(inout) :: u0c
    6226              :  real(dp),intent(in) :: kpt(3)
    6227              :  integer,intent(in) :: istwf_k, npw_k, nspinor, nband_k, kg_k(3,npw_k)
    6228              :  real(dp),intent(in) :: cg_k(2, npw_k*nspinor, nband_k)
    6229              : !************************************************************************
    6230              : 
    6231          127 :  if (.not. u0c%use_cache) return
    6232              : 
    6233           84 :  call u0c%free()
    6234           84 :  u0c%prev_npw_k = npw_k
    6235           84 :  u0c%prev_nband_k = nband_k
    6236           84 :  u0c%prev_istwf_k = istwf_k
    6237          336 :  u0c%prev_kpt = kpt
    6238              : 
    6239           84 :  call alloc_copy(kg_k, u0c%prev_kg_k)
    6240           84 :  call alloc_copy(cg_k, u0c%prev_cg_k)
    6241              : 
    6242              : end subroutine u0_cache_store_kpt
    6243              : 
    6244           82 : subroutine u0_cache_get_kpt(u0c, new_kpt, new_istwf_k, new_npw_k, nspinor, new_nband_k, new_kg_k, new_cg_k)
    6245              : 
    6246              : !Arguments ------------------------------------
    6247              :  class(u0_cache_t),intent(inout) :: u0c
    6248              :  real(dp),intent(in) :: new_kpt(3)
    6249              :  integer,intent(in) :: new_istwf_k, new_npw_k, nspinor, new_nband_k, new_kg_k(3,new_npw_k)
    6250              :  real(dp),intent(out) :: new_cg_k(2, new_npw_k*nspinor, new_nband_k)
    6251              : 
    6252              : !Local variables ------------------------------
    6253              :  integer :: mg1, mg2, mg3, work_ngfft(18)
    6254           82 :  real(dp),allocatable :: work(:,:,:,:)
    6255              : !************************************************************************
    6256              : 
    6257           82 :  if (.not. u0c%use_cache) return
    6258              : 
    6259           82 :  ABI_CHECK_IEQ(new_nband_k,  u0c%prev_nband_k, "This case is not yet implemented")
    6260              : 
    6261           96 :  if (all(abs(new_kpt - u0c%prev_kpt) < tol16) .and. new_npw_k == u0c%prev_npw_k) then
    6262            0 :    new_cg_k = u0c%prev_cg_k
    6263              :    return
    6264              :  end if
    6265              : 
    6266       210746 :  mg1 = max(maxval(abs(u0c%prev_kg_k(1,:))), maxval(abs(new_kg_k(1,:))))
    6267       210746 :  mg2 = max(maxval(abs(u0c%prev_kg_k(2,:))), maxval(abs(new_kg_k(2,:))))
    6268       210746 :  mg3 = max(maxval(abs(u0c%prev_kg_k(3,:))), maxval(abs(new_kg_k(3,:))))
    6269              : 
    6270           82 :  mg1 = 2*mg1 + 1
    6271           82 :  mg2 = 2*mg2 + 1
    6272           82 :  mg3 = 2*mg3 + 1
    6273              : 
    6274          328 :  call ngfft_seq(work_ngfft, [mg1, mg2, mg3])
    6275          410 :  ABI_MALLOC(work, (2, work_ngfft(4),work_ngfft(5),work_ngfft(6)))
    6276              : 
    6277              :  call cgtk_change_gsphere(nspinor*new_nband_k, u0c%prev_npw_k, u0c%prev_istwf_k, u0c%prev_kg_k, u0c%prev_cg_k, &
    6278           82 :                           new_npw_k, new_istwf_k, new_kg_k, new_cg_k, work_ngfft, work)
    6279              : 
    6280           82 :  ABI_FREE(work)
    6281              : 
    6282              : end subroutine u0_cache_get_kpt
    6283              : 
    6284           88 : subroutine u0_cache_free(u0c)
    6285              : 
    6286              : !Arguments ------------------------------------
    6287              :  class(u0_cache_t),intent(inout) :: u0c
    6288              : !************************************************************************
    6289           88 :  ABI_SFREE(u0c%prev_kg_k)
    6290           88 :  ABI_SFREE(u0c%prev_cg_k)
    6291           88 : end subroutine u0_cache_free
    6292              : 
    6293          579 : subroutine u1_cache_store(u1c, qpt, npw_kq, nspinor, natom3, bstart_ks, nbcalc_ks, kg_kq, cg1s_kq)
    6294              : 
    6295              : !Arguments ------------------------------------
    6296              :  class(u1_cache_t),intent(inout) :: u1c
    6297              :  real(dp),intent(in) :: qpt(3)
    6298              :  integer,intent(in) :: npw_kq, nspinor, natom3, bstart_ks, nbcalc_ks, kg_kq(3,npw_kq)
    6299              :  real(dp),intent(in) :: cg1s_kq(2, npw_kq*nspinor, natom3, nbcalc_ks)
    6300              : !************************************************************************
    6301              : 
    6302          579 :  call u1c%free()
    6303         2316 :  u1c%prev_qpt = qpt
    6304          579 :  u1c%prev_npw_kq = npw_kq
    6305          579 :  u1c%prev_bstart_ks = bstart_ks
    6306          579 :  u1c%prev_nbcalc_ks = nbcalc_ks
    6307          579 :  call alloc_copy(kg_kq, u1c%prev_kg_kq)
    6308          579 :  call alloc_copy(cg1s_kq, u1c%prev_cg1s_kq)
    6309          579 : end subroutine u1_cache_store
    6310              : 
    6311        14202 : integer function u1_cache_find_band(u1c, band) result(u1c_band)
    6312              : 
    6313              : !Arguments ------------------------------------
    6314              :  class(u1_cache_t),intent(inout) :: u1c
    6315              :  integer,intent(in) :: band
    6316              : !************************************************************************
    6317              : 
    6318              :  ! Make sure we have the proper global band index in the cache as bstart_ks depends on the
    6319              :  ! k-point in Sigma_{nk}. If not, fill cg1s_kq with zeros and return.
    6320        14202 :  u1c_band = -1
    6321        14202 :  if (u1c%prev_nbcalc_ks == -1) return
    6322        13704 :  u1c_band = band - u1c%prev_bstart_ks + 1
    6323        13704 :  if (.not. (u1c_band >= 1 .and. u1c_band <= u1c%prev_nbcalc_ks)) u1c_band = -1
    6324              :  if (u1c_band == -1) then
    6325            6 :    u1c%miss = u1c%miss + 1
    6326              :  else
    6327        13698 :    u1c%hits = u1c%hits + 1
    6328              :  end if
    6329              : end function u1_cache_find_band
    6330              : 
    6331          637 : subroutine u1_cache_free(u1c)
    6332              : 
    6333              : !Arguments ------------------------------------
    6334              :  class(u1_cache_t),intent(inout) :: u1c
    6335              : !************************************************************************
    6336          637 :  ABI_SFREE(u1c%prev_kg_kq)
    6337          637 :  ABI_SFREE(u1c%prev_cg1s_kq)
    6338          637 : end subroutine u1_cache_free
    6339              : 
    6340        16299 : end module m_wfd
    6341              : !!***
        

Generated by: LCOV version 2.3-1