LCOV - code coverage report
Current view: top level - src/79_seqpar_mpi - m_vtowfk.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 81.9 % 540 442
Test Date: 2026-09-19 15:24:51 Functions: 100.0 % 1 1

            Line data    Source code
       1              : !!****m* ABINIT/m_vtowfk
       2              : !! NAME
       3              : !!  m_vtowfk
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, MT)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~abinit/COPYING
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! SOURCE
      15              : 
      16              : #if defined HAVE_CONFIG_H
      17              : #include "config.h"
      18              : #endif
      19              : 
      20              : #include "abi_common.h"
      21              : 
      22              : ! nvtx related macro definition
      23              : #include "nvtx_macros.h"
      24              : 
      25              : module m_vtowfk
      26              : 
      27              :  use, intrinsic :: iso_fortran_env, only: int32, int64, real32, real64
      28              :  use, intrinsic :: iso_c_binding, only: c_size_t, c_loc
      29              : 
      30              :  use defs_basis
      31              :  use m_abicore
      32              :  use m_errors
      33              :  use m_xmpi
      34              :  use m_efield
      35              :  use m_linalg_interfaces
      36              :  use m_cgtools
      37              :  use m_dtset
      38              :  use m_dtfil
      39              :  use m_xomp
      40              :  use m_xg
      41              :  use m_xg_nonlop
      42              : 
      43              :  use defs_abitypes, only : MPI_type
      44              :  use m_time,        only : timab, cwtime, cwtime_report, sec2str
      45              :  use m_fstrings,    only : sjoin, itoa, ftoa
      46              :  use m_hamiltonian, only : gs_hamiltonian_type
      47              :  use m_getghc,      only : getghc_nucdip
      48              :  use m_paw_dmft,    only : paw_dmft_type
      49              :  use m_pawcprj,     only : pawcprj_type, pawcprj_alloc, pawcprj_free, pawcprj_put,pawcprj_copy
      50              :  use m_paw_dmft,    only : paw_dmft_type
      51              :  use m_gwls_hamiltonian, only : build_H
      52              :  use m_fftcore,     only : fftcore_set_mixprec, fftcore_mixprec
      53              :  use m_cgwf,        only : cgwf
      54              :  use m_cgwf_cprj,   only : cgwf_cprj,mksubovl,cprj_update,cprj_update_oneband
      55              :  use m_lobpcgwf_old,only : lobpcgwf
      56              :  use m_lobpcgwf,    only : lobpcgwf2
      57              :  use m_chebfiwf,    only : chebfiwf2
      58              :  use m_chebfiwf_cprj,only : chebfiwf2_cprj
      59              :  use m_lobpcgwf_cprj,only : lobpcgwf2_cprj
      60              :  use m_slicewf,     only : slicewf
      61              :  use m_slicewf_cprj,  only : slicewf_cprj
      62              :  use m_spacepar,    only : meanvalue_g, meanvalue_g_batch
      63              :  use m_chebfi,      only : chebfi
      64              :  use m_rmm_diis,    only : rmm_diis
      65              :  use m_nonlop,      only : nonlop !, nonlop_counter
      66              :  use m_prep_kgb,    only : prep_nonlop, prep_fourwf
      67              :  use m_cgprj,       only : cprj_rotate,xg_cprj_copy,XG_TO_CPRJ
      68              :  use m_fft,         only : fourwf, fourwf_optmem
      69              :  use m_cgtk,        only : cgtk_fixphase
      70              :  use m_common,      only : get_gemm_nonlop_ompgpu_blocksize
      71              :  use m_gemm_nonlop_projectors, only : gemm_nonlop_block_size, gemm_nonlop_is_distributed
      72              :  use m_gputk, only : gpu_copy
      73              : #if defined HAVE_YAKL
      74              :  use gator_mod
      75              : #endif
      76              : #if defined(HAVE_GPU_MARKERS)
      77              :  use m_nvtx_data
      78              : #endif
      79              : 
      80              :  implicit none
      81              : 
      82              :  private
      83              : !!***
      84              : 
      85              :  public :: vtowfk
      86              : !!***
      87              : 
      88              : contains
      89              : !!***
      90              : 
      91              : !!****f* ABINIT/vtowfk
      92              : !! NAME
      93              : !! vtowfk
      94              : !!
      95              : !! FUNCTION
      96              : !! This routine compute the partial density at a given k-point,
      97              : !! for a given spin-polarization, from a fixed Hamiltonian
      98              : !! but might also simply compute eigenvectors and eigenvalues at this k point
      99              : !!
     100              : !! INPUTS
     101              : !!  cgq = array that holds the WF of the nearest neighbours of
     102              : !!        the current k-point (electric field, MPI //)
     103              : !!  cpus= cpu time limit in seconds
     104              : !!  dtefield <type(efield_type)> = variables related to Berry phase
     105              : !!      calculations (see initberry.f)
     106              : !!  dtfil <type(datafiles_type)>=variables related to files
     107              : !!  dtset <type(dataset_type)>=all input variables for this dataset
     108              : !!  fixed_occ=true if electronic occupations are fixed (occopt<3)
     109              : !!  gs_hamk <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k
     110              : !!  ibg=shift to be applied on the location of data in the array cprj
     111              : !!  icg=shift to be applied on the location of data in the array cg
     112              : !!  ikpt=number of the k-point
     113              : !!  iscf=(<= 0  =>non-SCF), >0 => SCF
     114              : !!  isppol= 1 for unpolarized, 2 for spin-polarized
     115              : !!  kg_k(3,npw_k)=reduced planewave coordinates.
     116              : !!  kinpw(npw_k)=(modified) kinetic energy for each plane wave (Hartree)
     117              : !!  mcg=second dimension of the cg array
     118              : !!  mcgq=second dimension of the cgq array (electric field, MPI //)
     119              : !!  mcprj=size of projected wave-functions array (cprj) =nspinor*mband*mkmem*nsppol
     120              : !!  mkgq = second dimension of pwnsfacq
     121              : !!  mpi_enreg=information about MPI parallelization
     122              : !!  mpw=maximum dimensioned size of npw
     123              : !!  natom=number of atoms in cell.
     124              : !!  nband_k=number of bands at this k point for that spin polarization
     125              : !!  nkpt=number of k points.
     126              : !!  istep=index of the number of steps in the routine scfcv
     127              : !!  nnsclo_now=number of non-self-consistent loops for the current vtrial
     128              : !!             (often 1 for SCF calculation, =nstep for non-SCF calculations)
     129              : !!  npw_k=number of plane waves at this k point
     130              : !!  npwarr(nkpt)=number of planewaves in basis at this k point
     131              : !!  occ_k(nband_k)=occupation number for each band (usually 2) for each k.
     132              : !!  optforces=option for the computation of forces
     133              : !!  prtvol=control print volume and debugging output
     134              : !!  pwind(pwind_alloc,2,3)= array used to compute
     135              : !!           the overlap matrix smat between k-points (see initberry.f)
     136              : !!  pwind_alloc= first dimension of pwind
     137              : !!  pwnsfac(2,pwind_alloc)= phase factors for non-symmorphic translations
     138              : !!                          (see initberry.f)
     139              : !!  pwnsfacq(2,mkgq)= phase factors for the nearest neighbours of the
     140              : !!                    current k-point (electric field, MPI //)
     141              : !!  usebanfft=flag for band-fft parallelism
     142              : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
     143              : !!  wtk=weight assigned to the k point.
     144              : !!  zshift(nband_k)=energy shifts for the squared shifted hamiltonian algorithm
     145              : !!
     146              : !! OUTPUT
     147              : !!  dphase_k(3)=change in Zak phase for the current k-point
     148              : !!  eig_k(nband_k)=array for holding eigenvalues (hartree)
     149              : !!  ek_k(nband_k)=contribution from each band to kinetic energy, at this k-point
     150              : !!  ek_k_nd(2,nband_k,nband_k*use_dmft)=contribution to kinetic energy,
     151              : !!     including non-diagonal terms, at this k-point (useful if use_dmft)
     152              : !!  end_k(nband_k)=contribution from each band to nuclear dipole energy, at this k-point
     153              : !!  resid_k(nband_k)=residuals for each band over all k points, BEFORE the band rotation.
     154              : !!   In input: previous residuals.
     155              : !!  ==== if optforces>0 ====
     156              : !!    grnl_k(3*natom,nband_k)=nonlocal gradients, at this k-point
     157              : !!  ==== if gs_hamk%usepaw==0 ====
     158              : !!    enlx_k(nband_k)=contribution from each band to
     159              : !!                    nonlocal pseudopotential + Fock-type part of total energy, at this k-point
     160              : !!  ==== if (gs_hamk%usepaw==1) ====
     161              : !!    cprj(natom,mcprj*usecprj)= wave functions projected with non-local projectors:
     162              : !!                               cprj(n,k,i)=<p_i|Cnk> where p_i is a non-local projector.
     163              : !!
     164              : !! SIDE EFFECTS
     165              : !!  cg(2,mcg)=updated wavefunctions
     166              : !!  rhoaug(n4,n5,n6,nvloc)= density in electrons/bohr**3, on the augmented fft grid.
     167              : !!                    (cumulative, so input as well as output). Update only
     168              : !!                    for occopt<3 (fixed occupation numbers)
     169              : !!  rmm_diis_status: Status of the RMM-DIIS eigensolver. See m_rmm_diis.
     170              : !!
     171              : !! NOTES
     172              : !!  The cprj are distributed over band and spinors processors.
     173              : !!  One processor doesn't know all the cprj.
     174              : !!  Only the mod((iband-1)/mpi_enreg%bandpp,mpi_enreg%nproc_band) projectors
     175              : !!  are stored on each proc.
     176              : !!
     177              : !! SOURCE
     178              : 
     179       343291 : subroutine vtowfk(cg,cgq,cprj,cpus,dphase_k,dtefield,dtfil,dtset,&
     180       343291 : & eig_k,ek_k,ek_k_nd,end_k,enlx_k,fixed_occ,grnl_k,gs_hamk,&
     181       343291 : & ibg,icg,ikpt,iscf,isppol,kg_k,kinpw,mband_cprj,mcg,mcgq,mcprj,mkgq,mpi_enreg,&
     182       343291 : & mpw,natom,nband_k,nbdbuf,nkpt,istep,nnsclo_now,npw_k,npwarr,occ_k,optforces,prtvol,&
     183       343291 : & pwind,pwind_alloc,pwnsfac,pwnsfacq,resid_k,rhoaug,paw_dmft,wtk,xg_nonlop,zshift,rmm_diis_status)
     184              : 
     185              : !Arguments ------------------------------------
     186              :  integer, intent(in) :: ibg,icg,ikpt,iscf,isppol,mband_cprj,mcg,mcgq,mcprj,mkgq,mpw
     187              :  integer, intent(in) :: natom,nband_k,nbdbuf,nkpt,nnsclo_now,npw_k,optforces
     188              :  integer, intent(in) :: prtvol,pwind_alloc,istep
     189              :  logical,intent(in) :: fixed_occ
     190              :  real(dp), intent(in) :: cpus,wtk
     191              :  type(datafiles_type), intent(in) :: dtfil
     192              :  type(efield_type), intent(inout) :: dtefield
     193              :  type(dataset_type), intent(in) :: dtset
     194              :  type(gs_hamiltonian_type), intent(inout) :: gs_hamk
     195              :  type(MPI_type), intent(inout) :: mpi_enreg
     196              :  type(paw_dmft_type), intent(in)  :: paw_dmft
     197              :  integer, intent(in) :: kg_k(3,npw_k)
     198              :  integer, intent(in) :: npwarr(nkpt),pwind(pwind_alloc,2,3)
     199              :  integer, intent(inout) :: rmm_diis_status(2)
     200              :  real(dp), intent(in) :: cgq(2,mcgq),occ_k(nband_k)
     201              :  real(dp),target,intent(in) :: kinpw(npw_k)
     202              :  real(dp), intent(in) :: pwnsfac(2,pwind_alloc),pwnsfacq(2,mkgq)
     203              :  real(dp), intent(in) :: zshift(nband_k)
     204              :  real(dp), target, intent(out) :: eig_k(nband_k)
     205              :  real(dp), intent(out) :: ek_k(nband_k),dphase_k(3),ek_k_nd(2,nband_k,nband_k*paw_dmft%use_dmft)
     206              :  real(dp), intent(out) :: end_k(nband_k),enlx_k(nband_k)
     207              :  real(dp), intent(out),target :: grnl_k(3*natom,nband_k*optforces)
     208              :  real(dp), intent(inout) :: resid_k(nband_k)
     209              :  real(dp), intent(inout),target :: cg(2,mcg)
     210              :  real(dp), intent(inout) :: rhoaug(gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,gs_hamk%nvloc)
     211              :  type(pawcprj_type),intent(inout),target :: cprj(natom,mcprj*gs_hamk%usecprj)
     212              :  type(xg_nonlop_t),intent(in) :: xg_nonlop
     213              : 
     214              : !Local variables-------------------------------
     215              :  logical :: has_fock,xg_diago,update_cprj
     216              :  logical :: do_subdiago,do_ortho,rotate_subvnlx,use_rmm_diis,is_distrib_tmp
     217              :  integer,parameter :: level=112,tim_fourwf=2,tim_nonlop_prep=11,enough=3,tim_getcprj=5
     218              :  integer,save :: nskip=0
     219              : ! Flag use_subovl: 1 if "subovl" array is computed (see below)
     220              : ! subovl should be Identity (in that case we should use use_subovl=0)
     221              : ! But this is true only if conjugate gradient algo. converges
     222              :  integer :: use_subovl=0, use_subvnlx=0, use_totvnlx=0
     223              :  integer :: bandpp_cprj,blocksize,choice,cpopt,fftalg,iband,iband1,filter
     224              :  integer :: nstep_mixed
     225              :  integer :: iblock,iblocksize,ibs,idir,ierr,igs,igsc,ii,inonsc
     226              :  integer :: iorder_cprj,ipw,ispinor,iispinor,ispinor_index,istwf_k,iwavef,me_g0,mgsc,my_nspinor,n1,n2,n3 !kk
     227              :  integer :: nband_k_cprj,ncols_cprj,nblockbd,ncpgr,ndat,niter,nkpt_max,nnlout,ortalgo,ndat_fft
     228              :  integer :: paw_opt,quit,signs,space,spaceComm,tim_nonlop,wfoptalg,wfopta10
     229              :  integer :: gpu_option_tmp,nblk_gemm_nonlop,blksize_gemm_nonlop_tmp,nfft_blocks_tmp
     230              :  integer :: chunk,residuchunk
     231              :  logical :: nspinor1TreatedByThisProc,nspinor2TreatedByThisProc
     232              :  logical :: transfer_cg
     233              :  real(dp) :: ar,ar2,ar_im,eshift,occblock,norm
     234              :  real(dp) :: max_resid,weight,cpu,wall,gflops
     235              :  character(len=50) :: iter_name
     236              :  character(len=500) :: msg
     237              :  real(dp) :: dummy(2,1),nonlop_dum(1,1),nonlop_dum2(1,1),tsec(2)
     238       343291 :  real(dp),allocatable :: cwavef1(:,:),cwavef_x(:,:),cwavef_y(:,:),cwavefb(:,:,:)
     239              : #if defined HAVE_GPU && defined HAVE_YAKL
     240              :  real(real64), contiguous, pointer :: cwavef(:,:)  => null()
     241              :  real(real64), contiguous, pointer :: wfraug(:,:,:,:)
     242              : #else
     243       343291 :  real(dp),allocatable,target :: cwavef(:,:)
     244       343291 :  real(dp),allocatable :: wfraug(:,:,:,:)
     245              : #endif
     246       343291 :  real(dp),allocatable :: eig_save(:),enlout(:),evec(:,:),gsc(:,:),ghc_vectornd(:,:)
     247       343291 :  real(dp),allocatable :: subham(:),subovl(:),subvnlx(:),totvnlx(:,:)
     248       343291 :  real(dp),pointer :: cg_k(:,:),cg_k_block(:,:),grnl_k_block(:,:),eig_k_block(:)
     249       343291 :  real(dp),contiguous, pointer :: cwavef_iband(:,:), kinpw_ptr(:)
     250       343291 :  real(dp), allocatable :: weight_t(:) ! only allocated and used with GPU fourwf
     251       343291 :  type(pawcprj_type),pointer :: cwaveprj(:,:), cprj_cwavef_bands(:,:),cprj_cwavef(:,:)
     252              :  type(xgBlock_t) :: xgx0,xgeigen,xgforces
     253              :  type(xg_t) :: cprj_xgx0,cprj_work
     254              : ! **********************************************************************
     255              : 
     256              :  DBG_ENTER("COLL")
     257              : 
     258       343291 :  call timab(28,1,tsec) ! Keep track of total time spent in "vtowfk"
     259              : 
     260              : !Structured debugging if prtvol==-level
     261       343291 :  if(prtvol==-level)then
     262            0 :    write(msg,'(80a,a,a)') ('=',ii=1,80),ch10,'vtowfk: enter'
     263            0 :    call wrtout(std_out,msg,'PERS')
     264              :  end if
     265              : 
     266              : !=========================================================================
     267              : !============= INITIALIZATIONS AND ALLOCATIONS ===========================
     268              : !=========================================================================
     269              :  
     270       343291 :  nkpt_max=50; if(xmpi_paral==1)nkpt_max=-1
     271              : 
     272       343291 :  wfoptalg=mod(dtset%wfoptalg,100); wfopta10=mod(wfoptalg,10)
     273       343291 :  xg_diago = dtset%wfoptalg == 114 .or. dtset%wfoptalg == 112 .or. dtset%wfoptalg == 111
     274       343291 :  istwf_k=gs_hamk%istwf_k
     275       343291 :  has_fock=(associated(gs_hamk%fockcommon))
     276       343291 :  quit=0
     277       343291 :  igsc=0
     278              : 
     279              : !Parallelization over spinors management
     280       343291 :  my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
     281       343291 :  if (mpi_enreg%paral_spinor==0) then
     282       342731 :    ispinor_index=1
     283       342731 :    nspinor1TreatedByThisProc=.true.
     284       342731 :    nspinor2TreatedByThisProc=(dtset%nspinor==2)
     285              :  else
     286          560 :    ispinor_index=mpi_enreg%me_spinor+1
     287          560 :    nspinor1TreatedByThisProc=(mpi_enreg%me_spinor==0)
     288          560 :    nspinor2TreatedByThisProc=(mpi_enreg%me_spinor==1)
     289              :  end if
     290              : 
     291              : !Parallelism over FFT and/or bands: define sizes and tabs
     292              :  !if (mpi_enreg%paral_kgb==1) then
     293       343291 :  nblockbd=nband_k/(mpi_enreg%nproc_band*mpi_enreg%bandpp)
     294              :  !else
     295              :  !  nblockbd=nband_k/mpi_enreg%nproc_fft
     296              :  !  if (nband_k/=nblockbd*mpi_enreg%nproc_fft) nblockbd=nblockbd+1
     297              :  !end if
     298       343291 :  blocksize=nband_k/nblockbd
     299              : 
     300              : !Save eshift
     301       343291 :  if(wfoptalg==3)then
     302            6 :    eshift=zshift(1)
     303           18 :    ABI_MALLOC(eig_save,(nband_k))
     304           30 :    eig_save(:)=eshift
     305              :  end if
     306              : 
     307       343291 :  n1=gs_hamk%ngfft(1); n2=gs_hamk%ngfft(2); n3=gs_hamk%ngfft(3)
     308              : 
     309              :  ! Decide whether RMM-DIIS eigensolver should be activated.
     310              :  ! rmm_diis > 0 --> Activate it after (3 + rmm_diis) iterations with wfoptalg algorithm.
     311              :  ! rmm_diis < 0 --> Start with RMM-DIIS directly (risky)
     312       343291 :  use_rmm_diis = .False.
     313       343291 :  if (dtset%rmm_diis /= 0 .and. iscf > 0) then
     314          880 :    use_rmm_diis = istep > 3 + dtset%rmm_diis
     315              :    !if (use_rmm_diis) call wrtout(std_out, " Activating RMM-DIIS eigensolver in SCF mode.")
     316              :  end if
     317              :  !nonlop_counter = 0
     318              : 
     319       343291 :  mgsc=0
     320              :  igsc=0
     321       343291 :  if ((.not. xg_diago .and. dtset%cprj_in_memory==0) .or. dtset%rmm_diis /= 0) then
     322       299332 :    mgsc=nband_k*npw_k*my_nspinor*gs_hamk%usepaw
     323       897996 :    ABI_MALLOC_OR_DIE(gsc,(2,mgsc), ierr)
     324    978700567 :    gsc=zero
     325              :  else
     326        43959 :    ABI_MALLOC(gsc,(0,0))
     327              :  end if
     328              : 
     329       343291 :  if(wfopta10 /= 1 .and. .not. xg_diago) then
     330              :    !chebfi already does this stuff inside
     331      1493200 :    ABI_MALLOC(evec,(2*nband_k,nband_k))
     332       895920 :    ABI_MALLOC(subham,(nband_k*(nband_k+1)))
     333              : 
     334       298640 :    ABI_MALLOC(subvnlx,(0))
     335       298640 :    ABI_MALLOC(totvnlx,(0,0))
     336       298640 :    if (wfopta10==4) then
     337              : !    Later, will have to generalize to Fock case, like when wfopta10/=4
     338         1966 :      if (gs_hamk%usepaw==0) then
     339          612 :        ABI_FREE(totvnlx)
     340          612 :        if (istwf_k==1) then
     341         1608 :          ABI_MALLOC(totvnlx,(2*nband_k,nband_k))
     342           76 :        else if (istwf_k==2) then
     343          304 :          ABI_MALLOC(totvnlx,(nband_k,nband_k))
     344              :        end if
     345          612 :        use_totvnlx=1
     346              :      endif
     347              :    else
     348       296674 :      if (gs_hamk%usepaw==0 .or. has_fock) then
     349       224039 :        ABI_FREE(subvnlx)
     350       448078 :        ABI_MALLOC(subvnlx,(nband_k*(nband_k+1)))
     351       224039 :        use_subvnlx=1
     352              :      end if
     353              :    end if
     354              : 
     355       298640 :    if (use_subovl==1) then
     356            0 :      ABI_MALLOC(subovl,(nband_k*(nband_k+1)))
     357              :    else
     358       298640 :      ABI_MALLOC(subovl,(0))
     359              :    end if
     360              :  end if
     361              : 
     362              :  ! Carry out UP TO dtset%nline (or dtset%mdeg_filter) steps, or until resid for every band is < dtset%tolwfr
     363       343291 :  if (prtvol/=5 .and. (prtvol>2 .or. ikpt <= nkpt_max)) then
     364        14055 :    write(msg,'(a,i5,2x,a,3f9.5,2x,a)')' non-scf iterations; kpt # ',ikpt,', k= (',gs_hamk%kpt_k,'), band residuals:'
     365        14055 :    call wrtout(std_out,msg,'PERS')
     366              :  end if
     367              : 
     368       343291 :  if (dtset%cprj_in_memory==2) then
     369            0 :    if (ikpt==1) then
     370            0 :      write(msg,'(a,i3)') ' In vtowfk : use of cprj in memory with cprj_update_lvl=',dtset%cprj_update_lvl
     371            0 :      call wrtout(std_out,msg,'COLL')
     372              :    end if
     373            0 :    cprj_cwavef_bands => cprj(:,1+ibg:nband_k/mpi_enreg%nproc_band*my_nspinor+ibg)
     374              :  end if
     375              : 
     376              : !Electric field: initialize dphase_k
     377       343291 :  dphase_k(:) = zero
     378              : 
     379              : !=========================================================================
     380              : !==================== NON-SELF-CONSISTENT LOOP ===========================
     381              : !=========================================================================
     382              : 
     383              : !nnsclo_now=number of non-self-consistent loops for the current vtrial
     384              : !(often 1 for SCF calculation, =nstep for non-SCF calculations)
     385       343291 :  call timab(39,1,tsec) ! "vtowfk (loop)"
     386              : 
     387       343291 :  cg_k => cg(:,1+icg:npw_k*my_nspinor*nband_k+icg)
     388              : 
     389       343291 :  transfer_cg = .false.
     390              : #ifdef HAVE_OPENMP_OFFLOAD
     391              :  transfer_cg = .not. xomp_target_is_present(c_loc(cg))
     392              :  if(transfer_cg) then
     393              :    if(xg_diago) then
     394              :      !$OMP TARGET ENTER DATA MAP(alloc:cg_k) IF(dtset%gpu_option==ABI_GPU_OPENMP)
     395              :      !$OMP TARGET UPDATE TO(cg_k) IF(dtset%gpu_option==ABI_GPU_OPENMP .and. .not. use_rmm_diis)
     396              :    end if
     397              :  else if(istep == 1) then
     398              :    !$OMP TARGET UPDATE FROM(cg_k) IF(dtset%gpu_option==ABI_GPU_OPENMP .and. use_rmm_diis)
     399              :  end if
     400              : #endif
     401              : 
     402       818326 :  do inonsc=1,nnsclo_now
     403              :    ABI_NVTX_START_RANGE(NVTX_VTOWFK_EXTRA1)
     404       497291 :    if (iscf < 0 .and. (inonsc <= enough .or. mod(inonsc, 10) == 0)) call cwtime(cpu, wall, gflops, "start")
     405              : 
     406       497291 :    if (dtset%rmm_diis /= 0 .and. iscf < 0) then
     407           65 :      use_rmm_diis = inonsc > 3 + dtset%rmm_diis
     408              :      !if (use_rmm_diis) call wrtout(std_out, " Activating RMM-DIIS eigensolver in NSCF mode.")
     409              :    end if
     410              : 
     411              :    ! This initialisation is needed for the MPI-parallelisation (gathering using sum)
     412       497291 :    if(wfopta10 /= 1 .and. .not. xg_diago) then
     413     61425170 :      subham(:)=zero
     414       444302 :      if (gs_hamk%usepaw==0) then
     415       345113 :        if (wfopta10==4) then
     416        87328 :          totvnlx(:,:)=zero
     417              :        else
     418     34251691 :          subvnlx(:)=zero
     419              :        end if
     420              :      end if
     421       444302 :      if (use_subovl==1)subovl(:)=zero
     422              :    end if
     423              : 
     424              :    ! Filter the WFs when modified kinetic energy is too large (see routine mkkin.f)
     425              :    ! !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(igs,iwavef)
     426      4371944 :    do iband=1,nband_k
     427      3874653 :      iwavef=(iband-1)*npw_k*my_nspinor+icg
     428      3874653 :      cwavef_iband => cg(:,1+iwavef:npw_k*my_nspinor+iwavef)
     429      3874653 :      update_cprj=.False.
     430      8231898 :      do ispinor=1,my_nspinor
     431      4357245 :        iispinor=ispinor; if (mpi_enreg%paral_spinor==1) iispinor=mpi_enreg%me_spinor+1
     432      4357245 :        igs=(ispinor-1)*npw_k
     433      4357245 :        kinpw_ptr => kinpw
     434      4357245 :        if (gs_hamk%use_gbt /= 0) then
     435              :          ! Use different kinetic energies for up and down component (this won't work if paral_kgb /= 0)
     436        60032 :          if (iispinor == 1) kinpw_ptr => gs_hamk%kinpw_k
     437        60032 :          if (iispinor == 2) kinpw_ptr => gs_hamk%kinpw_kp
     438              :        end if
     439   1157736091 :        do ipw=1+igs,npw_k+igs
     440   1153861438 :          if(kinpw_ptr(ipw-igs)>huge(zero)*1.d-11)then
     441     21917467 :            norm=cwavef_iband(1,ipw)**2+cwavef_iband(2,ipw)**2
     442     21917467 :            if (norm>tol15*tol15) update_cprj=.True.
     443     65752401 :            cwavef_iband(:,ipw)=zero
     444              :          end if
     445              :        end do
     446              :      end do
     447      4371944 :      if (dtset%cprj_in_memory==2.and.update_cprj) then
     448            0 :        cprj_cwavef => cprj_cwavef_bands(:,my_nspinor*(iband-1)+1:my_nspinor*iband)
     449            0 :        call cprj_update_oneband(cwavef_iband,cprj_cwavef,gs_hamk,mpi_enreg,tim_getcprj)
     450              :      end if
     451              :    end do
     452              :    ABI_NVTX_END_RANGE()
     453              : 
     454              :    ! JLJ 17/10/2014: If it is a GWLS calculation, construct the hamiltonian
     455              :    ! as in a usual GS calc., but skip any minimisation procedure.
     456              :    ! This would be equivalent to nstep=0, if the latter did work.
     457       497291 :    if(dtset%optdriver/=RUNL_GWLS) then
     458              : 
     459       497283 :      if(wfopta10==4.or.wfopta10==1) then
     460              : 
     461        55217 :        if (dtset%gpu_option==ABI_GPU_KOKKOS) then
     462              :          ! Kokkos GPU branch is not OpenMP thread-safe, setting OpenMP num threads to 1
     463            0 :          call xomp_set_num_threads(1)
     464              :        end if
     465              : 
     466              : !    =========================================================================
     467              : !    ============ MINIMIZATION OF BANDS: LOBPCG ==============================
     468              : !    =========================================================================
     469        55217 :        if (wfopta10==4) then
     470              : 
     471        30777 :          if (use_rmm_diis) then
     472              :            call rmm_diis(istep, ikpt, isppol, cg_k, dtset, eig_k, occ_k, enlx_k, gs_hamk, kinpw, gsc, &
     473          428 :                          mpi_enreg, nband_k, npw_k, my_nspinor, resid_k, rmm_diis_status)
     474              : #ifdef HAVE_OPENMP_OFFLOAD
     475              :            !$OMP TARGET UPDATE TO(cg_k) IF(dtset%gpu_option==ABI_GPU_OPENMP .and. xg_diago)
     476              : #endif
     477              :          else
     478              : 
     479        30349 :            if ( .not. xg_diago ) then
     480              : 
     481              :              ABI_NVTX_START_RANGE(NVTX_LOBPCG1)
     482              :              call lobpcgwf(cg,dtset,gs_hamk,gsc,icg,igsc,kinpw,mcg,mgsc,mpi_enreg,&
     483         2250 :              nband_k,nblockbd,npw_k,prtvol,resid_k,subham,totvnlx,use_totvnlx)
     484              :              ! In case of FFT parallelism, exchange subspace arrays
     485         2250 :              spaceComm=mpi_enreg%comm_bandspinorfft
     486         2250 :              call xmpi_sum(subham,spaceComm,ierr)
     487         2250 :              if (gs_hamk%usepaw==0) then
     488          704 :                if (wfopta10==4) then
     489          704 :                  call xmpi_sum(totvnlx,spaceComm,ierr)
     490              :                else
     491              :                  call xmpi_sum(subvnlx,spaceComm,ierr)
     492              :                end if
     493              :              end if
     494         2250 :              if (use_subovl==1) call xmpi_sum(subovl,spaceComm,ierr)
     495              :              ABI_NVTX_END_RANGE()
     496              : 
     497              :            else
     498              : 
     499              :              ABI_NVTX_START_RANGE(NVTX_LOBPCG2)
     500        28099 :              if (dtset%cprj_in_memory==1) then
     501              :                call lobpcgwf2_cprj(cg_k,dtset,eig_k,occ_k,enlx_k,gs_hamk,isppol,ikpt,inonsc,istep,&
     502         4036 :                  kinpw,mpi_enreg,nband_k,npw_k,my_nspinor,prtvol,resid_k,nbdbuf,xg_nonlop)
     503              :              else
     504              :                call lobpcgwf2(cg_k,dtset,eig_k,occ_k,enlx_k,gs_hamk,isppol,ikpt,inonsc,istep,kinpw,mpi_enreg,&
     505        24063 :                  nband_k,npw_k,my_nspinor,prtvol,resid_k,nbdbuf)
     506              :              end if
     507              :              ABI_NVTX_END_RANGE()
     508              : 
     509              :            end if
     510              : 
     511              :          end if
     512              : 
     513              : !    =========================================================================
     514              : !    ============ MINIMIZATION OF BANDS: CHEBYSHEV FILTERING =================
     515              : !    =========================================================================
     516        24440 :        else if (wfopta10 == 1) then
     517        24440 :          if ( .not. xg_diago) then
     518              :            ABI_NVTX_START_RANGE(NVTX_CHEBFI1)
     519              :            call chebfi(cg_k,dtset,eig_k,enlx_k,gs_hamk,gsc,kinpw,&
     520           48 : &           mpi_enreg,nband_k,npw_k,my_nspinor,prtvol,resid_k)
     521              :            ABI_NVTX_END_RANGE()
     522        24392 :          else if (dtset%cprj_in_memory==1) then
     523              :            call chebfiwf2_cprj(cg_k,dtset,eig_k,occ_k,enlx_k,gs_hamk,&
     524        15368 :              mpi_enreg,nband_k,npw_k,my_nspinor,prtvol,resid_k,xg_nonlop)
     525              :          else
     526              :            ABI_NVTX_START_RANGE(NVTX_CHEBFI2)
     527              :            call chebfiwf2(cg_k,dtset,eig_k,occ_k,enlx_k,gs_hamk,&
     528         9024 : &           mpi_enreg,nband_k,npw_k,my_nspinor,prtvol,resid_k)
     529              :            ABI_NVTX_END_RANGE()
     530              :          end if
     531              :        end if
     532              : 
     533              : !    =========================================================================
     534              : !    ============ MINIMIZATION OF BANDS: SPECTRUM SLICING == =================
     535              : !    =========================================================================
     536       442066 :      else if (wfopta10 == 2) then
     537           18 :        nstep_mixed = dtset%nstep_mixed ! below which perform chebfi
     538           18 :        write(std_out,'(a,i0)') 'running vtowfk for nstep_mixed=', nstep_mixed
     539           18 :        if ( xg_diago .and. dtset%cprj_in_memory == 0 ) then
     540           18 :           if (istep > nstep_mixed) then
     541           18 :               write(std_out,'(a,i0)') 'entering slicewf'
     542              :               !ABI_NVTX_START_RANGE(NVTX_SPESLI)
     543              :               call slicewf(cg_k,dtset,eig_k,enlx_k,gs_hamk,mpi_enreg,&
     544           18 : &                          nband_k,npw_k,my_nspinor,prtvol,resid_k)
     545              :               !ABI_NVTX_END_RANGE()
     546              :           else
     547            0 :               write(std_out,'(a,i0)') 'entering chebfiwf2'
     548              :               ABI_NVTX_START_RANGE(NVTX_CHEBFI2)
     549              :               call chebfiwf2(cg_k,dtset,eig_k,occ_k,enlx_k,gs_hamk,&
     550            0 : &                            mpi_enreg,nband_k,npw_k,my_nspinor,prtvol,resid_k)
     551              :               ABI_NVTX_END_RANGE()
     552              :           end if
     553              :        else
     554            0 :            if (istep > nstep_mixed) then
     555            0 :               write(std_out,'(a,i0)') 'entering slicewf_cprj'
     556              :               ! ITEST
     557            0 :               write(901,*)
     558            0 :               write(901,*) '**'
     559            0 :               write(901,*) 'SCF iteration=', istep
     560            0 :               write(901,*) '**'
     561            0 :               write(901,*)
     562            0 :               flush(901)
     563              :               ! ITEST
     564              :               !ABI_NVTX_START_RANGE(NVTX_SPESLI)
     565              :               call slicewf_cprj(cg_k,dtset,eig_k,occ_k,enlx_k,gs_hamk,mpi_enreg,&
     566            0 : &                               nband_k,npw_k,my_nspinor,prtvol,resid_k,xg_nonlop)
     567              :               !ABI_NVTX_END_RANGE()
     568              :           else
     569            0 :               write(std_out,'(a,i0)') 'entering chebfiwf2_cprj'
     570              :               call chebfiwf2_cprj(cg_k,dtset,eig_k,occ_k,enlx_k,gs_hamk,&
     571            0 :                    mpi_enreg,nband_k,npw_k,my_nspinor,prtvol,resid_k,xg_nonlop)
     572              :           end if
     573              :        end if
     574              : 
     575              : !      =========================================================================
     576              : !      ======== MINIMIZATION OF BANDS: CONJUGATE GRADIENT (Teter et al.) =======
     577              : !      =========================================================================
     578              :      else
     579              :        ! use_subvnlx=0; if (gs_hamk%usepaw==0 .or. associated(gs_hamk%fockcommon)) use_subvnlx=1
     580              :        ! use_subvnlx=0; if (gs_hamk%usepaw==0) use_subvnlx=1
     581              : 
     582       442048 :        if (.not. use_rmm_diis) then
     583              : 
     584       441823 :          if (isppol==1.and.ikpt==1.and.inonsc==1.and.istep==1) then
     585         4979 :            if (dtset%tolwfr_diago/=zero) then
     586         1298 :              write(msg, '(a,es16.6)' ) ' cgwf: tolwfr_diago=',dtset%tolwfr_diago
     587         1298 :              call wrtout(std_out,msg,'COLL')
     588              :            end if
     589              :          end if
     590              : 
     591       441823 :          if (dtset%cprj_in_memory==2) then
     592              :            call cgwf_cprj(cg,cprj_cwavef_bands,dtset%cprj_update_lvl,eig_k,&
     593              :              gs_hamk,icg,mcg,mpi_enreg,nband_k,dtset%nline,&
     594            0 :              dtset%ortalg,prtvol,quit,resid_k,subham,dtset%tolrde,dtset%tolwfr_diago,wfoptalg)
     595              :          else
     596              :            call cgwf(dtset%berryopt,cg,cgq,dtset%chkexit,cpus,dphase_k,dtefield,dtfil%filnam_ds(1),&
     597              :              gsc,gs_hamk,icg,igsc,ikpt,inonsc,isppol,dtset%mband,mcg,mcgq,mgsc,mkgq,&
     598              :              mpi_enreg,mpw,nband_k,dtset%nbdblock,nkpt,dtset%nline,npw_k,npwarr,my_nspinor,&
     599              :              dtset%nsppol,dtset%ortalg,prtvol,pwind,pwind_alloc,pwnsfac,pwnsfacq,quit,resid_k,&
     600       441823 :              subham,subovl,subvnlx,dtset%tolrde,dtset%tolwfr_diago,use_subovl,use_subvnlx,wfoptalg,zshift)
     601              :          end if
     602              :        else
     603              :          call rmm_diis(istep, ikpt, isppol, cg(:,icg+1:), dtset, eig_k, occ_k, enlx_k, gs_hamk, kinpw, gsc, &
     604          225 :                        mpi_enreg, nband_k, npw_k, my_nspinor, resid_k, rmm_diis_status)
     605              :        end if
     606              : 
     607       442048 :        if (dtset%gpu_option==ABI_GPU_KOKKOS) then
     608              :          ! Kokkos GPU branch is not OpenMp thread-safe, restoring OpenMP threads num
     609            0 :          call xomp_set_num_threads(dtset%gpu_kokkos_nthrd)
     610              :        end if
     611              :      end if
     612              :    end if
     613              :  
     614              :    !  =========================================================================
     615              :    !  ===================== FIND LARGEST RESIDUAL =============================
     616              :    !  =========================================================================
     617              : 
     618              :    ! Find largest resid over bands at this k point
     619              :    ! Note that this operation is done BEFORE rotation of bands:
     620              :    ! it would be time-consuming to recompute the residuals after.
     621       497291 :    if (nbdbuf >= 0) then
     622      4506800 :      max_resid = maxval(resid_k(1:max(1,nband_k-nbdbuf)))
     623         1948 :    else if (nbdbuf==-101) then
     624        22712 :      max_resid = maxval(occ_k(1:nband_k)*resid_k(1:nband_k))
     625              :    else
     626            0 :      ABI_ERROR(sjoin('Bad value of nbdbuf:', itoa(nbdbuf)))
     627              :    end if
     628              : 
     629              :    ! Print residuals
     630       497291 :    if(prtvol/=5.and.(prtvol>2 .or. ikpt<=nkpt_max))then
     631        95908 :      do ii=0,(nband_k-1)/8
     632        69494 :        write(msg,'(a,8es10.2)')' res:',(resid_k(iband),iband=1+ii*8,min(nband_k,8+ii*8))
     633       566785 :        call wrtout(std_out,msg,'PERS')
     634              :      end do
     635              :    end if
     636              : 
     637              :    !  =========================================================================
     638              :    !  ========== DIAGONALIZATION OF HAMILTONIAN IN WFs SUBSPACE ===============
     639              :    !  =========================================================================
     640       497291 :    do_subdiago = .not. wfopta10 == 1 .and. .not. xg_diago
     641       497291 :    if (use_rmm_diis) do_subdiago = .False.  ! subdiago is already performed before RMM-DIIS.
     642              : 
     643              :    ABI_NVTX_START_RANGE(NVTX_SUB_SPC_DIAGO)
     644       496638 :    if (do_subdiago) then
     645       444077 :      if (prtvol > 1) call wrtout(std_out, " Performing subspace diagonalization.")
     646       444077 :      call timab(585,1,tsec) !"vtowfk(subdiago)"
     647       444077 :      if (dtset%cprj_in_memory==2) then
     648              :        call subdiago_low_memory(cg,eig_k,evec,icg,istwf_k,&
     649            0 :          mcg,nband_k,npw_k,my_nspinor,dtset%paral_kgb,subham)
     650            0 :        call timab(585,2,tsec)
     651            0 :        call timab(578,1,tsec)
     652            0 :        call cprj_rotate(cprj_cwavef_bands,evec,gs_hamk%dimcprj,natom,nband_k,gs_hamk%nspinor)
     653            0 :        call timab(578,2,tsec)
     654              :      else
     655              :        call subdiago(cg, eig_k, evec, gsc, icg, igsc, istwf_k, &
     656              :        mcg, mgsc, nband_k, npw_k, my_nspinor, dtset%paral_kgb, &
     657       444077 :        subham, subovl, use_subovl, gs_hamk%usepaw, mpi_enreg%me_g0)
     658       444077 :        call timab(585,2,tsec)
     659              :      end if
     660              :    end if
     661              :    ABI_NVTX_END_RANGE()
     662              : 
     663              :    !  Print energies
     664       497291 :    if(prtvol/=5.and.(prtvol>2 .or. ikpt<=nkpt_max))then
     665        95908 :      do ii=0,(nband_k-1)/8
     666        69494 :        write(msg, '(a,8es10.2)' )' ene:',(eig_k(iband),iband=1+ii*8,min(nband_k,8+ii*8))
     667       566785 :        call wrtout(std_out,msg,'PERS')
     668              :      end do
     669              :    end if
     670              : 
     671              :    !  THIS CHANGE OF SHIFT DOES NOT WORK WELL
     672              :    !  Update zshift in the case of wfoptalg==3
     673              :    !  if(wfoptalg==3 .and. inonsc/=1)then
     674              :    !  do iband=1,nband_k
     675              :    !  if(eig_k(iband)<eshift .and. eig_save(iband)<eshift) zshift(iband)=max(eig_k(iband),eig_save(iband))
     676              :    !  if(eig_k(iband)>eshift .and. eig_save(iband)>eshift) zshift(iband)=min(eig_k(iband),eig_save(iband))
     677              :    !  end do
     678              :    !  eig_save(:)=eig_k(:)
     679              :    !  end if
     680              : 
     681              :    !  =========================================================================
     682              :    !  =============== ORTHOGONALIZATION OF WFs (if needed) ====================
     683              :    !  =========================================================================
     684              : 
     685              :    !  Re-orthonormalize the wavefunctions at this k point.
     686              :    !  this step is redundant but is performed to combat rounding error in wavefunction orthogonality.
     687              :    !  This step is performed inside rmm_diis if RMM-DIIS is activated.
     688              : 
     689       497291 :    call timab(583,1,tsec) ! "vtowfk(pw_orthon)"
     690       497291 :    ortalgo = mpi_enreg%paral_kgb
     691              :    ! The orthogonalization is completely disabled with ortalg<=-10.
     692              :    ! This option is useful for testing only and is not documented.
     693       497291 :    do_ortho = (wfoptalg/=14 .and. wfoptalg /= 1 .and. wfoptalg /= 12 .and. wfoptalg /= 11 .and. dtset%ortalg>-10) .or. dtset%ortalg > 0
     694       497291 :    if (xg_diago) do_ortho = .false.
     695       497291 :    if (use_rmm_diis) do_ortho = .False.
     696              : 
     697       496638 :    if (do_ortho) then
     698              : 
     699              :      ABI_NVTX_START_RANGE(NVTX_ORTHO_WF)
     700              : 
     701       441941 :      if (prtvol > 0) call wrtout(std_out, " Calling pw_orthon to orthonormalize bands.")
     702       441941 :      if (dtset%cprj_in_memory==2) then
     703            0 :        ABI_FREE(subovl)
     704            0 :        ABI_MALLOC(subovl,(nband_k*(nband_k+1)))
     705            0 :        call mksubovl(cg,cprj_cwavef_bands,gs_hamk,icg,nband_k,subovl,mpi_enreg)
     706            0 :        call pw_orthon_cprj(icg,mcg,npw_k*my_nspinor,my_nspinor,nband_k,ortalgo,subovl,cg,cprj=cprj_cwavef_bands)
     707              :      else
     708              :        call pw_orthon(icg,igsc,istwf_k,mcg,mgsc,npw_k*my_nspinor,nband_k,ortalgo,gsc,gs_hamk%usepaw,cg,&
     709       441941 :          mpi_enreg%me_g0,mpi_enreg%comm_bandspinorfft)
     710              :      end if
     711              : 
     712              :      ABI_NVTX_END_RANGE()
     713              :    end if
     714       497291 :    call timab(583,2,tsec)
     715              : 
     716              :    ABI_NVTX_START_RANGE(NVTX_VTOWFK_EXTRA2)
     717              : 
     718              :    ! DEBUG seq==par comment next block
     719              :    ! Fix phases of all bands
     720       497291 :    if (xmpi_paral/=1 .or. mpi_enreg%paral_kgb/=1) then
     721              :      !call wrtout(std_out, "Calling cgtk_fixphase")
     722       453459 :      if ( (.not.xg_diago) .and. dtset%cprj_in_memory==0 ) then
     723       442670 :        call cgtk_fixphase(cg,gsc,icg,igsc,istwf_k,mcg,mgsc,mpi_enreg,nband_k,npw_k*my_nspinor,gs_hamk%usepaw)
     724              :      else if ( xg_diago ) then
     725              :        ! GSC is local to vtowfk and is completely useless since everything
     726              :        ! is calculated in my lobpcg, we don't care about the phase of gsc !
     727        10789 :        call cgtk_fixphase(cg,gsc,icg,igsc,istwf_k,mcg,mgsc,mpi_enreg,nband_k,npw_k*my_nspinor,0)
     728              :      else ! dtset%cprj_in_memory/=0 .and. .not.xg_diago
     729              :        call cgtk_fixphase(cg,gsc,icg,igsc,istwf_k,mcg,mgsc,mpi_enreg,nband_k,npw_k*my_nspinor,0,&
     730            0 :          & cprj=cprj_cwavef_bands,nspinor=dtset%nspinor)
     731              :      end if
     732              :    end if
     733              : 
     734       497291 :    if (iscf < 0) then
     735        70706 :      if (max_resid > dtset%tolwfr .and. max_resid < tol7) then
     736        31563 :        if (fftcore_mixprec == 1) call wrtout(std_out, " Approaching NSCF convergence. Activating FFT in double-precision")
     737        31563 :        ii = fftcore_set_mixprec(0)
     738              :      end if
     739              : 
     740              :      ! Print residual and wall-time required by NSCF iteration.
     741        70706 :      if (inonsc <= enough .or. mod(inonsc, 20) == 0) then
     742        36644 :        call cwtime(cpu, wall, gflops, "stop")
     743        36644 :        if (ikpt == 1 .or. mod(ikpt, 100) == 0) then
     744         1277 :          if (inonsc == 1) call wrtout(std_out, sjoin(" k-point: [", itoa(ikpt), "/", itoa(nkpt), "], spin:", itoa(isppol)))
     745              :          call wrtout(std_out, sjoin("   Max resid =", ftoa(max_resid, fmt="es13.5"), &
     746              :            " (exclude nbdbuf bands). One NSCF iteration cpu-time:", &
     747         1277 :            sec2str(cpu), ", wall-time:", sec2str(wall)), do_flush=.True.)
     748         1277 :          if (inonsc == enough) call wrtout(std_out, "   Printing residuals every mod(20) iterations...")
     749              :        end if
     750              :      end if
     751              :    end if
     752              :    ABI_NVTX_END_RANGE()
     753              : 
     754              :    ! Exit loop over inonsc if converged
     755       818326 :    if (max_resid < dtset%tolwfr) then
     756        22256 :      if (iscf < 0 .and. (ikpt == 1 .or. mod(ikpt, 100) == 0)) then
     757          517 :        call wrtout(std_out, sjoin("   NSCF loop completed after", itoa(inonsc), "iterations"))
     758              :      end if
     759              :      exit
     760              :    end if
     761              :  end do ! inonsc (NON SELF-CONSISTENT LOOP)
     762              : 
     763       343291 :  if (dtset%cprj_in_memory==2) then
     764            0 :    update_cprj=dtset%cprj_update_lvl<=3.and.dtset%cprj_update_lvl/=2
     765            0 :    if (update_cprj) call cprj_update(cg,cprj_cwavef_bands,gs_hamk,icg,nband_k,mpi_enreg,tim_getcprj)
     766              :  end if
     767              : 
     768       343291 :  call timab(39,2,tsec)
     769       343291 :  call timab(30,1,tsec) ! "vtowfk  (afterloop)"
     770              : 
     771              :  !if (dtset%prtvol > 0)
     772              :  !call wrtout(std_out, sjoin(" Number of Vnl|Psi> applications:", itoa(nonlop_counter)))
     773              : 
     774              :  !###################################################################
     775              : 
     776              :  !Compute kinetic energy and non-local energy for each band, and in the SCF
     777              :  !case, contribution to forces, and eventually accumulate rhoaug
     778              : 
     779       343291 :  ndat=1;if (mpi_enreg%paral_kgb==1) ndat=mpi_enreg%bandpp
     780       343291 :  if(iscf>0 .and. fixed_occ)  then
     781       229430 :    ndat_fft=ndat; if(mpi_enreg%paral_kgb==0) ndat_fft=blocksize
     782       229430 :    chunk = ndat_fft/gs_hamk%nfft_blocks ! Divide by 2 to construct chunk of even number of bands
     783       229430 :    residuchunk = ndat_fft - gs_hamk%nfft_blocks*chunk
     784       229430 :    if(dtset%gpu_option==ABI_GPU_KOKKOS) then
     785              : #if defined HAVE_GPU && defined HAVE_YAKL
     786              :      ABI_MALLOC_MANAGED(wfraug,(/2,gs_hamk%n4,gs_hamk%n5,gs_hamk%n6*ndat_fft/))
     787              : #endif
     788              :    else
     789       229430 :      fftalg = gs_hamk%ngfft(7)
     790       229430 :      if (gs_hamk%gpu_option==ABI_GPU_DISABLED.and.fftalg/=401) then
     791      1124995 :        ABI_MALLOC(wfraug,(2,gs_hamk%n4,gs_hamk%n5,gs_hamk%n6))
     792              :      else
     793        22155 :        ABI_MALLOC(wfraug,(2,gs_hamk%n4,gs_hamk%n5,gs_hamk%n6*(chunk+residuchunk)))
     794              :      end if
     795              :    end if
     796              :  end if
     797              : 
     798              : !"nonlop" routine input parameters
     799       343291 :  nnlout=3*natom*optforces
     800       343291 :  signs=1;idir=0
     801       343291 :  if (gs_hamk%usepaw==0) then
     802       235587 :    choice=1+optforces
     803       235587 :    paw_opt=0;cpopt=-1;tim_nonlop=2
     804              :  else
     805       107704 :    choice=2*optforces
     806       107704 :    paw_opt=2;cpopt=0;tim_nonlop=10-8*optforces
     807       107704 :    if (dtset%cprj_in_memory==2) cpopt=2 ! cprj are in memory (but not the derivatives)
     808       107704 :    if (dtset%usefock==1) then
     809              :      !if (dtset%optforces/= 0) then
     810          596 :      if (optforces/= 0) then
     811          217 :        choice=2;cpopt=1; nnlout=3*natom
     812              :      end if
     813              :    end if
     814              :  end if
     815              : 
     816      1029873 :  ABI_MALLOC(enlout,(nnlout*blocksize))
     817              : 
     818              :  ! Allocation of memory space for one block of waveforms containing blocksize waveforms
     819       343291 :  if(dtset%gpu_option==ABI_GPU_KOKKOS) then
     820              : #if defined HAVE_GPU && defined HAVE_YAKL
     821              :    ABI_MALLOC_MANAGED(cwavef, (/2,npw_k*my_nspinor*blocksize/))
     822              : #endif
     823              :  else
     824      1029873 :    ABI_MALLOC(cwavef, (2,npw_k*my_nspinor*blocksize))
     825              :  end if
     826              : 
     827       343291 :  if (dtset%cprj_in_memory/=2) then
     828       343291 :    if (gs_hamk%usepaw==1.and.(iscf>0.or.gs_hamk%usecprj==1)) then
     829       107704 :      iorder_cprj=0
     830       107704 :      nband_k_cprj=nband_k*(mband_cprj/dtset%mband)
     831       107704 :      bandpp_cprj=mpi_enreg%bandpp
     832      1341864 :      ABI_MALLOC(cwaveprj,(natom,my_nspinor*bandpp_cprj))
     833       107704 :      ncpgr=0;if (cpopt==1) ncpgr=cprj(1,1)%ncpgr
     834       107704 :      call pawcprj_alloc(cwaveprj,ncpgr,gs_hamk%dimcprj)
     835              :    else
     836       235587 :      ABI_MALLOC(cwaveprj,(0,0))
     837              :    end if
     838              :  end if
     839              : 
     840              : !The code below is more efficient if paral_kgb==1 (less MPI communications)
     841              : !however OMP is not compatible with paral_kgb since we should define
     842              : !which threads performs the call to MPI_ALL_REDUCE.
     843              : !This problem can be easily solved by removing MPI_enreg from meanvalue_g so that
     844              : !the MPI call is done only once outside the OMP parallel region.
     845              : 
     846              :  !call cwtime(cpu, wall, gflops, "start")
     847              : 
     848       343291 :  if (dtset%cprj_in_memory==1) then
     849        17084 :    ncols_cprj = blocksize*my_nspinor/mpi_enreg%nproc_band
     850        17084 :    call xg_init(cprj_xgx0,xg_nonlop%space_cprj,xg_nonlop%cprjdim,ncols_cprj,comm=xg_nonlop%comm_band)
     851        17084 :    call xg_init(cprj_work,xg_nonlop%space_cprj,xg_nonlop%cprjdim,ncols_cprj,comm=xg_nonlop%comm_band)
     852              :  end if
     853              : 
     854              :  ! In case of GEMM nonlop distribution + force computation,
     855              :  ! recompute distribution as projectors arrays are bigger in this case
     856       343291 :  gpu_option_tmp=gs_hamk%gpu_option
     857       343291 :  if(optforces==1 .and. gs_hamk%gpu_option==ABI_GPU_OPENMP) then
     858            0 :    blksize_gemm_nonlop_tmp = gemm_nonlop_block_size; is_distrib_tmp = gemm_nonlop_is_distributed
     859            0 :    nfft_blocks_tmp = gs_hamk%nfft_blocks
     860            0 :    gemm_nonlop_block_size = dtset%gpu_nl_splitsize
     861              :    call get_gemm_nonlop_ompgpu_blocksize(ikpt,gs_hamk,mpi_enreg%bandpp,nband_k,&
     862              :    &                        dtset%nspinor,dtset%nspden,mpi_enreg%paral_kgb,mpi_enreg%nproc_band,&
     863              :    &                        optforces,0,-1,gs_hamk%gpu_option,(dtset%gpu_nl_distrib/=0),&
     864              :    &                        gemm_nonlop_block_size,nblk_gemm_nonlop,gs_hamk%nfft_blocks,&
     865            0 :    &                        warn_on_fail=.true.,disable_output=(istep>1.and.ikpt>1))
     866            0 :    gemm_nonlop_is_distributed = (dtset%gpu_nl_distrib/=0 .and. nblk_gemm_nonlop > 0)
     867            0 :    if(nblk_gemm_nonlop==-1) then
     868            0 :      gs_hamk%gpu_option=ABI_GPU_DISABLED
     869            0 :      ABI_WARNING("GPU has been disabled for forces computation during SCF step due to memory constraints.")
     870              :    end if
     871              :  end if
     872              : 
     873              : #ifdef HAVE_OPENMP_OFFLOAD
     874              :  !$OMP TARGET ENTER DATA MAP(alloc:cwavef) IF(gs_hamk%gpu_option==ABI_GPU_OPENMP)
     875              :  !$OMP TARGET ENTER DATA MAP(to:kinpw) IF(gs_hamk%gpu_option==ABI_GPU_OPENMP)
     876              : #endif
     877              : 
     878              :  ! Transferring cg back is only needed in case of DMFT case or if GBT is on
     879              :  if (gs_hamk%use_gbt /= 0 .or. paw_dmft%use_dmft==1) then
     880              : #ifdef HAVE_OPENMP_OFFLOAD
     881              :    !$OMP TARGET UPDATE FROM(cg_k) IF(gs_hamk%gpu_option==ABI_GPU_OPENMP .and. xg_diago)
     882              : #endif
     883              :  end if
     884              :  ! Loop over bands or blocks of bands.
     885              :  ! Note that in sequential mode iblock=iband, nblockbd=nband_k and blocksize=1
     886      2493832 :  do iblock=1,nblockbd
     887      6914559 :    occblock=maxval(occ_k(1+(iblock-1)*blocksize:iblock*blocksize))
     888              :    !cwavef(:,:)=cg(:,1+(iblock-1)*npw_k*my_nspinor*blocksize+icg:iblock*npw_k*my_nspinor*blocksize+icg)
     889      2150541 :    if(gs_hamk%gpu_option==ABI_GPU_OPENMP) then
     890              : #ifdef HAVE_OPENMP_OFFLOAD
     891              :      ! cg is already on GPU, simply copy it in cwavef
     892              :      if(xg_diago) then
     893              :        call gpu_copy(cwavef, &
     894              :        &             cg_k(:,1+(iblock-1)*npw_k*my_nspinor*blocksize:iblock*npw_k*my_nspinor*blocksize),&
     895              :        &             int(2,c_size_t)*npw_k*my_nspinor*blocksize)
     896              :      else
     897              :        ! cg isn't on GPU, single transfer and copy it in cwavef
     898              :        !$OMP TARGET TEAMS DISTRIBUTE MAP(to:cg_k,cwavef) PRIVATE(iblocksize)
     899              :        do iblocksize=1,blocksize*my_nspinor
     900              :          !$OMP PARALLEL DO PRIVATE(ipw)
     901              :          do ipw=1,npw_k
     902              :            cwavef(1,ipw+(iblocksize-1)*npw_k)=cg_k(1,ipw+(iblocksize-1)*npw_k+(iblock-1)*npw_k*blocksize*my_nspinor)
     903              :            cwavef(2,ipw+(iblocksize-1)*npw_k)=cg_k(2,ipw+(iblocksize-1)*npw_k+(iblock-1)*npw_k*blocksize*my_nspinor)
     904              :          end do
     905              :        end do
     906              :      end if
     907              : #endif
     908              :    else
     909              :      call DCOPY(2*npw_k*my_nspinor*blocksize, &
     910      2150541 :        cg_k(:,1+(iblock-1)*npw_k*my_nspinor*blocksize:iblock*npw_k*my_nspinor*blocksize), 1, cwavef, 1)
     911              :    end if
     912              : 
     913              :    ! Compute kinetic energies for all bands in this block (use_gbt==0).
     914              :    ! meanvalue_g_batch handles both istwf_k==1 (phase 1) and istwf_k>=2 (phase 3).
     915      2150541 :    if (gs_hamk%use_gbt == 0) then
     916              :      call meanvalue_g_batch(ek_k(1+(iblock-1)*blocksize:iblock*blocksize), kinpw, &
     917              :      &    0, istwf_k, mpi_enreg, npw_k, my_nspinor, blocksize, &
     918      2124877 :      &    cwavef, cwavef, 0, gpu_option=gs_hamk%gpu_option)
     919              :     
     920              :      ! Compute nuclear dipole energies for all bands in this block (use_gbt==0).
     921     23213501 :      if(ANY(ABS(dtset%nucdipmom)>tol8)) then
     922       195300 :        ABI_MALLOC(ghc_vectornd,(2,npw_k*my_nspinor*blocksize))
     923              :        call getghc_nucdip(cwavef,ghc_vectornd,gs_hamk%gbound_k,gs_hamk%istwf_k,kg_k,gs_hamk%kpt_k,&
     924              :          & gs_hamk%mgfft,mpi_enreg,blocksize,gs_hamk%ngfft,npw_k,gs_hamk%nvloc,&
     925              :          & gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,my_nspinor,gs_hamk%vectornd,gs_hamk%vlocal,&
     926        65100 :          & gs_hamk%zora,gs_hamk%gpu_option)
     927       130200 :        do iblocksize=1,blocksize
     928        65100 :          iband=(iblock-1)*blocksize+iblocksize
     929              :          end_k(iband)=DOT_PRODUCT(cwavef(1,1+(iblocksize-1)*npw_k*my_nspinor:iblocksize*npw_k*my_nspinor),&
     930              :                                 & ghc_vectornd(1,1+(iblocksize-1)*npw_k*my_nspinor:iblocksize*npw_k*my_nspinor))+ &
     931              :                     & DOT_PRODUCT(cwavef(2,1+(iblocksize-1)*npw_k*my_nspinor:iblocksize*npw_k*my_nspinor),&
     932     92500512 :                                 & ghc_vectornd(2,1+(iblocksize-1)*npw_k*my_nspinor:iblocksize*npw_k*my_nspinor))
     933              :        end do
     934        65100 :        ABI_FREE(ghc_vectornd)
     935              :      end if
     936              : 
     937              :    end if
     938              : 
     939      4764018 :    do iblocksize=1,blocksize
     940      2613477 :      iband=(iblock-1)*blocksize+iblocksize
     941              : 
     942      2613477 :      cwavef_iband => cg(:,1+(iband-1)*npw_k*my_nspinor+icg:iband*npw_k*my_nspinor+icg)
     943              : 
     944      2613477 :      if (gs_hamk%use_gbt /= 0) then
     945              :        ! Treat up and down components separately.
     946              :        ! Note filter 1. Also: this won't work if paral_kgb 1 and/or spinor parallelism
     947        25664 :        filter = 1
     948              :        call meanvalue_g(ar, gs_hamk%kinpw_k, filter,istwf_k,mpi_enreg,npw_k,1,&
     949              :        &    cwavef_iband,             cwavef_iband,            0,&
     950        25664 :        &    gpu_thread_limit=dtset%gpu_thread_limit)
     951              : 
     952              :        call meanvalue_g(ar2,gs_hamk%kinpw_kp,filter,istwf_k,mpi_enreg,npw_k,1,&
     953              :        &    cwavef_iband(:,npw_k+1:), cwavef_iband(:,npw_k+1:),0,&
     954        25664 :        &    gpu_thread_limit=dtset%gpu_thread_limit)
     955              : 
     956        25664 :        ek_k(iband) = ar + ar2
     957              :      end if
     958              : 
     959      4764018 :      if(paw_dmft%use_dmft==1) then
     960       529272 :        do iband1=1,nband_k
     961              :          call meanvalue_g(ar,kinpw,0,istwf_k,mpi_enreg,npw_k,my_nspinor,&
     962              :            cg(:,1+(iband -1)*npw_k*my_nspinor+icg:iband *npw_k*my_nspinor+icg),&
     963              :            cg(:,1+(iband1-1)*npw_k*my_nspinor+icg:iband1*npw_k*my_nspinor+icg),&
     964       510096 :            paw_dmft%use_dmft,ar_im=ar_im,gpu_thread_limit=dtset%gpu_thread_limit)
     965       510096 :          ek_k_nd(1,iband,iband1)=ar
     966       529272 :          ek_k_nd(2,iband,iband1)=ar_im
     967              :        end do
     968              :      end if
     969              :    end do
     970              : 
     971      2150541 :    if (iscf>0) then
     972              : 
     973              :      ABI_NVTX_START_RANGE(NVTX_VTOWFK_FOURWF)
     974              :      ! In case of fixed occupation numbers, accumulates the partial density
     975      2026219 :      if (fixed_occ .and. mpi_enreg%paral_kgb/=1) then
     976              : 
     977              :        ! treat all bands at once on GPU
     978       858866 :        if (dtset%gpu_option /= ABI_GPU_DISABLED) then
     979              : 
     980            0 :          ABI_MALLOC(weight_t,(blocksize))
     981              :          ! compute weights
     982            0 :          do iblocksize=1,blocksize
     983            0 :            iband=(iblock-1)*blocksize+iblocksize
     984            0 :            weight_t(iblocksize) = occ_k(iband) * wtk / gs_hamk%ucvol
     985            0 :            if (abs(occ_k(iband)) < tol8) weight_t(iblocksize) = zero
     986              :          end do
     987              : 
     988            0 :          if(dtset%nspinor==1) then
     989              :            call fourwf_optmem(1,rhoaug(:,:,:,1),cwavef(:,:),dummy,wfraug,&
     990              :                gs_hamk%gbound_k,gs_hamk%gbound_k,istwf_k,kg_k,kg_k,&
     991              :                gs_hamk%mgfft,mpi_enreg,blocksize,gs_hamk%nfft_blocks,gs_hamk%ngfft,&
     992              :                npw_k,1,gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,1,tim_fourwf,weight,weight,&
     993              :                weight_array_r=weight_t,weight_array_i=weight_t,&
     994            0 :                gpu_option=dtset%gpu_option)
     995              : 
     996            0 :          else if(dtset%nspinor==2) then
     997            0 :            ABI_MALLOC(cwavefb,(2,npw_k*blocksize,2))
     998            0 :            ibs=(iblock-1)*npw_k*my_nspinor*blocksize
     999            0 :            if(gs_hamk%gpu_option==ABI_GPU_OPENMP) then
    1000              : #ifdef HAVE_OPENMP_OFFLOAD
    1001              :              !$OMP TARGET ENTER DATA MAP(alloc:cwavefb)
    1002              :              !$OMP TARGET TEAMS DISTRIBUTE MAP(to:cwavefb,cwavef) PRIVATE(iband)
    1003              :              do iband=1,blocksize
    1004              :                !$OMP PARALLEL DO PRIVATE(ipw)
    1005              :                do ipw=1,npw_k
    1006              :                  cwavefb(1,(iband-1)*npw_k+ipw,1)=cwavef(1,ipw+(2*iband-2)*npw_k)
    1007              :                  cwavefb(2,(iband-1)*npw_k+ipw,1)=cwavef(2,ipw+(2*iband-2)*npw_k)
    1008              : 
    1009              :                  cwavefb(1,(iband-1)*npw_k+ipw,2)=cwavef(1,ipw+(2*iband-1)*npw_k)
    1010              :                  cwavefb(2,(iband-1)*npw_k+ipw,2)=cwavef(2,ipw+(2*iband-1)*npw_k)
    1011              :                end do
    1012              :              end do
    1013              : #endif
    1014              :            else
    1015            0 :              do iband=1,blocksize
    1016            0 :                cwavefb(:,(iband-1)*npw_k+1:iband*npw_k,1)=cwavef(:,1+(2*iband-2)*npw_k:(iband*2-1)*npw_k)
    1017            0 :                cwavefb(:,(iband-1)*npw_k+1:iband*npw_k,2)=cwavef(:,1+(2*iband-1)*npw_k:iband*2*npw_k)
    1018              :              end do
    1019              :            end if
    1020              : 
    1021              :            call fourwf_optmem(1,rhoaug(:,:,:,1),cwavefb(:,:,1),dummy,wfraug,&
    1022              :                        gs_hamk%gbound_k,gs_hamk%gbound_k,istwf_k,kg_k,kg_k,&
    1023              :                        gs_hamk%mgfft,mpi_enreg,blocksize,gs_hamk%nfft_blocks,gs_hamk%ngfft,&
    1024              :                        npw_k,1,gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,1,tim_fourwf,weight,weight,&
    1025              :                        weight_array_r=weight_t,weight_array_i=weight_t,&
    1026            0 :                        gpu_option=dtset%gpu_option)
    1027              : 
    1028            0 :            if(dtset%nspden==1) then
    1029              :              call fourwf_optmem(1,rhoaug(:,:,:,1),cwavefb(:,:,2),dummy,wfraug,&
    1030              :                          gs_hamk%gbound_k,gs_hamk%gbound_k,istwf_k,kg_k,kg_k,&
    1031              :                          gs_hamk%mgfft,mpi_enreg,blocksize,gs_hamk%nfft_blocks,gs_hamk%ngfft,&
    1032              :                          npw_k,1,gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,1,tim_fourwf,weight,weight,&
    1033              :                          weight_array_r=weight_t,weight_array_i=weight_t,&
    1034            0 :                          gpu_option=dtset%gpu_option)
    1035              : 
    1036            0 :            else if (dtset%nspden==4) then
    1037              :              ! Build the four components of rho. We use only norm quantities and, so fourwf.
    1038              :              ! $\sum_{n} f_n \Psi^{* \alpha}_n \Psi^{\alpha}_n =\rho^{\alpha \alpha}$
    1039              :              ! $\sum_{n} f_n (\Psi^{1}+\Psi^{2})^*_n (\Psi^{1}+\Psi^{2})_n=rho+m_x$
    1040              :              ! $\sum_{n} f_n (\Psi^{1}-i \Psi^{2})^*_n (\Psi^{1}-i \Psi^{2})_n=rho+m_y$
    1041            0 :              ABI_MALLOC(cwavef_x,(2,npw_k*blocksize))
    1042            0 :              ABI_MALLOC(cwavef_y,(2,npw_k*blocksize))
    1043              : 
    1044            0 :              if(gs_hamk%gpu_option==ABI_GPU_OPENMP) then
    1045              : #ifdef HAVE_OPENMP_OFFLOAD
    1046              :                !$OMP TARGET ENTER DATA MAP(alloc:cwavef_x,cwavef_y)
    1047              :                !$OMP TARGET TEAMS DISTRIBUTE MAP(to:cwavef_x,cwavef_y,cwavefb) PRIVATE(iband)
    1048              :                do iband=1,blocksize
    1049              :                  !$OMP PARALLEL DO PRIVATE(ipw)
    1050              :                  do ipw=1,npw_k
    1051              :                    !$(\Psi^{1}+\Psi^{2})$
    1052              :                    cwavef_x(1,(iband-1)*npw_k+ipw)=cwavefb(1,(iband-1)*npw_k+ipw,1)+cwavefb(1,(iband-1)*npw_k+ipw,2)
    1053              :                    cwavef_x(2,(iband-1)*npw_k+ipw)=cwavefb(2,(iband-1)*npw_k+ipw,1)+cwavefb(2,(iband-1)*npw_k+ipw,2)
    1054              :                    !$(\Psi^{1}-i \Psi^{2})$
    1055              :                    cwavef_y(1,(iband-1)*npw_k+ipw)=cwavefb(1,(iband-1)*npw_k+ipw,1)+cwavefb(2,(iband-1)*npw_k+ipw,2)
    1056              :                    cwavef_y(2,(iband-1)*npw_k+ipw)=cwavefb(2,(iband-1)*npw_k+ipw,1)-cwavefb(1,(iband-1)*npw_k+ipw,2)
    1057              :                  end do
    1058              :                end do
    1059              : #endif
    1060              :              else
    1061              :                !$(\Psi^{1}+\Psi^{2})$
    1062            0 :                cwavef_x(:,:)=cwavefb(:,1:npw_k*blocksize,1)+cwavefb(:,1:npw_k*blocksize,2)
    1063              :                !$(\Psi^{1}-i \Psi^{2})$
    1064            0 :                cwavef_y(1,:)=cwavefb(1,1:npw_k*blocksize,1)+cwavefb(2,1:npw_k*blocksize,2)
    1065            0 :                cwavef_y(2,:)=cwavefb(2,1:npw_k*blocksize,1)-cwavefb(1,1:npw_k*blocksize,2)
    1066              :              end if
    1067              : 
    1068              :              ! z component
    1069              :              call fourwf_optmem(1,rhoaug(:,:,:,4),cwavefb(:,:,2),dummy,wfraug,&
    1070              :                          gs_hamk%gbound_k,gs_hamk%gbound_k,istwf_k,kg_k,kg_k,&
    1071              :                          gs_hamk%mgfft,mpi_enreg,blocksize,gs_hamk%nfft_blocks,gs_hamk%ngfft,&
    1072              :                          npw_k,1,gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,1,tim_fourwf,weight,weight,&
    1073              :                          weight_array_r=weight_t,weight_array_i=weight_t,&
    1074            0 :                          gpu_option=dtset%gpu_option)
    1075              :              ! x component
    1076              :              call fourwf_optmem(1,rhoaug(:,:,:,2),cwavef_x(:,:),dummy,wfraug,&
    1077              :                          gs_hamk%gbound_k,gs_hamk%gbound_k,istwf_k,kg_k,kg_k,&
    1078              :                          gs_hamk%mgfft,mpi_enreg,blocksize,gs_hamk%nfft_blocks,gs_hamk%ngfft,&
    1079              :                          npw_k,1,gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,1,tim_fourwf,weight,weight,&
    1080              :                          weight_array_r=weight_t,weight_array_i=weight_t,&
    1081            0 :                          gpu_option=dtset%gpu_option)
    1082              :              ! y component
    1083              :              call fourwf_optmem(1,rhoaug(:,:,:,3),cwavef_y(:,:),dummy,wfraug,&
    1084              :                          gs_hamk%gbound_k,gs_hamk%gbound_k,istwf_k,kg_k,kg_k,&
    1085              :                          gs_hamk%mgfft,mpi_enreg,blocksize,gs_hamk%nfft_blocks,gs_hamk%ngfft,&
    1086              :                          npw_k,1,gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,1,tim_fourwf,weight,weight,&
    1087              :                          weight_array_r=weight_t,weight_array_i=weight_t,&
    1088            0 :                          gpu_option=dtset%gpu_option)
    1089              : #ifdef HAVE_OPENMP_OFFLOAD
    1090              :              !$OMP TARGET EXIT DATA MAP(delete:cwavef_x,cwavef_y) IF(gs_hamk%gpu_option==ABI_GPU_OPENMP)
    1091              : #endif
    1092            0 :              ABI_FREE(cwavef_x)
    1093            0 :              ABI_FREE(cwavef_y)
    1094              :            end if
    1095              : 
    1096              : #ifdef HAVE_OPENMP_OFFLOAD
    1097              :            !$OMP TARGET EXIT DATA MAP(delete:cwavefb) IF(gs_hamk%gpu_option==ABI_GPU_OPENMP)
    1098              : #endif
    1099            0 :            ABI_FREE(cwavefb)
    1100              :          end if
    1101              : 
    1102            0 :          ABI_FREE(weight_t)
    1103              : 
    1104              :        else
    1105      1792812 :          do iblocksize=1,blocksize
    1106       933946 :            iband=(iblock-1)*blocksize+iblocksize
    1107       933946 :            cwavef_iband => cwavef(:,1+(iblocksize-1)*npw_k*my_nspinor:iblocksize*npw_k*my_nspinor)
    1108              : 
    1109      1792812 :            if (abs(occ_k(iband))>=tol8) then
    1110       703285 :              weight = occ_k(iband) * wtk / gs_hamk%ucvol
    1111              : 
    1112              :              ! Accumulate charge density in real space in array rhoaug
    1113              :              ! The same section of code is also found in mkrho.F90 : should be rationalized !
    1114              :              call fourwf(1,rhoaug(:,:,:,1),cwavef_iband,dummy,wfraug,gs_hamk%gbound_k,gs_hamk%gbound_k,&
    1115              :                          istwf_k,gs_hamk%kg_k,gs_hamk%kg_k,gs_hamk%mgfft,mpi_enreg,1,gs_hamk%ngfft,npw_k,1,&
    1116              :                          gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,1,&
    1117       703285 :                          tim_fourwf,weight,weight,gpu_option=dtset%gpu_option)
    1118              : 
    1119       703285 :              if(dtset%nspinor==2)then
    1120       244866 :                ABI_MALLOC(cwavef1,(2,npw_k))
    1121     93039964 :                cwavef1(:,:)=cwavef_iband(:,1+npw_k:2*npw_k) ! EB FR spin dn part and used for m_z component (cwavef_z)
    1122              : 
    1123        81622 :                if(dtset%nspden==1) then
    1124              : 
    1125              :                  call fourwf(1,rhoaug(:,:,:,1),cwavef1,dummy,wfraug,&
    1126              :                              gs_hamk%gbound_k,gs_hamk%gbound_k,&
    1127              :                              istwf_k,gs_hamk%kg_k,gs_hamk%kg_k,gs_hamk%mgfft,mpi_enreg,1,gs_hamk%ngfft,npw_k,1,&
    1128              :                              gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,1,&
    1129        40292 :                              tim_fourwf,weight,weight,gpu_option=dtset%gpu_option)
    1130              : 
    1131        41330 :                else if(dtset%nspden==4) then
    1132              :                  ! Build the four components of rho. We use only norm quantities and, so fourwf.
    1133              :                  ! $\sum_{n} f_n \Psi^{* \alpha}_n \Psi^{\alpha}_n =\rho^{\alpha \alpha}$
    1134              :                  ! $\sum_{n} f_n (\Psi^{1}+\Psi^{2})^*_n (\Psi^{1}+\Psi^{2})_n=rho+m_x$
    1135              :                  ! $\sum_{n} f_n (\Psi^{1}-i \Psi^{2})^*_n (\Psi^{1}-i \Psi^{2})_n=rho+m_y$
    1136       123990 :                  ABI_MALLOC(cwavef_x,(2,npw_k))
    1137        82660 :                  ABI_MALLOC(cwavef_y,(2,npw_k))
    1138              :                  !$(\Psi^{1}+\Psi^{2})$
    1139     26454140 :                  cwavef_x(:,:)=cwavef_iband(:,1:npw_k)+cwavef1(:,1:npw_k)
    1140              :                  !$(\Psi^{1}-i \Psi^{2})$
    1141      8845600 :                  cwavef_y(1,:)=cwavef_iband(1,1:npw_k)+cwavef1(2,1:npw_k)
    1142      8845600 :                  cwavef_y(2,:)=cwavef_iband(2,1:npw_k)-cwavef1(1,1:npw_k)
    1143              :                  ! z component
    1144              :                  call fourwf(1,rhoaug(:,:,:,4),cwavef1,dummy,wfraug,gs_hamk%gbound_k,gs_hamk%gbound_k,&
    1145              :                              istwf_k,gs_hamk%kg_k,gs_hamk%kg_k,gs_hamk%mgfft,mpi_enreg,1,gs_hamk%ngfft,npw_k,1,&
    1146              :                              gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,1,&
    1147        41330 :                              tim_fourwf,weight,weight,gpu_option=dtset%gpu_option)
    1148              :                  ! x component
    1149              :                  call fourwf(1,rhoaug(:,:,:,2),cwavef_x,dummy,wfraug,gs_hamk%gbound_k,gs_hamk%gbound_k,&
    1150              :                              istwf_k,gs_hamk%kg_k,gs_hamk%kg_k,gs_hamk%mgfft,mpi_enreg,1,gs_hamk%ngfft,npw_k,1,&
    1151              :                              gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,1,&
    1152        41330 :                              tim_fourwf,weight,weight,gpu_option=dtset%gpu_option)
    1153              :                  ! y component
    1154              :                  call fourwf(1,rhoaug(:,:,:,3),cwavef_y,dummy,wfraug,gs_hamk%gbound_k,gs_hamk%gbound_k,&
    1155              :                              istwf_k,gs_hamk%kg_k,gs_hamk%kg_k,gs_hamk%mgfft,mpi_enreg,1,gs_hamk%ngfft,npw_k,1,&
    1156              :                              gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,1,&
    1157        41330 :                              tim_fourwf,weight,weight,gpu_option=dtset%gpu_option)
    1158              : 
    1159        41330 :                  ABI_FREE(cwavef_x)
    1160        41330 :                  ABI_FREE(cwavef_y)
    1161              : 
    1162              :                end if ! dtset%nspden/=4
    1163        81622 :                ABI_FREE(cwavef1)
    1164              :              end if
    1165              :            else
    1166       230661 :              nskip=nskip+1
    1167              :            end if
    1168              :          end do  ! Loop inside a block of bands
    1169              : 
    1170              :        end if ! dtset%gpu_option
    1171              : 
    1172              : 
    1173      1167353 :      else if (fixed_occ .and. mpi_enreg%paral_kgb==1) then
    1174              :        ! In case of fixed occupation numbers,in bandFFT mode accumulates the partial density
    1175              : 
    1176        68990 :        if (dtset%nspinor==1) then
    1177        48270 :          call timab(537,1,tsec) ! "prep_fourwf%vtow"
    1178              :          call prep_fourwf(rhoaug(:,:,:,1),blocksize,cwavef,wfraug,iblock,istwf_k,&
    1179              :            gs_hamk%mgfft,mpi_enreg,nband_k,ndat,gs_hamk%ngfft,npw_k,&
    1180              :            gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,occ_k,&
    1181        48270 :            1,gs_hamk%ucvol,wtk,gs_hamk%nfft_blocks,gpu_option=dtset%gpu_option)
    1182        48270 :          call timab(537,2,tsec)
    1183        20720 :        else if (dtset%nspinor==2) then
    1184        82880 :          ABI_MALLOC(cwavefb,(2,npw_k*blocksize,2))
    1185        20720 :          if(gs_hamk%gpu_option==ABI_GPU_OPENMP) then
    1186              :            ! --- No parallelization over spinors ---
    1187            0 :            if (mpi_enreg%paral_spinor==0) then
    1188              : #ifdef HAVE_OPENMP_OFFLOAD
    1189              :              !$OMP TARGET ENTER DATA MAP(alloc:cwavefb)
    1190              :              !$OMP TARGET TEAMS DISTRIBUTE MAP(to:cwavefb,cwavef) PRIVATE(iband)
    1191              :              do iband=1,blocksize
    1192              :                !$OMP PARALLEL DO PRIVATE(ipw)
    1193              :                do ipw=1,npw_k
    1194              :                  cwavefb(1,(iband-1)*npw_k+ipw,1)=cwavef(1,ipw+(2*iband-2)*npw_k)
    1195              :                  cwavefb(2,(iband-1)*npw_k+ipw,1)=cwavef(2,ipw+(2*iband-2)*npw_k)
    1196              : 
    1197              :                  cwavefb(1,(iband-1)*npw_k+ipw,2)=cwavef(1,ipw+(2*iband-1)*npw_k)
    1198              :                  cwavefb(2,(iband-1)*npw_k+ipw,2)=cwavef(2,ipw+(2*iband-1)*npw_k)
    1199              :                end do
    1200              :              end do
    1201              : #endif
    1202              :            else
    1203            0 :              ABI_BUG("Parallelisation on spinor isn't supported with OpenMP GPU")
    1204              :            end if
    1205              :          else
    1206              :            ! --- No parallelization over spinors ---
    1207        20720 :            if (mpi_enreg%paral_spinor==0) then
    1208        95680 :              do iband=1,blocksize
    1209      9033380 :                cwavefb(:,(iband-1)*npw_k+1:iband*npw_k,1)=cwavef(:,1+(2*iband-2)*npw_k:(iband*2-1)*npw_k)
    1210      9045940 :                cwavefb(:,(iband-1)*npw_k+1:iband*npw_k,2)=cwavef(:,1+(2*iband-1)*npw_k:iband*2*npw_k)
    1211              :              end do
    1212              :            else
    1213              :              ! --- Parallelization over spinors ---
    1214              :              ! (split the work between 2 procs)
    1215      9855216 :              cwavefb(:,:,3-ispinor_index)=zero
    1216        24832 :              do iband=1,blocksize
    1217      9871888 :                cwavefb(:,(iband-1)*npw_k+1:iband*npw_k,ispinor_index) = cwavef(:,1+(iband-1)*npw_k:iband*npw_k)
    1218              :              end do
    1219         8160 :              call xmpi_sum(cwavefb,mpi_enreg%comm_spinor,ierr)
    1220              :            end if
    1221              :          end if !gpu_option
    1222              : 
    1223        20720 :          call timab(537,1,tsec) !"prep_fourwf%vtow"
    1224        20720 :          if (nspinor1TreatedByThisProc) then
    1225              :            call prep_fourwf(rhoaug(:,:,:,1),blocksize,cwavefb(:,:,1),wfraug,iblock,&
    1226              :              istwf_k,gs_hamk%mgfft,mpi_enreg,nband_k,ndat,gs_hamk%ngfft,npw_k,&
    1227              :              gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,occ_k,1,gs_hamk%ucvol,wtk,gs_hamk%nfft_blocks,&
    1228        16640 :              gpu_option=dtset%gpu_option)
    1229              :          end if
    1230        20720 :          if(dtset%nspden==1) then
    1231         9376 :            if (nspinor2TreatedByThisProc) then
    1232              :              call prep_fourwf(rhoaug(:,:,:,1),blocksize,cwavefb(:,:,2),wfraug,&
    1233              :                iblock,istwf_k,gs_hamk%mgfft,mpi_enreg,nband_k,ndat,&
    1234              :                gs_hamk%ngfft,npw_k,gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,occ_k,1,&
    1235         8768 :                gs_hamk%ucvol,wtk,gs_hamk%nfft_blocks,gpu_option=dtset%gpu_option)
    1236              :            end if
    1237        11344 :          else if(dtset%nspden==4) then
    1238        34032 :            ABI_MALLOC(cwavef_x,(2,npw_k*blocksize))
    1239        22688 :            ABI_MALLOC(cwavef_y,(2,npw_k*blocksize))
    1240        11344 :            if(gs_hamk%gpu_option==ABI_GPU_OPENMP) then
    1241              : #ifdef HAVE_OPENMP_OFFLOAD
    1242              :              !$OMP TARGET ENTER DATA MAP(alloc:cwavef_x,cwavef_y)
    1243              :              !$OMP TARGET TEAMS DISTRIBUTE MAP(to:cwavef_x,cwavef_y,cwavefb) PRIVATE(iband)
    1244              :              do iband=1,blocksize
    1245              :                !$OMP PARALLEL DO PRIVATE(ipw)
    1246              :                do ipw=1,npw_k
    1247              :                  !$(\Psi^{1}+\Psi^{2})$
    1248              :                  cwavef_x(1,(iband-1)*npw_k+ipw)=cwavefb(1,(iband-1)*npw_k+ipw,1)+cwavefb(1,(iband-1)*npw_k+ipw,2)
    1249              :                  cwavef_x(2,(iband-1)*npw_k+ipw)=cwavefb(2,(iband-1)*npw_k+ipw,1)+cwavefb(2,(iband-1)*npw_k+ipw,2)
    1250              :                  !$(\Psi^{1}-i \Psi^{2})$
    1251              :                  cwavef_y(1,(iband-1)*npw_k+ipw)=cwavefb(1,(iband-1)*npw_k+ipw,1)+cwavefb(2,(iband-1)*npw_k+ipw,2)
    1252              :                  cwavef_y(2,(iband-1)*npw_k+ipw)=cwavefb(2,(iband-1)*npw_k+ipw,1)-cwavefb(1,(iband-1)*npw_k+ipw,2)
    1253              :                end do
    1254              :              end do
    1255              : #endif
    1256              :            else
    1257      5978296 :              cwavef_x(:,:)=cwavefb(:,1:npw_k*blocksize,1)+cwavefb(:,:,2)
    1258      2000328 :              cwavef_y(1,:)=cwavefb(1,1:npw_k*blocksize,1)+cwavefb(2,:,2)
    1259      2000328 :              cwavef_y(2,:)=cwavefb(2,:,1)-cwavefb(1,:,2)
    1260              :            end if
    1261        11344 :            if (nspinor1TreatedByThisProc) then
    1262              :              call prep_fourwf(rhoaug(:,:,:,4),blocksize,cwavefb(:,:,2),wfraug,&
    1263              :                iblock,istwf_k,gs_hamk%mgfft,mpi_enreg,nband_k,ndat,gs_hamk%ngfft,&
    1264              :                npw_k,gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,occ_k,1,gs_hamk%ucvol,wtk,gs_hamk%nfft_blocks,&
    1265         7872 :                gpu_option=dtset%gpu_option)
    1266              :            end if
    1267        11344 :            if (nspinor2TreatedByThisProc) then
    1268              :              call prep_fourwf(rhoaug(:,:,:,2),blocksize,cwavef_x,wfraug,&
    1269              :                iblock,istwf_k,gs_hamk%mgfft,mpi_enreg,nband_k,ndat,gs_hamk%ngfft,&
    1270              :                npw_k,gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,occ_k,1,gs_hamk%ucvol,wtk,gs_hamk%nfft_blocks,&
    1271         7872 :                gpu_option=dtset%gpu_option)
    1272              :              call prep_fourwf(rhoaug(:,:,:,3),blocksize,cwavef_y,wfraug,&
    1273              :                iblock,istwf_k,gs_hamk%mgfft,mpi_enreg,nband_k,ndat,gs_hamk%ngfft,&
    1274              :                npw_k,gs_hamk%n4,gs_hamk%n5,gs_hamk%n6,occ_k,1,gs_hamk%ucvol,wtk,gs_hamk%nfft_blocks,&
    1275         7872 :                gpu_option=dtset%gpu_option)
    1276              :            end if
    1277              : #ifdef HAVE_OPENMP_OFFLOAD
    1278              :            !$OMP TARGET EXIT DATA MAP(delete:cwavef_x,cwavef_y) IF(gs_hamk%gpu_option==ABI_GPU_OPENMP)
    1279              : #endif
    1280        11344 :            ABI_FREE(cwavef_x)
    1281        11344 :            ABI_FREE(cwavef_y)
    1282              :          end if
    1283        20720 :          call timab(537,2,tsec)
    1284              : #ifdef HAVE_OPENMP_OFFLOAD
    1285              :          !$OMP TARGET EXIT DATA MAP(delete:cwavefb) IF(gs_hamk%gpu_option==ABI_GPU_OPENMP)
    1286              : #endif
    1287        20720 :          ABI_FREE(cwavefb)
    1288              :        end if
    1289              :      end if
    1290              :      ABI_NVTX_END_RANGE()
    1291              :    end if ! End of SCF calculation
    1292              : 
    1293              :    ! Call to nonlocal operator:
    1294              :    ! - Compute nonlocal forces from most recent wfs
    1295              :    ! - PAW: compute projections of WF onto NL projectors (cprj)
    1296              :    ABI_NVTX_START_RANGE(NVTX_VTOWFK_NONLOP)
    1297      2150541 :    eig_k_block => eig_k(1+(iblock-1)*blocksize:iblock*blocksize)
    1298      2150541 :    cg_k_block => cg_k(:,1+(iblock-1)*blocksize*my_nspinor*npw_k:iblock*blocksize*my_nspinor*npw_k)
    1299      2493832 :    if (dtset%cprj_in_memory==2) then
    1300            0 :      if (optforces>0) then
    1301            0 :        call timab(554,1,tsec)  ! "vtowfk:rhoij"
    1302              :        ! Treat all wavefunctions in case of PAW
    1303            0 :        cwaveprj => cprj(:,1+(iblock-1)*my_nspinor*blocksize+ibg:iblock*my_nspinor*blocksize+ibg)
    1304              :        call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamk,idir,eig_k_block,&
    1305            0 :          mpi_enreg,blocksize,nnlout,paw_opt,signs,nonlop_dum,tim_nonlop,cwavef,nonlop_dum2)
    1306              :        ! Accumulate forces
    1307            0 :        iband=(iblock-1)*blocksize
    1308            0 :        do iblocksize=1,blocksize
    1309            0 :          ii=0
    1310            0 :          if (nnlout>3*natom) ii=6
    1311            0 :          iband=iband+1;ibs=ii+nnlout*(iblocksize-1)
    1312            0 :          grnl_k(1:nnlout,iband)=enlout(ibs+1:ibs+nnlout)
    1313              :        end do
    1314            0 :        call timab(554,2,tsec)  ! "vtowfk:rhoij"
    1315              :      end if ! PAW or forces
    1316              :    else
    1317      2150541 :      if(iscf>0.or.gs_hamk%usecprj==1)then
    1318      2033702 :        if (gs_hamk%usepaw==1.or.optforces/=0) then
    1319              :          ! Treat all wavefunctions in case of varying occupation numbers or PAW
    1320              :          ! Only treat occupied bands in case of fixed occupation numbers and NCPP
    1321      1201196 :          if(fixed_occ.and.abs(occblock)<=tol8.and.gs_hamk%usepaw==0) then
    1322       242199 :            if (optforces>0) grnl_k(:,(iblock-1)*blocksize+1:iblock*blocksize)=zero
    1323              :          else
    1324      1188251 :            if (dtset%cprj_in_memory/=1) then
    1325      1163499 :              if(gs_hamk%usepaw==1) then
    1326       968254 :                call timab(554,1,tsec)  ! "vtowfk:rhoij"
    1327              :              end if
    1328      1163499 :              if(cpopt==1) then
    1329          916 :                iband=1+(iblock-1)*bandpp_cprj
    1330          916 :                call pawcprj_copy(cprj(:,1+(iblock-1)*my_nspinor*blocksize+ibg:iblock*my_nspinor*blocksize+ibg),cwaveprj)
    1331              :              end if
    1332      1163499 :              if (mpi_enreg%paral_kgb==1) then
    1333        85604 :                call timab(572,1,tsec) ! 'prep_nonlop%vtowfk'
    1334              :                call prep_nonlop(choice,cpopt,cwaveprj,enlout,gs_hamk,idir, &
    1335              :                  eig_k_block,blocksize,&
    1336        85604 :                  mpi_enreg,nnlout,paw_opt,signs,nonlop_dum,tim_nonlop_prep,cwavef,nonlop_dum2,already_transposed=.false.)
    1337        85604 :                call timab(572,2,tsec)
    1338              :              else
    1339              :                call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamk,idir,eig_k_block,&
    1340              :                  mpi_enreg,blocksize,nnlout,&
    1341      1077895 :                  paw_opt,signs,nonlop_dum,tim_nonlop,cwavef,cwavef)
    1342              :              end if
    1343      1163499 :              if(gs_hamk%usepaw==1) then
    1344       968254 :                call timab(554,2,tsec)
    1345              :              end if
    1346              :              ! Acccumulate forces
    1347      1163499 :              if (optforces>0) then
    1348       323191 :                iband=(iblock-1)*blocksize
    1349       766844 :                do iblocksize=1,blocksize
    1350       443653 :                  ii=0
    1351       443653 :                  if (nnlout>3*natom) ii=6
    1352       443653 :                  iband=iband+1;ibs=ii+nnlout*(iblocksize-1)
    1353      5098886 :                  grnl_k(1:nnlout,iband)=enlout(ibs+1:ibs+nnlout)
    1354              :                end do
    1355              :              end if
    1356              :              ! Store cprj (<Pnl|Psi>)
    1357      1163499 :              if (gs_hamk%usepaw==1.and.gs_hamk%usecprj==1) then
    1358       968254 :                iband=1+(iblock-1)*bandpp_cprj
    1359              :                call pawcprj_put(gs_hamk%atindx,cwaveprj,cprj,natom,iband,ibg,ikpt,iorder_cprj,isppol,&
    1360              :                  mband_cprj,dtset%mkmem,natom,bandpp_cprj,nband_k_cprj,gs_hamk%dimcprj,my_nspinor,&
    1361       968254 :                  dtset%nsppol,dtfil%unpaw,mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
    1362              :              end if
    1363              : 
    1364              :            else ! cprj_in_memory==1
    1365              : 
    1366        24752 :              call timab(222,1,tsec) ! 'nonlop%vtowfk'
    1367              : 
    1368        24752 :              if ( gs_hamk%istwf_k > 1 ) then ! Real only
    1369        10154 :                space = SPACE_CR
    1370              :              else ! complex
    1371        14598 :                space = SPACE_C
    1372              :              end if
    1373        24752 :              me_g0 = -1
    1374        24752 :              if (space==SPACE_CR) then
    1375        10154 :                me_g0 = 0
    1376        10154 :                if (gs_hamk%istwf_k == 2) then
    1377         1544 :                  if (mpi_enreg%me_g0 == 1) me_g0 = 1
    1378              :                end if
    1379              :              end if
    1380              :              call xgBlock_map(xgx0,cg_k_block,space,npw_k*my_nspinor,blocksize,comm=mpi_enreg%comm_band,me_g0=me_g0,&
    1381        24752 :               gpu_option=dtset%gpu_option)
    1382        24752 :              call xgBlock_map_1d(xgeigen,eig_k_block,SPACE_R,blocksize)
    1383              : 
    1384        24752 :              if (optforces/=0.or.gs_hamk%usepaw==1) then
    1385        24752 :                call xg_nonlop_getcprj(xg_nonlop,xgx0,cprj_xgx0%self,cprj_work%self)
    1386              :              end if
    1387              : 
    1388        24752 :              if (optforces/=0) then
    1389        17752 :                grnl_k_block => grnl_k(:,1+(iblock-1)*blocksize:iblock*blocksize)
    1390        17752 :                call xgBlock_map(xgforces,grnl_k_block,SPACE_R,3*natom,blocksize)
    1391        17752 :                call xg_nonlop_forces_stress(xg_nonlop,xgx0,cprj_xgx0%self,cprj_work%self,xgeigen,forces=xgforces)
    1392              :              end if
    1393              : 
    1394        24752 :              call timab(222,2,tsec) ! 'nonlop%vtowfk'
    1395              : 
    1396        24752 :              if (gs_hamk%usepaw==1) then
    1397        23072 :                cprj_cwavef_bands => cprj(:,1+ibg+(iblock-1)*ncols_cprj:iblock*ncols_cprj+ibg)
    1398        23072 :                call xg_cprj_copy(cprj_cwavef_bands,cprj_xgx0%self,xg_nonlop,XG_TO_CPRJ)
    1399              :              end if
    1400              : 
    1401              :            end if
    1402              :          end if
    1403              :        end if ! PAW or forces
    1404              :      end if ! iscf>0 or iscf=-3
    1405              :    end if
    1406              :    ABI_NVTX_END_RANGE()
    1407              :  end do !  End of loop on blocks
    1408              : 
    1409              : #ifdef HAVE_OPENMP_OFFLOAD
    1410              :  !$OMP TARGET EXIT DATA MAP(delete:cwavef) IF(gs_hamk%gpu_option==ABI_GPU_OPENMP)
    1411              :  !$OMP TARGET EXIT DATA MAP(delete:kinpw) IF(gs_hamk%gpu_option==ABI_GPU_OPENMP)
    1412              : #endif
    1413              : 
    1414              :  ! restore safe value related to GEMM nonlop slicing and GPU in case of forces compute
    1415       343291 :  if(optforces==1 .and. gpu_option_tmp==ABI_GPU_OPENMP) then
    1416            0 :    gs_hamk%gpu_option = gpu_option_tmp
    1417            0 :    gemm_nonlop_block_size = blksize_gemm_nonlop_tmp
    1418            0 :    gemm_nonlop_is_distributed = is_distrib_tmp
    1419            0 :    gs_hamk%nfft_blocks = nfft_blocks_tmp
    1420              :  end if
    1421              : 
    1422       343291 :  if (dtset%cprj_in_memory==1) then
    1423        17084 :    call xg_free(cprj_xgx0)
    1424        17084 :    call xg_free(cprj_work)
    1425              :  end if
    1426              : 
    1427              :  !call cwtime_report(" Block loop", cpu, wall, gflops)
    1428              : 
    1429       343291 :  if(dtset%gpu_option==ABI_GPU_KOKKOS) then
    1430              : #if defined HAVE_GPU && defined HAVE_YAKL
    1431              :    ABI_FREE_MANAGED(cwavef)
    1432              : #endif
    1433              :  else
    1434       343291 :    ABI_FREE(cwavef)
    1435              :  end if
    1436              : 
    1437       343291 :  ABI_FREE(enlout)
    1438              : 
    1439       343291 :  if (dtset%cprj_in_memory/=2) then
    1440       343291 :    if (gs_hamk%usepaw==1.and.(iscf>0.or.gs_hamk%usecprj==1)) then
    1441       107704 :      call pawcprj_free(cwaveprj)
    1442              :    end if
    1443       343291 :    ABI_FREE(cwaveprj)
    1444              :  else
    1445            0 :    nullify(cwaveprj)
    1446              :  end if
    1447              : 
    1448       343291 :  if (fixed_occ.and.iscf>0) then
    1449       229430 :    if(dtset%gpu_option==ABI_GPU_KOKKOS) then
    1450              : #if defined HAVE_GPU && defined HAVE_YAKL
    1451              :      ABI_FREE_MANAGED(wfraug)
    1452              : #endif
    1453              :    else
    1454       229430 :      ABI_FREE(wfraug)
    1455              :    end if
    1456              :  end if
    1457              : 
    1458              : !Write the number of one-way 3D ffts skipped until now (in case of fixed occupation numbers
    1459       343291 :  if(iscf>0 .and. fixed_occ .and. (prtvol>2 .or. ikpt<=nkpt_max) )then
    1460         2090 :    write(msg,'(a,i0)')' vtowfk: number of one-way 3D ffts skipped in vtowfk until now =',nskip
    1461         2090 :    call wrtout(std_out,msg,'PERS')
    1462              :  end if
    1463              : 
    1464              :  ! Norm-conserving or FockACE: Compute nonlocal+FockACE part of total energy: rotate subvnlx elements
    1465              :  ! Note the two calls. For (old) lobpcgwf we have a (nband_k, nband_k) matrix, whereas cgwf
    1466              :  ! returns results in packed form.
    1467              :  ! CHEBYSHEV, NEW LOBPCG and RMM-DIIS do not need this
    1468              :  !
    1469       343291 :  rotate_subvnlx = gs_hamk%usepaw == 0 .and. wfopta10 /= 1 .and. .not. xg_diago
    1470       343291 :  if (use_rmm_diis) rotate_subvnlx = .False.
    1471              : 
    1472       342743 :  if (rotate_subvnlx) then
    1473       223951 :    call timab(586,1,tsec)   ! 'vtowfk(nonlocalpart)'
    1474       223951 :    if (wfopta10==4) then
    1475          612 :      call cg_hrotate_and_get_diag(istwf_k, nband_k, totvnlx, evec, enlx_k)
    1476              :    else
    1477       223339 :      call cg_hprotate_and_get_diag(nband_k, subvnlx, evec, enlx_k)
    1478              :    end if
    1479       223951 :    call timab(586,2,tsec)
    1480              :  end if
    1481              : 
    1482              : !###################################################################
    1483              : 
    1484       343291 :  if (iscf<=0 .and. max_resid > dtset%tolwfr) then
    1485              :    write(msg,'(2(a,i0),a,es13.5)')&
    1486          710 :     "Wavefunctions not converged for ikpt: ", ikpt, ", nnsclo: ",nnsclo_now,', max resid: ',max_resid
    1487          710 :    ABI_WARNING(msg)
    1488              :  end if
    1489              : 
    1490              :  ! Print out eigenvalues (hartree)
    1491       343291 :  if (mod(dtset%wfoptalg,10)==1) then
    1492        21504 :    niter=dtset%mdeg_filter
    1493        21504 :    iter_name='as the degree of the polynomial filter'
    1494              :  else
    1495       321787 :    niter=dtset%nline
    1496       321787 :    iter_name='CG line minimizations'
    1497              :  end if
    1498       343291 :  if (prtvol/=5.and.(prtvol>2 .or. ikpt<=nkpt_max)) then
    1499              :    write(msg, '(5x,a,i5,2x,a,a,a,i4,a,i4,2a)' ) &
    1500        14055 :     'eigenvalues (hartree) for',nband_k,'bands',ch10,&
    1501        28110 :     '              after ',inonsc,' non-SCF iterations with ',niter,' ',trim(iter_name)
    1502        14055 :    call wrtout(std_out,msg,'PERS')
    1503        56224 :    do ii=0,(nband_k-1)/6
    1504        42169 :      write(msg, '(1p,6e12.4)' ) (eig_k(iband),iband=1+6*ii,min(6+6*ii,nband_k))
    1505        56224 :      call wrtout(std_out,msg,'PERS')
    1506              :    end do
    1507       329236 :  else if(ikpt==nkpt_max+1)then
    1508            0 :    call wrtout(std_out,' vtowfk : prtvol=0 or 1, do not print more k-points.','PERS')
    1509              :  end if
    1510              : 
    1511              :  ! Print out decomposition of eigenvalues in the non-selfconsistent case or if prtvol>=10
    1512       343291 :  if( (iscf<0 .and. (prtvol>2 .or. ikpt<=nkpt_max)) .or. prtvol>=10)then
    1513              :    write(msg, '(5x,a,i5,2x,a,a,a,i4,a,i4,2a)' ) &
    1514         4449 :    ' mean kinetic energy (hartree) for ',nband_k,' bands',ch10,&
    1515         8898 :    '              after ',inonsc,' non-SCF iterations with ',niter,' ',trim(iter_name)
    1516         4449 :    call wrtout(std_out,msg,'PERS')
    1517              : 
    1518        13012 :    do ii=0,(nband_k-1)/6
    1519         8563 :      write(msg, '(1p,6e12.4)' ) (ek_k(iband),iband=1+6*ii,min(6+6*ii,nband_k))
    1520        13012 :      call wrtout(std_out,msg,'PERS')
    1521              :    end do
    1522              : 
    1523         4449 :    if (gs_hamk%usepaw==0) then
    1524              :      write(msg, '(5x,a,i5,2x,a,a,a,i4,a,i4,2a)' ) &
    1525         3076 :      ' mean NL+Fock-type energy (hartree) for ',nband_k,' bands',ch10,&
    1526         6152 :      '              after ',inonsc,' non-SCF iterations with ',niter,' ',trim(iter_name)
    1527         3076 :      call wrtout(std_out,msg,'PERS')
    1528              : 
    1529         8029 :      do ii=0,(nband_k-1)/6
    1530         4953 :        write(msg,'(1p,6e12.4)') (enlx_k(iband),iband=1+6*ii,min(6+6*ii,nband_k))
    1531         8029 :        call wrtout(std_out,msg,'PERS')
    1532              :      end do
    1533              :    end if
    1534              :  end if
    1535              : 
    1536              :  ! Hamiltonian constructor for gwls_sternheimer
    1537       343291 :  if (dtset%optdriver==RUNL_GWLS) call build_H(dtset,mpi_enreg,cpopt,cg,gs_hamk,kg_k,kinpw)
    1538              : 
    1539       343291 :  if (dtset%cprj_in_memory==2) nullify(cprj_cwavef_bands)
    1540              : 
    1541              : #ifdef HAVE_OPENMP_OFFLOAD
    1542              :  if(transfer_cg) then
    1543              :    !$OMP TARGET EXIT DATA MAP(from:cg_k) IF(gs_hamk%gpu_option==ABI_GPU_OPENMP .and. xg_diago)
    1544              :  end if
    1545              : #endif
    1546       343291 :  if(wfopta10 /= 1 .and. .not. xg_diago) then
    1547       298640 :    ABI_FREE(evec)
    1548       298640 :    ABI_FREE(subham)
    1549       298640 :    ABI_FREE(totvnlx)
    1550       298640 :    ABI_FREE(subvnlx)
    1551       298640 :    ABI_FREE(subovl)
    1552              :  end if
    1553              : 
    1554       343291 :  ABI_SFREE(gsc)
    1555              : 
    1556       343291 :  if(wfoptalg==3) then
    1557            6 :    ABI_FREE(eig_save)
    1558              :  end if
    1559              : 
    1560       343291 :  if (prtvol==-level) then
    1561              :    ! Structured debugging: if prtvol=-level, stop here.
    1562            0 :    write(msg,'(3a,i0,a)')' vtowfk: exit ',ch10,'  prtvol=-',level,', debugging mode => stop '
    1563            0 :    ABI_ERROR(msg)
    1564              :  end if
    1565              : 
    1566       343291 :  call timab(30,2,tsec)
    1567       343291 :  call timab(28,2,tsec)
    1568              : 
    1569              :  DBG_EXIT("COLL")
    1570              : 
    1571       686582 : end subroutine vtowfk
    1572              : !!***
    1573              : 
    1574              : end module m_vtowfk
    1575              : !!***
        

Generated by: LCOV version 2.3-1