LCOV - code coverage report
Current view: top level - src/72_response - m_dfpt_nstwf.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.4 % 1169 1103
Test Date: 2026-09-19 17:42:43 Functions: 100.0 % 3 3

            Line data    Source code
       1              : !!****m* ABINIT/m_dfpt_nstwf
       2              : !! NAME
       3              : !!  m_dfpt_nstwf
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !! COPYRIGHT
       8              : !!  Copyright (C) 2008-2026 ABINIT group ()
       9              : !!  This file is distributed under the terms of the
      10              : !!  GNU General Public License, see ~abinit/COPYING
      11              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      12              : !!
      13              : !! SOURCE
      14              : 
      15              : #if defined HAVE_CONFIG_H
      16              : #include "config.h"
      17              : #endif
      18              : 
      19              : #include "abi_common.h"
      20              : 
      21              : ! nvtx related macro definition
      22              : #include "nvtx_macros.h"
      23              : 
      24              : module m_dfpt_nstwf
      25              : 
      26              :  use defs_basis
      27              :  use m_xmpi
      28              :  use m_errors
      29              :  use m_abicore
      30              :  use m_wfk
      31              :  use m_hamiltonian
      32              :  use m_cgtools
      33              :  use m_nctk
      34              :  use m_dtset
      35              :  use m_dtfil
      36              :  use m_gputk
      37              :  use m_abi_linalg
      38              : 
      39              :  use defs_datatypes, only : pseudopotential_type
      40              :  use defs_abitypes, only : MPI_type
      41              :  use m_time,     only : timab
      42              :  use m_io_tools, only : file_exists
      43              :  use m_fourier_interpol, only : transgrid
      44              :  use m_gemm_nonlop_projectors, only : set_gemm_nonlop_ikpt, gemm_nonlop_use_gemm
      45              :  use m_geometry, only : stresssym
      46              :  use m_dynmat,   only : dfpt_sygra
      47              :  use m_mpinfo,   only : destroy_mpi_enreg, initmpi_seq, proc_distrb_cycle, proc_distrb_band, proc_distrb_nband
      48              :  use m_hdr,      only : hdr_skip
      49              :  use m_occ,      only : occeig
      50              :  use m_pawang,   only : pawang_type
      51              :  use m_pawrad,   only : pawrad_type
      52              :  use m_pawtab,   only : pawtab_type
      53              :  use m_paw_an,   only : paw_an_type, paw_an_reset_flags
      54              :  use m_paw_ij,   only : paw_ij_type, paw_ij_init, paw_ij_free, paw_ij_nullify, paw_ij_reset_flags
      55              :  use m_pawfgrtab,only : pawfgrtab_type
      56              :  use m_pawrhoij, only : pawrhoij_type, pawrhoij_alloc, pawrhoij_free, pawrhoij_copy, pawrhoij_nullify, &
      57              :                         pawrhoij_init_unpacked, pawrhoij_mpisum_unpacked, pawrhoij_inquire_dim
      58              :  use m_pawcprj,  only : pawcprj_type, pawcprj_alloc, pawcprj_free, pawcprj_get, pawcprj_copy, pawcprj_output
      59              :  use m_pawdij,   only : pawdijfr
      60              :  use m_pawfgr,   only : pawfgr_type
      61              :  use m_paw_mkrho,only : pawmkrho
      62              :  use m_paw_nhat, only : pawnhatfr
      63              :  use m_paw_dfpt, only : pawdfptenergy
      64              :  use m_kg,       only : mkkin, kpgstr, mkkpg
      65              :  use m_fft,      only : fftpac
      66              :  use m_spacepar, only : hartrestr, symrhg
      67              :  use m_initylmg, only : initylmg
      68              :  use m_mkffnl,   only : mkffnl
      69              :  use m_getgh1c,  only : getgh1c, getdc1
      70              :  use m_dfpt_mkrho, only : dfpt_accrho
      71              :  use m_atm2fft,    only : dfpt_atm2fft
      72              :  use m_mkcore,     only : dfpt_mkcore
      73              :  use m_dfpt_mkvxc,    only : dfpt_mkvxc, dfpt_mkvxc_noncoll
      74              :  use m_dfpt_mkvxcstr, only : dfpt_mkvxcstr
      75              :  use m_mklocl,     only : dfpt_vlocal, vlocalstr
      76              :  use m_cgprj,      only : getcprj
      77              : 
      78              :  use, intrinsic :: iso_c_binding, only: c_size_t, c_loc
      79              : 
      80              : #if defined(HAVE_GPU_MARKERS)
      81              :  use m_nvtx_data
      82              : #endif
      83              : 
      84              :  implicit none
      85              : 
      86              :  private
      87              : !!***
      88              : 
      89              :  public :: dfpt_nstpaw
      90              :  public :: dfpt_nstwf
      91              :  public :: gaugetransfo
      92              : !!***
      93              : 
      94              : contains
      95              : !!***
      96              : 
      97              : !!****f* ABINIT/dfpt_nstpaw
      98              : !! NAME
      99              : !! dfpt_nstpaw
     100              : !!
     101              : !! FUNCTION
     102              : !! Initially designed for PAW approach, but works also for NCPP.
     103              : !! This routine compute the non-stationary expression for the
     104              : !! second derivative of the total energy, for a whole row of
     105              : !! mixed derivatives (including diagonal terms contributing
     106              : !! to non-stationary 2nd-order total energy).
     107              : !! Compared with NC-pseudopotentials, PAW contributions include:
     108              : !!  - changes of the overlap between 0-order wave-functions,
     109              : !!  - on-site contributions.
     110              : !!
     111              : !! COPYRIGHT
     112              : !! Copyright (C) 2010-2026 ABINIT group (MT, AM)
     113              : !! This file is distributed under the terms of the
     114              : !! GNU General Public License, see ~abinit/COPYING
     115              : !! or http://www.gnu.org/copyleft/gpl.txt .
     116              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
     117              : !!
     118              : !! INPUTS
     119              : !!  cg (2,mpw *nspinor*mband_mem*mkmem*nsppol)=planewave coefficients of wavefunctions at k
     120              : !!  cgq(2,mpw1*nspinor*mband_mem*mkqmem*nsppol)=pw coefficients of GS wavefunctions at k+q.
     121              : !!  cg1(2,mpw1*nspinor*mband_mem*mk1mem*nsppol)=pw coefficients of RF wavefunctions at k,q.
     122              : !!  cplex=if 1, real space 1-order functions on FFT grid are REAL, if 2, COMPLEX
     123              : !!  cprj(natom,nspinor*mband_mem*mkmem*nsppol*usecprj)= wave functions at k projected with non-local projectors
     124              : !!  cprjq(natom,nspinor*mband_mem*mkqmem*nsppol*usecprj)= wave functions at k+q projected with non-local projectors
     125              : !!  docckqde(mband*nkpt_rbz*nsppol)=derivative of occkq wrt the energy
     126              : !!  doccde_rbz(mband*nkpt_rbz*nsppol)=derivative of occ_rbz wrt the energy
     127              : !!  dtfil <type(datafiles_type)>=variables related to files
     128              : !!  dtset <type(dataset_type)>=all input variables for this dataset
     129              : !!  eigenq(mband*nkpt_rbz*nsppol)=GS eigenvalues at k+q (hartree)
     130              : !!  eigen0(mband*nkpt_rbz*nsppol)=GS eigenvalues at k (hartree)
     131              : !!  eigen1(2*mband*mband*nkpt_rbz*nsppol)=1st-order eigenvalues at k,q (hartree)
     132              : !!  gmet(3,3)=reciprocal space metric tensor in bohr**-2.
     133              : !!  gprimd(3,3)=dimensional reciprocal space primitive translations
     134              : !!  gsqcut=cutoff on (k+G)^2 (bohr^-2)
     135              : !!  idir=direction of the perturbation
     136              : !!  indkpt1(nkpt_rbz)=non-symmetrized indices of the k-points
     137              : !!  indsy1(4,nsym1,natom)=indirect indexing array for atom labels
     138              : !!  ipert=type of the perturbation
     139              : !!  irrzon1(nfft**(1-1/nsym1),2,(nspden/nsppol)-3*(nspden/4))=irreducible zone data for RF symmetries
     140              : !!  istwfk_rbz(nkpt_rbz)=input option parameter that describes the storage of wfs
     141              : !!  kg(3,mpw*mkmem)=reduced planewave coordinates.
     142              : !!  kg1(3,mpw1*mk1mem)=reduced planewave coordinates at k+q, with RF k points
     143              : !!  kpt_rbz(3,nkpt_rbz)=reduced coordinates of k points in the reduced BZ
     144              : !!  kxc(nfftf,nkxc)=exchange and correlation kernel
     145              : !!  mgfftf=maximum size of 1D FFTs for the "fine" grid (see NOTES in respfn.F90)
     146              : !!  mkmem =number of k points treated by this node.
     147              : !!  mkqmem =number of k+q points treated by this node (GS data).
     148              : !!  mk1mem =number of k points treated by this node (RF data)
     149              : !!  mpert =maximum number of ipert
     150              : !!  mpi_enreg=information about MPI parallelization
     151              : !!  mpw=maximum dimensioned size of npw or wfs at k
     152              : !!  mpw1=maximum dimensioned size of npw for wfs at k+q (also for 1-order wfs).
     153              : !!  nattyp(ntypat)= # atoms of each type.
     154              : !!  nband_rbz(nkpt_rbz*nsppol)=number of bands at each RF k point for each spin
     155              : !!  mband_mem=number of bands per processor
     156              : !!  ncpgr=number of gradients stored in cprj array (cprj=<p_i|Cnk>)
     157              : !!  nfftf=(effective) number of FFT grid points (for this proc) for the "fine" grid
     158              : !!  ngfftf(1:18)=integer array with FFT box dimensions and other for the "fine" grid
     159              : !!  nhat(nfft,nspden*nhatdim)= -PAW only- compensation density
     160              : !!  nhat1(cplex*nfftf,nspden*usepaw)=1st-order compensation charge density (PAW)
     161              : !!  nkpt_rbz=number of k points in the reduced BZ for this perturbation
     162              : !!  nkxc=second dimension of the kxc array
     163              : !!  npwarr(nkpt_rbz)=number of planewaves in basis at this GS k point
     164              : !!  npwar1(nkpt_rbz)=number of planewaves in basis at this RF k+q point
     165              : !!  nspden=number of spin-density components
     166              : !!  nspinor=number of spinorial components of the wavefunctions
     167              : !!  nsppol=1 for unpolarized, 2 for spin-polarized
     168              : !!  nsym1=number of symmetry elements in space group consistent with i perturbation
     169              : !!  n3xccc=dimension of xccc3d1 ; 0 if no XC core correction is used otherwise, cplex*nfftf
     170              : !!  occkq(mband*nkpt_rbz*nsppol)=occupation number for each band at each k+q point of the reduced BZ
     171              : !!  occ_rbz(mband*nkpt_rbz*nsppol)=occupation number for each band and k in the reduced BZ
     172              : !!  paw_an(natom) <type(paw_an_type)>=paw arrays given on angular mesh for the GS
     173              : !!  paw_an1(natom) <type(paw_an_type)>=1st-order paw arrays given on angular mesh for the perturbation (j1)
     174              : !!  paw_ij(natom*usepaw) <type(paw_ij_type)>=paw arrays given on (i,j) channels for the GS
     175              : !!  paw_ij1(natom) <type(paw_ij_type)>=1st-order paw arrays given on (i,j) channels
     176              : !!  pawang <type(pawang_type)>=paw angular mesh and related data
     177              : !!  pawang1 <type(pawang_type)>=pawang datastructure containing only the symmetries preserving the perturbation
     178              : !!  pawfgr <type(pawfgr_type)>=fine grid parameters and related data
     179              : !!  pawfgrtab(natom*usepaw) <type(pawfgrtab_type)>=atomic data given on fine rectangular grid for the GS
     180              : !!  pawrad(ntypat*usepaw) <type(pawrad_type)>=paw radial mesh and related data
     181              : !!  pawrhoij(natom) <type(pawrhoij_type)>= paw rhoij occupancies and related data for the GS
     182              : !!  pawrhoij1(natom) <type(pawrhoij_type)>= 1st-order paw rhoij occupancies and related data
     183              : !!  pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
     184              : !!  phnons1(2,nfft**(1-1/nsym1),(nspden/nsppol)-3*(nspden/4))=nonsymmorphic transl. phases, for RF symmetries
     185              : !!  ph1d(2,3*(2*mgfft+1)*natom)=one-dimensional structure factor information
     186              : !!  ph1df(2,3*(2*mgfftf+1)*natom)=one-dimensional structure factor information for the "fine" grid
     187              : !!  psps <type(pseudopotential_type)>=variables related to pseudopotentials
     188              : !!  rhor(nfft,nspden)=array for GS electron density in electrons/bohr**3.
     189              : !!  rhor1(cplex*nfftf,nspden)=RF electron density in electrons/bohr**3.
     190              : !!  rmet(3,3)=real space metric (bohr**2)
     191              : !!  rprimd(3,3)=dimensional primitive translations in real space (bohr)
     192              : !!  symaf1(nsym1)=anti(ferromagnetic) part of symmetry operations
     193              : !!  symrc1(3,3,nsym1)=symmetry operations in reciprocal space
     194              : !!  symrl1(3,3,nsym1)=symmetry operations in real space in terms
     195              : !!  ucvol=unit cell volume in bohr**3.
     196              : !!  usecprj= 1 if cprj, cprjq arrays are stored in memory
     197              : !!  usepaw= 0 for non paw calculation; =1 for paw calculation
     198              : !!  usevxctau=1 if if XC functional depends on kinetic energy density
     199              : !!  usexcnhat= -PAW only- flag controlling use of compensation density in Vxc
     200              : !!  useylmgr1= 1 if ylmgr1 array is allocated
     201              : !!  vectornd(with_vectornd*nfftf,3)=nuclear dipole moment vector potential
     202              : !!  vhartr1(cplex*nfft)=1-order Hartree potential
     203              : !!  vpsp1(cplex*nfftf)=first-order derivative of the ionic potential
     204              : !!  vtrial(nfftf,nspden)=GS potential (Hartree).
     205              : !!  vtrial1(cplex*nfftf,nspden)= RF 1st-order potential (Hartree).
     206              : !!  vxc(nfftf,nspden)=XC GS potential
     207              : !!  vxctau(nfftf,nspden,4*usevxctau)=derivative of e_xc with respect to kinetic energy density, for mGGA
     208              : !!  with_vectornd = 1 if vectornd allocated
     209              : !!  wtk_rbz(nkpt_rbz)=weight assigned to each k point in the reduced BZ
     210              : !!  xccc3d1(cplex*n3xccc)=3D change in core charge density, see n3xccc
     211              : !!  xred(3,natom)=reduced dimensionless atomic coordinates
     212              : !!  ylm(mpw*mkmem,mpsang*mpsang*useylm)= real spherical harmonics for each G and k point
     213              : !!  ylm1(mpw1*mk1mem,mpsang*mpsang*useylm)= real spherical harmonics for each G and k+q point
     214              : !!  ylmgr1(mpw1*mk1mem,3,mpsang*mpsang*useylm)= gradients of real spherical harmonics at k+q
     215              : !!
     216              : !! OUTPUT
     217              : !!  blkflg(3,mpert,3,mpert)=flags for each element of the 2DTE (=1 if computed)
     218              : !!  d2lo(2,3,mpert,3,mpert)=local contributions to the 2DTEs
     219              : !!  d2nl(2,3,mpert,3,mpert)=non-local contributions to the 2DTEs
     220              : !!  d2ovl(2,3,mpert,3,mpert*usepaw)=overlap contributions to the 2DTEs (PAW only)
     221              : !!  eovl1=1st-order change of wave-functions overlap, part of 2nd-order energy
     222              : !!        PAW only - Eq(79) and Eq(80) of PRB 78, 035105 (2008) [[cite:Audouze2008]]
     223              : !!
     224              : !! NOTES
     225              : !!   We perform here the computation of
     226              : !!     delta_u^(j1)=-1/2 Sum_{j}[<u0_k+q_j|S^(j1)|u0_k_i>.|u0_k+q_j>]
     227              : !!     see PRB 78, 035105 (2008), Eq. (42) [[cite:Audouze2008]]
     228              : !!
     229              : !! SOURCE
     230              : 
     231         1041 : subroutine dfpt_nstpaw(blkflg,cg,cgq,cg1,cplex,cprj,cprjq,docckqde,doccde_rbz,dtfil,dtset,d2lo,d2nl,d2ovl,&
     232          694 : &                  eigenq,eigen0,eigen1,eovl1,gmet,gprimd,gsqcut,idir,indkpt1,indsy1,ipert,irrzon1,istwfk_rbz,&
     233          347 : &                  kg,kg1,kpt_rbz,kxc,mgfftf,mkmem,mkqmem,mk1mem,&
     234         1041 : &                  mpert,mpi_enreg,mpw,mpw1,nattyp,nband_rbz,mband_mem_rbz,ncpgr,nfftf,ngfftf,nhat,nhat1,&
     235          694 : &                  nkpt_rbz,nkxc,npwarr,npwar1,nspden,nspinor,nsppol,nsym1,n3xccc,occkq,occ_rbz,&
     236          347 : &                  paw_an,paw_an1,paw_ij,paw_ij1,pawang,pawang1,pawfgr,pawfgrtab,pawrad,pawrhoij,&
     237          347 : &                  pawrhoij1,pawtab,phnons1,ph1d,ph1df,psps,rhog,rhor,rhor1,rmet,rprimd,symaf1,symrc1,symrl1,tnons1,&
     238          347 : &                  ucvol,usecprj,usepaw,usevxctau,usexcnhat,useylmgr1,vectornd,vhartr1,vpsp1,vtrial,vtrial1,vxc,vxctau,&
     239          347 : &                  with_vectornd,wtk_rbz,xccc3d1,xred,ylm,ylm1,ylmgr1)
     240              : 
     241              : !Arguments -------------------------------
     242              : !scalars
     243              :  integer,intent(in) :: cplex,idir,ipert,mgfftf,mkmem,mkqmem,mk1mem,mpert,mpw,mpw1
     244              :  integer,intent(in) :: ncpgr,nfftf,nkpt_rbz,nkxc,nspden,nspinor,nsppol,nsym1
     245              :  integer,intent(in) :: n3xccc,usecprj,usepaw,usevxctau,usexcnhat,useylmgr1
     246              :  integer,intent(in) :: mband_mem_rbz,with_vectornd
     247              :  real(dp),intent(in) :: gsqcut,ucvol
     248              :  real(dp),intent(out) :: eovl1
     249              :  type(datafiles_type),intent(in) :: dtfil
     250              :  type(dataset_type),intent(in) :: dtset
     251              :  type(MPI_type),intent(in) :: mpi_enreg
     252              :  type(pawang_type),intent(in) :: pawang,pawang1
     253              :  type(pawfgr_type),intent(in) :: pawfgr
     254              :  type(pseudopotential_type),intent(in) :: psps
     255              : !arrays
     256              :  integer,intent(in) :: nattyp(dtset%ntypat),nband_rbz(nkpt_rbz*nsppol)
     257              :  integer,intent(in) :: indkpt1(nkpt_rbz),indsy1(4,nsym1,dtset%natom)
     258              :  integer,intent(in) :: irrzon1(dtset%nfft**(1-1/nsym1),2,(nspden/nsppol)-3*(nspden/4))
     259              :  integer,intent(in) :: istwfk_rbz(nkpt_rbz),kg(3,mpw*mkmem),kg1(3,mpw1*mk1mem)
     260              :  integer,intent(in) :: ngfftf(18),npwarr(nkpt_rbz),npwar1(nkpt_rbz)
     261              :  integer,intent(in) :: symaf1(nsym1),symrc1(3,3,nsym1),symrl1(3,3,nsym1)
     262              :  integer,intent(inout) :: blkflg(3,mpert,3,mpert)
     263              :  real(dp),intent(in),target :: cg(2,mpw*nspinor*mband_mem_rbz*mkmem*nsppol)
     264              :  real(dp),intent(in),target :: cgq(2,mpw1*nspinor*mband_mem_rbz*mkqmem*nsppol)
     265              :  real(dp),intent(in),target :: cg1(2,mpw1*nspinor*mband_mem_rbz*mk1mem*nsppol)
     266              :  real(dp),intent(in) :: docckqde(dtset%mband*nkpt_rbz*nsppol)
     267              :  real(dp),intent(in) :: doccde_rbz(dtset%mband*nkpt_rbz*nsppol)
     268              :  real(dp),intent(in) :: eigenq(dtset%mband*nkpt_rbz*nsppol),eigen0(dtset%mband*nkpt_rbz*nsppol)
     269              :  real(dp),intent(in) :: eigen1(2*dtset%mband*dtset%mband*nkpt_rbz*nsppol)
     270              :  real(dp),intent(in) :: gmet(3,3),gprimd(3,3),kpt_rbz(3,nkpt_rbz)
     271              :  real(dp),intent(in) :: kxc(nfftf,nkxc),nhat(nfftf,nspden),nhat1(cplex*nfftf,nspden*usepaw)
     272              :  real(dp),intent(in) :: occkq(dtset%mband*nkpt_rbz*dtset%nsppol)
     273              :  real(dp),intent(in) :: occ_rbz(dtset%mband*nkpt_rbz*nsppol)
     274              :  real(dp),intent(in) :: phnons1(2,dtset%nfft**(1-1/nsym1),(nspden/nsppol)-3*(nspden/4))
     275              :  real(dp),intent(in) :: ph1d(2,3*(2*dtset%mgfft+1)*dtset%natom)
     276              :  real(dp),intent(in) :: ph1df(2,3*(2*mgfftf+1)*dtset%natom),rhog(2,nfftf)
     277              :  real(dp),intent(in) :: rhor(cplex*nfftf,nspden),rhor1(cplex*nfftf,nspden),rmet(3,3),rprimd(3,3)
     278              :  real(dp),intent(in) :: tnons1(3,nsym1),vhartr1(cplex*nfftf),vtrial1(cplex*nfftf,nspden),vxc(nfftf,nspden)
     279              :  real(dp),intent(in) :: wtk_rbz(nkpt_rbz),xred(3,dtset%natom)
     280              :  real(dp),intent(in) :: ylm(mpw*mkmem,psps%mpsang*psps%mpsang*psps%useylm)
     281              :  real(dp),intent(in) :: ylm1(mpw1*mk1mem,psps%mpsang*psps%mpsang*psps%useylm)
     282              :  real(dp),intent(in) :: ylmgr1(mpw1*mk1mem,3,psps%mpsang*psps%mpsang*psps%useylm*useylmgr1)
     283              :  real(dp),target,intent(in) :: vpsp1(cplex*nfftf),vtrial(nfftf,nspden),xccc3d1(cplex*n3xccc)
     284              :  real(dp),intent(inout) :: d2nl(2,3,mpert,3,mpert)
     285              :  real(dp),intent(inout) :: d2lo(2,3,mpert,3,mpert),d2ovl(2,3,mpert,3,mpert*usepaw)
     286              :  real(dp),intent(inout) :: vectornd(with_vectornd*nfftf,3)
     287              :  real(dp),intent(inout) :: vxctau(nfftf,dtset%nspden,4*usevxctau)
     288              :  type(pawcprj_type),intent(in) :: cprj(dtset%natom,nspinor*mband_mem_rbz*mkmem*nsppol*usecprj)
     289              :  type(pawcprj_type),intent(in) :: cprjq(dtset%natom,nspinor*mband_mem_rbz*mkqmem*nsppol*usecprj)
     290              :  type(paw_an_type),intent(in) :: paw_an(:)
     291              :  type(paw_an_type),intent(inout) :: paw_an1(:)
     292              :  type(paw_ij_type),intent(in) :: paw_ij(:)
     293              :  type(paw_ij_type),intent(inout) :: paw_ij1(:)
     294              :  type(pawfgrtab_type),intent(inout) :: pawfgrtab(:)
     295              :  type(pawrad_type),intent(in) :: pawrad(dtset%ntypat*usepaw)
     296              :  type(pawrhoij_type),intent(in) :: pawrhoij(:)
     297              :  type(pawrhoij_type),intent(in) :: pawrhoij1(:)
     298              :  type(pawtab_type),intent(in) :: pawtab(dtset%ntypat*usepaw)
     299              : 
     300              : !Local variables-------------------------------
     301              : !scalars
     302              :  integer,parameter :: tim_fourwf=18,tim_getgh1c=2,tim_projbd=3,formeig1=1
     303              :  integer :: bd2tot_index,bdtot_index,berryopt,bufsz,choice,cpopt,cplex_rhoij,ddkcase
     304              :  integer :: dimffnl,dimffnl1,dimffnl1_idir1,dimylmgr1,g0term
     305              :  integer :: ia,iatom,iband,ibg,ibgq,ibg1,icg,icgq,icg1,ider,idir0,idir1,idir_cprj,ipw
     306              :  integer :: ierr,ii,ikg,ikg1,ikpt,ikpt_me,ilmn,iorder_cprj,ipert1
     307              :  integer :: ispden,isppol,istwf_k,istr,istr1,itypat,jband,jj,kdir1,kpert1,master,mcgq,mcprjq
     308              :  integer :: mdir1,me,mpert1,my_natom,my_comm_atom,my_nsppol,nband_k,nband_kocc,need_ylmgr1,my_nproc_band
     309              :  integer :: nfftot,nkpg,nkpg1,nkpt_me,npw_,npw_k,npw1_k,nspden_rhoij
     310              :  integer :: nvh1,nvxc1,nzlmopt_ipert,nzlmopt_ipert1,optlocal,optnl
     311              :  integer :: option,opt_gvnlx1,qphase_rhoij,sij_opt,spaceworld,usevnl,wfcorr,ik_ddk
     312              :  integer :: nband_me, iband_me, jband_me, iband_
     313              :  integer :: do_scprod, do_bcast
     314              :  integer :: startband, endband
     315              :  integer :: ndat,idat,ispinor
     316              :  integer :: gpu_option
     317              :  real(dp) :: arg,doti,dotr,dot1i,dot1r,dot2i,dot2r,dot3i,dot3r,elfd_fact,invocc,lambda,wtk_k
     318              :  logical :: force_recompute,has_dcwf,has_dcwf2,has_drho,has_ddk_file,has_vectornd
     319              :  logical :: is_metal,is_metal_or_qne0,need_ddk_file,need_pawij10
     320              :  logical :: need_wfk,need_wf1,nmxc,paral_atom,qne0,t_exist,use_ompgpu,with_vxctau
     321              :  character(len=500) :: msg
     322              :  character(len=fnlen) :: fiwfddk(3)
     323              :  complex(dp), parameter :: cminusone  = (-1._dp,0._dp)
     324          347 :  type(gs_hamiltonian_type) :: gs_hamkq
     325          347 :  type(rf_hamiltonian_type) :: rf_hamkq
     326          347 :  type(MPI_type) :: mpi_enreg_seq
     327              : !arrays
     328              :  integer :: ddkfil(3),my_spintab(2),nband_tmp(1),npwar1_tmp(1)
     329          347 :  integer,allocatable,target :: bands_treated_now_ndat(:,:),band_procs(:)
     330          347 :  integer,pointer     :: bands_treated_now(:)
     331          347 :  integer,allocatable :: jpert1(:),jdir1(:),kg1_k(:,:),kg_k(:,:)
     332          347 :  integer,pointer :: my_atmtab(:)
     333              :  real(dp) :: dum1(1,1),dum2(1,1),dum3(1,1),epawnst(2),kpoint(3),kpq(3)
     334          347 :  real(dp),allocatable :: vdotr(:),vdoti(:),vdot1r(:),vdot1i(:),vdot2r(:),vdot2i(:)
     335              :  real(dp) :: sumelfd(2),symfact(3),tsec(2),ylmgr_dum(1,3,1)
     336          347 :  real(dp),allocatable :: buffer(:),ch1c(:,:,:,:),cs1c(:,:,:,:)
     337          347 :  real(dp),allocatable,target :: ch1c_tmp(:,:)
     338          347 :  real(dp),allocatable :: cs1c_tmp(:,:)
     339          347 :  real(dp),allocatable :: dcwavef(:,:)
     340          347 :  real(dp), contiguous, pointer :: cwave0(:,:),cwavef(:,:)!,dcwavef(:,:)
     341          347 :  real(dp),allocatable :: cg_ddk(:,:,:)
     342          347 :  real(dp),allocatable :: doccde_k(:),doccde_kq(:)
     343          347 :  real(dp),allocatable :: dnhat1(:,:),drhoaug1(:,:,:,:)
     344          347 :  real(dp),allocatable :: drhor1(:,:),drho1wfg(:,:),drho1wfr(:,:,:)
     345          694 :  real(dp),allocatable :: d2nl_elfd(:,:),dkinpw(:)
     346          347 :  real(dp),allocatable :: d2nl_k(:,:),d2ovl_drho(:,:,:,:,:),d2ovl_k(:,:)
     347          347 :  real(dp),allocatable :: eig_k(:),eig_kq(:),eig1_k(:)
     348          347 :  real(dp),allocatable,target :: e1kbfr_spin(:,:,:,:,:,:),ffnlk(:,:,:,:),ffnl1(:,:,:,:)
     349          347 :  real(dp),allocatable,target :: gh1(:,:),gs1(:,:),gvnlx1(:,:),gvnlx2(:,:),kinpw1(:),kpg_k(:,:),kpg1_k(:,:)
     350          347 :  real(dp),allocatable,target :: gvnlx1_tmp(:,:)
     351          347 :  real(dp),allocatable :: occ_k(:),occ_kq(:),ph3d(:,:,:),ph3d1(:,:,:),rhotmp(:,:),rocceig(:,:)
     352          347 :  real(dp),allocatable :: vectornd_pac(:,:,:,:,:),vectornd_pac_idir(:,:,:,:),vlocal(:,:,:,:),vtrial_(:,:)
     353          347 :  real(dp),allocatable :: vxctaulocal(:,:,:,:,:)
     354          347 :  real(dp),allocatable :: ylm_k(:,:),ylm1_k(:,:),ylmgr1_k(:,:,:),vtmp1(:,:),vxc10(:,:)
     355          347 :  real(dp),allocatable,target :: work(:,:,:),e1kb_work(:,:,:,:)
     356          347 :  real(dp),pointer :: e1kbfr(:,:,:,:,:),e1kb_ptr(:,:,:,:)
     357          347 :  real(dp), contiguous, pointer :: ffnl1_idir1(:,:,:,:)
     358          347 :  real(dp),pointer :: vhartr01(:),vpsp1_idir1(:),xccc3d1_idir1(:)
     359          347 :  type(pawcprj_type),allocatable :: dcwaveprj(:,:)
     360          347 :  type(pawcprj_type),allocatable,target :: cwaveprj0(:,:)
     361          347 :  type(pawcprj_type),pointer :: cwaveprj0_idir1(:,:)
     362          347 :  type(paw_ij_type),allocatable :: paw_ij10(:,:)
     363          347 :  type(pawrhoij_type),target,allocatable :: pawdrhoij1(:,:)
     364          347 :  type(pawrhoij_type),pointer :: pawdrhoij1_unsym(:,:)
     365        34006 :  type(wfk_t) :: ddks(3)
     366              : 
     367              : ! *********************************************************************
     368              : 
     369              :  DBG_ENTER("COLL")
     370              : 
     371              :  ABI_NVTX_START_RANGE(NVTX_DFPT_NSTPAW)
     372              : 
     373              : !Keep track of total time spent in dfpt_nstpaw
     374          347 :  call timab(566,1,tsec)
     375              : 
     376              : !Not valid for PrintBandByBand
     377          347 :  if (dtset%prtbbb/=0) then
     378            0 :    ABI_BUG('not yet valid for prtbbb/=0!')
     379              :  end if
     380              : 
     381              : !NCPP restrictions
     382          347 :  if (usepaw==0) then
     383              : !  cprj cannot be used
     384            0 :    if (usecprj/=0) then
     385            0 :      ABI_BUG('NCPP: usecprj should be 0!')
     386              :    end if
     387              : !  d2ovl cannot be used
     388            0 :    if (size(d2ovl)/=0) then
     389            0 :      ABI_BUG('NCPP: d2ovl should not be allocated!')
     390              :    end if
     391              :  end if
     392              : 
     393              : !PAW restrictions
     394          347 :  if (usepaw==1) then
     395              : !  Test on FFT grid sizes
     396          347 :    if (pawfgr%nfft/=nfftf) then
     397            0 :      ABI_BUG('PAW: wrong values for nfft, nfftf!')
     398              :    end if
     399              : !  Test gradients of cprj
     400          347 :    if (ipert<=dtset%natom.and.ncpgr/=3) then
     401            0 :      ABI_BUG('PAW: wrong value of ncpgr for ipert<=natom!')
     402              :    end if
     403          347 :    if (ipert==dtset%natom+1.and.ncpgr/=1.and.dtset%orbmag==0) then
     404            0 :      ABI_BUG('PAW: wrong value of ncpgr for ipert=natom+1!')
     405              :    end if
     406          347 :    if (ipert==dtset%natom+2.and.ncpgr/=3) then
     407            0 :      ABI_BUG('PAW: wrong value of ncpgr for ipert=natom+2!')
     408              :    end if
     409          347 :    if ((ipert==dtset%natom+3.or.ipert==dtset%natom+4).and.ncpgr/=1) then
     410            0 :      ABI_BUG('PAW: wrong value of ncpgr for ipert=natom+3 or 4!')
     411              :    end if
     412              : !  Test on availability of DijHartree and XC on-site potentials
     413          347 :    if (mpi_enreg%my_natom>0.and.ipert/=dtset%natom+1)  then
     414          216 :      if (paw_ij1(1)%has_dijhartree==0.or.paw_an1(1)%has_vxc==0) then
     415            0 :        msg='PAW: paw_ij1%dijhartree and paw=_an1%vxc1 should be allocated !'
     416              :      end if
     417              :    end if
     418              :  end if
     419              : 
     420              : !Set up parallelism
     421          347 :  gpu_option=dtset%gpu_option
     422          347 :  ndat=dtset%bandpp
     423          347 :  master=0;me=mpi_enreg%me_kpt
     424          347 :  spaceworld=mpi_enreg%comm_cell
     425          347 :  paral_atom=(mpi_enreg%my_natom/=dtset%natom)
     426          347 :  my_comm_atom=mpi_enreg%comm_atom
     427          347 :  my_natom=mpi_enreg%my_natom
     428          347 :  my_nproc_band=mpi_enreg%nproc_band
     429          347 :  my_atmtab=>mpi_enreg%my_atmtab
     430         1041 :  my_spintab=mpi_enreg%my_isppoltab
     431         1041 :  my_nsppol=count(my_spintab==1)
     432          347 :  use_ompgpu=(gpu_option==ABI_GPU_OPENMP)
     433              : 
     434              : !Fake MPI data to be used in sequential calls to parallel routines
     435          347 :  call initmpi_seq(mpi_enreg_seq)
     436          347 :  mpi_enreg_seq%my_natom=dtset%natom
     437              : 
     438              : !Compute effective number of k-points
     439              :  nkpt_me=nkpt_rbz
     440              :  if(xmpi_paral==1)then
     441          347 :    nkpt_me=0
     442          727 :    do isppol=1,nsppol
     443        15486 :      do ikpt=1,nkpt_rbz
     444        14759 :        nband_k=nband_rbz(ikpt+(isppol-1)*nkpt_rbz)
     445        15139 :        if (.not.(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me))) nkpt_me=nkpt_me+1
     446              :      end do
     447              :    end do
     448              :  end if
     449              : 
     450              : !Sizes for WF at k+q
     451          347 :  mcgq=mpw1*nspinor*mband_mem_rbz*mkqmem*nsppol
     452          347 :  mcprjq=nspinor*mband_mem_rbz*mkqmem*nsppol*usecprj
     453              : 
     454        16147 :  ABI_MALLOC(bands_treated_now_ndat, (maxval(nband_rbz),ndat))
     455              : 
     456              : #ifdef HAVE_OPENMP_OFFLOAD
     457              :  !$OMP TARGET ENTER DATA MAP(to:cg,cg1) IF(gpu_option==ABI_GPU_OPENMP)
     458              : #endif
     459              : 
     460              : !Check ddk files (needed to compute electric field perturbations)
     461          347 :  ddkfil(:)=0
     462         1388 :  do idir1=1,3
     463         1041 :    ddkcase=idir1+dtset%natom*3
     464         1041 :    call appdig(ddkcase,dtfil%fnamewffddk,fiwfddk(idir1))
     465         1041 :    t_exist = file_exists(fiwfddk(idir1))
     466              : 
     467         1041 :    if (.not. t_exist) then
     468              :      ! Try netcdf file.
     469         1041 :      t_exist = file_exists(nctk_ncify(fiwfddk(idir1)))
     470         1041 :      if (t_exist) then
     471          402 :        fiwfddk(idir1) = nctk_ncify(fiwfddk(idir1))
     472          402 :        write(msg,"(3a)")"- File: ",trim(fiwfddk(idir1))," does not exist but found netcdf file with similar name."
     473          402 :        call wrtout(std_out,msg,'COLL')
     474              :      end if
     475              :    end if
     476              : 
     477          347 :    if (t_exist) then
     478          402 :      ddkfil(idir1)=20+idir1 ! Note the use of unit numbers 21, 22 and 23
     479              :    end if
     480              :  end do
     481          986 :  has_ddk_file=(any(ddkfil(:)>0))
     482              : 
     483              : !Define the set of perturbations (j1)=(ipert1,idir1)
     484              : !The first perturbation must be (j1)=(j2)=(ipert,idir)
     485              : !because we need to compute <g|H^(j2)-Eps.S^(j2)|u0> first.
     486          347 :  if (ipert/=dtset%natom+1) then
     487          218 :    mpert1=0
     488          654 :    ABI_MALLOC(jpert1,(mpert))
     489         2478 :    jpert1 = 0
     490          218 :    if (ipert/=dtset%natom+2.or.has_ddk_file) then
     491          218 :      mpert1=mpert1+1;jpert1(mpert1)=ipert
     492              :    end if
     493         2478 :    do ipert1=1,mpert
     494         2478 :      if (ipert1/=ipert) then
     495         2042 :        if(dtset%usepaw==1) then
     496         2042 :          if((ipert1<=dtset%natom.or.(ipert1==dtset%natom+2.and.has_ddk_file).or.&
     497              : &            ((ipert>dtset%natom.and.ipert/=dtset%natom+5.and.ipert/=dtset%natom+6).and.(ipert1==dtset%natom+3.or.ipert1==dtset%natom+4)).or. &
     498              : &            ((ipert1==dtset%natom+2).and.has_ddk_file))) then
     499          858 :            mpert1=mpert1+1;jpert1(mpert1)=ipert1
     500              :          end if
     501              :        else ! dtset%usepaw==0
     502            0 :          if ((ipert1<=dtset%natom.or.(ipert1==dtset%natom+2.and.has_ddk_file)).or.&
     503              :     &     ((ipert==dtset%natom+3.or.ipert==dtset%natom+4).and.(ipert1==dtset%natom+3.or.ipert1==dtset%natom+4))) then
     504            0 :            mpert1=mpert1+1;jpert1(mpert1)=ipert1
     505              :          end if
     506              :        end if
     507              :      end if
     508              :    end do
     509              :  else
     510          129 :    mpert1=1
     511          129 :    ABI_MALLOC(jpert1,(mpert1))
     512          129 :    jpert1(1)=dtset%natom+1
     513              :  end if
     514          347 :  mdir1=3
     515          347 :  ABI_MALLOC(jdir1,(mdir1))
     516         1388 :  jdir1(1:3)= (/ (idir1,idir1=1,3) /)
     517          347 :  jdir1(1)=idir;jdir1(idir)=1
     518              : 
     519              : !Index of strain perturbation, if any
     520          347 :  istr=idir;if (ipert==dtset%natom+4) istr=idir+3
     521              : 
     522              : !Open ddk WF file(s) in sequential mode
     523          347 :  if (has_ddk_file) then
     524          536 :    do kdir1=1,mdir1
     525          402 :      idir1=jdir1(kdir1)
     526          536 :      if (ddkfil(idir1)/=0) then
     527          402 :        write(msg, '(a,a)') '-open ddk wf file :',trim(fiwfddk(idir1))
     528         1206 :        call wrtout([std_out, ab_out],msg)
     529          402 :        call ddks(idir1)%open_read(fiwfddk(idir1), formeig1, dtset%iomode, ddkfil(idir1), xmpi_comm_self)
     530              :      end if
     531              :    end do
     532              : 
     533          536 :    ABI_MALLOC(cg_ddk,(2,mpw1*nspinor*mband_mem_rbz,3))
     534      4045928 :    cg_ddk = zero ! not all may be initialized below if only certain ddk directions are provided
     535              :  end if
     536              : 
     537              : !Zero only portion of matrix to be computed here
     538        24477 :  d2nl(:,:,1:dtset%natom+4,idir,ipert)=zero
     539        24477 :  if (usepaw==1) d2ovl(:,:,1:dtset%natom+4,idir,ipert)=zero
     540              : 
     541              : !Update list of computed matrix elements
     542         1552 :  do kpert1=1,mpert1
     543         1205 :    ipert1=jpert1(kpert1)
     544         5167 :    do kdir1=1,mdir1
     545         3615 :      idir1=jdir1(kdir1)
     546              :      if ((ipert1<=dtset%natom).or.ipert1==dtset%natom+3.or.ipert1==dtset%natom+4.or.&
     547              : &     (ipert1==dtset%natom+1.and.((ddkfil(idir1)/=0).or.(dtset%rfdir(idir1)/=0.and.idir1<=idir))).or.&
     548         3615 : &     (ipert1==dtset%natom+2.and.ddkfil(idir1)/=0).or.&
     549         1205 : &     ((ipert1==dtset%natom+3.or.ipert1==dtset%natom+4).and.ddkfil(idir1)/=0)) then
     550         3474 :        blkflg(idir1,ipert1,idir,ipert)=1
     551              :      end if
     552              :    end do
     553              :  end do
     554              : 
     555              : !Initialize most of the (1st-order) Hamiltonian
     556              : !1) Allocate all arrays and initialize quantities that do not depend on k and spin.
     557              : !2) Perform the setup needed for the non-local factors:
     558              :  call gs_hamkq%init(psps,pawtab,nspinor,nsppol,nspden,dtset%natom,&
     559              : &  dtset%typat,xred,dtset%nfft,dtset%mgfft,dtset%ngfft,rprimd,dtset%nloalg,ph1d=ph1d,&
     560              : &  paw_ij=paw_ij,mpi_atmtab=my_atmtab,comm_atom=my_comm_atom,mpi_spintab=mpi_enreg%my_isppoltab,&
     561          347 : &  usecprj=usecprj,nucdipmom=dtset%nucdipmom,gpu_option=gpu_option)
     562          347 :  has_vectornd = (with_vectornd .EQ. 1)
     563          347 :  if(has_vectornd) then
     564              :     ! vlocal is needed when vectornd is present, for zora
     565          270 :     ABI_MALLOC(vlocal,(dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6),gs_hamkq%nvloc))
     566          180 :     ABI_MALLOC(vtrial_,(nfftf,nspden))
     567              :     ! need a mutable version of vtrial
     568      4185354 :     vtrial_=vtrial
     569          315 :     ABI_MALLOC(vectornd_pac,(dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6),gs_hamkq%nvloc,3))
     570          225 :     ABI_MALLOC(vectornd_pac_idir,(dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6),gs_hamkq%nvloc))
     571              :  end if
     572          347 :  with_vxctau = ( usevxctau > 0 )
     573          347 :  if(with_vxctau) then
     574           42 :     ABI_MALLOC(vxctaulocal,(dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6),gs_hamkq%nvloc,4))
     575              :  end if
     576              : 
     577              : !Variables common to all perturbations
     578       171841 :  arg=maxval(occ_rbz)-minval(occ_rbz)
     579          347 :  qne0=(dtset%qptn(1)**2+dtset%qptn(2)**2+dtset%qptn(3)**2>=tol14)
     580          347 :  is_metal=((dtset%occopt>=3.and.dtset%occopt<=8).or.(abs(arg)>tol8))
     581          347 :  is_metal_or_qne0=((is_metal).or.(qne0))
     582          347 :  nmxc=(dtset%usepaw==1.and.mod(abs(dtset%usepawu),10)==4)
     583         1735 :  ABI_MALLOC(ch1c,(2,mband_mem_rbz,dtset%mband,nkpt_me))
     584         1041 :  ABI_MALLOC(ch1c_tmp,(2,mband_mem_rbz))
     585      2175550 :  ch1c(:,:,:,:)=zero
     586              : #ifdef HAVE_OPENMP_OFFLOAD
     587              :  !$OMP TARGET ENTER DATA MAP(alloc:ch1c,ch1c_tmp) IF(gpu_option==ABI_GPU_OPENMP)
     588              :  !$OMP TARGET UPDATE TO(ch1c) IF(gpu_option==ABI_GPU_OPENMP)
     589              : #endif
     590          347 :  nzlmopt_ipert=0;nzlmopt_ipert1=0
     591          347 :  if (usepaw==1) then
     592         1735 :    ABI_MALLOC(d2ovl_drho,(2,3,mpert,3,mpert))
     593      1071543 :    d2ovl_drho=zero
     594          347 :    if (dtset%pawnzlm/=0) then
     595          347 :      nzlmopt_ipert=1;if (dtset%nstep<2) nzlmopt_ipert=-1
     596          347 :      nzlmopt_ipert1=-1
     597              :    end if
     598          347 :    if (is_metal_or_qne0) then
     599         1250 :      ABI_MALLOC(cs1c,(2,dtset%mband,mband_mem_rbz,nkpt_me))
     600          750 :      ABI_MALLOC(cs1c_tmp,(2,dtset%mband))
     601      1895832 :      cs1c(:,:,:,:)=zero
     602              :    end if
     603              :  end if
     604              : 
     605              : !Force the recomputation of on-site potentials and DijHartree
     606          347 :  if (usepaw==1) then
     607          347 :    call paw_an_reset_flags(paw_an1)
     608          347 :    call paw_ij_reset_flags(paw_ij1,dijhartree=.true.)
     609              :  end if
     610              : 
     611              : !LOOP OVER PERTURBATION TYPES (j1)
     612         1552 :  do kpert1=1,mpert1
     613         1205 :    ipert1=jpert1(kpert1)
     614              : 
     615              : !  Flag for use of DDK file
     616         1205 :    need_ddk_file=(has_ddk_file.and.(ipert1==dtset%natom+1.or.ipert1==dtset%natom+2))
     617              : 
     618              : !  Factor to be applied for electric Field (Eff. charges and piezo. tensor are "minus" d2E)
     619         1205 :    elfd_fact=one
     620         1205 :    if ((ipert <=dtset%natom.or.ipert ==dtset%natom+3.or.ipert ==dtset%natom+4).and. &
     621         1205 :        (ipert1==dtset%natom+2)) elfd_fact=-one
     622         1205 :    if ((ipert1<=dtset%natom.or.ipert1==dtset%natom+3.or.ipert1==dtset%natom+4).and. &
     623         1205 :        (ipert ==dtset%natom+2)) elfd_fact=-one
     624              : 
     625              : !  We want to compute delta_u^(j1))=-1/2 Sum_{j}[<u0_k+q_j|S^(j1)|u0_k_i>.|u0_k+q_j>]
     626              : !  see PRB 78, 035105 (2008) [[cite:Audouze2008]], Eq. (42)
     627         1205 :    has_dcwf=.false.;has_dcwf2=.false.;has_drho=.false.
     628         1205 :    if (usepaw==1) then
     629         1205 :      has_dcwf =(ipert1/=dtset%natom+2)
     630         1205 :      has_dcwf2=(ipert /=dtset%natom+2)
     631         1205 :      has_drho =(has_dcwf.and.ipert1/=dtset%natom+1)
     632              :    end if
     633              : 
     634              : !  Select which WF are needed
     635         1205 :    need_wfk=.true.
     636         1205 :    need_wf1=.true.
     637              : 
     638              : !  Initialize data for NL 1st-order (j1) hamiltonian
     639         1205 :    call rf_hamkq%init(cplex,gs_hamkq,ipert1,mpi_spintab=[0,0])
     640              : 
     641              : !  The following contributions are needed only for non-DDK perturbation:
     642              : !  - Frozen part of 1st-order Dij
     643              : !  - Contribution from local potential to dynamical matrix (due to Vxc^(j1)(tild_nc)+VH^(j1)(tild_nZc))
     644         1205 :    if (ipert/=dtset%natom+1.and.ipert1/=dtset%natom+1) then
     645              : 
     646              : !    Allocations
     647         1076 :      force_recompute=(usepaw==0) ! This is dangerous...
     648         1076 :      nfftot=ngfftf(1)*ngfftf(2)*ngfftf(3)
     649         1076 :      nvxc1=0;if (ipert1<=dtset%natom.or.ipert1==dtset%natom+3.or.ipert1==dtset%natom+4) nvxc1=nspden
     650         1076 :      nvh1=0;if (ipert1==dtset%natom+3.or.ipert1==dtset%natom+4) nvh1=1
     651         4304 :      ABI_MALLOC(vxc10,(cplex*nfftf,nvxc1))
     652         3228 :      ABI_MALLOC(vhartr01,(cplex*nfftf*nvh1))
     653         1076 :      need_pawij10=(usepaw==1)
     654         1076 :      if (need_pawij10) then
     655        13269 :        ABI_MALLOC(paw_ij10,(my_natom,mdir1))
     656         8608 :        ABI_MALLOC(e1kbfr_spin,(rf_hamkq%dime1kb1,rf_hamkq%dime1kb2,nspinor**2,cplex,mdir1,my_nsppol))
     657              :      else
     658            0 :        ABI_MALLOC(paw_ij10,(0,0))
     659              :      end if
     660              : 
     661              : !    LOOP OVER PERTURBATION DIRECTIONS
     662         4304 :      do kdir1=1,mdir1
     663         3228 :        idir1=jdir1(kdir1)
     664         3228 :        istr1=idir1;if (ipert1==dtset%natom+4) istr1=idir1+3
     665              : 
     666              : !      Get first-order local potential and first-order pseudo core density
     667         3228 :        if (ipert==ipert1.and.idir==idir1.and.(.not.force_recompute)) then
     668          218 :          vpsp1_idir1 => vpsp1
     669          218 :          xccc3d1_idir1 => xccc3d1
     670              :        else
     671         9030 :          ABI_MALLOC(vpsp1_idir1,(cplex*nfftf))
     672         9030 :          ABI_MALLOC(xccc3d1_idir1,(cplex*n3xccc))
     673         3010 :          if (usepaw==1) then
     674              :            call dfpt_atm2fft(gs_hamkq%atindx,cplex,gmet,gprimd,gsqcut,istr1,ipert1,&
     675              : &           mgfftf,psps%mqgrid_vl,dtset%natom,1,nfftf,ngfftf,dtset%ntypat,&
     676              : &           ph1df,psps%qgrid_vl,dtset%qptn,dtset%typat,ucvol,psps%usepaw,xred,psps,pawtab,&
     677              : &           atmrhor1=xccc3d1_idir1,atmvlocr1=vpsp1_idir1,optv_in=1,optn_in=n3xccc/nfftf,optn2_in=1,&
     678         3010 : &           vspl=psps%vlspl)
     679              :          else
     680            0 :            if(ipert1==dtset%natom+3.or.ipert1==dtset%natom+4) then
     681              : 
     682              :              !To compute Absolute Deformation Potentials together with FxE tensor
     683              :              !the reference has to be the same as in the FxE routines
     684            0 :              g0term=0; if (dtset%rfstrs_ref==1) g0term=1
     685              : 
     686              :              call vlocalstr(gmet,gprimd,gsqcut,istr1,mgfftf,mpi_enreg,psps%mqgrid_vl,dtset%natom,&
     687              : &             nattyp,nfftf,ngfftf,dtset%ntypat,ph1df,psps%qgrid_vl,ucvol,&
     688            0 : &             psps%vlspl,vpsp1_idir1,g0term=g0term)
     689              :            else
     690              :              call dfpt_vlocal(gs_hamkq%atindx,cplex,gmet,gsqcut,dtset%icutcoul,idir1,ipert1,mpi_enreg,psps%mqgrid_vl,&
     691              : &             dtset%natom,nattyp,nfftf,ngfftf,dtset%nkpt,dtset%ntypat,ngfftf(1),ngfftf(2),ngfftf(3),&
     692              : &             ph1df,psps%qgrid_vl,dtset%qptn,dtset%rcut,rprimd,ucvol,dtset%vcutgeo,psps%vlspl,vpsp1_idir1,xred,&
     693            0 : &             zion=dtset%ziontypat)
     694              :            end if
     695            0 :            if(psps%n1xccc/=0)then
     696              :              call dfpt_mkcore(cplex,idir1,ipert1,dtset%natom,dtset%ntypat,ngfftf(1),psps%n1xccc,&
     697              : &             ngfftf(2),ngfftf(3),dtset%qptn,rprimd,dtset%typat,ucvol,&
     698            0 : &             psps%xcccrc,psps%xccc1d,xccc3d1_idir1,xred)
     699              :            end if
     700              :          end if
     701              :        end if
     702              : 
     703              : !      Compute 1st-order non-local factors (Dij^(j1)_fr)
     704         3228 :        if (need_pawij10) then
     705         3228 :          call paw_ij_nullify(paw_ij10(:,idir1))
     706              :          call paw_ij_init(paw_ij10(:,idir1),cplex,nspinor,dtset%nsppol,dtset%nspden,&
     707              : &         0,dtset%natom,dtset%ntypat,dtset%typat,pawtab,has_dijfr=1,&
     708         3228 : &         mpi_atmtab=my_atmtab,comm_atom=my_comm_atom)
     709         3228 :          if (ipert/=ipert1.or.idir/=idir1.or.force_recompute) then
     710         3010 :            option=0
     711              :            call pawdijfr(gprimd,idir1,ipert1,my_natom,dtset%natom,nfftf,ngfftf,&
     712              : &           nspden,nsppol,dtset%ntypat,option,paw_ij10(:,idir1),pawang,pawfgrtab,pawrad,&
     713              : &           pawtab,cplex,dtset%qptn,rprimd,ucvol,vpsp1_idir1,vtrial,vxc,xred,&
     714         3010 : &           mpi_atmtab=my_atmtab,comm_atom=my_comm_atom)
     715              :          else
     716          653 :            do iatom=1,my_natom
     717          435 :              paw_ij10(iatom,idir1)%has_dijfr=paw_ij1(iatom)%has_dijfr
     718        23681 :              if (paw_ij1(iatom)%has_dijfr==2) paw_ij10(iatom,idir1)%dijfr=paw_ij1(iatom)%dijfr
     719              :            end do
     720              :          end if
     721              :        end if
     722              : 
     723              : !      Get first-order exchange-correlation potential (core-correction contribution only)
     724         3228 :        if (nvxc1>0) then
     725         2826 :          if(ipert1==dtset%natom+3.or.ipert1==dtset%natom+4) then
     726          624 :            option=0
     727              :            call dfpt_mkvxcstr(cplex,idir1,ipert1,kxc,mpi_enreg,dtset%natom,nfftf,ngfftf,&
     728              : &           nhat,nhat1,nkxc,nmxc,nspden,n3xccc,option,dtset%qptn,rhor,rhor1,rprimd,&
     729          624 : &           usepaw,usexcnhat,vxc10,xccc3d1_idir1)
     730              :          else
     731              : !          Non-collinear magnetism (should the second nkxc be nkxc_cur ?)
     732         2202 :            if (nspden==4) then
     733            0 :              option=0
     734              :              call dfpt_mkvxc_noncoll(cplex,dtset%ixc,kxc,mpi_enreg,nfftf,ngfftf,dum1,0,dum2,0,dum3,0,nkxc,&
     735              : &             nmxc,nspden,n3xccc,1,option,dtset%qptn,dum1,dum1,rprimd,0,vxc,&
     736            0 : &             vxc10,xccc3d1_idir1)
     737              :            else
     738              :              call dfpt_mkvxc(cplex,dtset%ixc,kxc,mpi_enreg,nfftf,ngfftf,dum2,0,dum3,0,nkxc,&
     739         2202 : &             nmxc,nspden,n3xccc,0,dtset%qptn,dum1,rprimd,0,vxc10,xccc3d1_idir1)
     740              :            end if
     741              :          end if
     742              :        end if
     743              : 
     744              : !      Get first-order Hartree potential (metric tensor contribution only)
     745         3228 :        if (nvh1>0) then
     746              :          call hartrestr(gsqcut,idir1,ipert1,mpi_enreg,dtset%natom,&
     747          624 : &         nfftf,ngfftf,rhog,rprimd,vhartr01)
     748              :        end if
     749              : 
     750              : !      Get Hartree + xc + local contributions to dynamical matrix or elastic tensor
     751         3228 :        if (ipert1<=dtset%natom.or.ipert1==dtset%natom+3.or.ipert1==dtset%natom+4) then
     752         2826 :          if (usepaw==0) then
     753              : !          vxc1 is integrated with the total 1st-order density (rhor1 )
     754              : !          vpsp1 is integrated with the 1st-order pseudo density (rhor1)
     755            0 :            call dotprod_vn(cplex,rhor1,dot1r,dot1i,nfftf,nfftot,nspden,2,vxc10,ucvol)
     756            0 :            call dotprod_vn(cplex,rhor1,dot2r,dot2i,nfftf,nfftot,1,2,vpsp1_idir1,ucvol)
     757         2826 :          else if (usexcnhat/=0) then
     758              : !          vxc1 is integrated with the total 1st-order density (rhor1 including nhat1)
     759              : !          vpsp1 is integrated with the 1st-order pseudo density (rhor1 without nhat1)
     760         6057 :            ABI_MALLOC(rhotmp,(cplex*nfftf,1))
     761     22954731 :            rhotmp(:,1)=rhor1(:,1)-nhat1(:,1)
     762         2019 :            call dotprod_vn(cplex,rhor1,dot1r,dot1i,nfftf,nfftot,nspden,2,vxc10,ucvol)
     763         2019 :            call dotprod_vn(cplex,rhotmp,dot2r,dot2i,nfftf,nfftot,1,2,vpsp1_idir1,ucvol)
     764         2019 :            ABI_FREE(rhotmp)
     765              :          else
     766              : !          vxc1 is integrated with the 1st-order pseudo density (rhor1 without nhat1)
     767              : !          vpsp1 is integrated with the 1st-order pseudo density (rhor1 without nhat1)
     768         3228 :            ABI_MALLOC(rhotmp,(cplex*nfftf,nspden))
     769     38357748 :            rhotmp(:,:)=rhor1(:,:)-nhat1(:,:)
     770          807 :            call dotprod_vn(cplex,rhotmp,dot1r,dot1i,nfftf,nfftot,nspden,2,vxc10,ucvol)
     771          807 :            call dotprod_vn(cplex,rhotmp,dot2r,dot2i,nfftf,nfftot,1,2,vpsp1_idir1,ucvol)
     772          807 :            ABI_FREE(rhotmp)
     773              :          end if
     774         2826 :          if (nvh1>0) then
     775          624 :            call dotprod_vn(cplex,rhor1,dot3r,dot3i,nfftf,nfftot,1,2,vhartr01,ucvol)
     776              :          else
     777         2202 :            dot3r=zero ; dot3i=zero
     778              :          end if
     779              : !        Note: factor 2 (from d2E/dj1dj2=2E^(j1j2)) eliminated by factor 1/2
     780         2826 :          dotr=dot1r+dot2r+dot3r;doti=dot1i+dot2i+dot3i
     781              : !        In case ipert = natom+2, these lines compute the local part
     782              : !        of the Born effective charges from phonon and electric
     783              : !        field type perturbations, see eq. 43 of X. Gonze and C. Lee, PRB 55, 10355 (1997) [[cite:Gonze1997a]]
     784              : !        The minus sign is due to the fact that the effective charges
     785              : !        are minus the second derivatives of the energy
     786              :          if (ipert/=dtset%natom+1) then
     787         2826 :            d2lo(1,idir1,ipert1,idir,ipert)=elfd_fact*dotr
     788         2826 :            d2lo(2,idir1,ipert1,idir,ipert)=elfd_fact*doti
     789              :          end if
     790              :        end if ! ipert1<=natom
     791              : 
     792         4304 :        if (ipert/=ipert1.or.idir/=idir1.or.force_recompute)  then
     793         3010 :          ABI_FREE(vpsp1_idir1)
     794         3010 :          ABI_FREE(xccc3d1_idir1)
     795              :        end if
     796              : 
     797              : !      End loop on directions
     798              :      end do
     799              : 
     800              : !    Free memory
     801         1076 :      ABI_FREE(vxc10)
     802         1076 :      ABI_FREE(vhartr01)
     803              : 
     804              :    else ! ddk perturbation
     805         1290 :      d2lo(1:2,1:mdir1,ipert1,idir,ipert)=zero
     806          129 :      need_pawij10=.false.
     807          129 :      ABI_MALLOC(paw_ij10,(0,0))
     808              :    end if
     809              : 
     810              : !  Prepare RF PAW files for reading and writing if mkmem, mkqmem or mk1mem==0
     811         1205 :    iorder_cprj=0
     812              : 
     813              : !  Allocate arrays used to accumulate density change due to overlap
     814         1205 :    if (has_drho) then
     815         5652 :      ABI_MALLOC(drhoaug1,(cplex*dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6),mdir1))
     816         4710 :      ABI_MALLOC(drho1wfr,(cplex*dtset%nfft,dtset%nspden,mdir1))
     817        11691 :      ABI_MALLOC(pawdrhoij1,(my_natom,mdir1))
     818          942 :      if (paral_atom) then
     819        11148 :        ABI_MALLOC(pawdrhoij1_unsym,(dtset%natom,mdir1))
     820              :      else
     821          394 :        pawdrhoij1_unsym => pawdrhoij1
     822              :      end if
     823         3768 :      do kdir1=1,mdir1
     824         2826 :        idir1=jdir1(kdir1)
     825     30823944 :        drho1wfr(:,:,idir1)=zero
     826              :        call pawrhoij_inquire_dim(cplex_rhoij=cplex_rhoij,qphase_rhoij=qphase_rhoij,nspden_rhoij=nspden_rhoij,&
     827         2826 : &                            nspden=dtset%nspden,spnorb=dtset%pawspnorb,cplex=cplex,cpxocc=dtset%pawcpxocc)
     828              :        call pawrhoij_alloc(pawdrhoij1(:,idir1),cplex_rhoij,nspden_rhoij,dtset%nspinor,&
     829              : &       dtset%nsppol,dtset%typat,qphase=qphase_rhoij,pawtab=pawtab,use_rhoijp=1,use_rhoij_=0,&
     830         2826 : &       comm_atom=mpi_enreg%comm_atom,mpi_atmtab=my_atmtab)
     831         6594 :        if (paral_atom) then
     832              :          call pawrhoij_alloc(pawdrhoij1_unsym(:,idir1),cplex_rhoij,nspden_rhoij,dtset%nspinor,&
     833              : &         dtset%nsppol,dtset%typat,qphase=qphase_rhoij,pawtab=pawtab,&
     834         1644 : &         use_rhoijp=0,use_rhoij_=1)
     835              :        else
     836         1182 :          call pawrhoij_init_unpacked(pawdrhoij1_unsym(:,idir1))
     837              :        end if
     838              :      end do
     839              :    end if
     840              : 
     841              : !  Initialize shifts for global arrays
     842         1205 :    bdtot_index=0
     843         1205 :    bd2tot_index=0
     844         1205 :    ibg=0;icg=0
     845         1205 :    ibg1=0;icg1=0
     846         1205 :    ibgq=0;icgq=0
     847              : 
     848              : 
     849              : !  Has to get 1st-order non-local factors before the loop over spins
     850              : !  because this needs a communication over comm_atom (=comm_spinkpt)
     851         1205 :    if (need_pawij10) then
     852         1076 :      if (my_nsppol<nsppol) then
     853            0 :        ABI_MALLOC(e1kb_work,(rf_hamkq%dime1kb1,rf_hamkq%dime1kb2,nspinor**2,cplex))
     854              :      end if
     855         1076 :      ii=0
     856         2210 :      do isppol=1,nsppol
     857         1134 :        if (my_spintab(isppol)==1) ii=ii+1
     858         1134 :        if (my_spintab(isppol)/=1) e1kb_ptr => e1kb_work
     859         5612 :        do kdir1=1,mdir1
     860         3402 :          idir1=jdir1(kdir1)
     861         3402 :          if (my_spintab(isppol)==1) e1kb_ptr => e1kbfr_spin(:,:,:,:,idir1,ii)
     862         4536 :          call pawdij2e1kb(paw_ij10(:,idir1),isppol,my_comm_atom,e1kbfr=e1kb_ptr,mpi_atmtab=my_atmtab)
     863              :        end do
     864              :      end do
     865         1076 :      if (my_nsppol<nsppol) then
     866            0 :        ABI_FREE(e1kb_work)
     867              :      end if
     868              :    end if
     869              : 
     870              : !  LOOP OVER SPINS
     871         2483 :    do isppol=1,nsppol
     872              : 
     873         1278 :      ikpt_me=0
     874              : 
     875              : !    Rewind (k+G) data if needed
     876         1278 :      ikg=0;ikg1=0
     877              : 
     878              : !    Continue to initialize the GS/RF Hamiltonian
     879         1278 :      call gs_hamkq%load_spin(isppol,with_nonlocal=.true.)
     880         1278 :      if (need_pawij10) then
     881         1134 :        ii=min(isppol,size(e1kbfr_spin,6))
     882         1134 :        if (ii>0) e1kbfr => e1kbfr_spin(:,:,:,:,:,ii)
     883              :      end if
     884              : 
     885              :      ! if vectornd is present, set it up for addition to gs_hamkq and rf_hamkq.
     886              :      ! Note that it must be done for the three Cartesian directions. Also, the following
     887              :      ! code assumes explicitly and implicitly that nvloc = 1. This should eventually be generalized.
     888         1278 :      if(has_vectornd) then
     889              :        call gspot_transgrid_and_pack(isppol, psps%usepaw, dtset%paral_kgb, dtset%nfft, dtset%ngfft, nfftf, &
     890           48 :          & dtset%nspden, gs_hamkq%nvloc, 0, pawfgr, mpi_enreg, vtrial_,vlocal)
     891              :        call gspot_transgrid_and_pack(isppol, psps%usepaw, dtset%paral_kgb, dtset%nfft, dtset%ngfft, nfftf, &
     892           48 :          & dtset%nspden, gs_hamkq%nvloc, 3, pawfgr, mpi_enreg, vectornd,vectornd_pac)
     893           48 :        call gs_hamkq%load_spin(isppol, vlocal=vlocal,vectornd=vectornd_pac)
     894      1917882 :        vectornd_pac_idir(:,:,:,:)=vectornd_pac(:,:,:,:,idir)
     895           48 :        call rf_hamkq%load_spin(isppol, vectornd=vectornd_pac_idir)
     896              :      end if
     897              :      !! add vxctau for mGGA to GS hamiltonian and RF hamiltonian
     898         1278 :      if (with_vxctau) then
     899              :        call gspot_transgrid_and_pack(isppol, psps%usepaw, dtset%paral_kgb, dtset%nfft, dtset%ngfft, nfftf, &
     900            6 :          dtset%nspden, gs_hamkq%nvloc, 4, pawfgr, mpi_enreg, vxctau, vxctaulocal)
     901            6 :        call gs_hamkq%load_spin(isppol, vxctaulocal=vxctaulocal)
     902            6 :        call rf_hamkq%load_spin(isppol, vxctaulocal=vxctaulocal)
     903              :      end if
     904              : 
     905              : !    Initialize accumulation of density
     906     35279700 :      if (has_drho) drhoaug1(:,:,:,:)=zero
     907              : 
     908              : !    LOOP OVER K-POINTS
     909        32811 :      do ikpt=1,nkpt_rbz
     910              : 
     911              : !      Load dimensions for this k-point
     912        31533 :        nband_k=nband_rbz(ikpt+(isppol-1)*nkpt_rbz)
     913        31533 :        istwf_k=istwfk_rbz(ikpt)
     914        31533 :        npw_k=npwarr(ikpt)
     915        31533 :        npw1_k=npwar1(ikpt)
     916        31533 :        nband_me = proc_distrb_nband(mpi_enreg%proc_distrb,ikpt,nband_k,isppol,me)
     917              : 
     918              : !      Skip loop if this k-point is not to be treated by this proc
     919        31533 :        if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me)) then
     920         8416 :          bdtot_index=bdtot_index+nband_k
     921         8416 :          bd2tot_index=bd2tot_index+2*nband_k**2
     922         8416 :          cycle ! Skip the rest of the k-point loop
     923              :        end if
     924              : 
     925              : !      Allocate/initialize local arrays and scalars for this k-point
     926        23117 :        ABI_MALLOC(d2nl_k,(2,3))
     927        23117 :        ABI_MALLOC(d2ovl_k,(2,3))
     928        69351 :        ABI_MALLOC(eig_k,(nband_k))
     929        46234 :        ABI_MALLOC(eig_kq,(nband_k))
     930        69351 :        ABI_MALLOC(eig1_k,(2*nband_k**2))
     931        46234 :        ABI_MALLOC(occ_k,(nband_k))
     932        46234 :        ABI_MALLOC(vdotr,(nband_k))
     933        46234 :        ABI_MALLOC(vdoti,(nband_k))
     934        46234 :        ABI_MALLOC(vdot1r,(nband_k))
     935        46234 :        ABI_MALLOC(vdot1i,(nband_k))
     936        46234 :        ABI_MALLOC(vdot2r,(nband_k))
     937        46234 :        ABI_MALLOC(vdot2i,(nband_k))
     938              : #ifdef HAVE_OPENMP_OFFLOAD
     939              :        !$OMP TARGET ENTER DATA MAP(alloc:vdotr,vdoti,vdot1r,vdot1i,vdot2r,vdot2i) IF(gpu_option==ABI_GPU_OPENMP)
     940              : #endif
     941       231170 :        d2nl_k(:,:)=zero
     942       231170 :        d2ovl_k(:,:)=zero
     943       160469 :        eig_k (:)=eigen0(1+bdtot_index:nband_k+bdtot_index)
     944       160469 :        eig_kq(:)=eigenq(1+bdtot_index:nband_k+bdtot_index)
     945      2443013 :        eig1_k(:)=eigen1(1+bd2tot_index:2*nband_k**2+bd2tot_index)
     946       160469 :        occ_k(:)=occ_rbz(1+bdtot_index:nband_k+bdtot_index)
     947       160469 :        nband_kocc=count(abs(occ_k(:))>tol8)
     948        92468 :        kpoint(:)=kpt_rbz(:,ikpt)
     949        86912 :        kpq(:)=kpoint(:);if (ipert1<dtset%natom+3) kpq(:)=kpq(:)+dtset%qptn(1:3)
     950        23117 :        wtk_k=wtk_rbz(ikpt)
     951        23117 :        need_ylmgr1=0;dimylmgr1=0
     952        23117 :        nkpg=0;nkpg1=0
     953        23117 :        ikpt_me=ikpt_me+1
     954        23117 :        if (is_metal) then
     955              : !        For each pair of active bands (m,n), generates the ratios
     956              : !        rocceig(m,n)=(occ_kq(m)-occ_k(n))/(eig0_kq(m)-eig0_k(n))
     957        11784 :          ABI_MALLOC(doccde_k,(nband_k))
     958        11784 :          ABI_MALLOC(doccde_kq,(nband_k))
     959        11784 :          ABI_MALLOC(occ_kq,(nband_k))
     960        23568 :          ABI_MALLOC(rocceig,(nband_k,nband_k))
     961        69172 :          doccde_k(:)=doccde_rbz(1+bdtot_index:nband_k+bdtot_index)
     962        69172 :          doccde_kq(:)=docckqde(1+bdtot_index:nband_k+bdtot_index)
     963        69172 :          occ_kq(:)=occkq(1+bdtot_index:nband_k+bdtot_index)
     964         5892 :          call occeig(doccde_k,doccde_kq,eig_k,eig_kq,nband_k,dtset%occopt,occ_k,occ_kq,rocceig)
     965              :        end if
     966              : 
     967              : !      Take care of the npw and kg records in WF and DDK files
     968        23117 :        if (need_ddk_file) then
     969         6208 :          do kdir1=1,mdir1
     970         4656 :            idir1=jdir1(kdir1)
     971         6208 :            if (ddkfil(idir1)/=0)then
     972              :              !ik_ddk = wfk_findk(ddks(idir1), kpt_rbz(:,ikpt)
     973         4656 :              ik_ddk = indkpt1(ikpt)
     974         4656 :              npw_ = ddks(idir1)%hdr%npwarr(ik_ddk)
     975         4656 :              if (npw_/=npw_k) then
     976              :                write(msg, '(a,i0,a,i0,a,i0,a,a,i0,a,a,i0)')&
     977            0 :                'For isppol = ',isppol,', ikpt = ',ikpt,' and idir = ',idir,ch10,&
     978            0 :                'the number of plane waves in the ddk file is equal to', npw_,ch10,&
     979            0 :                'while it should be ',npw_k
     980            0 :                ABI_ERROR(msg)
     981              :              end if
     982              : 
     983              : !   NB: this will fail if the bands are not contiguous.
     984         4656 :              startband = nband_k
     985         4656 :              endband = 1
     986        34944 :              do iband=1,nband_k
     987        34944 :                if(mpi_enreg%proc_distrb(ikpt,iband,isppol) == mpi_enreg%me_kpt) then
     988        30288 :                  if (iband < startband) startband = iband
     989        30288 :                  if (iband > endband) endband = iband
     990              :                end if
     991              :              end do
     992              : ! NB: eig_k is band distributed in call to read_band_block, though array has full size,
     993              : !     only certain columns for my iband are filled, then used below
     994              :              call ddks(idir1)%read_band_block((/startband,endband/),ik_ddk,isppol,xmpio_collective, &
     995        13968 : &                 cg_k=cg_ddk(:,:,idir1))
     996              :            end if ! ddk file is already present
     997              :          end do
     998              :        end if
     999              : 
    1000              : !      Allocate arrays used for NL form factors
    1001        69351 :        ABI_MALLOC(kg_k,(3,npw_k))
    1002        69351 :        ABI_MALLOC(kg1_k,(3,npw1_k))
    1003        92468 :        ABI_MALLOC(ylm_k,(npw_k,psps%mpsang*psps%mpsang*psps%useylm))
    1004        92468 :        ABI_MALLOC(ylm1_k,(npw1_k,psps%mpsang*psps%mpsang*psps%useylm))
    1005        23117 :        if (psps%useylm==1.and.(need_ddk_file.or.ipert1==dtset%natom+1)) need_ylmgr1=1
    1006        23117 :        if (psps%useylm==1.and.(ipert1==dtset%natom+3.or.ipert1==dtset%natom+4)) need_ylmgr1=1
    1007        23117 :        dimylmgr1=max(useylmgr1,need_ylmgr1)
    1008        92468 :        ABI_MALLOC(ylmgr1_k,(npw1_k,3,psps%mpsang*psps%mpsang*psps%useylm*dimylmgr1))
    1009              : 
    1010              : !      Get plane-wave vectors and related data at k
    1011     12635225 :        kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
    1012        23117 :        if (psps%useylm==1) then
    1013       121095 :          do jj=1,psps%mpsang*psps%mpsang
    1014     13489493 :            ylm_k(1:npw_k,jj)=ylm(1+ikg:npw_k+ikg,jj)
    1015              :          end do
    1016              :        end if
    1017              : 
    1018              : !      Get plane-wave vectors and related data at k+q
    1019     12635225 :        kg1_k(:,1:npw1_k)=kg1(:,1+ikg1:npw1_k+ikg1)
    1020        23117 :        if (psps%useylm==1) then
    1021       121095 :          do jj=1,psps%mpsang*psps%mpsang
    1022     13489493 :            ylm1_k(1:npw1_k,jj)=ylm1(1+ikg1:npw1_k+ikg1,jj)
    1023              :          end do
    1024        23117 :          if (need_ylmgr1==1.and.useylmgr1/=0) then
    1025        35925 :            do jj=1,psps%mpsang*psps%mpsang
    1026       123819 :              do ia=1,3
    1027     14630142 :                ylmgr1_k(1:npw1_k,ia,jj)=ylmgr1(1+ikg1:npw1_k+ikg1,ia,jj)
    1028              :              end do
    1029              :            end do
    1030              :          end if
    1031              :        end if
    1032              : 
    1033              : !      If Ylm gradients at k+q are needed and not in memory, compute them
    1034         7379 :        if (need_ylmgr1==1.and.useylmgr1==0) then
    1035          752 :          option=-1;npwar1_tmp(1)=npw1_k;nband_tmp(1)=nband_k
    1036              :          !Subtlety: initylmg is called in sequential mode
    1037              :          call initylmg(gprimd,kg1_k,kpq,1,mpi_enreg_seq,psps%mpsang,&
    1038              : &         npw1_k,nband_tmp,1,npwar1_tmp,nsppol,option,rprimd,&
    1039          752 : &         ylm1_k,ylmgr1_k)
    1040              :        end if
    1041              : 
    1042              : !      Compute (k+G) vectors
    1043        23117 :        nkpg=0;if(ipert1<=dtset%natom) nkpg=3*dtset%nloalg(3)
    1044        92468 :        ABI_MALLOC(kpg_k,(npw_k,nkpg))
    1045        23117 :        if (nkpg>0) then
    1046        15738 :          call mkkpg(kg_k,kpg_k,kpoint,nkpg,npw_k)
    1047              :        end if
    1048              : 
    1049              : !      Compute (k+q+G) vectors
    1050        23117 :        nkpg1=0;if(ipert1<=dtset%natom.or.need_ylmgr1==1) nkpg1=3*dtset%nloalg(3)
    1051        92468 :        ABI_MALLOC(kpg1_k,(npw1_k,nkpg1))
    1052        23117 :        if (nkpg1>0) then
    1053        23117 :          call mkkpg(kg1_k,kpg1_k,kpq,nkpg1,npw1_k)
    1054              :        end if
    1055              : 
    1056              : !      Allocate kinetic contributions
    1057        69351 :        ABI_MALLOC(dkinpw,(npw_k))
    1058        69351 :        ABI_MALLOC(kinpw1,(npw1_k))
    1059      3176144 :        dkinpw=zero
    1060              : !      Compute (1/2) (2 Pi)**2 (k+q+G)**2:
    1061              : !       call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg1_k,kinpw1,kpq,npw1_k)
    1062        23117 :        call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg1_k,kinpw1,kpq,npw1_k,0,0)
    1063              : 
    1064              : !      Compute nonlocal form factors ffnl at (k+G), for all atoms
    1065        23117 :        ider=0;idir0=0
    1066        23117 :        dimffnl=0;if (ipert1<=dtset%natom) dimffnl=1
    1067       138702 :        ABI_MALLOC(ffnlk,(npw_k,dimffnl,psps%lmnmax,psps%ntypat))
    1068        23117 :        if (ipert1<=dtset%natom) then
    1069              :          call mkffnl(psps%dimekb,dimffnl,psps%ekb,ffnlk,psps%ffspl,gs_hamkq%gmet,gs_hamkq%gprimd,&
    1070              : &         ider,idir0,psps%indlmn,kg_k,kpg_k,kpoint,psps%lmnmax,psps%lnmax,psps%mpsang,&
    1071              : &         psps%mqgrid_ff,nkpg,npw_k,psps%ntypat,psps%pspso,psps%qgrid_ff,rmet,usepaw,&
    1072        15738 : &         psps%useylm,ylm_k,ylmgr_dum)
    1073              : #ifdef HAVE_OPENMP_OFFLOAD
    1074              :          !$OMP TARGET ENTER DATA MAP(to:ffnlk) IF(gpu_option==ABI_GPU_OPENMP)
    1075              : #endif
    1076              :        end if
    1077              : 
    1078              : !      Compute nonlocal form factors ffnl1 at (k+q+G), for all atoms
    1079        23117 :        ider=1;if (ipert1<=dtset%natom) ider=0
    1080        23117 :        if(ipert1==dtset%natom+3.or.ipert1==dtset%natom+4)then
    1081         1852 :          dimffnl1=1;if (ider>=1) dimffnl1=2+5*psps%useylm
    1082         1852 :          idir0=0;if (ider>0.and.psps%useylm==1) idir0=-7
    1083              :        else
    1084        21265 :          dimffnl1=1;if (ider>=1) dimffnl1=2+2*psps%useylm
    1085        21265 :          idir0=0;if (ider>0.and.psps%useylm==1) idir0=4
    1086              :        end if
    1087       138702 :        ABI_MALLOC(ffnl1,(npw1_k,dimffnl1,psps%lmnmax,psps%ntypat))
    1088              :        call mkffnl(psps%dimekb,dimffnl1,psps%ekb,ffnl1,psps%ffspl,gs_hamkq%gmet,gs_hamkq%gprimd,&
    1089              : &       ider,idir0,psps%indlmn,kg1_k,kpg1_k,kpq,psps%lmnmax,psps%lnmax,psps%mpsang,&
    1090              : &       psps%mqgrid_ff,nkpg1,npw1_k,psps%ntypat,psps%pspso,psps%qgrid_ff,rmet,usepaw,&
    1091        23117 : &       psps%useylm,ylm1_k,ylmgr1_k)
    1092              : #ifdef HAVE_OPENMP_OFFLOAD
    1093              :        !$OMP TARGET ENTER DATA MAP(to:ffnl1) IF(gpu_option==ABI_GPU_OPENMP)
    1094              : #endif
    1095              : 
    1096              : !      Extract non-local form factors for H^(j1)
    1097        23117 :        if (ipert1<=dtset%natom) then
    1098        15738 :          ffnl1_idir1 => ffnl1(:,:,:,:)
    1099        15738 :          dimffnl1_idir1=dimffnl1
    1100              :        else
    1101         7379 :          dimffnl1_idir1=1+ider
    1102        44274 :          ABI_MALLOC(ffnl1_idir1,(npw1_k,dimffnl1_idir1,psps%lmnmax,psps%ntypat))
    1103         7379 :          ii=1;if (psps%useylm==0) ii=1+ider
    1104        20818 :          do itypat=1,psps%ntypat
    1105       137316 :            do ilmn=1,psps%lmnmax
    1106     38524081 :              ffnl1_idir1(1:npw1_k,1:ii,ilmn,itypat)=ffnl1(1:npw1_k,1:ii,ilmn,itypat)
    1107              :            end do
    1108              :          end do
    1109              : #ifdef HAVE_OPENMP_OFFLOAD
    1110              :          !$OMP TARGET ENTER DATA MAP(to:ffnl1_idir1) IF(gpu_option==ABI_GPU_OPENMP)
    1111              : #endif
    1112              :        end if
    1113              : 
    1114              : !      Load k-dependent part in the Hamiltonian datastructure
    1115        92468 :        ABI_MALLOC(ph3d,(2,npw_k,gs_hamkq%matblk))
    1116              :        call gs_hamkq%load_k(kpt_k=kpoint,npw_k=npw_k,istwf_k=istwf_k,kg_k=kg_k,kpg_k=kpg_k,&
    1117        23117 : &       ph3d_k=ph3d,compute_ph3d=.true.,compute_gbound=.true.)
    1118              : #ifdef HAVE_OPENMP_OFFLOAD
    1119              :        !$OMP TARGET ENTER DATA MAP(to:ph3d) IF(gpu_option==ABI_GPU_OPENMP)
    1120              : #endif
    1121       115585 :        if (size(ffnlk)>0) then
    1122        15738 :          call gs_hamkq%load_k(ffnl_k=ffnlk)
    1123              :        else
    1124         7379 :          call gs_hamkq%load_k(ffnl_k=ffnl1)
    1125              :        end if
    1126              : 
    1127              : !      Load k+q-dependent part in the Hamiltonian datastructure
    1128              : !          Note: istwf_k is imposed to 1 for RF calculations (should use istwf_kq instead)
    1129              :        call gs_hamkq%load_kprime(kpt_kp=kpq,npw_kp=npw1_k,istwf_kp=istwf_k,&
    1130              : &       kinpw_kp=kinpw1,kg_kp=kg1_k,kpg_kp=kpg1_k,ffnl_kp=ffnl1_idir1,&
    1131        23117 : &       compute_gbound=.true.)
    1132        23117 :        if (qne0) then
    1133        45440 :          ABI_MALLOC(ph3d1,(2,npw1_k,gs_hamkq%matblk))
    1134        11360 :          call gs_hamkq%load_kprime(ph3d_kp=ph3d1,compute_ph3d=.true.)
    1135              :        end if
    1136              : 
    1137              : !      Load k-dependent part in the 1st-order Hamiltonian datastructure
    1138        23117 :        call rf_hamkq%load_k(npw_k=npw_k,dkinpw_k=dkinpw)
    1139              : 
    1140              : !      Allocate memory space for one band
    1141        69351 :        ABI_MALLOC(gh1,(2,npw1_k*nspinor*ndat))
    1142              : #ifdef HAVE_OPENMP_OFFLOAD
    1143              :        !$OMP TARGET ENTER DATA MAP(alloc:gh1) IF(gpu_option==ABI_GPU_OPENMP)
    1144              : #endif
    1145        23117 :        nullify(cwaveprj0_idir1)
    1146        23117 :        if (usecprj==1) then
    1147       167526 :          ABI_MALLOC(cwaveprj0,(dtset%natom,nspinor*ndat))
    1148        23117 :          call pawcprj_alloc(cwaveprj0,ncpgr,gs_hamkq%dimcprj)
    1149              :        end if
    1150        23117 :        if (has_dcwf) then
    1151        43130 :          ABI_MALLOC(gs1,(2,npw1_k*nspinor*ndat))
    1152              : #ifdef HAVE_OPENMP_OFFLOAD
    1153              :          !$OMP TARGET ENTER DATA MAP(alloc:gs1) IF(gpu_option==ABI_GPU_OPENMP)
    1154              : #endif
    1155              :        else
    1156         1552 :          ABI_MALLOC(gs1,(1,1))
    1157              :        end if
    1158              : 
    1159        69351 :        ABI_MALLOC(band_procs, (nband_k))
    1160              :        call proc_distrb_band(band_procs,mpi_enreg%proc_distrb,ikpt,isppol,nband_k,&
    1161        23117 : &        mpi_enreg%me_band,mpi_enreg%me_kpt,mpi_enreg%comm_band)
    1162              : 
    1163        46234 :        ABI_MALLOC(gvnlx1,    (2,npw1_k*nspinor*ndat))
    1164        69351 :        ABI_MALLOC(gvnlx1_tmp,(2,npw1_k*nspinor))
    1165              : #ifdef HAVE_OPENMP_OFFLOAD
    1166              :        !$OMP TARGET ENTER DATA MAP(alloc:gvnlx1(1:2,1:npw1_k*nspinor*ndat)) IF(gpu_option==ABI_GPU_OPENMP)
    1167              :        !$OMP TARGET ENTER DATA MAP(alloc:gvnlx1_tmp(1:2,1:npw1_k*nspinor)) IF(gpu_option==ABI_GPU_OPENMP)
    1168              : #endif
    1169        23117 :        if (has_dcwf.and.is_metal_or_qne0) then
    1170        48624 :          ABI_MALLOC(gvnlx2,    (2,npw1_k*nspinor*nband_k))
    1171              : #ifdef HAVE_OPENMP_OFFLOAD
    1172              :          !$OMP TARGET ENTER DATA MAP(alloc:gvnlx2(1:2,1:npw1_k*nspinor*nband_k)) IF(gpu_option==ABI_GPU_OPENMP)
    1173              : #endif
    1174              :        end if
    1175              : 
    1176              : !      LOOP OVER BANDS
    1177        23117 :        iband_me = 0
    1178       160469 :        do iband=1,nband_k,ndat
    1179              : 
    1180              : !        Skip band if not to be treated by this proc
    1181              :          if (xmpi_paral==1) then
    1182       137352 :            if (mpi_enreg%proc_distrb(ikpt,iband,isppol)/=me) cycle
    1183              :          end if
    1184       135408 :          iband_me = iband_me + ndat
    1185              : 
    1186       135408 :          if(gpu_option==ABI_GPU_DISABLED) then
    1187      3590292 :            ch1c_tmp(:,:) = zero
    1188            0 :          else if(gpu_option==ABI_GPU_OPENMP) then
    1189            0 :            call gpu_set_to_zero(ch1c_tmp,int(2,c_size_t)*mband_mem_rbz)
    1190              :          end if
    1191              : 
    1192              : !        Extract GS wavefunctions
    1193              :          if (need_wfk) then
    1194              :            cwave0(1:2,1:npw_k*nspinor*ndat) => &
    1195       135408 :            &    cg(:,1+(iband_me-ndat)*npw_k*nspinor+icg:iband_me*npw_k*nspinor+icg)
    1196       135408 :            if (usecprj==1) then
    1197       270816 :              do idat=1,ndat
    1198              :                call pawcprj_get(gs_hamkq%atindx1,cwaveprj0(:,1+(idat-1)*nspinor:idat*nspinor),cprj,dtset%natom,iband_me-(ndat-idat),ibg,ikpt,iorder_cprj,&
    1199       270816 : &               isppol,mband_mem_rbz,mkmem,dtset%natom,1,nband_me,nspinor,nsppol,dtfil%unpaw)
    1200              :              end do
    1201              : ! in distributed cprj memory, no need for these? cg and cprj have same distribution
    1202              : !&             mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
    1203              :            end if
    1204              :          end if
    1205              : 
    1206              : !        Extract 1st-order wavefunctions
    1207              :          if (need_wf1) then
    1208              :            cwavef(1:2,1:npw1_k*nspinor*ndat) => &
    1209       135408 :            &    cg1(:,1+(iband_me-ndat)*npw1_k*nspinor+icg1:iband_me*npw1_k*nspinor+icg1)
    1210              :          end if
    1211              : 
    1212              : !        LOOP OVER PERTURBATION DIRECTIONS
    1213       564749 :          do kdir1=1,mdir1
    1214       406224 :            idir1=jdir1(kdir1)
    1215       406224 :            istr1=idir1;if(ipert1==dtset%natom+4) istr1=idir1+3
    1216              : 
    1217              : !          Not able to compute if ipert1=(Elect. field) and no ddk WF file
    1218       406224 :            if (ipert1==dtset%natom+2.and.ddkfil(idir1)==0) cycle
    1219              : 
    1220       406224 :            if(gpu_option==ABI_GPU_DISABLED) then
    1221    213262110 :              gvnlx1(:,:)=zero
    1222            0 :            else if(gpu_option==ABI_GPU_OPENMP) then
    1223            0 :              call gpu_set_to_zero(gvnlx1,int(2,c_size_t)*npw1_k*nspinor*ndat)
    1224              :            end if
    1225              : 
    1226              : !          Extract 1st-order NL form factors derivatives for this idir1
    1227       406224 :            if (dimffnl1_idir1>=2.and.psps%useylm==1.and.ipert1>dtset%natom) then
    1228       447612 :              do itypat=1,psps%ntypat
    1229      3305640 :                do ilmn=1,psps%lmnmax
    1230   1087613088 :                  ffnl1_idir1(1:npw1_k,2,ilmn,itypat)=ffnl1(1:npw1_k,1+istr1,ilmn,itypat)
    1231              :                end do
    1232              :              end do
    1233              : #ifdef HAVE_OPENMP_OFFLOAD
    1234              :              !$OMP TARGET UPDATE TO(ffnl1_idir1) IF(gpu_option==ABI_GPU_OPENMP)
    1235              : #endif
    1236              :            end if
    1237              : 
    1238              :            ! Setup gemm_nonlop
    1239       406224 :            if (gemm_nonlop_use_gemm) then
    1240              :              call set_gemm_nonlop_ikpt(ikpt,gs_hamkq%npw_fft_k,gs_hamkq%istwf_k,gs_hamkq%indlmn,&
    1241            0 :              &    gs_hamkq%ntypat,gs_hamkq%nattyp,gs_hamkq%gpu_option)
    1242              :            end if ! gemm_nonlop_use_gemm
    1243              : 
    1244              : !          Extract ground state projected WF and derivatives in idir1 direction
    1245       406224 :            if (usecprj==1) then
    1246       406224 :              cpopt=1
    1247              : 
    1248              : !            === Atomic displ. perturbation
    1249       406224 :              if (ipert<=dtset%natom) then
    1250      1458864 :                ABI_MALLOC(cwaveprj0_idir1,(dtset%natom,nspinor*ndat))
    1251       202896 :                call pawcprj_alloc(cwaveprj0_idir1,1,gs_hamkq%dimcprj)
    1252       202896 :                if (ipert1<=dtset%natom) then
    1253       188688 :                  call pawcprj_copy(cwaveprj0,cwaveprj0_idir1,icpgr=idir1)
    1254              :                else
    1255        14208 :                  if (ipert1==dtset%natom+2) then
    1256        14208 :                    idir_cprj=idir1;choice=5
    1257              :                  end if
    1258        14208 :                  if (ipert1==dtset%natom+3.or.ipert1==dtset%natom+4) then
    1259            0 :                    idir_cprj=istr1;choice=3
    1260              :                  end if
    1261        14208 :                  call pawcprj_copy(cwaveprj0,cwaveprj0_idir1,icpgr=-1)
    1262              :                  call getcprj(choice,cpopt,cwave0,&
    1263              : &                 cwaveprj0_idir1,&
    1264              : &                 gs_hamkq%ffnl_kp,idir_cprj,gs_hamkq%indlmn,gs_hamkq%istwf_kp,&
    1265              : &                 gs_hamkq%kg_kp,gs_hamkq%kpg_kp,gs_hamkq%kpt_kp,gs_hamkq%lmnmax,&
    1266              : &                 gs_hamkq%mgfft,mpi_enreg,ndat,gs_hamkq%natom,gs_hamkq%nattyp,gs_hamkq%ngfft,&
    1267              : &                 gs_hamkq%nloalg,gs_hamkq%npw_kp,gs_hamkq%nspinor,gs_hamkq%ntypat,gs_hamkq%phkpxred,&
    1268        14208 : &                 gs_hamkq%ph1d,gs_hamkq%ph3d_kp,gs_hamkq%ucvol,gs_hamkq%useylm,is_kprime=.true.,gpu_option=gpu_option)
    1269              :                end if
    1270              : 
    1271              : !            === Wave-vector perturbation
    1272       203328 :              else if (ipert==dtset%natom+1) then
    1273        94572 :                cwaveprj0_idir1 => cwaveprj0
    1274              : 
    1275              : !            == Electric field perturbation
    1276       108756 :              else if (ipert==dtset%natom+2) then
    1277       465360 :                ABI_MALLOC(cwaveprj0_idir1,(dtset%natom,nspinor*ndat))
    1278        62640 :                call pawcprj_alloc(cwaveprj0_idir1,1,gs_hamkq%dimcprj)
    1279        62640 :                if (ipert1==dtset%natom+2) then
    1280        11760 :                  call pawcprj_copy(cwaveprj0,cwaveprj0_idir1,icpgr=idir1)
    1281              :                else
    1282        50880 :                  if (ipert1<=dtset%natom) then
    1283        27360 :                    idir_cprj=idir1;choice=2
    1284              :                  end if
    1285        50880 :                  if (ipert1==dtset%natom+3.or.ipert1==dtset%natom+4) then
    1286        23520 :                    idir_cprj=istr1;choice=3
    1287              :                  end if
    1288        50880 :                  call pawcprj_copy(cwaveprj0,cwaveprj0_idir1,icpgr=-1)
    1289              :                  call getcprj(choice,cpopt,cwave0,&
    1290              : &                 cwaveprj0_idir1,&
    1291              : &                 gs_hamkq%ffnl_kp,idir_cprj,gs_hamkq%indlmn,gs_hamkq%istwf_kp,&
    1292              : &                 gs_hamkq%kg_kp,gs_hamkq%kpg_kp,gs_hamkq%kpt_kp,gs_hamkq%lmnmax,&
    1293              : &                 gs_hamkq%mgfft,mpi_enreg,ndat,gs_hamkq%natom,gs_hamkq%nattyp,gs_hamkq%ngfft,gs_hamkq%nloalg,&
    1294              : &                 gs_hamkq%npw_kp,gs_hamkq%nspinor,gs_hamkq%ntypat,gs_hamkq%phkpxred,gs_hamkq%ph1d,&
    1295        50880 : &                 gs_hamkq%ph3d_kp,gs_hamkq%ucvol,gs_hamkq%useylm,is_kprime=.true.,gpu_option=gpu_option)
    1296              :                end if
    1297              : 
    1298              : !            === Strain perturbation
    1299        46116 :              else if (ipert==dtset%natom+3.or.ipert==dtset%natom+4) then
    1300        46116 :                if ((ipert1==dtset%natom+3.or.ipert1==dtset%natom+4).and.(istr==istr1)) then
    1301         2484 :                  cwaveprj0_idir1 => cwaveprj0
    1302              :                else
    1303       384912 :                  ABI_MALLOC(cwaveprj0_idir1,(dtset%natom,nspinor*ndat))
    1304        43632 :                  call pawcprj_alloc(cwaveprj0_idir1,ncpgr,gs_hamkq%dimcprj)
    1305        43632 :                  if (ipert1<=dtset%natom) then
    1306        26892 :                    idir_cprj=idir1;choice=2
    1307              :                  end if
    1308        43632 :                  if (ipert1==dtset%natom+2) then
    1309         4320 :                    idir_cprj=idir1;choice=5
    1310              :                  end if
    1311        43632 :                  if (ipert1==dtset%natom+3.or.ipert1==dtset%natom+4) then
    1312        12420 :                    idir_cprj=istr1;choice=3
    1313              :                  end if
    1314        43632 :                  call pawcprj_copy(cwaveprj0,cwaveprj0_idir1,icpgr=-1)
    1315              :                  call getcprj(choice,cpopt,cwave0,&
    1316              : &                 cwaveprj0_idir1,&
    1317              : &                 gs_hamkq%ffnl_kp,idir_cprj,gs_hamkq%indlmn,gs_hamkq%istwf_kp,gs_hamkq%kg_kp,&
    1318              : &                 gs_hamkq%kpg_kp,gs_hamkq%kpt_kp,gs_hamkq%lmnmax,gs_hamkq%mgfft,mpi_enreg,ndat,&
    1319              : &                 gs_hamkq%natom,gs_hamkq%nattyp,gs_hamkq%ngfft,gs_hamkq%nloalg,gs_hamkq%npw_kp,&
    1320              : &                 gs_hamkq%nspinor,gs_hamkq%ntypat,gs_hamkq%phkpxred,gs_hamkq%ph1d,gs_hamkq%ph3d_kp,&
    1321        43632 : &                 gs_hamkq%ucvol,gs_hamkq%useylm,is_kprime=.true.,gpu_option=gpu_option)
    1322              :                end if
    1323              :              end if ! ipert
    1324              : 
    1325              :            else ! usecprj=0: cwaveprj0_idir1 is not used
    1326            0 :              cwaveprj0_idir1 => cwaveprj0
    1327              :            end if
    1328              : 
    1329              : !          Eventually compute 1st-order kinetic operator
    1330       406224 :            if (ipert1==dtset%natom+1) then
    1331        94572 :              call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,dkinpw,kpoint,npw_k,idir1,0)
    1332       311652 :            else if (ipert1==dtset%natom+3.or.ipert1==dtset%natom+4) then
    1333        38424 :              call kpgstr(dkinpw,dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,gprimd,istr1,kg_k,kpoint,npw_k)
    1334              :            end if
    1335              : 
    1336              : !          Finalize initialization of 1st-order NL hamiltonian
    1337       406224 :            if (need_pawij10) rf_hamkq%e1kbfr => e1kbfr(:,:,:,:,idir1)
    1338              : 
    1339              : !          Read DDK wave function (if ipert1=electric field)
    1340       406224 :            if (ipert1==dtset%natom+2) then
    1341        30288 :              usevnl=1
    1342        30288 :              if (need_ddk_file) then
    1343        30288 :                if (ddkfil(idir1)/=0) then
    1344              :                  !ik_ddk = wfk_findk(ddks(idir1), kpt_rbz(:,ikpt)
    1345              :                  !ik_ddk = indkpt1(ikpt)
    1346              :                  !call ddks(idir1)%read_bks(iband, ik_ddk, isppol, xmpio_single, cg_bks=gvnlx1)
    1347     17863404 :                  gvnlx1 = cg_ddk(:,1+(iband_me-ndat)*npw_k*nspinor:iband_me*npw_k*nspinor,idir1)
    1348              :                else
    1349            0 :                  gvnlx1=zero
    1350              :                end if
    1351        30288 :                if (ipert1==dtset%natom+2) then
    1352      5964564 :                  do ii=1,npw1_k*nspinor*ndat ! Multiply ddk by +i (to be consistent with getgh1c)
    1353      5934276 :                    arg=gvnlx1(1,ii)
    1354      5934276 :                    gvnlx1(1,ii)=-gvnlx1(2,ii)
    1355      5964564 :                    gvnlx1(2,ii)=arg
    1356              :                  end do
    1357              :                end if
    1358              :              else
    1359            0 :                gvnlx1=zero
    1360              :              end if
    1361              : #ifdef HAVE_OPENMP_OFFLOAD
    1362              :              !$OMP TARGET UPDATE TO(gvnlx1) IF(gpu_option==ABI_GPU_OPENMP)
    1363              : #endif
    1364              :            else
    1365       375936 :              usevnl=0
    1366              :            end if
    1367              : 
    1368              : !          Get |H^(j2)-Eps_k_i.S^(j2)|u0_k_i> (VHxc-dependent part not taken into account) and S^(j2)|u0>
    1369       406224 :            lambda=eig_k(iband);berryopt=0;optlocal=0
    1370       406224 :            optnl=0;if (ipert1/=dtset%natom+1.or.idir==idir1) optnl=1
    1371       406224 :            opt_gvnlx1=0;if (ipert1==dtset%natom+2) opt_gvnlx1=2
    1372       406224 :            sij_opt=-1;if (has_dcwf) sij_opt=1
    1373       406224 :            if (usepaw==0) sij_opt=0
    1374              :            call getgh1c(berryopt,cwave0,&
    1375              : &             cwaveprj0_idir1,&
    1376              : &             gh1,dum1,&
    1377              : &             gs1,gs_hamkq,&
    1378              : &             gvnlx1,&
    1379              : &             idir1,ipert1,&
    1380       406224 : &             eig_k(iband:iband+ndat-1),mpi_enreg,ndat,optlocal,optnl,opt_gvnlx1,rf_hamkq,sij_opt,tim_getgh1c,usevnl)
    1381       406224 :            if (sij_opt==1.and.optnl==1) then
    1382       312888 :              if(gpu_option==ABI_GPU_DISABLED) then
    1383       625776 :                do idat=1,ndat
    1384              :                  gh1(:,1+(idat-1)*npw1_k*nspinor:idat*npw1_k*nspinor) = &
    1385    164157702 :   &                 gh1(:,1+(idat-1)*npw1_k*nspinor:idat*npw1_k*nspinor)-eig_k(iband+idat-1) * gs1(:,1+(idat-1)*npw1_k*nspinor:idat*npw1_k*nspinor)
    1386              :                end do
    1387            0 :              else if(gpu_option==ABI_GPU_OPENMP) then
    1388              : #ifdef HAVE_OPENMP_OFFLOAD
    1389              :                !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(2) PRIVATE(ipw,idat) MAP(to:gs1,gh1,eig_k)
    1390              : #endif
    1391            0 :                do idat=1,ndat
    1392            0 :                  do ispinor=1,nspinor
    1393            0 :                    do ipw=1,npw1_k
    1394              :                      gh1(1,(idat-1)*nspinor*npw1_k+(ispinor-1)*npw1_k+ipw) = &
    1395              :                      &    gh1(1,(idat-1)*nspinor*npw1_k+(ispinor-1)*npw1_k+ipw) &
    1396            0 :                      &    - eig_k(iband+idat-1) * gs1(1,(idat-1)*nspinor*npw1_k+(ispinor-1)*npw1_k+ipw)
    1397              :                      gh1(2,(idat-1)*nspinor*npw1_k+(ispinor-1)*npw1_k+ipw) = &
    1398              :                      &    gh1(2,(idat-1)*nspinor*npw1_k+(ispinor-1)*npw1_k+ipw) &
    1399            0 :                      &    - eig_k(iband+idat-1) * gs1(2,(idat-1)*nspinor*npw1_k+(ispinor-1)*npw1_k+ipw)
    1400              :                    end do
    1401              :                  end do
    1402              :                end do
    1403              :              end if
    1404              :            end if
    1405              : 
    1406              : !          If needed, compute here <delta_u^(j1)_k_i|H^(j2)-Eps_k_i.S^(j2)|u0_k_i>
    1407              : !          with delta_u^(j1)=-1/2 Sum_{j}[<u0_k+q_j|S^(j1)|u0_k_i>.|u0_k+q_j>]
    1408              : !          (see PRB 78, 035105 (2008) [[cite:Audouze2008]], Eq. (42))
    1409              : !          This can be rewritten as:
    1410              : !          -1/2.<u0_k_i|S^(j1)| Sum_{j}[<u0_k+q_j|H^(j2)-Eps_k_i.S^(j2)|u0_k_i>.|u0_k+q_j>
    1411              : !          The sum over j can be computed with a single call to projbd routine
    1412              : !          At first call (when j1=j2), ch1c=<u0_k+q_j|H^(j2)-Eps_k_i.S^(j2)|u0_k_i> is stored
    1413              : !          For the next calls, it is reused.
    1414       406224 :            if (has_dcwf.or.(ipert==ipert1.and.idir==idir1.and.usepaw==1)) then
    1415              : !            note: gvnlx1 used as temporary space
    1416       379856 :              if (ipert==ipert1.and.idir==idir1) then
    1417        70240 :                option=0;
    1418        70240 :                if(gpu_option==ABI_GPU_DISABLED) then
    1419     30052490 :                  gvnlx1=gh1
    1420              :                else if(gpu_option==ABI_GPU_OPENMP) then
    1421              : #ifdef HAVE_OPENMP_OFFLOAD
    1422              :                  call gpu_copy(gvnlx1, gh1, int(2,c_size_t)*npw1_k*nspinor*ndat)
    1423              : #endif
    1424              :                end if
    1425              :              else
    1426       309616 :                option=1;
    1427       309616 :                if(gpu_option==ABI_GPU_DISABLED) then
    1428    167264392 :                  gvnlx1=zero
    1429            0 :                else if(gpu_option==ABI_GPU_OPENMP) then
    1430            0 :                  call gpu_set_to_zero(gvnlx1,int(2,c_size_t)*npw1_k*nspinor*ndat)
    1431              :                end if
    1432              :              end if
    1433              : 
    1434              : 
    1435              : 
    1436       759712 :              do idat=1,ndat
    1437              : 
    1438       379856 :                bands_treated_now => bands_treated_now_ndat(:,idat)
    1439      3655972 :                bands_treated_now = 0
    1440       379856 :                bands_treated_now(iband+idat-1) = 1
    1441       379856 :                call xmpi_sum(bands_treated_now,mpi_enreg%comm_band,ierr)
    1442      4035828 :                do iband_=1, nband_k
    1443      3276116 :                  if (bands_treated_now(iband_) == 0) cycle
    1444              : 
    1445              : ! distribute gvnlx1 to my subcomm
    1446       385688 :                  if(gpu_option==ABI_GPU_DISABLED) then
    1447    223443986 :                    gvnlx1_tmp = zero
    1448            0 :                  else if(gpu_option==ABI_GPU_OPENMP) then
    1449            0 :                    call gpu_set_to_zero(gvnlx1_tmp,int(2,c_size_t)*npw1_k*nspinor)
    1450              :                  end if
    1451       385688 :                  if (iband_ == iband+idat-1) then
    1452       379856 :                    if(gpu_option==ABI_GPU_DISABLED) then
    1453    197626498 :                      gvnlx1_tmp = gvnlx1(:,1+(idat-1)*npw1_k*nspinor:idat*npw1_k*nspinor)
    1454              :                    else if(gpu_option==ABI_GPU_OPENMP) then
    1455              : #ifdef HAVE_OPENMP_OFFLOAD
    1456              :                      call gpu_copy(gvnlx1_tmp,&
    1457              :                      &    gvnlx1(:,1+(idat-1)*npw1_k*nspinor:idat*npw1_k*nspinor),&
    1458              :                      &    int(2,c_size_t)*npw1_k*nspinor)
    1459              : #endif
    1460              :                    end if
    1461              :                  end if
    1462              : 
    1463              : ! TODO CHECK IF IT IS BAND_PROCS(IBAND_)
    1464              :                  !call xmpi_bcast(gvnlx1_tmp, band_procs(iband_), mpi_enreg%comm_band, ierr)
    1465       385688 :                  if(xmpi_comm_size(mpi_enreg%comm_band)>1) then
    1466         7776 :                    call xmpi_sum(gvnlx1_tmp,mpi_enreg%comm_band,ierr,use_omp_map=use_ompgpu)
    1467              :                  end if
    1468              : 
    1469       385688 :                  if (option == 1) then
    1470              : ! in case I need to reuse the ch1c (option 1) then load them here
    1471       315232 :                    if(gpu_option==ABI_GPU_DISABLED) then
    1472      8050456 :                      ch1c_tmp(:,1:nband_me) = ch1c(:,1:nband_me,iband_,ikpt_me)
    1473              :                    else
    1474              : #ifdef HAVE_OPENMP_OFFLOAD
    1475              :                      call gpu_copy(ch1c_tmp, ch1c(:,1:nband_me,iband_,ikpt_me),&
    1476              : &                         int(2,c_size_t)*nband_me)
    1477              : #endif
    1478              :                    end if
    1479              :                  end if
    1480              : 
    1481              : 
    1482              : !            Compute -Sum_{j}[<u0_k+q_j|H^(j2)-Eps_k_i.S^(j2)|u0_k_i>.|u0_k+q_j>
    1483              :                  call projbd(cgq,gvnlx1_tmp,-1,icgq,0,istwf_k,mcgq,0,nband_me,npw1_k,nspinor,&
    1484       385688 :   &                 dum1,ch1c_tmp,option,tim_projbd,0,mpi_enreg%me_g0,mpi_enreg%comm_fft,gpu_option=gpu_option)
    1485              : 
    1486              : !sum over all jband by combining the projbd
    1487       385688 :                  if(xmpi_comm_size(mpi_enreg%comm_band)>1) then
    1488         7776 :                    call xmpi_sum(gvnlx1_tmp,mpi_enreg%comm_band,ierr,use_omp_map=use_ompgpu)
    1489              :                  end if
    1490              : 
    1491              : ! keep my own gvnlx
    1492       385688 :                if (iband_ == iband+idat-1) then
    1493              : ! if bands are parallelized, I have only projected against bands on my cpu
    1494              : !   Pc|work>  = |work> - Sum_l <psi_{k+q, l}|work> |psi_{k+q, l}>
    1495              : !             = Sum_nproc_band (|work> - Sum_{my l} <psi_{k+q, l}|work> |psi_{k+q, l}>) - (nproc_band-1) |work>
    1496              : !TODO: make this a blas call? zaxpy
    1497       379856 :                    if(gpu_option==ABI_GPU_DISABLED) then
    1498              :                      gvnlx1(:,1+(idat-1)*npw1_k*nspinor:idat*npw1_k*nspinor) = &
    1499    197246642 :                        gvnlx1_tmp - (my_nproc_band-1)*gvnlx1(:,1+(idat-1)*npw1_k*nspinor:idat*npw1_k*nspinor)
    1500              :                    else if(gpu_option==ABI_GPU_OPENMP) then
    1501              : #ifdef HAVE_OPENMP_OFFLOAD
    1502              :                      !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO PRIVATE(ipw) MAP(to:gvnlx1,gvnlx1_tmp)
    1503              :                      do ipw=1,npw1_k*nspinor
    1504              :                        gvnlx1(1,(idat-1)*npw1_k*nspinor + ipw) = &
    1505              :                          gvnlx1_tmp(1,ipw) - (my_nproc_band-1)*gvnlx1(1,(idat-1)*npw1_k*nspinor + ipw)
    1506              :                        gvnlx1(2,(idat-1)*npw1_k*nspinor + ipw) = &
    1507              :                          gvnlx1_tmp(2,ipw) - (my_nproc_band-1)*gvnlx1(2,(idat-1)*npw1_k*nspinor + ipw)
    1508              :                      end do
    1509              : #endif
    1510              :                    end if
    1511              :                  end if
    1512              : 
    1513       765544 :                  if (option == 0) then
    1514              : ! save ch1c for all of the iband_ on each proc, for later use. First band index only for my nband_me which matches cgq
    1515        70456 :                    if(gpu_option==ABI_GPU_DISABLED) then
    1516      2163580 :                      ch1c(:,1:nband_me,iband_,ikpt_me) = ch1c_tmp(:,1:nband_me)
    1517              :                    else if(gpu_option==ABI_GPU_OPENMP) then
    1518              : #ifdef HAVE_OPENMP_OFFLOAD
    1519              :                      call gpu_copy(ch1c(:,1:nband_me,iband_,ikpt_me), ch1c_tmp, &
    1520              : &                         int(2,c_size_t)*nband_me)
    1521              : #endif
    1522              :                    end if
    1523              :                  end if
    1524              :                end do ! iband_
    1525              :              end do !idat
    1526              : 
    1527       379856 :              if (has_dcwf) then
    1528       375936 :                if (ipert==ipert1.and.idir==idir1) then
    1529        66320 :                  if(gpu_option==ABI_GPU_DISABLED) then
    1530     28230922 :                    gvnlx1 = gvnlx1-gh1
    1531            0 :                  else if(gpu_option==ABI_GPU_OPENMP) then
    1532              :                    call abi_xaxpy(2*npw1_k*nspinor*ndat, cminusone, &
    1533            0 :                    &    gh1, 1, gvnlx1, 1, gpu_option=gpu_option)
    1534              :                  end if
    1535              :                end if
    1536       375936 :                do_scprod=0
    1537       751872 :                do idat=1,ndat
    1538       751872 :                  if (abs(occ_k(iband+idat-1))>tol8) do_scprod=1
    1539              :                end do !idat
    1540       375936 :                if(do_scprod==1) then
    1541              : !                Compute: -<u0_k_i|S^(j1)| Sum_{j}[<u0_k+q_j|H^(j2)-Eps_k_i.S^(j2)|u0_k_i>.|u0_k+q_j>
    1542              :                  call dotprod_g_batch_full(vdotr,vdoti,istwf_k,npw1_k*nspinor,ndat,2,&
    1543              : &                     gs1,&
    1544              : &                     gvnlx1,&
    1545       309414 : &                     mpi_enreg%me_g0,mpi_enreg%comm_spinorfft,gpu_option=gpu_option)
    1546              : #ifdef HAVE_OPENMP_OFFLOAD
    1547              :                  !$OMP TARGET UPDATE FROM(vdotr,vdoti) IF(gpu_option==ABI_GPU_OPENMP)
    1548              : #endif
    1549              : !                Add contribution to DDB
    1550              : !                Note: factor 2 (from d2E/dj1dj2=2E^(j1j2)) eliminated by factor 1/2
    1551              : !                (-1) factor already present
    1552       618828 :                  do idat=1,ndat
    1553       618828 :                    if (abs(occ_k(iband+idat-1))>tol8) then
    1554       309414 :                      d2ovl_k(1,idir1)=d2ovl_k(1,idir1)+wtk_k*occ_k(iband+idat-1)*elfd_fact*vdotr(idat)
    1555       309414 :                      d2ovl_k(2,idir1)=d2ovl_k(2,idir1)+wtk_k*occ_k(iband+idat-1)*elfd_fact*vdoti(idat)
    1556              :                    end if
    1557              :                  end do !idat
    1558              :                end if
    1559              :              end if
    1560              :            end if
    1561              : 
    1562              : 
    1563       402304 :            if (has_dcwf.and.is_metal_or_qne0) then
    1564              : 
    1565       302724 :              if(gpu_option==ABI_GPU_DISABLED) then
    1566   1599641766 :                gvnlx2 = zero
    1567            0 :              else if(gpu_option==ABI_GPU_OPENMP) then
    1568            0 :                call gpu_set_to_zero(gvnlx2,int(2,c_size_t)*npw1_k*nspinor*nband_k)
    1569              :              end if
    1570              : 
    1571       302724 :              jband_me = 0
    1572      3133440 :              do jband=1,nband_k
    1573      3133440 :                if (mpi_enreg%proc_distrb(ikpt,jband,isppol)==me) then
    1574      2830716 :                  jband_me = jband_me + 1
    1575              : ! gvnlx1 depends on j only, I have it, and everyone needs it
    1576      2830716 :                  if(gpu_option==ABI_GPU_DISABLED) then
    1577   1602169758 :                    gvnlx2(:,1+(jband-1)*npw1_k*nspinor:jband*npw1_k*nspinor)=cgq(:,1+npw1_k*nspinor*(jband_me-1)+icgq:npw1_k*nspinor*jband_me+icgq)
    1578              :                  else if(gpu_option==ABI_GPU_OPENMP) then
    1579              : #ifdef HAVE_OPENMP_OFFLOAD
    1580              :                    call gpu_copy(gvnlx2(:,1+(jband-1)*npw1_k*nspinor:jband*npw1_k*nspinor), &
    1581              : &                       cgq(:,1+npw1_k*nspinor*(jband_me-1)+icgq:npw1_k*nspinor*jband_me+icgq),&
    1582              : &                       int(2,c_size_t)*npw1_k*nspinor)
    1583              : #endif
    1584              :                  end if
    1585              :                end if
    1586              : ! xmpi bcast the current jband to other procs in band pool
    1587              :              end do
    1588              : 
    1589       302724 :              if(xmpi_comm_size(mpi_enreg%comm_band)>1) then
    1590            0 :                call xmpi_sum(gvnlx2, mpi_enreg%comm_band, ierr, use_omp_map=use_ompgpu)
    1591              :              end if
    1592              :            end if
    1593              : 
    1594       812448 :            do idat=1,ndat
    1595              : 
    1596       406224 :              bands_treated_now => bands_treated_now_ndat(:,idat)
    1597              : 
    1598              : !          If needed, compute here <delta_u^(j1)_k_i|H-Eps_k_i.S|u^(j2)_k_i>
    1599              : !          This is equal to <delta_u^(j1)_k_i|H-Eps_k_i.S|delta_u^(j2)_k_i>  (I)
    1600              : !                          +<delta_u^(j1)_k_i|H-Eps_k_i.S|u^paral^(j2)_k_i>  (II)
    1601              : !          (u^paral^(j2)_k_i is the part of u^(j2)_k_i parallel to active space : metals)
    1602              : !          (I) can be rewritten as:
    1603              : !          Sum_j{ 1/4.<u0_k_i|S^(j1)|u0_k+q_j>.<u0_k+q_j|S^(j2)|u0_k_i>.(Eps_k+q_j-Eps_k_i) }
    1604              : !          (II) can be rewritten as:
    1605              : !          Sum_j{1/2.(occ_kq_j-occ_k_i).Eps1_k,q_ij.<u0_k_i|S^(j1)|u0_k+q_j> }
    1606              : !          where Eps1_k,q_ij=<u0_k+q_j|H^(j2)-1/2(Eps_k+q_j-Eps_k_i)S^(j2)|u0_k_i>
    1607              : !          At first call (when j1=j2), cs1c=<u0_k_i|S^(j1)|u0_k+q_j> is stored
    1608              : !          For the next calls, it is reused.
    1609       812448 :              if (has_dcwf.and.is_metal_or_qne0) then
    1610              : ! dotX is local to my proc, and should accumulate sum over all jband, for my iband_me
    1611       302724 :                dotr=zero;doti=zero
    1612              : ! flag to broadcast the j dependent vector in the band pool, to get full sum over j
    1613       302724 :                do_bcast = 0
    1614              : ! flag to do scalar product: only needed if we are saving cs1c or if the band is occupied
    1615       302724 :                do_scprod = 0
    1616       302724 :                if ((ipert==ipert1.and.idir==idir1)) then
    1617       302724 :                  do_bcast = 1
    1618       302724 :                  do_scprod = 1
    1619              :                end if
    1620       302724 :                invocc=zero
    1621       302724 :                if (abs(occ_k(iband+idat-1))>tol8) then
    1622       236202 :                  invocc=two/occ_k(iband+idat-1)
    1623       236202 :                  do_scprod = 1
    1624              :                end if
    1625              :                ! does anyone else need the cgq(j) below?
    1626      3133440 :                do iband_ = 1, nband_k
    1627      3133440 :                  if (bands_treated_now(iband_) > 0 .and. abs(occ_k(iband_))>tol8) then
    1628      2830716 :                    do_bcast = 1
    1629              :                  end if
    1630              :                end do
    1631              : 
    1632              : 
    1633       302724 :                if (do_bcast > 0) then
    1634              : !              Computation of cs1c=<u0_k_i|S^(j1)|u0_k+q_j>
    1635              : !                  do _I_ need to calculate the dot1X?
    1636       249990 :                  if (do_scprod > 0) then
    1637              :                    call dotprod_g_batch_half(vdot1r,vdot1i,istwf_k,npw1_k*nspinor,nband_k,2,&
    1638              : &                     gs1(:,1+(idat-1)*npw1_k*nspinor:idat*npw1_k*nspinor),&
    1639       249990 : &                     gvnlx2,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft,gpu_option=gpu_option)
    1640              : #ifdef HAVE_OPENMP_OFFLOAD
    1641              :                    !$OMP TARGET UPDATE FROM(vdot1r,vdot1i) IF(gpu_option==ABI_GPU_OPENMP)
    1642              : #endif
    1643       249990 :                    if (ipert==ipert1.and.idir==idir1.and.has_dcwf2) then
    1644       643848 :                      cs1c(1,:,iband_me-(ndat-idat),ikpt_me)=vdot1r(:)
    1645       643848 :                      cs1c(2,:,iband_me-(ndat-idat),ikpt_me)=vdot1i(:)
    1646              :                    end if
    1647              :                  end if
    1648              :                end if ! ipert==ipert1.and.idir==idir1 or some iband for some proc in pool is filled
    1649              : 
    1650       302724 :                if (do_scprod > 0) then
    1651      2297790 :                  do jband=1,nband_k
    1652              : !                Computation of term (I)
    1653      2047800 :                    if (has_dcwf2) then
    1654      1891128 :                      arg=eig_kq(jband)-eig_k(iband+idat-1)
    1655      1891128 :                      dot2r=cs1c(1,jband,iband_me-(ndat-idat),ikpt_me)
    1656      1891128 :                      dot2i=cs1c(2,jband,iband_me-(ndat-idat),ikpt_me)
    1657      1891128 :                      dotr=dotr+(vdot1r(jband)*dot2r+vdot1i(jband)*dot2i)*arg
    1658      1891128 :                      doti=doti+(vdot1i(jband)*dot2r-vdot1r(jband)*dot2i)*arg
    1659              :                    end if
    1660              : !                Computation of term (II) TODO: the next two ifs could be combined
    1661      2297790 :                    if (is_metal) then
    1662      1522488 :                      if (abs(rocceig(jband,iband+idat-1))>tol8) then
    1663       496836 :                        ii=2*jband-1+(iband+idat-2)*2*nband_k
    1664       496836 :                        arg=invocc*rocceig(jband,iband+idat-1)*(eig_k(iband+idat-1)-eig_kq(jband))
    1665       496836 :                        dot2r=eig1_k(ii)
    1666       496836 :                        dot2i=eig1_k(ii+1)
    1667       496836 :                        dotr=dotr+arg*(vdot1r(jband)*dot2r-vdot1i(jband)*dot2i)
    1668       496836 :                        doti=doti+arg*(vdot1r(jband)*dot2i+dot2r*vdot1i(jband))
    1669              :                      end if
    1670              :                    end if
    1671              :                  end do
    1672              :                end if ! occ bands
    1673              : 
    1674       302724 :                dotr=quarter*dotr
    1675       302724 :                doti=quarter*doti
    1676              : 
    1677              : !            Note: factor 2 (from d2E/dj1dj2=2E^(j1j2))
    1678              : !  Note2: do not sum over bands here - comm_band is a sub communicator of spacecomm, and a full sum is done later
    1679       302724 :                d2ovl_k(1,idir1)=d2ovl_k(1,idir1)+wtk_k*occ_k(iband+idat-1)*two*elfd_fact*dotr
    1680       302724 :                d2ovl_k(2,idir1)=d2ovl_k(2,idir1)+wtk_k*occ_k(iband+idat-1)*two*elfd_fact*doti
    1681              :              end if
    1682              :            end do !idat
    1683              : 
    1684              : !          Build the matrix element <u0_k_i|H^(j1)-Eps_k_i.S^(j1)|u^(j2)_k,q_i>
    1685              : !          and add contribution to DDB
    1686       406224 :            if (ipert1/=dtset%natom+1) then
    1687              :              do_scprod=0
    1688       623304 :              do idat=1,ndat
    1689       623304 :                if (abs(occ_k(iband+idat-1))>tol8) do_scprod=1
    1690              :              end do !idat
    1691       311652 :              if(do_scprod==1) then
    1692              :                call dotprod_g_batch_full(vdotr,vdoti,istwf_k,npw1_k*nspinor,ndat,2,&
    1693              : &                   gh1,&
    1694              : &                   cwavef,&
    1695       268956 : &                   mpi_enreg%me_g0,mpi_enreg%comm_spinorfft,gpu_option=gpu_option)
    1696              : #ifdef HAVE_OPENMP_OFFLOAD
    1697              :                !$OMP TARGET UPDATE FROM(vdotr,vdoti) IF(gpu_option==ABI_GPU_OPENMP)
    1698              : #endif
    1699              :              end if
    1700       623304 :              do idat=1,ndat
    1701       623304 :                if (abs(occ_k(iband+idat-1))>tol8) then
    1702              : !              Case ipert1=natom+2 (electric field):
    1703              : !              gh1 contains H^(j1)|u0_k_i> (VHxc constant) which corresponds
    1704              : !              to i.d/dk in Eq. (38) of Gonze, PRB 55, 10355 (1997) [[cite:Gonze1997a]].
    1705              : !              * if ipert==natom+2, we apply directly Eq. (38)
    1706              : !              * if ipert/=natom+2, Born effective charges are minus D2E
    1707       268956 :                  d2nl_k(1,idir1)=d2nl_k(1,idir1)+wtk_k*occ_k(iband+idat-1)*two*elfd_fact*vdotr(idat)
    1708       268956 :                  d2nl_k(2,idir1)=d2nl_k(2,idir1)+wtk_k*occ_k(iband+idat-1)*two*elfd_fact*vdoti(idat)
    1709              :                end if
    1710              :              end do !idat
    1711              : 
    1712              : !            Or compute localisation tensor (ddk)
    1713              : !            See M. Veithen thesis Eq(2.5)
    1714              : !            MT jan-2010: this is probably not correctly implemented for PAW !!!
    1715              : !            missing terms due to S^(1) and S^(2)
    1716              :            else
    1717              : !            note: gh1 used as temporary space (to store idir ddk WF)
    1718        94572 :              if (idir==idir1) then
    1719        31524 :                if(gpu_option==ABI_GPU_DISABLED) then
    1720     31552656 :                  gvnlx1(:,1:ndat*npw1_k*nspinor)=cwavef(:,1:ndat*npw1_k*nspinor)
    1721              :                else if(gpu_option==ABI_GPU_OPENMP) then
    1722              : #ifdef HAVE_OPENMP_OFFLOAD
    1723              :                  call gpu_copy(gvnlx1, cwavef, int(2,c_size_t)*npw1_k*nspinor*ndat)
    1724              : #endif
    1725              :                end if
    1726              :              else
    1727        63048 :                if (need_ddk_file.and.ddkfil(idir1)/=0) then
    1728              :                  !ik_ddk = wfk_findk(ddks(idir1), kpt_rbz(:,ikpt)
    1729              :                  !ik_ddk = indkpt1(ikpt)
    1730              :                  !call ddks(idir1)%read_bks(iband, ik_ddk, isppol, xmpio_single, cg_bks=gvnlx1_tmp)
    1731            0 :                  gvnlx1(:,1:ndat*npw1_k*nspinor) = cg_ddk(:,1+(iband_me-ndat)*npw1_k*nspinor:iband_me*npw1_k*nspinor,idir1)
    1732              : #ifdef HAVE_OPENMP_OFFLOAD
    1733              :                  !$OMP TARGET UPDATE TO(gvnlx1) IF(gpu_option==ABI_GPU_OPENMP)
    1734              : #endif
    1735              :                else
    1736        63048 :                  if(gpu_option==ABI_GPU_DISABLED) then
    1737     31584180 :                    gvnlx1=zero
    1738            0 :                  else if(gpu_option==ABI_GPU_OPENMP) then
    1739            0 :                    call gpu_set_to_zero(gvnlx1,int(2,c_size_t)*npw1_k*nspinor*ndat)
    1740              :                  end if
    1741              :                end if
    1742              :              end if
    1743        94572 :              do_scprod=0
    1744       189144 :              do idat=1,ndat
    1745       189144 :                if (abs(occ_k(iband+idat-1))>tol8) then
    1746        63486 :                  do_scprod=1
    1747              :                end if
    1748              :              end do
    1749        94572 :              if (do_scprod==1) then
    1750              :                call dotprod_g_batch_full(vdotr,vdoti,istwf_k,npw1_k*nspinor,ndat,2,&
    1751              : &                  gvnlx1,&
    1752              : &                  cwavef,&
    1753        63486 : &                  mpi_enreg%me_g0,mpi_enreg%comm_spinorfft,gpu_option=gpu_option)
    1754              :                call dotprod_g_batch_full(vdot1r,vdot1i,istwf_k,npw1_k*nspinor,ndat,2,&
    1755              : &                  cwave0,&
    1756              : &                  gvnlx1,&
    1757        63486 : &                  mpi_enreg%me_g0,mpi_enreg%comm_spinorfft,gpu_option=gpu_option)
    1758              :                call dotprod_g_batch_full(vdot2r,vdot2i,istwf_k,npw1_k*nspinor,ndat,2,&
    1759              : &                  cwavef,&
    1760              : &                  cwave0,&
    1761        63486 : &                  mpi_enreg%me_g0,mpi_enreg%comm_spinorfft,gpu_option=gpu_option)
    1762              : #ifdef HAVE_OPENMP_OFFLOAD
    1763              :                !$OMP TARGET UPDATE FROM(vdotr,vdoti,vdot1r,vdot1i,vdot2r,vdot2i) IF(gpu_option==ABI_GPU_OPENMP)
    1764              : #endif
    1765       126972 :                do idat=1,ndat
    1766       126972 :                  if (abs(occ_k(iband+idat-1))>tol8) then
    1767        63486 :                    vdotr(idat)=vdotr(idat)-(vdot1r(idat)*vdot2r(idat)-vdot1i(idat)*vdot2i(idat))
    1768        63486 :                    vdoti(idat)=vdoti(idat)-(vdot1r(idat)*vdot2i(idat)+vdot1i(idat)*vdot2r(idat))
    1769        63486 :                    d2nl_k(1,idir1)=d2nl_k(1,idir1)+wtk_k*occ_k(iband+idat-1)*vdotr(idat)/(nband_kocc*two)
    1770        63486 :                    d2nl_k(2,idir1)=d2nl_k(2,idir1)+wtk_k*occ_k(iband+idat-1)*vdoti(idat)/(nband_kocc*two)
    1771              :                  end if
    1772              :                end do !idat
    1773              :              end if
    1774              :            end if
    1775              : 
    1776              : !          Accumulate here 1st-order density change due to overlap operator changes (if any)
    1777       406224 :            if (has_drho) then
    1778              : !            Compute here delta_u^(j1)=-1/2 Sum_{j}[<u0_k+q_j|S^(j1)|u0_k_i>.|u0_k+q_j>]
    1779              : !            (see PRB 78, 035105 (2008) [[cite:Audouze2008]], Eq. (42))
    1780       844092 :              ABI_MALLOC(dcwavef,(2,npw1_k*nspinor*ndat))
    1781              : #ifdef HAVE_OPENMP_OFFLOAD
    1782              :              !$OMP TARGET ENTER DATA MAP(alloc:dcwavef) IF(gpu_option==ABI_GPU_OPENMP)
    1783              : #endif
    1784      2100264 :              ABI_MALLOC(dcwaveprj,(dtset%natom,nspinor*ndat))
    1785       281364 :              call pawcprj_alloc(dcwaveprj,0,gs_hamkq%dimcprj)
    1786              : ! NB: have to call getdc with all band processors to distribute cgq cprjq correctly
    1787              :              call getdc1(iband,band_procs,bands_treated_now_ndat,cgq,cprjq,&
    1788              : &                 dcwavef,&
    1789              : &                 dcwaveprj,&
    1790              : &                 ibgq,icgq,istwf_k,mcgq,&
    1791              : &                 mcprjq,mpi_enreg,ndat,dtset%natom,nband_k,nband_me,npw1_k,nspinor,1,&
    1792       281364 : &                 gs1,gpu_option=gpu_option)
    1793              : 
    1794       281364 :              option=1;wfcorr=0
    1795       281364 :              if (abs(occ_k(iband))>tol8) then
    1796              : !              Accumulate 1st-order density due to delta_u^(j1)
    1797              :                call dfpt_accrho(cplex,cwave0,&
    1798              : &                 dcwavef,&
    1799              : &                 dcwavef,&
    1800              : &                 cwaveprj0_idir1,&
    1801              : &                 dcwaveprj,&
    1802              : &                 eig_k(iband:iband+ndat-1),gs_hamkq,iband,idir1,ipert1,isppol,dtset%kptopt,&
    1803              : &                 mpi_enreg,ndat,dtset%natom,nband_k,1,npw_k,npw1_k,nspinor,occ_k,option,&
    1804       245928 : &                 pawdrhoij1_unsym(:,idir1),drhoaug1(:,:,:,idir1),tim_fourwf,wfcorr,wtk_k)
    1805              :              end if
    1806              : 
    1807       281364 :              call pawcprj_free(dcwaveprj)
    1808       974808 :              ABI_FREE(dcwaveprj)
    1809              : #ifdef HAVE_OPENMP_OFFLOAD
    1810              :              !$OMP TARGET EXIT DATA MAP(delete:dcwavef) IF(gpu_option==ABI_GPU_OPENMP)
    1811              : #endif
    1812       281364 :              ABI_FREE(dcwavef)
    1813              :            end if ! has_drho
    1814              :          !do idat=1,ndat
    1815              :          !  !call pawcprj_output(cwaveprj0_idir1(:,1+(idat-1)*nspinor:idat*nspinor),prtgrads=1)
    1816              :          !end do
    1817              : 
    1818       543576 :            if((usecprj==1).and..not.(associated(cwaveprj0_idir1,cwaveprj0)))then
    1819       309168 :              call pawcprj_free(cwaveprj0_idir1)
    1820       309168 :              ABI_FREE(cwaveprj0_idir1)
    1821              :            end if
    1822              : 
    1823              : !          End of loops
    1824              :          end do   ! idir1
    1825              :        end do     ! iband
    1826              : 
    1827        23117 :        ABI_FREE(band_procs)
    1828              : 
    1829              : !      Accumulate contribution of this k-point
    1830       231170 :        d2nl (:,:,ipert1,idir,ipert)=d2nl (:,:,ipert1,idir,ipert)+d2nl_k (:,:)
    1831       231170 :        if (usepaw==1) d2ovl(:,:,ipert1,idir,ipert)=d2ovl(:,:,ipert1,idir,ipert)+d2ovl_k(:,:)
    1832              : 
    1833              : 
    1834              : !      Deallocations of arrays used for this k-point
    1835              : #ifdef HAVE_OPENMP_OFFLOAD
    1836              :        !$OMP TARGET EXIT DATA MAP(delete:gvnlx1,gvnlx1_tmp) IF(gpu_option==ABI_GPU_OPENMP)
    1837              : 
    1838              :        !$OMP TARGET EXIT DATA MAP(delete:gh1) IF(gpu_option==ABI_GPU_OPENMP)
    1839              :        !$OMP TARGET EXIT DATA MAP(delete:gs1) IF(has_dcwf .and. gpu_option==ABI_GPU_OPENMP)
    1840              : #endif
    1841        23117 :        if (has_dcwf.and.is_metal_or_qne0) then
    1842              : #ifdef HAVE_OPENMP_OFFLOAD
    1843              :          !$OMP TARGET EXIT DATA MAP(delete:gvnlx2) IF(gpu_option==ABI_GPU_OPENMP)
    1844              : #endif
    1845        16208 :          ABI_FREE(gvnlx2)
    1846              :        end if
    1847              : 
    1848        23117 :        ABI_FREE(gvnlx1)
    1849        23117 :        ABI_FREE(gvnlx1_tmp)
    1850        23117 :        ABI_FREE(gh1)
    1851        23117 :        ABI_FREE(gs1)
    1852              :        if (need_wfk)  then
    1853        23117 :          nullify(cwave0)
    1854              :        end if
    1855              :        if (need_wf1)  then
    1856        23117 :          nullify(cwavef)
    1857              :        end if
    1858        23117 :        ABI_FREE(kg_k)
    1859        23117 :        ABI_FREE(kg1_k)
    1860        23117 :        ABI_FREE(ylm_k)
    1861        23117 :        ABI_FREE(ylm1_k)
    1862        23117 :        ABI_FREE(ylmgr1_k)
    1863        23117 :        ABI_FREE(kpg_k)
    1864        23117 :        ABI_FREE(kpg1_k)
    1865        23117 :        ABI_FREE(d2nl_k)
    1866        23117 :        ABI_FREE(d2ovl_k)
    1867        23117 :        ABI_FREE(eig_k)
    1868        23117 :        ABI_FREE(eig_kq)
    1869        23117 :        ABI_FREE(eig1_k)
    1870        23117 :        ABI_FREE(occ_k)
    1871              : #ifdef HAVE_OPENMP_OFFLOAD
    1872              :        !$OMP TARGET EXIT DATA MAP(delete:vdotr,vdoti,vdot1r,vdot1i,vdot2r,vdot2i) IF(gpu_option==ABI_GPU_OPENMP)
    1873              : #endif
    1874        23117 :        ABI_FREE(vdotr)
    1875        23117 :        ABI_FREE(vdoti)
    1876        23117 :        ABI_FREE(vdot1r)
    1877        23117 :        ABI_FREE(vdot1i)
    1878        23117 :        ABI_FREE(vdot2r)
    1879        23117 :        ABI_FREE(vdot2i)
    1880        23117 :        if (is_metal)  then
    1881         5892 :          ABI_FREE(doccde_k)
    1882         5892 :          ABI_FREE(doccde_kq)
    1883         5892 :          ABI_FREE(occ_kq)
    1884         5892 :          ABI_FREE(rocceig)
    1885              :        end if
    1886        23117 :        ABI_FREE(dkinpw)
    1887        23117 :        ABI_FREE(kinpw1)
    1888              : #ifdef HAVE_OPENMP_OFFLOAD
    1889              :        if (ipert1<=dtset%natom) then
    1890              :          !$OMP TARGET EXIT DATA MAP(delete:ffnlk) IF(gpu_option==ABI_GPU_OPENMP)
    1891              :        end if
    1892              :        !$OMP TARGET EXIT DATA MAP(delete:ffnl1) IF(gpu_option==ABI_GPU_OPENMP)
    1893              :        !$OMP TARGET EXIT DATA MAP(delete:ph3d) IF(gpu_option==ABI_GPU_OPENMP)
    1894              : #endif
    1895        23117 :        ABI_FREE(ph3d)
    1896        23117 :        if (allocated(ph3d1)) then
    1897        11360 :          ABI_FREE(ph3d1)
    1898              :        end if
    1899        23117 :        ABI_FREE(ffnlk)
    1900        23117 :        ABI_FREE(ffnl1)
    1901        23117 :        if (ipert1>dtset%natom)  then
    1902              : #ifdef HAVE_OPENMP_OFFLOAD
    1903              :          !$OMP TARGET EXIT DATA MAP(delete:ffnl1_idir1) IF(gpu_option==ABI_GPU_OPENMP)
    1904              : #endif
    1905         7379 :          ABI_FREE(ffnl1_idir1)
    1906              :        end if
    1907        23117 :        nullify(ffnl1_idir1)
    1908        23117 :        if (usecprj==1) then
    1909        23117 :          call pawcprj_free(cwaveprj0)
    1910        74656 :          ABI_FREE(cwaveprj0)
    1911              :        end if
    1912        23117 :        nullify(cwaveprj0_idir1)
    1913              : !      Shift arrays
    1914        23117 :        bdtot_index=bdtot_index+nband_k
    1915        23117 :        bd2tot_index=bd2tot_index+2*nband_k**2
    1916        23117 :        if (mkmem/=0) then
    1917        23117 :          ibg=ibg+nspinor*nband_me
    1918        23117 :          icg=icg+npw_k*nspinor*nband_me
    1919        23117 :          ikg=ikg+npw_k
    1920              :        end if
    1921        23117 :        if (mkqmem/=0) then
    1922        23117 :          ibgq=ibgq+nspinor*nband_me
    1923        23117 :          icgq=icgq+npw1_k*nspinor*nband_me
    1924              :        end if
    1925        24395 :        if (mk1mem/=0) then
    1926        23117 :          ibg1=ibg1+nspinor*nband_me
    1927        23117 :          icg1=icg1+npw1_k*nspinor*nband_me
    1928        23117 :          ikg1=ikg1+npw1_k
    1929              :        end if
    1930              : 
    1931              : 
    1932              :      end do ! End loop over K-POINTS
    1933              : !----------------------------------------------------------------
    1934              : 
    1935              : !    Transfer 1st-order density change due to overlap; also take into account the spin.
    1936         2483 :      if(has_drho) then
    1937         3944 :        do kdir1=1,mdir1
    1938         2958 :          idir1=jdir1(kdir1)
    1939              :          call fftpac(isppol,mpi_enreg,nspden,cplex*dtset%ngfft(1),dtset%ngfft(2),dtset%ngfft(3),&
    1940              : &         cplex*dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6),&
    1941         3944 : &         dtset%ngfft,drho1wfr(:,:,idir1),drhoaug1(:,:,:,idir1),1)
    1942              :        end do
    1943              :      end if
    1944              : 
    1945              :    end do ! End loop over SPINS
    1946              : !----------------------------------------------------------------
    1947              : 
    1948              : !  Free memory used for this type of perturbation
    1949         1205 :    call rf_hamkq%free()
    1950         1205 :    if (has_vectornd) then
    1951           45 :      ABI_FREE(vectornd_pac_idir)
    1952              :    end if
    1953         1205 :    if (allocated(vlocal)) then
    1954           45 :      ABI_FREE(vlocal)
    1955              :    end if
    1956         1205 :    if (allocated(vtrial_)) then
    1957           45 :      ABI_FREE(vtrial_)
    1958              :    end if
    1959         1205 :    if (has_drho)  then
    1960          942 :      ABI_FREE(drhoaug1)
    1961              :    end if
    1962         1205 :    if (need_pawij10) then
    1963         4304 :      do kdir1=1,mdir1
    1964         3228 :        idir1=jdir1(kdir1)
    1965         4304 :        call paw_ij_free(paw_ij10(:,idir1))
    1966              :      end do
    1967         1076 :      ABI_FREE(e1kbfr_spin)
    1968              :    end if
    1969         8018 :    ABI_FREE(paw_ij10)
    1970              : 
    1971              : !  In case of parallelism, sum 1st-order density and occupation matrix over processors
    1972         1205 :    if (has_drho.and.xmpi_paral==1) then
    1973              : 
    1974              : !    Accumulate 1st-order density
    1975          942 :      call timab(48,1,tsec)
    1976          942 :      bufsz=cplex*dtset%nfft*nspden*mdir1
    1977         2826 :      ABI_MALLOC(buffer,(bufsz))
    1978         1884 :      buffer(1:bufsz)=reshape(drho1wfr,(/bufsz/))
    1979          942 :      call xmpi_sum(buffer,bufsz,spaceworld,ierr)
    1980         3768 :      drho1wfr(:,:,:)=reshape(buffer(1:bufsz),(/cplex*dtset%nfft,nspden,mdir1/))
    1981          942 :      ABI_FREE(buffer)
    1982          942 :      call timab(48,2,tsec)
    1983              : 
    1984              : !    Accumulate 1st-order PAW occupancies
    1985         1884 :      if (usepaw==1) then
    1986          942 :        call pawrhoij_mpisum_unpacked(pawdrhoij1_unsym,spaceworld)
    1987              :      end if
    1988              : 
    1989              :    end if
    1990              : 
    1991              : !  Compute second part of overlap contribution (due to VHxc^(j2)(tild_n+hat_n))
    1992          347 :    if (has_drho) then
    1993              : 
    1994         3768 :      ABI_MALLOC(drhor1,(cplex*nfftf,nspden))
    1995         2826 :      ABI_MALLOC(dnhat1,(cplex*nfftf,nspden))
    1996              : 
    1997              : !    LOOP OVER PERTURBATION DIRECTIONS
    1998         3768 :      do kdir1=1,mdir1
    1999         2826 :        idir1=jdir1(kdir1)
    2000              : 
    2001              : !      Build and symmetrize 1st-order density change due to change of overlap
    2002         8478 :        ABI_MALLOC(drho1wfg,(2,dtset%nfft))
    2003              :        call symrhg(cplex,gprimd,irrzon1,mpi_enreg,dtset%nfft,dtset%nfft,dtset%ngfft,&
    2004              : &       nspden,nsppol,nsym1,phnons1,drho1wfg,drho1wfr(:,:,idir1),&
    2005         2826 : &       rprimd,symaf1,symrl1,tnons1)
    2006         2826 :        if (dtset%pawstgylm/=0) then
    2007         2826 :          option=0
    2008              :          call pawnhatfr(option,idir1,ipert1,my_natom,dtset%natom,nspden,dtset%ntypat,&
    2009              : &         pawang,pawfgrtab,pawrhoij,pawtab,rprimd,&
    2010         2826 : &         mpi_atmtab=my_atmtab,comm_atom=my_comm_atom)
    2011              :        end if
    2012              :        call pawmkrho(1,arg,cplex,gprimd,idir1,indsy1,ipert1,&
    2013              : &       mpi_enreg,my_natom,dtset%natom,nspden,nsym1,dtset%ntypat,dtset%paral_kgb,pawang,&
    2014              : &       pawfgr,pawfgrtab,-10001,pawdrhoij1(:,idir1),pawdrhoij1_unsym(:,idir1),pawtab,&
    2015              : &       dtset%qptn,drho1wfg,drho1wfr(:,:,idir1),drhor1,rprimd,symaf1,symrc1,dtset%typat,&
    2016         2826 : &       ucvol,dtset%usewvl,xred,pawang_sym=pawang1,pawnhat=dnhat1,pawrhoij0=pawrhoij)
    2017         2826 :        ABI_FREE(drho1wfg)
    2018              : 
    2019              : !      Compute plane-wave contribution to overlap contribution
    2020              : !      This is subtle as it is a mix of Eq(79) and Eq(80) of PRB 78, 035105 (2008) [[cite:Audouze2008]]
    2021              : !      Details:
    2022              : !      The VH(tild_nZc)^(1) term of Eq(79) is:
    2023              : !      <VH(tild_nZc)^(j2)|delta_tild_rho^(j1)>            = <vpsp1|drhor1-dnhat1>
    2024              : !      The first term of Eq(80) is:
    2025              : !      <VHxc^(j2)|delta_tild_rho^(j1)+delta_hat_rho^(j1)> = <vtrial1-vpsp1|drhor1>
    2026              : !      The addition of these two terms gives:
    2027              : !      <vtrial1|drhor1>-<vpsp1|dnhat1>
    2028              : !      And this is more subtle when usexcnhat=0
    2029         2826 :        call dotprod_vn(cplex,drhor1,dot1r,dot1i,nfftf,nfftot,nspden,2,vtrial1,ucvol)
    2030         2826 :        if (usexcnhat/=0) then
    2031         2019 :          call dotprod_vn(cplex,dnhat1,dot2r,dot2i,nfftf,nfftot,1   ,2,vpsp1,ucvol)
    2032              :        else
    2033         2421 :          ABI_MALLOC(vtmp1,(cplex*nfftf,nspden))
    2034         1740 :          do ispden=1,nspden
    2035     38357748 :            vtmp1(:,ispden)=vtrial1(:,ispden)-vhartr1(:)
    2036              :          end do
    2037          807 :          call dotprod_vn(cplex,dnhat1,dot2r,dot2i,nfftf,nfftot,nspden,2,vtmp1,ucvol)
    2038          807 :          ABI_FREE(vtmp1)
    2039              :        end if
    2040         2826 :        dotr=dot1r-dot2r;doti=dot1i-dot2i
    2041              : 
    2042              : !      Compute on-site contributions to overlap contribution
    2043              : !      (two last terms of Eq(80) of PRB 78, 035105 (2008)) [[cite:Audouze2008]]
    2044              : !      (note: Dij^(j2) and Vxc^(j2) are computed for ipert at first call)
    2045              :        call pawdfptenergy(epawnst,ipert,ipert1,dtset%ixc,my_natom,dtset%natom,dtset%ntypat,&
    2046              : &       nzlmopt_ipert,nzlmopt_ipert1,paw_an,paw_an1,paw_ij1,pawang,dtset%pawprtvol,&
    2047              : &       pawrad,pawrhoij1,pawdrhoij1(:,idir1),pawtab,dtset%pawxcdev,dtset%xclevel,&
    2048         2826 : &       mpi_atmtab=my_atmtab,comm_atom=my_comm_atom)
    2049              : 
    2050              : !      Accumulate in 2nd-order matrix:
    2051              : !      Note: factor 2 (from d2E/dj1dj2=2E^(j1j2)) eliminated by factor 1/2
    2052              : !      has to take the complex conjugate because we want here Int[VHxc^(j1)^*.delta_rho^(j2)]
    2053         2826 :        dotr=dotr+epawnst(1);doti=-(doti+epawnst(2))
    2054         2826 :        d2ovl_drho(1,idir1,ipert1,idir,ipert)=elfd_fact*dotr
    2055         3768 :        d2ovl_drho(2,idir1,ipert1,idir,ipert)=elfd_fact*doti
    2056              : 
    2057              :        !if(kpert1==5) then
    2058              :        !  ABI_BUG("toto")
    2059              :        !end if
    2060              :      end do ! End loop over perturbation directions
    2061              : 
    2062              : !    Free no more needed memory
    2063          942 :      ABI_FREE(drhor1)
    2064          942 :      ABI_FREE(dnhat1)
    2065          942 :      ABI_FREE(drho1wfr)
    2066         2955 :      do iatom=1,my_natom
    2067         2013 :        if (pawfgrtab(iatom)%nhatfr_allocated>0)  then
    2068         2013 :          ABI_FREE(pawfgrtab(iatom)%nhatfr)
    2069              :        end if
    2070         2955 :        pawfgrtab(iatom)%nhatfr_allocated=0
    2071              :      end do
    2072          942 :      if (paral_atom) then
    2073         2192 :        do kdir1=1,mdir1
    2074         1644 :          idir1=jdir1(kdir1)
    2075         2192 :          call pawrhoij_free(pawdrhoij1_unsym(:,idir1))
    2076              :        end do
    2077          548 :        ABI_FREE(pawdrhoij1_unsym)
    2078              :      end if
    2079         3768 :      do kdir1=1,mdir1
    2080         2826 :        idir1=jdir1(kdir1)
    2081         3768 :        call pawrhoij_free(pawdrhoij1(:,idir1))
    2082              :      end do
    2083         6981 :      ABI_FREE(pawdrhoij1)
    2084              :    end if ! has_drho
    2085              : 
    2086              : !  End loop over perturbations (j1)
    2087              :  end do
    2088              : 
    2089              : #ifdef HAVE_OPENMP_OFFLOAD
    2090              :  !$OMP TARGET EXIT DATA MAP(delete:ch1c,ch1c_tmp) IF(gpu_option==ABI_GPU_OPENMP)
    2091              : #endif
    2092              : !Final deallocations
    2093          347 :  ABI_FREE(ch1c)
    2094          347 :  ABI_FREE(ch1c_tmp)
    2095          347 :  if (usepaw==1.and.is_metal_or_qne0) then
    2096          250 :    ABI_FREE(cs1c)
    2097          250 :    ABI_FREE(cs1c_tmp)
    2098              :  end if
    2099          347 :  call gs_hamkq%free()
    2100          347 :  if(allocated(vectornd_pac)) then
    2101           45 :    ABI_FREE(vectornd_pac)
    2102              :  end if
    2103          347 :  if(allocated(vxctaulocal)) then
    2104            6 :    ABI_FREE(vxctaulocal)
    2105              :  end if
    2106              : 
    2107              : !In case of parallelism, sum over processors
    2108              :  if (xmpi_paral==1)then
    2109          347 :    call timab(161,1,tsec)
    2110          347 :    call xmpi_barrier(spaceworld)
    2111          347 :    call timab(161,2,tsec)
    2112         1041 :    ABI_MALLOC(buffer,(6*mpert*(1+usepaw)))
    2113          694 :    buffer(1:6*mpert)=reshape(d2nl(:,:,:,idir,ipert),(/6*mpert/))
    2114          694 :    if (usepaw==1) buffer(6*mpert+1:6*mpert+6*mpert)=reshape(d2ovl(:,:,:,idir,ipert),(/6*mpert/))
    2115          347 :    call timab(48,1,tsec)
    2116          347 :    call xmpi_sum(buffer,6*mpert*(1+usepaw),spaceworld,ierr)
    2117          347 :    call timab(48,2,tsec)
    2118         1388 :    d2nl (:,:,:,idir,ipert)=reshape(buffer(1:6*mpert),(/2,3,mpert/))
    2119         1388 :    if (usepaw==1) d2ovl(:,:,:,idir,ipert)=reshape(buffer(6*mpert+1:6*mpert+6*mpert),(/2,3,mpert/))
    2120          347 :    ABI_FREE(buffer)
    2121              :  end if
    2122              : 
    2123              : !Build complete d2ovl matrix
    2124        34887 :  if (usepaw==1) d2ovl(:,:,:,idir,ipert)=d2ovl(:,:,:,idir,ipert)+d2ovl_drho(:,:,:,idir,ipert)
    2125              : 
    2126          347 :  if (usepaw==1) then
    2127          347 :    ABI_FREE(d2ovl_drho)
    2128              :  end if
    2129              : 
    2130              : !Close the ddk WF files
    2131          347 :  if (has_ddk_file) then
    2132          536 :    do kdir1=1,mdir1
    2133          402 :      idir1=jdir1(kdir1)
    2134          536 :      if (ddkfil(idir1)/=0) call ddks(idir1)%close()
    2135              :    end do
    2136          134 :    ABI_FREE(cg_ddk)
    2137              :  end if
    2138          347 :  ABI_FREE(jpert1)
    2139          347 :  ABI_FREE(jdir1)
    2140              : 
    2141              : !Symmetrize the phonons contributions, as was needed for the forces in a GS calculation
    2142         1041 :  ABI_MALLOC(work,(2,3,dtset%natom))
    2143         1372 :  do ipert1=1,dtset%natom
    2144         4447 :    do idir1=1,3
    2145        10250 :      work(:,idir1,ipert1)=d2nl(:,idir1,ipert1,idir,ipert)
    2146              :    end do
    2147              :  end do
    2148          347 :  call dfpt_sygra(dtset%natom,d2nl(:,:,:,idir,ipert),work,indsy1,ipert,nsym1,dtset%qptn,symrc1)
    2149          347 :  if (usepaw==1) then
    2150         1372 :    do ipert1=1,dtset%natom
    2151         4447 :      do idir1=1,3
    2152        10250 :        work(:,idir1,ipert1)=d2ovl(:,idir1,ipert1,idir,ipert)
    2153              :      end do
    2154              :    end do
    2155          347 :    call dfpt_sygra(dtset%natom,d2ovl(:,:,:,idir,ipert),work,indsy1,ipert,nsym1,dtset%qptn,symrc1)
    2156              :  end if
    2157          347 :  ABI_FREE(work)
    2158              : 
    2159              : !In the case of the strain perturbation time-reversal symmetry will always
    2160              : !be true so imaginary part of d2nl will be must be set to zero here since
    2161              : !the symmetry-reduced kpt set will leave a non-zero imaginary part.
    2162          347 :  if(ipert==dtset%natom+3.or.ipert==dtset%natom+4) then
    2163         3096 :    d2nl(2,:,:,idir,ipert)=zero
    2164         3096 :    if (usepaw==1) d2ovl(2,:,:,idir,ipert)=zero
    2165              :  else
    2166         2475 :    d2nl(2,:,dtset%natom+3:dtset%natom+4,idir,ipert)=zero
    2167         2475 :    if (usepaw==1) d2ovl(2,:,dtset%natom+3:dtset%natom+4,idir,ipert)=zero
    2168              :  end if
    2169              : 
    2170              : 
    2171              : !Symmetrize the strain perturbation contributions, as was needed for the stresses in a GS calculation
    2172              : !if (ipert==dtset%natom+3.or.ipert==dtset%natom+4)then
    2173          347 :  if (nsym1>1) then
    2174          122 :    ABI_MALLOC(work,(6,1,1))
    2175          122 :    ii=0
    2176          366 :    do ipert1=dtset%natom+3,dtset%natom+4
    2177         1098 :      do idir1=1,3
    2178          732 :        ii=ii+1
    2179          976 :        work(ii,1,1)=d2nl(1,idir1,ipert1,idir,ipert)
    2180              :      end do
    2181              :    end do
    2182          122 :    call stresssym(gprimd,nsym1,work(:,1,1),symrc1)
    2183          122 :    ii=0
    2184          366 :    do ipert1=dtset%natom+3,dtset%natom+4
    2185         1098 :      do idir1=1,3
    2186          732 :        ii=ii+1
    2187          976 :        d2nl(1,idir1,ipert1,idir,ipert)=work(ii,1,1)
    2188              :      end do
    2189              :    end do
    2190          122 :    if (usepaw==1) then
    2191          122 :      ii=0
    2192          366 :      do ipert1=dtset%natom+3,dtset%natom+4
    2193         1098 :        do idir1=1,3
    2194          732 :          ii=ii+1
    2195          976 :          work(ii,1,1)=d2ovl(1,idir1,ipert1,idir,ipert)
    2196              :        end do
    2197              :      end do
    2198          122 :      call stresssym(gprimd,nsym1,work(:,1,1),symrc1)
    2199          122 :      ii=0
    2200          366 :      do ipert1=dtset%natom+3,dtset%natom+4
    2201         1098 :        do idir1=1,3
    2202          732 :          ii=ii+1
    2203          976 :          d2ovl(1,idir1,ipert1,idir,ipert)=work(ii,1,1)
    2204              :        end do
    2205              :      end do
    2206          122 :      ABI_FREE(work)
    2207              :    end if
    2208              :  end if
    2209              : !end if
    2210              : 
    2211              : !Must also symmetrize the electric field perturbation response !
    2212              : !Note: d2ovl is not symetrized because it is zero for electric field perturbation
    2213          347 :  if (has_ddk_file) then
    2214          134 :    ABI_MALLOC(d2nl_elfd,(2,3))
    2215              : !  There should not be any imaginary part, but stay general (for debugging)
    2216         1340 :    d2nl_elfd (:,:)=d2nl(:,:,dtset%natom+2,idir,ipert)
    2217          536 :    do ii=1,3
    2218          402 :      sumelfd(:)=zero
    2219         1572 :      do ia=1,nsym1
    2220         4680 :        do jj=1,3
    2221         4680 :          if(symrl1(ii,jj,ia)/=0)then
    2222         1306 :            if(ddkfil(jj)==0)then
    2223            0 :              blkflg(ii,dtset%natom+2,idir,ipert)=0
    2224              :            end if
    2225              :          end if
    2226              :        end do
    2227         1170 :        symfact(1)=dble(symrl1(ii,1,ia))
    2228         1170 :        symfact(2)=dble(symrl1(ii,2,ia))
    2229         1170 :        symfact(3)=dble(symrl1(ii,3,ia))
    2230              :        sumelfd(:)=sumelfd(:)+symfact(1)*d2nl_elfd(:,1) &
    2231         3912 : &       +symfact(2)*d2nl_elfd(:,2)+symfact(3)*d2nl_elfd(:,3)
    2232              :      end do
    2233         1340 :      d2nl(:,ii,dtset%natom+2,idir,ipert)=sumelfd(:)/dble(nsym1)
    2234              :    end do
    2235          134 :    ABI_FREE(d2nl_elfd)
    2236              :  end if
    2237              : 
    2238              : !Overlap: store the diagonal part of the matrix in the
    2239              : !         2nd-order energy non-stationnary expression
    2240          347 :  eovl1=zero;if (usepaw==1) eovl1=d2ovl(1,idir,ipert,idir,ipert)
    2241              : 
    2242          347 :  ABI_FREE(bands_treated_now_ndat)
    2243              : 
    2244              : #ifdef HAVE_OPENMP_OFFLOAD
    2245              :  !$OMP TARGET EXIT DATA MAP(delete:cg,cg1) IF(gpu_option==ABI_GPU_OPENMP)
    2246              : #endif
    2247              : 
    2248          347 :  call destroy_mpi_enreg(mpi_enreg_seq)
    2249          347 :  call timab(566,2,tsec)
    2250              : 
    2251              :  ABI_NVTX_END_RANGE()
    2252              : 
    2253              :  DBG_EXIT("COLL")
    2254              : 
    2255         1388 : end subroutine dfpt_nstpaw
    2256              : !!***
    2257              : 
    2258              : !!****f* ABINIT/dfpt_nstwf
    2259              : !! NAME
    2260              : !! dfpt_nstwf
    2261              : !!
    2262              : !! FUNCTION
    2263              : !! This routine computes the non-local contribution to the
    2264              : !! 2DTE matrix elements, in the non-stationary formulation
    2265              : !! Only for norm-conserving pseudopotentials (no PAW)
    2266              : !!
    2267              : !! COPYRIGHT
    2268              : !! Copyright (C) 1999-2026 ABINIT group (XG,AR,MB,MVer,MT, MVeithen)
    2269              : !! This file is distributed under the terms of the
    2270              : !! GNU General Public License, see ~abinit/COPYING
    2271              : !! or http://www.gnu.org/copyleft/gpl.txt .
    2272              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
    2273              : !!
    2274              : !! INPUTS
    2275              : !!  cg(2,mpw*nspinor*mband_mem*mkmem*nsppol)=planewave coefficients of wavefunctions at k
    2276              : !!  cg1(2,mpw1*nspinor*mband_mem*mk1mem*nsppol)=pw coefficients of RF wavefunctions at k,q.
    2277              : !!  ddkfil(3)=unit numbers for the three possible ddk files for ipert1
    2278              : !!       equal to 0 if no dot file is available for this direction
    2279              : !!  dtset <type(dataset_type)>=all input variables for this dataset
    2280              : !!  eig_k(mband*nsppol)=GS eigenvalues at k (hartree)
    2281              : !!  eig1_k(2*nsppol*mband**2)=matrix of first-order eigenvalues (hartree)
    2282              : !!  gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k+q
    2283              : !!  icg=shift to be applied on the location of data in the array cg
    2284              : !!  icg1=shift to be applied on the location of data in the array cg1
    2285              : !!  idir=direction of the current perturbation
    2286              : !!  ikpt=number of the k-point
    2287              : !!  ipert=type of the perturbation
    2288              : !!  isppol=1 for unpolarized, 2 for spin-polarized
    2289              : !!  istwf_k=parameter that describes the storage of wfs
    2290              : !!  kg_k(3,npw_k)=reduced planewave coordinates.
    2291              : !!  kg1_k(3,npw1_k)=reduced planewave coordinates at k+q, with RF k points
    2292              : !!  kpt(3)=reduced coordinates of k point
    2293              : !!  kpq(3)=reduced coordinates of k+q point
    2294              : !!  mkmem =number of k points treated by this node
    2295              : !!  mk1mem =number of k points treated by this node (RF data)
    2296              : !!  mpert =maximum number of ipert
    2297              : !!  mpi_enreg=information about MPI parallelization
    2298              : !!  mpw=maximum dimensioned size of npw or wfs at k
    2299              : !!  mpw1=maximum dimensioned size of npw for wfs at k+q (also for 1-order wfs).
    2300              : !!  nband_k=number of bands at this k point for that spin polarization
    2301              : !!  npw_k=number of plane waves at this k point
    2302              : !!  npw1_k=number of plane waves at this k+q point
    2303              : !!  nsppol=1 for unpolarized, 2 for spin-polarized
    2304              : !!  occ_k(nband_k)=occupation number for each band (usually 2) for each k.
    2305              : !!  psps <type(pseudopotential_type)>=variables related to pseudopotentials
    2306              : !!  rmet(3,3)=real space metric (bohr**2)
    2307              : !!  ddks(3)<wfk_t>=struct info for for the three possible DDK files for ipert1
    2308              : !!  wtk_k=weight assigned to the k point.
    2309              : !!  ylm(mpw*mkmem,mpsang*mpsang*useylm)= real spherical harmonics for each G and k point
    2310              : !!  ylm1(mpw1*mk1mem,mpsang*mpsang*useylm)= real spherical harmonics for each G and k+q point
    2311              : !!
    2312              : !! OUTPUT
    2313              : !!  d2bbb_k(2,3,mband,mband*prtbbb)=band by band decomposition of the second
    2314              : !!   order derivatives, for the present k point, and perturbation idir, ipert
    2315              : !!  d2nl_k(2,3,mpert)=non-local contributions to
    2316              : !!   non-stationary 2DTE, for the present k point, and perturbation idir, ipert
    2317              : !!
    2318              : !! TODO
    2319              : !!  XG 20141103 The localization tensor cannot be defined in the metallic case. It should not be computed.
    2320              : !!
    2321              : !! SOURCE
    2322              : 
    2323        99323 : subroutine dfpt_nstwf(cg,cg1,ddkfil,dtset,d2bbb_k,d2nl_k,eig_k,eig1_k,gs_hamkq,&
    2324        99323 : &                 icg,icg1,idir,ikpt,ipert,isppol,istwf_k,kg_k,kg1_k,kpt,kpq,&
    2325              : &                 mband_mem_rbz,mkmem,mk1mem,mpert,mpi_enreg,mpw,mpw1,nband_k,npw_k,npw1_k,nsppol,&
    2326        99323 : &                 occ_k,psps,rmet,ddks,wtk_k,ylm,ylm1)
    2327              : 
    2328              : !Arguments ------------------------------------
    2329              : !scalars
    2330              :  integer,intent(in) :: icg,icg1,idir,ikpt,ipert,isppol,istwf_k
    2331              :  integer,intent(in) :: mkmem,mk1mem,mpert,mpw,mpw1,nsppol
    2332              :  integer,intent(in) :: mband_mem_rbz
    2333              :  integer,intent(inout) :: nband_k,npw1_k,npw_k
    2334              :  real(dp),intent(in) :: wtk_k
    2335              :  type(MPI_type),intent(in) :: mpi_enreg
    2336              :  type(dataset_type),intent(in) :: dtset
    2337              :  type(gs_hamiltonian_type),intent(inout) :: gs_hamkq
    2338              :  type(pseudopotential_type),intent(in) :: psps
    2339              : !arrays
    2340              :  integer,intent(in) :: ddkfil(3),kg1_k(3,npw1_k)
    2341              :  integer,intent(in) :: kg_k(3,npw_k)
    2342              :  real(dp),intent(in) :: cg(2,mpw*dtset%nspinor*mband_mem_rbz*mkmem*nsppol)
    2343              :  real(dp),intent(in) :: cg1(2,mpw1*dtset%nspinor*mband_mem_rbz*mk1mem*nsppol)
    2344              :  real(dp),intent(in) :: eig_k(dtset%mband*nsppol),kpt(3),kpq(3),occ_k(nband_k),rmet(3,3)
    2345              :  real(dp),intent(in) :: ylm(npw_k,psps%mpsang*psps%mpsang*psps%useylm)
    2346              :  real(dp),intent(in) :: ylm1(npw1_k,psps%mpsang*psps%mpsang*psps%useylm)
    2347              :  real(dp),intent(inout) :: eig1_k(2*nsppol*dtset%mband**2)
    2348              :  real(dp),intent(out) :: d2bbb_k(2,3,dtset%mband,dtset%mband*dtset%prtbbb)
    2349              :  real(dp),intent(inout) :: d2nl_k(2,3,mpert)
    2350              :  type(wfk_t),intent(inout) :: ddks(3)
    2351              : 
    2352              : !Local variables-------------------------------
    2353              : !scalars
    2354              :  integer :: berryopt,dimffnl,dimffnl1,dimph3d
    2355              :  integer :: iband,ider,idir1,ipert1,ipw,jband,nband_kocc,nkpg,nkpg1
    2356              :  integer :: ierr, iband_me, jband_me
    2357              :  integer :: npw_disk,nsp,optlocal,optnl,opt_gvnlx1,sij_opt,tim_getgh1c,usevnl
    2358              :  integer :: nddk_needed, startband, endband
    2359              :  logical :: ddk
    2360              :  real(dp) :: aa,dot1i,dot1r,dot2i,dot2r,dot_ndiagi,dot_ndiagr,doti,dotr,lambda
    2361              :  character(len=500) :: msg
    2362        99323 :  type(rf_hamiltonian_type) :: rf_hamkq
    2363              : !arrays
    2364              :  integer :: ik_ddks(3)
    2365       198646 :  integer :: band_procs(nband_k)
    2366       198646 :  logical :: distrb_cycle(nband_k)
    2367              :  real(dp) :: dum_grad_berry(1,1),dum_gvnlx1(1,1),dum_gs1(1,1),dum_ylmgr(1,3,1),tsec(2)
    2368        99323 :  real(dp),allocatable :: cg_k(:,:),cwave0(:,:),cwavef(:,:),cwavef_da(:,:)
    2369        99323 :  real(dp),allocatable :: cwaveddk(:,:,:)
    2370        99323 :  real(dp),allocatable :: cg_ddk(:,:,:) !2,mpw1*dtset%nspinor*mband_mem_rbz*mk1mem*nsppol,3) ==
    2371              : 
    2372        99323 :  real(dp),allocatable :: cwavef_db(:,:),dkinpw(:),eig2_k(:),ffnl1(:,:,:,:),ffnlk(:,:,:,:)
    2373        99323 :  real(dp),allocatable :: eig2_ddk(:,:)
    2374        99323 :  real(dp),allocatable :: gvnlx1(:,:),kinpw1(:),kpg1_k(:,:),kpg_k(:,:),ph3d(:,:,:)
    2375        99323 :  type(pawcprj_type),allocatable :: dum_cwaveprj(:,:)
    2376              : 
    2377              : ! *********************************************************************
    2378              : 
    2379              :  DBG_ENTER("COLL")
    2380              : 
    2381              :  ABI_NVTX_START_RANGE(NVTX_DFPT_NSTWF)
    2382              : 
    2383              : !Not valid for PAW
    2384        99323 :  if (psps%usepaw==1) then
    2385            0 :    msg='  This routine cannot be used for PAW (use pawnst3 instead) !'
    2386            0 :    ABI_BUG(msg)
    2387              :  end if
    2388              : 
    2389              : !Keep track of total time spent in dfpt_nstwf
    2390        99323 :  call timab(112,1,tsec)
    2391        99323 :  tim_getgh1c=2
    2392              : 
    2393              : !Miscellaneous inits
    2394        99323 :  ABI_MALLOC(dum_cwaveprj,(0,0))
    2395        99323 :  ddk=(ipert==dtset%natom+1.or.ipert==dtset%natom+10.or.ipert==dtset%natom+11)
    2396              : 
    2397              : ! filter for bands on this cpu for cg cg1 etc.
    2398       678003 :  distrb_cycle = (mpi_enreg%proc_distrb(ikpt,1:nband_k,isppol) /= mpi_enreg%me_kpt)
    2399              :  call proc_distrb_band(band_procs,mpi_enreg%proc_distrb,ikpt,isppol,nband_k,&
    2400        99323 : &  mpi_enreg%me_band,mpi_enreg%me_kpt,mpi_enreg%comm_band)
    2401              : 
    2402              : !Additional allocations
    2403        99323 :  if (.not.ddk) then
    2404       245859 :    ABI_MALLOC(dkinpw,(npw_k))
    2405       245859 :    ABI_MALLOC(kinpw1,(npw1_k))
    2406     26222013 :    kinpw1=zero;dkinpw=zero
    2407              :  else
    2408        17370 :    ABI_MALLOC(dkinpw,(0))
    2409        17370 :    ABI_MALLOC(kinpw1,(0))
    2410              :  end if
    2411       297969 :  ABI_MALLOC(gvnlx1,(2,npw1_k*dtset%nspinor))
    2412       397292 :  ABI_MALLOC(eig2_k,(2*nsppol*dtset%mband**2))
    2413       297969 :  ABI_MALLOC(cwave0,(2,npw_k*dtset%nspinor))
    2414       198646 :  ABI_MALLOC(cwavef,(2,npw1_k*dtset%nspinor))
    2415              : 
    2416        99323 :  nddk_needed = 0
    2417       397292 :  do idir1=1,3
    2418       397292 :    if (ddkfil(idir1)/=0)  nddk_needed = nddk_needed+1
    2419              :  end do
    2420        99323 :  if (nddk_needed > 0) then
    2421       104720 :    ABI_MALLOC(cwaveddk,(2,npw1_k*dtset%nspinor,3))
    2422              : !TODO: for the moment avoid indirect indexing of the ddk directions in case not all are present. Here all are allocated and read in
    2423       104720 :    ABI_MALLOC(cg_ddk,(2,mpw1*dtset%nspinor*mband_mem_rbz,3))
    2424    137915825 :    cg_ddk = zero ! not all may be initialized below if only certain ddk directions are provided
    2425              : 
    2426       104720 :    ABI_MALLOC(eig2_ddk,(2*dtset%mband**2,3))
    2427      4768418 :    eig2_ddk = zero
    2428              :  end if
    2429              : 
    2430              : !Compute (k+G) vectors
    2431        99323 :  nkpg=0;if (.not.ddk) nkpg=3*gs_hamkq%nloalg(3)
    2432       397292 :  ABI_MALLOC(kpg_k,(npw_k,nkpg))
    2433        99323 :  if (nkpg>0) then
    2434            0 :    call mkkpg(kg_k,kpg_k,kpt,nkpg,npw_k)
    2435              :  end if
    2436              : 
    2437              : !Compute (k+q+G) vectors
    2438        99323 :  nkpg1=0;if (.not.ddk) nkpg1=3*gs_hamkq%nloalg(3)
    2439       397292 :  ABI_MALLOC(kpg1_k,(npw1_k,nkpg1))
    2440        99323 :  if (nkpg1>0) then
    2441            0 :    call mkkpg(kg1_k,kpg1_k,kpq,nkpg1,npw1_k)
    2442              :  end if
    2443              : 
    2444              : !Compute nonlocal form factors ffnl at (k+G)
    2445        99323 :  dimffnl=0;if (.not.ddk) dimffnl=1
    2446       595938 :  ABI_MALLOC(ffnlk,(npw_k,dimffnl,psps%lmnmax,psps%ntypat))
    2447        99323 :  if (.not.ddk) then
    2448        81953 :    ider=0
    2449              :    call mkffnl(psps%dimekb,dimffnl,psps%ekb,ffnlk,psps%ffspl,gs_hamkq%gmet,&
    2450              : &   gs_hamkq%gprimd,ider,ider,psps%indlmn,kg_k,kpg_k,kpt,psps%lmnmax,&
    2451              : &   psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,npw_k,psps%ntypat,psps%pspso,&
    2452        81953 : &   psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm,dum_ylmgr)
    2453              :  end if
    2454              : 
    2455              : !Compute nonlocal form factors ffnl1 at (k+q+G)
    2456        99323 :  dimffnl1=0;if (.not.ddk) dimffnl1=1
    2457       595938 :  ABI_MALLOC(ffnl1,(npw1_k,dimffnl1,psps%lmnmax,psps%ntypat))
    2458        99323 :  if (.not.ddk) then
    2459        81953 :    ider=0
    2460              :    call mkffnl(psps%dimekb,dimffnl1,psps%ekb,ffnl1,psps%ffspl,gs_hamkq%gmet,&
    2461              : &   gs_hamkq%gprimd,ider,ider,psps%indlmn,kg1_k,kpg1_k,kpq,&
    2462              : &   psps%lmnmax,psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg1,npw1_k,psps%ntypat,&
    2463        81953 : &   psps%pspso,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm1,dum_ylmgr)
    2464              :  end if
    2465              : 
    2466              : !Load k-dependent part in the Hamiltonian datastructure
    2467              :  call gs_hamkq%load_k(kpt_k=kpt,npw_k=npw_k,istwf_k=istwf_k,&
    2468        99323 : & kg_k=kg_k,kpg_k=kpg_k,ffnl_k=ffnlk)
    2469              : 
    2470              : !Load k+q-dependent part in the Hamiltonian datastructure
    2471              : !    Note: istwf_k is imposed to 1 for RF calculations (should use istwf_kq instead)
    2472        99323 :  dimph3d=0;if (.not.ddk) dimph3d=gs_hamkq%matblk
    2473       397292 :  ABI_MALLOC(ph3d,(2,npw1_k,dimph3d))
    2474              :  call gs_hamkq%load_kprime(kpt_kp=kpq,npw_kp=npw1_k,istwf_kp=istwf_k,&
    2475              : & kinpw_kp=kinpw1,kg_kp=kg1_k,kpg_kp=kpg1_k,ffnl_kp=ffnl1,&
    2476        99323 : & ph3d_kp=ph3d,compute_ph3d=(.not.ddk))
    2477              : 
    2478              : !Load k-dependent part in the 1st-order Hamiltonian datastructure
    2479        99323 :  call rf_hamkq%load_k(npw_k=npw_k,dkinpw_k=dkinpw)
    2480              : 
    2481              : !Take care of the npw and kg records
    2482              : !NOTE : one should be able to modify the rwwf routine to take care
    2483              : !of the band parallelism, which is not the case yet ...
    2484        99323 :  ik_ddks = 0
    2485       397292 :  do idir1=1,3
    2486       397292 :    if (ddkfil(idir1)/=0)then
    2487              : !    Read npw record
    2488        75546 :      nsp=dtset%nspinor
    2489        75546 :      ik_ddks(idir1) = ddks(idir1)%findk(kpt)
    2490        75546 :      ABI_CHECK(ik_ddks(idir1) /= -1, "Cannot find kpt")
    2491        75546 :      npw_disk = ddks(idir1)%hdr%npwarr(ik_ddks(idir1))
    2492        75546 :      if (npw_k /= npw_disk) then
    2493              :        write(unit=msg,fmt='(a,i3,a,i5,a,i3,a,a,i5,a,a,i5)')&
    2494            0 : &       'For isppol = ',isppol,', ikpt = ',ikpt,' and idir = ',idir,ch10,&
    2495            0 : &       'the number of plane waves in the ddk file is equal to', npw_disk,ch10,&
    2496            0 : &       'while it should be ',npw_k
    2497            0 :        ABI_BUG(msg)
    2498              :      end if
    2499              : 
    2500              : !   NB: this will fail if the bands are not contiguous.
    2501        75546 :      startband = nband_k
    2502        75546 :      endband = 1
    2503       406077 :      do iband=1,nband_k
    2504       406077 :        if(mpi_enreg%proc_distrb(ikpt,iband,isppol) == mpi_enreg%me_kpt) then
    2505       330531 :          if (iband < startband) startband = iband
    2506       330531 :          if (iband > endband) endband = iband
    2507              :        end if
    2508              :      end do
    2509              : ! NB: eig_k is band distributed in call to read_band_block, though array has full size,
    2510              : !     only certain columns for my iband are filled, then used below
    2511              :      call ddks(idir1)%read_band_block((/startband,endband/),ik_ddks(idir1),isppol,xmpio_collective, &
    2512       226638 : &         cg_k=cg_ddk(:,:,idir1), eig_k=eig2_ddk(:,idir1))
    2513              :    end if ! ddk file is already present
    2514              :  end do ! idir1
    2515              : 
    2516        99323 :  if (ipert==dtset%natom+1) then
    2517        17370 :    nband_kocc = 0
    2518       129761 :    do iband = 1,nband_k
    2519       112391 :      if (abs(occ_k(iband)) > tol8) nband_kocc = nband_kocc + 1
    2520       129761 :      nband_kocc = max (nband_kocc, 1)
    2521              :    end do
    2522              :  end if
    2523              : 
    2524        99323 :  if(dtset%prtbbb==1)then
    2525          456 :    ABI_MALLOC(cwavef_da,(2,npw1_k*dtset%nspinor))
    2526          304 :    ABI_MALLOC(cwavef_db,(2,npw1_k*dtset%nspinor))
    2527          456 :    ABI_MALLOC(cg_k,(2,npw_k*dtset%nspinor*mband_mem_rbz))
    2528              :    if ((ipert == dtset%natom + 1).or.(ipert <= dtset%natom).or. &
    2529          152 : &      (ipert == dtset%natom + 2).or.(ipert == dtset%natom + 5)) then
    2530       533912 :      cg_k(:,:) = cg(:,1+icg:icg+mband_mem_rbz*npw_k*dtset%nspinor)
    2531              :    end if
    2532        98648 :    d2bbb_k(:,:,:,:) = zero
    2533              :  end if
    2534              : 
    2535              : !Loop over ALL bands
    2536        99323 :  iband_me = 0
    2537       678003 :  do iband=1,nband_k
    2538              :  ABI_NVTX_START_RANGE(NVTX_DFPT_NSTWF_BAND)
    2539              : 
    2540              : ! if band is mine, retrieve it and then broadcast it
    2541       578680 :    if(mpi_enreg%proc_distrb(ikpt,iband,isppol) == mpi_enreg%me_kpt) then
    2542       578464 :      iband_me = iband_me + 1
    2543              : 
    2544              : !  Read ground-state wavefunction for iband
    2545       578464 :      if (dtset%prtbbb==0 .or. ipert==dtset%natom+2) then
    2546    365415724 :        cwave0(:,:)=cg(:,1+(iband_me-1)*npw_k*dtset%nspinor+icg:iband_me*npw_k*dtset%nspinor+icg)
    2547              :      else    ! prtbbb==1 and ipert<=natom , already in cg_k
    2548       422400 :        cwave0(:,:)=cg_k(:,1+(iband_me-1)*npw_k*dtset%nspinor:iband_me*npw_k*dtset%nspinor)
    2549              :      end if
    2550              : 
    2551              : !  Get first-order wavefunctions for iband
    2552    365760304 :      cwavef(:,:)=cg1(:,1+(iband_me-1)*npw1_k*dtset%nspinor+icg1:iband_me*npw1_k*dtset%nspinor+icg1)
    2553              : !  Get ddk wavefunctions for iband
    2554       578464 :      if(nddk_needed > 0) then
    2555    132778161 :        cwaveddk(:,:,:)=cg_ddk(:,1+(iband_me-1)*npw1_k*dtset%nspinor:iband_me*npw1_k*dtset%nspinor,:)
    2556              :      end if
    2557              :    end if
    2558       578680 :    call xmpi_bcast(cwave0, band_procs(iband), mpi_enreg%comm_band, ierr)
    2559       578680 :    call xmpi_bcast(cwavef, band_procs(iband), mpi_enreg%comm_band, ierr)
    2560       578680 :    if(nddk_needed > 0) then
    2561       114975 :      call xmpi_bcast(cwaveddk, band_procs(iband), mpi_enreg%comm_band, ierr)
    2562              :    end if
    2563              : 
    2564              : !  In case non ddk perturbation
    2565       578680 :    if (ipert /= dtset%natom + 1) then
    2566              : 
    2567      4693048 :      do ipert1=1,mpert
    2568              : 
    2569      4693048 :        if( ipert1<=dtset%natom .or. ipert1==dtset%natom+2 )then
    2570              : 
    2571              : !        Initialize data for NL 1st-order hamiltonian
    2572      1328225 :          call rf_hamkq%init(1,gs_hamkq,ipert1)
    2573              : 
    2574              :          if (((ipert <= dtset%natom).or.(ipert == dtset%natom + 2)) &
    2575      1328225 : &         .and.(ipert1 == dtset%natom+2).and. dtset%prtbbb==1) then
    2576              :            call gaugetransfo(cg_k,cwavef,cwavef_db,mpi_enreg%comm_band,distrb_cycle,eig_k,eig1_k,&
    2577              :              & dtset%ggtrcut,iband,nband_k,dtset%mband,mband_mem_rbz,npw_k,npw1_k,dtset%nspinor,&
    2578          448 :              & nsppol,mpi_enreg%nproc_band,occ_k)
    2579       197248 :            cwavef(:,:) = cwavef_db(:,:)
    2580              :          end if
    2581              : 
    2582              : !        Define the direction along which to move the atom :
    2583              : !        the polarisation (ipert1,idir1) is referred as j1.
    2584      5312900 :          do idir1=1,3
    2585      5312900 :            if (ipert1<=dtset%natom.or.(ipert1==dtset%natom+2.and.ddkfil(idir1)/=0)) then
    2586              : 
    2587              : !            Get |Vnon-locj^(1)|u0> :
    2588              : !            First-order non-local, applied to zero-order wavefunction
    2589              : !            This routine gives MINUS the non-local contribution
    2590              : 
    2591              : !            ==== Atomic displ. perturbation
    2592      2915187 :              if( ipert1<=dtset%natom )then
    2593      2585808 :                lambda=eig_k((isppol-1)*nband_k+iband)
    2594      2585808 :                berryopt=1;optlocal=0;optnl=1;usevnl=0;opt_gvnlx1=0;sij_opt=0
    2595              :                call getgh1c(berryopt,cwave0,dum_cwaveprj,gvnlx1,dum_grad_berry,&
    2596              : &               dum_gs1,gs_hamkq,dum_gvnlx1,idir1,ipert1,(/lambda/),mpi_enreg,1,optlocal,&
    2597      5171616 : &               optnl,opt_gvnlx1,rf_hamkq,sij_opt,tim_getgh1c,usevnl)
    2598              : 
    2599              : !              ==== Electric field perturbation
    2600       329379 :              else if( ipert1==dtset%natom+2 )then
    2601              :                ! TODO: Several tests fail here ifdef HAVE_MPI_IO_DEFAULT
    2602              :                ! The problem is somehow related to the use of MPI-IO file views!.
    2603              : !TODO MJV: Check if it works with HAVE_MPI_IO_DEFAULT now.
    2604              : 
    2605    128343861 :                gvnlx1 = cwaveddk(:,:,idir1)
    2606      4699101 :                eig2_k(1+(iband-1)*2*nband_k:iband*2*nband_k) = eig2_ddk(1+(iband-1)*2*nband_k:iband*2*nband_k,idir1)
    2607              : 
    2608              :                !write(777,*)"eig2_k, gvnlx1 for band: ",iband,", ikpt: ",ikpt
    2609              :                !do ii=1,2*nband_k
    2610              :                !  write(777,*)eig2_k(ii+(iband-1))
    2611              :                !end do
    2612              :                !write(777,*)gvnlx1
    2613              : 
    2614              : !              In case of band-by-band,
    2615              : !              construct the first-order wavefunctions in the diagonal gauge
    2616       329379 :                if (((ipert <= dtset%natom).or.(ipert == dtset%natom + 2)).and.(dtset%prtbbb==1)) then
    2617              :                  call gaugetransfo(cg_k,gvnlx1,cwavef_da,mpi_enreg%comm_band,distrb_cycle,eig_k,eig2_k,&
    2618              :                    & dtset%ggtrcut,iband,nband_k,dtset%mband,mband_mem_rbz,npw_k,npw1_k,dtset%nspinor,&
    2619         1344 :                    & nsppol,mpi_enreg%nproc_band,occ_k)
    2620       591744 :                  gvnlx1(:,:) = cwavef_da(:,:)
    2621              :                end if
    2622              : !              Multiplication by -i
    2623     42891080 :                do ipw=1,npw1_k*dtset%nspinor
    2624     42561701 :                  aa=gvnlx1(1,ipw)
    2625     42561701 :                  gvnlx1(1,ipw)=gvnlx1(2,ipw)
    2626     42891080 :                  gvnlx1(2,ipw)=-aa
    2627              :                end do
    2628              : 
    2629              : !              MRoyo 030925 :
    2630              : !              3) Case ipert1=natom+2 and ipert=natom+5 or ipert=natom+12:2*natom+11
    2631              : !              the computation of mixed derivatives wrt to Zeeman and electric fields needs $i \frac{d}{dk}.
    2632      7450899 :                if (ipert==dtset%natom+5.or.(ipert>=dtset%natom+12.and.ipert<=2*dtset%natom+11)) gvnlx1(:,:) = -gvnlx1(:,:)
    2633              : 
    2634              :              end if
    2635              : 
    2636              : ! at this stage if iband is not mine I can cycle
    2637      2915187 :              if (mpi_enreg%proc_distrb(ikpt,iband,isppol) /= mpi_enreg%me_kpt) then
    2638              :                cycle
    2639              :              end if
    2640              : 
    2641              : !            MVeithen 021212 :
    2642              : !            1) Case ipert1 = natom + 2 and ipert = natom + 2:
    2643              : !            the second derivative of the energy with respect to an electric
    2644              : !            field is computed from Eq. (38) of X. Gonze, PRB 55 ,10355 (1997) [[cite:Gonze1997a]].
    2645              : !            The evaluation of this formula needs the operator $i \frac{d}{dk}.
    2646              : !            2) Case ipert1 = natom + 2 and ipert < natom:
    2647              : !            the computation of the Born effective charge tensor uses
    2648              : !            the operator $-i \frac{d}{dk}.
    2649    184161492 :              if (ipert==dtset%natom+2) gvnlx1(:,:) = -gvnlx1(:,:)
    2650              : 
    2651              : 
    2652              : !            <G|Vnl1|Cnk> is contained in gvnlx1
    2653              : !            construct the matrix element (<uj2|vj1|u0>)complex conjug and add it to the 2nd-order matrix
    2654      2909355 :              call dotprod_g(dotr,doti,istwf_k,npw1_k*dtset%nspinor,2,cwavef,gvnlx1,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
    2655      2909355 :              d2nl_k(1,idir1,ipert1)=d2nl_k(1,idir1,ipert1)+wtk_k*occ_k(iband)*two*dotr
    2656      2909355 :              d2nl_k(2,idir1,ipert1)=d2nl_k(2,idir1,ipert1)-wtk_k*occ_k(iband)*two*doti
    2657              : 
    2658              : !            Band by band decomposition of the Born effective charges
    2659              : !            calculated from a phonon perturbation
    2660      2909355 :              if(dtset%prtbbb==1) then ! .and. mpi_enreg%proc_distrb(ikpt,iband,isppol) == mpi_enreg%me_kpt)then
    2661         4032 :                d2bbb_k(1,idir1,iband,iband) =      wtk_k*occ_k(iband)*two*dotr
    2662         4032 :                d2bbb_k(2,idir1,iband,iband) = -one*wtk_k*occ_k(iband)*two*doti
    2663              :              end if
    2664              : 
    2665              :            end if
    2666              :          end do ! idir
    2667              : 
    2668      1328225 :          call rf_hamkq%free()
    2669              :        end if     ! ipert1<=dtset%natom .or. ipert1==dtset%natom+2
    2670              :      end do     ! ipert1
    2671              :    end if     ! ipert /= natom +1
    2672              : 
    2673              : !  Compute the localization tensor
    2674              : 
    2675      1256683 :    if (ipert==dtset%natom+1) then
    2676              : 
    2677       112391 :      ipert1=dtset%natom+1
    2678       112391 :      if(dtset%prtbbb==1)then
    2679              :        call gaugetransfo(cg_k,cwavef,cwavef_db,mpi_enreg%comm_band,distrb_cycle,eig_k,eig1_k,&
    2680              :          & dtset%ggtrcut,iband,nband_k,dtset%mband,mband_mem_rbz,npw_k,npw1_k,dtset%nspinor,&
    2681          768 :          & nsppol,mpi_enreg%nproc_band,occ_k)
    2682       337728 :        cwavef(:,:) = cwavef_db(:,:)
    2683              :      end if
    2684              : 
    2685       449564 :      do idir1 = 1,3
    2686    143637471 :        eig2_k(:) = zero
    2687    116095911 :        gvnlx1(:,:) = zero
    2688       337173 :        if (idir == idir1) then
    2689     38698637 :          gvnlx1(:,:) = cwavef(:,:)
    2690     47879157 :          eig2_k(:) = eig1_k(:)
    2691              :        else
    2692       224782 :          if (ddkfil(idir1) /= 0) then
    2693       356544 :            gvnlx1 = cwaveddk(:,:,idir1)
    2694        16512 :            eig2_k(1+(iband-1)*2*nband_k:iband*2*nband_k) = eig2_ddk(1+(iband-1)*2*nband_k:iband*2*nband_k,idir1)
    2695              : 
    2696              :            !write(778,*)"eig2_k, gvnlx1 for band: ",iband,", ikpt: ",ikpt
    2697              :            !do ii=1,2*nband_k
    2698              :            !  write(778,*)eig2_k(ii+(iband-1))
    2699              :            !end do
    2700              :            !write(778,*)gvnlx1
    2701              : 
    2702         1152 :            if(dtset%prtbbb==1)then
    2703              :              call gaugetransfo(cg_k,gvnlx1,cwavef_da,mpi_enreg%comm_band,distrb_cycle,eig_k,eig2_k,&
    2704              :                & dtset%ggtrcut,iband,nband_k,dtset%mband,mband_mem_rbz,npw_k,npw1_k,dtset%nspinor,&
    2705          768 :                & nsppol,mpi_enreg%nproc_band,occ_k)
    2706              : 
    2707       337728 :              gvnlx1(:,:) = cwavef_da(:,:)
    2708              :            end if
    2709              : 
    2710              :          end if    !ddkfil(idir1)
    2711              :        end if    !idir == idir1
    2712              : 
    2713              : !      <G|du/dqa> is contained in gvnlx1 and <G|du/dqb> in cwavef
    2714              : !      construct the matrix elements <du/dqa|du/dqb> -> dot
    2715              : !      <u|du/dqa> -> dot1
    2716              : !      <du/dqb|u> -> dot2
    2717              : !      and add them to the 2nd-order matrix
    2718              : 
    2719       337173 :        call dotprod_g(dotr,doti,istwf_k,npw1_k*dtset%nspinor,2,gvnlx1,cwavef,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
    2720       337173 :        d2nl_k(1,idir1,ipert1)=d2nl_k(1,idir1,ipert1)+wtk_k*occ_k(iband)*dotr/(nband_kocc*two)
    2721       337173 :        d2nl_k(2,idir1,ipert1)=d2nl_k(2,idir1,ipert1)+wtk_k*occ_k(iband)*doti/(nband_kocc*two)
    2722              : 
    2723              : 
    2724              : !      XG 020216 : Marek, could you check the next forty lines
    2725              : !      In the parallel gauge, dot1 and dot2 vanishes
    2726       449564 :        if(dtset%prtbbb==1)then
    2727         2304 :          if (mpi_enreg%proc_distrb(ikpt,iband,isppol) == mpi_enreg%me_kpt) then
    2728         2304 :            d2bbb_k(1,idir1,iband,iband)=d2bbb_k(1,idir1,iband,iband)+dotr
    2729         2304 :            d2bbb_k(2,idir1,iband,iband)=d2bbb_k(2,idir1,iband,iband)+doti
    2730              :          end if
    2731         2304 :          dot_ndiagr=zero ; dot_ndiagi=zero
    2732         2304 :          jband_me = 0
    2733        20736 :          do jband = 1,nband_k              !compute dot1 and dot2
    2734        18432 :            if (mpi_enreg%proc_distrb(ikpt,jband,isppol) /= mpi_enreg%me_kpt) then
    2735              :              cycle
    2736              :            end if
    2737        18432 :            jband_me = jband_me + 1
    2738              : 
    2739        20736 :            if (abs(occ_k(jband)) > tol8) then
    2740        18432 :              dot1r=zero ; dot1i=zero
    2741        18432 :              dot2r=zero ; dot2i=zero
    2742      8105472 :              cwave0(:,:)=cg_k(:,1+(jband_me-1)*npw_k*dtset%nspinor:jband_me*npw_k*dtset%nspinor)
    2743              : 
    2744        18432 :              call dotprod_g(dot1r,dot1i,istwf_k,npw1_k*dtset%nspinor,2,cwave0,gvnlx1,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
    2745        18432 :              call dotprod_g(dot2r,dot2i,istwf_k,npw1_k*dtset%nspinor,2,cwavef,cwave0,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
    2746              : 
    2747        18432 :              dot_ndiagr = dot_ndiagr + dot1r*dot2r - dot1i*dot2i
    2748        18432 :              dot_ndiagi = dot_ndiagi + dot1r*dot2i + dot1i*dot2r
    2749              : ! this should fill all of the iband but only the local cpu jband indices
    2750              :              d2bbb_k(1,idir1,iband,jband) = d2bbb_k(1,idir1,iband,jband) - &
    2751        18432 : &               (dot1r*dot2r - dot1i*dot2i)
    2752              :              d2bbb_k(2,idir1,iband,jband) = d2bbb_k(2,idir1,iband,jband) - &
    2753        18432 : &               (dot1r*dot2i + dot1i*dot2r)
    2754              :            end if  ! occ_k
    2755              :          end do !jband
    2756              : 
    2757        57600 :          d2bbb_k(:,idir1,iband,:)=d2bbb_k(:,idir1,iband,:)*wtk_k*occ_k(iband)*half
    2758              :          d2nl_k(1,idir1,ipert1)= &
    2759         2304 : &         d2nl_k(1,idir1,ipert1)-wtk_k*occ_k(iband)*dot_ndiagr/(nband_kocc*two)
    2760              :          d2nl_k(2,idir1,ipert1)=&
    2761         2304 : &         d2nl_k(2,idir1,ipert1)-wtk_k*occ_k(iband)*dot_ndiagi/(nband_kocc*two)
    2762              :        end if ! prtbbb==1
    2763              : 
    2764              :      end do  ! idir1
    2765              :    end if   ! Compute localization tensor, ipert=natom+1
    2766              : 
    2767              :    ABI_NVTX_END_RANGE()
    2768              :  end do !  End loop over iband
    2769              : 
    2770              : 
    2771              : ! if(dtset%prtbbb==1)then
    2772              : !   ! complete over jband index
    2773              : !   call xmpi_sum(d2bbb_k, mpi_enreg%comm_band, ierr)
    2774              : ! end if
    2775              : 
    2776              : !Final deallocations
    2777        99323 :  ABI_FREE(cwave0)
    2778        99323 :  ABI_FREE(cwavef)
    2779        99323 :  ABI_FREE(eig2_k)
    2780        99323 :  ABI_FREE(gvnlx1)
    2781        99323 :  ABI_FREE(ffnlk)
    2782        99323 :  ABI_FREE(ffnl1)
    2783        99323 :  ABI_FREE(dkinpw)
    2784        99323 :  ABI_FREE(kinpw1)
    2785        99323 :  ABI_FREE(kpg_k)
    2786        99323 :  ABI_FREE(kpg1_k)
    2787        99323 :  ABI_FREE(ph3d)
    2788        99323 :  ABI_FREE(dum_cwaveprj)
    2789        99323 :  if(dtset%prtbbb==1)  then
    2790          152 :    ABI_FREE(cg_k)
    2791          152 :    ABI_FREE(cwavef_da)
    2792          152 :    ABI_FREE(cwavef_db)
    2793              :  end if
    2794        99323 :  if (nddk_needed > 0) then
    2795        26180 :    ABI_FREE(cwaveddk)
    2796        26180 :    ABI_FREE(cg_ddk)
    2797        26180 :    ABI_FREE(eig2_ddk)
    2798              :  end if
    2799              : 
    2800        99323 :  call timab(112,2,tsec)
    2801              : 
    2802              :  ABI_NVTX_END_RANGE()
    2803              : 
    2804              :  DBG_EXIT("COLL")
    2805              : 
    2806        99323 : end subroutine dfpt_nstwf
    2807              : !!***
    2808              : 
    2809              : !!****f* ABINIT/gaugetransfo
    2810              : !! NAME
    2811              : !! gaugetransfo
    2812              : !!
    2813              : !! FUNCTION
    2814              : !! This routine allows the passage from the parallel-transport gauge
    2815              : !! to the diagonal gauge for the first-order wavefunctions
    2816              : !!
    2817              : !! INPUTS
    2818              : !!  cg_k(2,mpw*nspinor*mband_mem*nsppol)=planewave coefficients of wavefunctions
    2819              : !!                                   for a particular k point.
    2820              : !!  cwavef(2,npw1_k*nspinor)=first order wavefunction for a particular k point
    2821              : !!                           in the parallel gauge
    2822              : !!  comm=mpi communicator for bands
    2823              : !!  distrb_cycle=array of logical flags to skip certain bands in parallelization scheme
    2824              : !!  eig_k(mband*nsppol)=GS eigenvalues at k (hartree)
    2825              : !!  eig1_k(2*nsppol*mband**2)=matrix of first-order eigenvalues (hartree)
    2826              : !!  ggtrcut=cutoff to reject unstable band pairs
    2827              : !!  iband=band index of the 1WF for which the transformation has to be applied
    2828              : !!  mband=maximum number of bands
    2829              : !!  mband_mem_rbz=maximum number of bands on this cpu
    2830              : !!  nband_k=number of bands for this k point
    2831              : !!  npw_k=maximum dimensioned size of npw or wfs at k
    2832              : !!  npw1_k=number of plane waves at this k+q point
    2833              : !!  nspinor=number of spinorial components of the wavefunctions
    2834              : !!  nsppol=1 for unpolarized, 2 for spin-polarized
    2835              : !!  occ_k(nband_k)=occupation number for each band (usually 2) for each k
    2836              : !!
    2837              : !! OUTPUT
    2838              : !!  cwavef_d(2,npw1_k*nspinor)=first order wavefunction for a particular k point
    2839              : !!                             in the diagonal gauge
    2840              : !!
    2841              : !! SOURCE
    2842              : 
    2843         3328 : subroutine gaugetransfo(cg_k,cwavef,cwavef_d,comm,distrb_cycle,eig_k,eig1_k,ggtrcut,iband,nband_k, &
    2844         3328 : &                      mband,mband_mem_rbz,npw_k,npw1_k,nspinor,nsppol,nproc_band,occ_k)
    2845              : 
    2846              : !Arguments ------------------------------------
    2847              : !scalars
    2848              :  integer,intent(in) :: iband,mband,mband_mem_rbz,nband_k,npw1_k,npw_k,nspinor,nsppol
    2849              :  integer,intent(in) :: comm, nproc_band
    2850              :  real(dp),intent(in) :: ggtrcut
    2851              : !arrays
    2852              :  logical, intent(in) :: distrb_cycle(nband_k)
    2853              :  real(dp),intent(in) :: cg_k(2,npw_k*nspinor*mband_mem_rbz),cwavef(2,npw1_k*nspinor)
    2854              :  real(dp),intent(in) :: eig1_k(2*nsppol*mband**2),eig_k(mband*nsppol)
    2855              :  real(dp),intent(in) :: occ_k(nband_k)
    2856              :  real(dp),intent(out) :: cwavef_d(2,npw1_k*nspinor)
    2857              : 
    2858              : !Local variables-------------------------------
    2859              : !tolerance for non degenerated levels
    2860              : !scalars
    2861              :  integer :: ierr, jband,jband_me
    2862              : !arrays
    2863         3328 :  real(dp) :: cwave0(2,npw1_k*nspinor),eig1(2)
    2864              : 
    2865              : ! *********************************************************************
    2866              : 
    2867      1464448 :    cwavef_d(:,:) = cwavef(:,:)
    2868              : 
    2869              :    jband_me = 0
    2870        29952 :    do jband = 1,nband_k !loop over bands
    2871        26624 :      if (distrb_cycle(jband)) cycle
    2872        26624 :      jband_me = jband_me + 1
    2873              : 
    2874              :      ! the default value of ggtrcut is 0.001, was formerly a parameter in this routine 
    2875              :      ! called etol=0.001_dp
    2876        29952 :      if ((abs(eig_k(iband)-eig_k(jband)) > ggtrcut).and.(abs(occ_k(jband)) > tol8 )) then
    2877              : 
    2878      9948064 :        cwave0(:,:) = cg_k(:,1+(jband_me-1)*npw_k*nspinor:jband_me*npw_k*nspinor)
    2879              : 
    2880        22624 :        eig1(1) = eig1_k(2*jband-1+(iband-1)*2*nband_k)
    2881        22624 :        eig1(2) = eig1_k(2*jband +(iband-1)*2*nband_k)
    2882              : 
    2883              :        cwavef_d(1,:)=cwavef_d(1,:) &
    2884      3331104 : &       - (eig1(1)*cwave0(1,:)-eig1(2)*cwave0(2,:))/(eig_k(jband)-eig_k(iband))
    2885              :        cwavef_d(2,:)=cwavef_d(2,:) &
    2886      3331104 : &       - (eig1(1)*cwave0(2,:)+eig1(2)*cwave0(1,:))/(eig_k(jband)-eig_k(iband))
    2887              : 
    2888              :      end if
    2889              : 
    2890              :    end do    !loop over bands
    2891         3328 :    call xmpi_sum(cwavef_d, comm, ierr)
    2892              :    ! here we have summed the cwavef N times (N-1 too many), but the correction is completed over bands
    2893      1464448 :    cwavef_d = cwavef_d - dble(nproc_band-1)*cwavef
    2894              : 
    2895         3328 :   end subroutine gaugetransfo
    2896              : !!***
    2897              : 
    2898              : 
    2899              : end module m_dfpt_nstwf
    2900              : !!***
        

Generated by: LCOV version 2.3-1