LCOV - code coverage report
Current view: top level - src/66_wfs - m_getgh1c.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 88.1 % 876 772
Test Date: 2026-09-19 17:42:43 Functions: 100.0 % 8 8

            Line data    Source code
       1              : !!****m* ABINIT/m_getgh1c
       2              : !! NAME
       3              : !!  m_getgh1c
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 1998-2026 ABINIT group (XG, DRH, MT, SPr)
      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_getgh1c
      26              : 
      27              :  use defs_basis
      28              :  use m_abicore
      29              :  use m_errors
      30              :  use m_dtset
      31              :  use m_xmpi
      32              :  use m_xomp
      33              :  use m_gputk
      34              :  use m_abi_linalg
      35              : 
      36              :  use, intrinsic :: iso_c_binding, only : c_ptr,c_loc,c_size_t
      37              :  use defs_abitypes, only : MPI_type
      38              :  use defs_datatypes, only : pseudopotential_type
      39              :  use m_time,        only : timab
      40              :  use m_fstrings,    only : sjoin, ltoa, itoa
      41              :  use m_pawcprj,     only : pawcprj_type, pawcprj_alloc, pawcprj_free, &
      42              :                            pawcprj_copy, pawcprj_lincom, pawcprj_axpby, pawcprj_mpi_sum
      43              :  use m_kg,          only : kpgstr, mkkin, mkkpg, mkkin_metdqdq
      44              :  use m_mkffnl,      only : mkffnl
      45              :  use m_pawfgr,      only : pawfgr_type
      46              :  use m_fft,         only : fftpac, fourwf
      47              :  use m_hamiltonian, only : gs_hamiltonian_type, rf_hamiltonian_type
      48              :  use m_cgtools,          only : projbd
      49              :  use m_nonlop,           only : nonlop
      50              :  use m_fourier_interpol, only : transgrid
      51              : 
      52              : #if defined(HAVE_GPU_MARKERS)
      53              :  use m_nvtx_data
      54              : #endif
      55              : 
      56              :  implicit none
      57              : 
      58              :  private
      59              : !!***
      60              : 
      61              :  public :: getgh1c
      62              :  public :: rf_transgrid_and_pack
      63              :  public :: getgh1c_setup
      64              :  public :: getdc1
      65              :  public :: getgh1dqc
      66              :  public :: getgh1dqc_setup
      67              :  public :: getgh1ndc
      68              :  public :: getgh1c_mGGA
      69              : !!***
      70              : 
      71              : contains
      72              : !!***
      73              : 
      74              : !!****f* ABINIT/getgh1c
      75              : !!
      76              : !! NAME
      77              : !! getgh1c
      78              : !!
      79              : !! FUNCTION
      80              : !! Compute <G|H^(1)|C> (or <G|H^(1)-lambda.S^(1)|C>) for input vector |C> expressed in reciprocal space.
      81              : !! (H^(1) is the 1st-order pertubed Hamiltonian, S^(1) is the 1st-order perturbed overlap operator).
      82              : !! Result is put in array gh1c.
      83              : !! If required, part of <G|K(1)+Vnonlocal^(1)|C> not depending on VHxc^(1) is also returned in gvnlx1c.
      84              : !! If required, <G|S^(1)|C> is returned in gs1c (S=overlap - PAW only)
      85              : !!
      86              : !! INPUTS
      87              : !!  berryopt=option for Berry phase
      88              : !!  cwave(2,npw*nspinor)=input wavefunction, in reciprocal space
      89              : !!  cwaveprj(natom,nspinor*usecprj)=<p_lmn|C> coefficients for wavefunction |C> (and 1st derivatives)
      90              : !!     if not allocated or size=0, they are locally computed (and not sorted)
      91              : !!  dkinpw(npw)=derivative of the (modified) kinetic energy for each plane wave at k (Hartree)
      92              : !!  grad_berry(2,npw1*nspinor*(berryopt/4))= the gradient of the Berry phase term
      93              : !!  gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k+q
      94              : !!  idir=direction of the perturbation
      95              : !!  ipert=type of the perturbation
      96              : !!  lambda=real use to apply H^(1)-lambda.S^(1)
      97              : !!  mpi_enreg=information about MPI parallelization
      98              : !!  ndat=number of bands to compute in parallel
      99              : !!  npw=number of planewaves in basis sphere at given k.
     100              : !!  npw1=number of planewaves in basis sphere at k+q
     101              : !!  optlocal=0: local part of H^(1) is not computed in gh1c=<G|H^(1)|C>
     102              : !!           1: local part of H^(1) is computed in gh1c=<G|H^(1)|C>
     103              : !!  optnl=0: non-local part of H^(1) is not computed in gh1c=<G|H^(1)|C>
     104              : !!        1: non-local part of H^(1) depending on VHxc^(1) is not computed in gh1c=<G|H^(1)|C>
     105              : !!        2: non-local part of H^(1) is totally computed in gh1c=<G|H^(1)|C>
     106              : !!  opt_gvnlx1=option controlling the use of gvnlx1 array:
     107              : !!            0: used as an output
     108              : !!            1: used as an input:   (only for ipert=natom+2)
     109              : !!                 NCPP: contains the ddk 1-st order WF
     110              : !!                 PAW: contains frozen part of 1st-order hamiltonian
     111              : !!            2: used as input/output:    - used only for PAW and ipert=natom+2
     112              : !!                 At input: contains the ddk 1-st order WF (times i)
     113              : !!                 At output: contains frozen part of 1st-order hamiltonian
     114              : !!  rf_hamkq <type(rf_hamiltonian_type)>=all data for the 1st-order Hamiltonian at k,k+q
     115              : !!  sij_opt= -PAW ONLY-  if  0, only matrix elements <G|H^(1)|C> have to be computed
     116              : !!     (S=overlap)       if  1, matrix elements <G|S^(1)|C> have to be computed in gs1c in addition to gh1c
     117              : !!                       if -1, matrix elements <G|H^(1)-lambda.S^(1)|C> have to be computed in gh1c (gs1c not used)
     118              : !!  tim_getgh1c=timing code of the calling subroutine (can be set to 0 if not attributed)
     119              : !!  usevnl=1 if gvnlx1=(part of <G|K^(1)+Vnl^(1)-lambda.S^(1)|C> not depending on VHxc^(1)) has to be input/output
     120              : !!
     121              : !! OUTPUT
     122              : !! gh1c(2,npw1*nspinor)= <G|H^(1)|C> or  <G|H^(1)-lambda.S^(1)|C> on the k+q sphere
     123              : !!                     (only kinetic+non-local parts if optlocal=0)
     124              : !! if (usevnl==1)
     125              : !!  gvnlx1(2,npw1*nspinor*ndat)=  part of <G|K^(1)+Vnl^(1)|C> not depending on VHxc^(1)              (sij_opt/=-1)
     126              : !!                       or part of <G|K^(1)+Vnl^(1)-lambda.S^(1)|C> not depending on VHxc^(1) (sij_opt==-1)
     127              : !! if (sij_opt=1)
     128              : !!  gs1c(2,npw1*nspinor)=<G|S^(1)|C> (S=overlap) on the k+q sphere.
     129              : !!
     130              : !! SOURCE
     131              : 
     132      8601471 : subroutine getgh1c(berryopt,cwave,cwaveprj,gh1c,grad_berry,gs1c,gs_hamkq,&
     133      8601471 :                    gvnlx1,idir,ipert,lambda,mpi_enreg,ndat,optlocal,optnl,opt_gvnlx1,&
     134              :                    rf_hamkq,sij_opt,tim_getgh1c,usevnl, &
     135              :                    conj) ! optional
     136              : 
     137              : !Arguments ------------------------------------
     138              : !scalars
     139              :  logical,intent(in),optional :: conj
     140              :  integer,intent(in) :: berryopt,idir,ipert,optlocal,optnl,opt_gvnlx1,sij_opt,tim_getgh1c,usevnl,ndat
     141              :  type(MPI_type),intent(in) :: mpi_enreg
     142              :  type(gs_hamiltonian_type),intent(inout),target :: gs_hamkq
     143              :  type(rf_hamiltonian_type),intent(inout),target :: rf_hamkq
     144              : !arrays
     145              :  real(dp),intent(in) :: lambda(ndat)
     146              :  real(dp),intent(in) :: grad_berry(:,:)
     147              :  real(dp),intent(inout),target :: cwave(2,gs_hamkq%npw_k*gs_hamkq%nspinor*ndat)
     148              :  real(dp),intent(out),target :: gh1c(2,gs_hamkq%npw_kp*gs_hamkq%nspinor*ndat)
     149              :  real(dp),intent(out),target :: gs1c(2,gs_hamkq%npw_kp*gs_hamkq%nspinor*ndat)
     150              :  real(dp),intent(inout),target :: gvnlx1(2,gs_hamkq%npw_kp*gs_hamkq%nspinor*ndat)
     151              :  type(pawcprj_type),intent(inout),target :: cwaveprj(:,:)
     152              : 
     153              : !Local variables-------------------------------
     154              : !scalars
     155              :  integer,parameter :: level=16
     156              :  integer :: choice,cplex1,cpopt,ipw,ipws,ispinor,istr,i1,i2,i3,idat, ndat__
     157              :  integer :: my_nspinor,natom,ncpgr,nnlout=1,npw,npw1,paw_opt,signs
     158              :  integer :: tim_fourwf,tim_nonlop,usecprj
     159              :  logical :: compute_conjugate,has_kin,has_mGGA1,has_nd1,usevnl2
     160              :  real(dp) :: weight !, cpu, wall, gflops
     161              :  real(dp),parameter :: threshold=huge(zero)*1.d-11
     162              :  !character(len=500) :: msg
     163              : !arrays
     164     17202942 :  real(dp) :: enlout(ndat),tsec(2),svectout_dum(1,1),vectout_dum(1,1)
     165      8601471 :  real(dp),allocatable :: cwave_sp(:,:),cwavef1(:,:),cwavef2(:,:)
     166      8601471 :  real(dp),allocatable :: gh1c_sp(:,:),gh1c1(:,:),gh1c2(:,:),gh1c3(:,:),gh1c4(:,:)
     167      8601471 :  real(dp),allocatable :: gh1c_mGGA(:,:),gh1ndc(:,:),gvnl2(:,:)
     168      8601471 :  real(dp),target,allocatable :: nonlop_out(:,:),vlocal1_tmp(:,:,:)
     169              : !#define _DEV_USE_WORK
     170              : !#ifdef _DEV_USE_WORK
     171      8601471 :  real(dp),target,allocatable :: work(:,:,:,:)
     172              : !#endif
     173      8601471 :  real(dp),contiguous, pointer :: gvnlx1_(:,:), dkinpw(:),kinpw1(:)
     174      8601471 :  type(pawcprj_type),allocatable,target :: cwaveprj_tmp(:,:)
     175      8601471 :  type(pawcprj_type),pointer :: cwaveprj_ptr(:,:)
     176              : #ifdef HAVE_OPENMP_OFFLOAD
     177              :  logical :: map_gh1c,map_gs1c,map_cwave,map_gvnlx1_
     178              : #endif
     179              : ! *********************************************************************
     180              : 
     181              :  DBG_ENTER("COLL")
     182              : 
     183              :  ! Keep track of total time spent in getgh1c
     184      8601471 :  call timab(196+tim_getgh1c,1,tsec)
     185              :  ABI_NVTX_START_RANGE(NVTX_GETGH1C)
     186              : 
     187              : !======================================================================
     188              : !== Initialisations and compatibility tests
     189              : !======================================================================
     190              : 
     191      8601471 :  npw  = gs_hamkq%npw_k
     192      8601471 :  npw1 = gs_hamkq%npw_kp
     193      8601471 :  natom = gs_hamkq%natom
     194              : 
     195              :  ! Compatibility tests
     196      8601471 :  if(gs_hamkq%usepaw==1.and.(ipert>=0.and.(ipert<=natom.or.ipert==natom+3.or.ipert==natom+4))) then
     197       671080 :    if ((optnl>=1.and.(.not.associated(rf_hamkq%e1kbfr))) .or. &
     198              :        (optnl==2.and.(.not.associated(rf_hamkq%e1kbsc)))) then
     199            0 :      ABI_BUG('ekb derivatives must be allocated for ipert<=natom or natom+3/4 !')
     200              :    end if
     201              :  end if
     202      8601471 :  if(gs_hamkq%usepaw==1.and.(ipert==natom+2)) then
     203       106864 :    if ((optnl>=1.and.(.not.associated(rf_hamkq%e1kbfr))) .or. &
     204              :        (optnl==2.and.(.not.associated(rf_hamkq%e1kbsc)))) then
     205            0 :      ABI_BUG('ekb derivatives must be allocated for ipert=natom+2 !')
     206              :    end if
     207       106864 :    if (usevnl==0) then
     208            0 :      ABI_BUG('gvnlx1 must be allocated for ipert=natom+2 !')
     209              :    end if
     210              :  end if
     211      8601471 :  if(ipert==natom+2.and.opt_gvnlx1==0) then
     212            0 :    ABI_BUG('opt_gvnlx1=0 not compatible with ipert=natom+2 !')
     213              :  end if
     214      8601471 :  if (mpi_enreg%paral_spinor==1) then
     215            0 :    ABI_BUG('Not compatible with parallelization over spinorial components !')
     216              :  end if
     217              : 
     218              :  ! Check sizes
     219      8601471 :  my_nspinor=max(1,gs_hamkq%nspinor/mpi_enreg%nproc_spinor)
     220     25804413 :  ABI_CHECK_IGEQ(size(cwave), 2*npw*my_nspinor*ndat, 'wrong size for cwave!')
     221     25804413 :  ABI_CHECK_IGEQ(size(gh1c), 2*npw1*my_nspinor*ndat, 'wrong size for gh1c!')
     222      8601471 :  if (usevnl/=0) then
     223     13997223 :    ABI_CHECK_IGEQ(size(gvnlx1), 2*npw1*my_nspinor*ndat, 'wrong size for gvnlx1!')
     224              :  end if
     225      8601471 :  if (sij_opt==1) then
     226      3019308 :    ABI_CHECK_IGEQ(size(gs1c), 2*npw1*my_nspinor*ndat, 'wrong size for gs1c!')
     227              :  end if
     228      8601471 :  if (berryopt>=4) then
     229         9312 :    ABI_CHECK_IGEQ(size(grad_berry), 2*npw1*my_nspinor*ndat, 'wrong size for grad_berry!')
     230              :  end if
     231              : 
     232              :  ! PAW: specific treatment for usecprj input arg. force it to zero if cwaveprj is not allocated
     233      8601471 :  usecprj=gs_hamkq%usecprj ; ncpgr=0
     234      8601471 :  if(gs_hamkq%usepaw==1) then
     235      3110328 :    if (size(cwaveprj)==0) usecprj=0
     236      1007976 :    if (usecprj/=0) then
     237      1007976 :      ncpgr=cwaveprj(1,1)%ncpgr
     238      3023928 :      ABI_CHECK_IGEQ(size(cwaveprj), gs_hamkq%natom*my_nspinor*ndat, 'wrong size for cwaveprj!')
     239      1007976 :      if(gs_hamkq%usepaw==1.and.(ipert>=0.and.(ipert<=natom.or.ipert==natom+3.or.ipert==natom+4))) then
     240       663400 :        if (ncpgr/=1)then
     241            0 :          ABI_BUG('Projected WFs (cprj) derivatives are not correctly stored !')
     242              :        end if
     243              :      end if
     244              :    end if
     245              :  else
     246      7564695 :    if(usecprj==1)then
     247            0 :      ABI_BUG('usecprj==1 not allowed for NC psps !')
     248              :    end if
     249              :  end if
     250              : 
     251      8601471 :  tim_nonlop=8
     252      8601471 :  if (tim_getgh1c==1.and.ipert<=natom) tim_nonlop=7
     253      8601471 :  if (tim_getgh1c==2.and.ipert<=natom) tim_nonlop=5
     254      8601471 :  if (tim_getgh1c==1.and.ipert> natom) tim_nonlop=8
     255      8601471 :  if (tim_getgh1c==2.and.ipert> natom) tim_nonlop=5
     256      8601471 :  if (tim_getgh1c==3                 ) tim_nonlop=0
     257              : 
     258      8601471 :  compute_conjugate = .false.
     259      8601471 :  if(present(conj)) compute_conjugate = conj
     260              : 
     261              :  if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) then
     262              : #ifdef HAVE_OPENMP_OFFLOAD
     263              :    map_gh1c  =  .not. ( xomp_target_is_present(c_loc(gh1c)))
     264              :    map_gs1c  =  .not. ( xomp_target_is_present(c_loc(gs1c))) .and. sij_opt==1
     265              :    map_cwave =  .not. ( xomp_target_is_present(c_loc(cwave)))
     266              :    !print *, "getgh1c: map_gh1c=", map_gh1c, ", map_gs1c=", map_gs1c, ", map_cwave=", map_cwave
     267              : 
     268              :    !$OMP TARGET ENTER DATA MAP(alloc:gh1c) IF(map_gh1c)
     269              :    !$OMP TARGET ENTER DATA MAP(alloc:gs1c) IF(map_gs1c)
     270              :    !$OMP TARGET ENTER DATA MAP(to:cwave)   IF(map_cwave)
     271              : #endif
     272              :  end if
     273      8601471 :  has_mGGA1=( (ipert .EQ. natom+1) .AND. ASSOCIATED(rf_hamkq%vxctaulocal) )
     274              : 
     275              : !======================================================================
     276              : !== Apply the 1st-order local potential to the wavefunction
     277              : !======================================================================
     278              : ! Phonon perturbation or
     279              : ! Electric field perturbation or
     280              : ! Strain perturbation
     281              : !-------------------------------------------
     282      8601471 :  if ((ipert<=natom+6.or.(ipert>natom+11.and.ipert<=2*natom+11)).and.ipert/=natom+1.and.optlocal>0) then !SPr deb
     283              : 
     284              :    ABI_NVTX_START_RANGE(NVTX_GETGH1_LOCPOT)
     285              : 
     286              :    ! Important: work (aka fofr) must be allocated with "ndat", but fourwf with option 2 never accesses it, so this allocation wastes memory.
     287              :    ! but it is neeeded to run on GPUs.
     288              :    ! Note that we use ndat__, since when nspinor 2 with nvloc 1, we can compute <g|vlocal1|u> for all ndat bands and the two spinor components
     289              :    ! with a single call to fourwf.
     290      4259527 :    ndat__ = ndat
     291      4259527 :    if (gs_hamkq%nvloc==1) ndat__ = ndat * gs_hamkq%nspinor
     292              : 
     293              : !#ifdef _DEV_USE_WORK
     294     21297635 :    ABI_MALLOC(work,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6*ndat__))
     295              : #ifdef HAVE_OPENMP_OFFLOAD
     296              :    if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_enter_map_alloc(work,2*gs_hamkq%n4*gs_hamkq%n5*gs_hamkq%n6*ndat__)
     297              : #endif
     298              : !#endif
     299              : 
     300              : !#else
     301              : !   call gs_hamkq%alloc_fofr_work(ndat__)
     302              : !   associate (work => gs_hamkq%fofr_work)
     303              : !#endif
     304              : 
     305      4259527 :    if (gs_hamkq%nvloc==1) then
     306              : 
     307      4170687 :      weight=one; tim_fourwf=4
     308              :      call fourwf(rf_hamkq%cplex,rf_hamkq%vlocal1,cwave,gh1c,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
     309              :        gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,ndat__,gs_hamkq%ngfft,&
     310      4170687 :        npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight, gpu_option=gs_hamkq%gpu_option)
     311              : 
     312      4170687 :      if(gs_hamkq%nspinor==2 .and. ndat__ == ndat)then
     313              :      ! Note: when ndat__ = ndat*nspinor (nvloc==1), fourwf above already handles both spinors
     314              :      ! This block is skipped.
     315            0 :        ABI_CHECK_IEQ(ndat, 1, "ndat > 1 with nspinor 2 and nspden 1 is buggy")
     316            0 :        ABI_MALLOC(cwave_sp,(2,npw))
     317            0 :        ABI_MALLOC(gh1c_sp,(2,npw1))
     318              : !$OMP PARALLEL DO
     319            0 :        do ipw=1,npw
     320            0 :          cwave_sp(1,ipw)=cwave(1,ipw+npw)
     321            0 :          cwave_sp(2,ipw)=cwave(2,ipw+npw)
     322              :        end do
     323              :        call fourwf(rf_hamkq%cplex,rf_hamkq%vlocal1,cwave_sp,gh1c_sp,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
     324              :          gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,ndat,gs_hamkq%ngfft,&
     325            0 :          npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight, gpu_option=gs_hamkq%gpu_option)
     326              : !$OMP PARALLEL DO
     327            0 :        do ipw=1,npw1
     328            0 :          gh1c(1,ipw+npw1)=gh1c_sp(1,ipw)
     329            0 :          gh1c(2,ipw+npw1)=gh1c_sp(2,ipw)
     330              :        end do
     331            0 :        ABI_FREE(cwave_sp)
     332            0 :        ABI_FREE(gh1c_sp)
     333              :      end if ! nspinor == 2
     334              : 
     335              :    else
     336              :      ! Non-Collinear magnetism for nvloc=4
     337        88840 :      if (gs_hamkq%nspinor==2) then
     338        88840 :        weight=one ; tim_fourwf=4
     339       266520 :        ABI_MALLOC(gh1c1,(2,npw1*ndat))
     340       177680 :        ABI_MALLOC(gh1c2,(2,npw1*ndat))
     341       177680 :        ABI_MALLOC(gh1c3,(2,npw1*ndat))
     342       177680 :        ABI_MALLOC(gh1c4,(2,npw1*ndat))
     343    205912456 :        gh1c1(:,:)=zero; gh1c2(:,:)=zero; gh1c3(:,:)=zero ;  gh1c4(:,:)=zero
     344       444200 :        ABI_MALLOC(vlocal1_tmp,(rf_hamkq%cplex*gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
     345              :        !SPr: notation/dimension corrected vlocal_tmp -> vlocal1_tmp
     346       266520 :        ABI_MALLOC(cwavef1,(2,npw*ndat))
     347       177680 :        ABI_MALLOC(cwavef2,(2,npw*ndat))
     348       177680 :        do idat=1,ndat
     349     17329648 :          do ipw=1,npw
     350     51455904 :            cwavef1(1:2,ipw+(idat-1)*npw)=cwave(1:2,ipw+(idat-1)*my_nspinor*npw)
     351     51544744 :            cwavef2(1:2,ipw+(idat-1)*npw)=cwave(1:2,ipw+(idat-1)*my_nspinor*npw+npw)
     352              :          end do
     353              :        end do
     354              :        ! gh1c1=v11*phi1
     355    748753432 :        vlocal1_tmp(:,:,:)=rf_hamkq%vlocal1(:,:,:,1)
     356              :        call fourwf(rf_hamkq%cplex,vlocal1_tmp,cwavef1,gh1c1,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
     357              :          gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,ndat,gs_hamkq%ngfft,&
     358        88840 :          npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight, gpu_option=gs_hamkq%gpu_option)
     359              :        ! gh1c2=v22*phi2
     360    748753432 :        vlocal1_tmp(:,:,:)=rf_hamkq%vlocal1(:,:,:,2)
     361              :        call fourwf(rf_hamkq%cplex,vlocal1_tmp,cwavef2,gh1c2,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
     362              :          gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,ndat,gs_hamkq%ngfft,&
     363        88840 :          npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight, gpu_option=gs_hamkq%gpu_option)
     364        88840 :        ABI_FREE(vlocal1_tmp)
     365        88840 :        cplex1=2
     366       444200 :        ABI_MALLOC(vlocal1_tmp,(cplex1*gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
     367              :        ! gh1c3=(re(v12)-im(v12))*phi1 => v^21*phi1
     368        88840 :        if(rf_hamkq%cplex==1) then
     369       816984 :          do i3=1,gs_hamkq%n6
     370     12716424 :            do i2=1,gs_hamkq%n5
     371    193744656 :              do i1=1,gs_hamkq%n4
     372    181062000 :                vlocal1_tmp(2*i1-1,i2,i3)= rf_hamkq%vlocal1(i1,i2,i3,3)
     373    192961440 :                vlocal1_tmp(2*i1  ,i2,i3)=-rf_hamkq%vlocal1(i1,i2,i3,4)
     374              :              end do
     375              :            end do
     376              :          end do
     377              :        else
     378              :          !SPr: modified definition of local potential components for cplex=2 (see dotprod_vn)
     379              :          !also, v21==v12* not always holds (e.g. magnetic field perturbation)
     380       747808 :          do i3=1,gs_hamkq%n6
     381     14195488 :            do i2=1,gs_hamkq%n5
     382    284530176 :              do i1=1,gs_hamkq%n4
     383    270389760 :                vlocal1_tmp(2*i1-1,i2,i3)= rf_hamkq%vlocal1(2*i1  ,i2,i3,4)
     384    283837440 :                vlocal1_tmp(2*i1  ,i2,i3)=-rf_hamkq%vlocal1(2*i1-1,i2,i3,4)
     385              :              end do
     386              :            end do
     387              :          end do
     388              :        end if
     389              :        call fourwf(cplex1,vlocal1_tmp,cwavef1,gh1c3,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
     390              :          gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,ndat,gs_hamkq%ngfft,&
     391        88840 :          npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight,gpu_option=gs_hamkq%gpu_option)
     392              :        ! gh1c4=(re(v12)+im(v12))*phi2 => v^12*phi2
     393        88840 :        if(rf_hamkq%cplex==1) then
     394       816984 :          do i3=1,gs_hamkq%n6
     395     12716424 :            do i2=1,gs_hamkq%n5
     396    193744656 :              do i1=1,gs_hamkq%n4
     397    192961440 :                vlocal1_tmp(2*i1,i2,i3)=-vlocal1_tmp(2*i1,i2,i3)
     398              :              end do
     399              :            end do
     400              :          end do
     401              :        else
     402              :          !for cplex=2 and time-reversal breaking perturbations,v21/=v12*
     403       747808 :          do i3=1,gs_hamkq%n6
     404     14195488 :            do i2=1,gs_hamkq%n5
     405    284530176 :              do i1=1,gs_hamkq%n4
     406    270389760 :                vlocal1_tmp(2*i1-1,i2,i3)= rf_hamkq%vlocal1(2*i1-1,i2,i3,3)
     407    283837440 :                vlocal1_tmp(2*i1  ,i2,i3)= rf_hamkq%vlocal1(2*i1  ,i2,i3,3)
     408              :              end do
     409              :            end do
     410              :          end do
     411              :        end if
     412              :        call fourwf(cplex1,vlocal1_tmp,cwavef2,gh1c4,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
     413              :          gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,ndat,gs_hamkq%ngfft,&
     414        88840 :          npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight, gpu_option=gs_hamkq%gpu_option)
     415        88840 :        ABI_FREE(vlocal1_tmp)
     416              :        ! Build gh1c from pieces
     417              :        ! gh1c_1 = (v11, v12) (psi1) matrix vector product
     418              :        ! gh1c_2 = (v12*,v22) (psi2)
     419       177680 :        do idat=1,ndat
     420     17329648 :          do ipw=1,npw1
     421     51455904 :            gh1c(1:2,ipw+(idat-1)*my_nspinor*npw1)     =gh1c1(1:2,ipw+(idat-1)*my_nspinor*npw1)+gh1c4(1:2,ipw+(idat-1)*my_nspinor*npw1)
     422     51544744 :            gh1c(1:2,ipw+(idat-1)*my_nspinor*npw1+npw1)=gh1c3(1:2,ipw+(idat-1)*my_nspinor*npw1)+gh1c2(1:2,ipw+(idat-1)*my_nspinor*npw1)
     423              :          end do
     424              :        end do
     425        88840 :        ABI_FREE(gh1c1)
     426        88840 :        ABI_FREE(gh1c2)
     427        88840 :        ABI_FREE(gh1c3)
     428        88840 :        ABI_FREE(gh1c4)
     429        88840 :        ABI_FREE(cwavef1)
     430        88840 :        ABI_FREE(cwavef2)
     431              :      else
     432            0 :        ABI_BUG('nspinor/=1 for Non-collinear calculations!')
     433              :      end if
     434              :    end if ! nvloc
     435              : 
     436              : !#ifndef _DEV_USE_WORK
     437              : !   end associate
     438              : !#endif
     439              : 
     440              : !#ifdef _DEV_USE_WORK
     441              : #ifdef HAVE_OPENMP_OFFLOAD
     442              :    if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_exit_map_delete(work,2*gs_hamkq%n4*gs_hamkq%n5*gs_hamkq%n6*ndat__)
     443              : #endif
     444      4259527 :    ABI_FREE(work)
     445              : !#endif
     446              :   ABI_NVTX_END_RANGE()
     447              : 
     448              : !  k-point perturbation (or no local part, i.e. optlocal=0)
     449              : !  -------------------------------------------
     450      4341944 :  else if (ipert==natom+1.or.optlocal==0) then
     451              : 
     452              : !  In the case of ddk operator, no local contribution (also because no self-consistency)
     453      4341944 :    if(gs_hamkq%gpu_option/=ABI_GPU_OPENMP) then
     454              :      !$OMP PARALLEL DO
     455    980236178 :      do ipw=1,npw1*my_nspinor*ndat
     456   2932024646 :        gh1c(:,ipw)=zero
     457              :      end do
     458              :    else
     459              : #ifdef HAVE_OPENMP_OFFLOAD
     460              :      call gpu_set_to_zero(gh1c,int(2,c_size_t)*npw1*my_nspinor*ndat)
     461              : #endif
     462              :    end if
     463              : 
     464              :  end if
     465              : 
     466              : !======================================================================
     467              : !== Apply the 1st-order non-local potential to the wavefunction
     468              : !======================================================================
     469              : 
     470              : !Use of gvnlx1 depends on usevnl
     471      8601471 :  if (usevnl==1) then
     472      4665741 :    gvnlx1_ => gvnlx1
     473              :  else
     474     11807190 :    ABI_MALLOC(gvnlx1_,(2,npw1*my_nspinor*ndat))
     475              :  end if
     476              :  if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) then
     477              : #ifdef HAVE_OPENMP_OFFLOAD
     478              :    map_gvnlx1_ =  .not. ( xomp_target_is_present(c_loc(gvnlx1_)))
     479              :    if(map_gvnlx1_) call ompgpu_enter_map_alloc(gvnlx1_,2*npw1*my_nspinor*ndat)
     480              :    !$OMP TARGET UPDATE TO(gvnlx1_) IF(usevnl==1 .and. gs_hamkq%gpu_option==ABI_GPU_OPENMP)
     481              : #endif
     482              :  end if
     483              : 
     484              : !Phonon perturbation
     485              : !-------------------------------------------
     486      8601471 :  if (ipert<=natom.and.(optnl>0.or.sij_opt/=0)) then
     487              : 
     488              :    ABI_NVTX_START_RANGE(NVTX_GETGH1_NLOCPOT)
     489              : 
     490              : !  PAW:
     491      6233393 :    if (gs_hamkq%usepaw==1) then
     492              : 
     493       608116 :      if (usecprj==1) then
     494       600436 :        cwaveprj_ptr => cwaveprj
     495              :      else
     496        53760 :        ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor*ndat))
     497         7680 :        call pawcprj_alloc(cwaveprj_tmp,1,gs_hamkq%dimcprj)
     498         7680 :        cwaveprj_ptr => cwaveprj_tmp
     499              :      end if
     500              : 
     501              : !    1- Compute derivatives due to projectors |p_i>^(1)
     502              : !    Only displaced atom contributes
     503       608116 :      cpopt=-1+5*usecprj ; choice=2 ; signs=2
     504       608116 :      paw_opt=1;if (sij_opt/=0) paw_opt=sij_opt+3
     505              :      call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,idir,lambda,mpi_enreg,ndat,nnlout,&
     506       608116 :                  paw_opt,signs,gs1c,tim_nonlop,cwave,gvnlx1_,iatom_only=ipert)
     507              : 
     508              : !    2- Compute derivatives due to frozen part of D_ij^(1) (independent of VHxc^(1))
     509              : !    All atoms contribute
     510       608116 :      if (optnl>=1) then
     511      1824348 :        ABI_MALLOC(nonlop_out,(2,npw1*my_nspinor*ndat))
     512              : #ifdef HAVE_OPENMP_OFFLOAD
     513              :        if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_enter_map_alloc(nonlop_out,2*npw1*my_nspinor*ndat)
     514              : #endif
     515       608116 :        cpopt=1+3*usecprj ; choice=1 ; signs=2 ; paw_opt=1
     516              :        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,idir,lambda,mpi_enreg,ndat,nnlout,&
     517       608116 :                    paw_opt,signs,svectout_dum,tim_nonlop,cwave,nonlop_out,enl=rf_hamkq%e1kbfr)
     518       608116 :        if(gs_hamkq%gpu_option/=ABI_GPU_OPENMP) then
     519              :          !$OMP PARALLEL DO
     520     77194050 :          do ipw=1,npw1*my_nspinor*ndat
     521    383537786 :            gvnlx1_(:,ipw)=gvnlx1_(:,ipw)+nonlop_out(:,ipw)
     522              :          end do
     523              :        else
     524            0 :          call abi_xaxpy(2*npw1*my_nspinor*ndat, cone, nonlop_out, 1, gvnlx1_, 1, x_cplx=1, gpu_option=gs_hamkq%gpu_option)
     525              :        end if
     526              : #ifdef HAVE_OPENMP_OFFLOAD
     527              :        if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_exit_map_delete(nonlop_out,2*npw1*my_nspinor*ndat)
     528              : #endif
     529       608116 :        ABI_FREE(nonlop_out)
     530              :      end if
     531              : 
     532              : !    3- Compute derivatives due to self-consistent part of D_ij^(1) (depending on VHxc^(1))
     533              : !    All atoms contribute
     534       608116 :      if (optnl==2) then
     535      1095480 :        ABI_MALLOC(gvnl2,(2,npw1*my_nspinor*ndat))
     536              : #ifdef HAVE_OPENMP_OFFLOAD
     537              :        if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_enter_map_alloc(gvnl2,2*npw1*my_nspinor*ndat)
     538              : #endif
     539       365160 :        cpopt=4 ; choice=1 ; signs=2 ; paw_opt=1
     540              :        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,idir,lambda,mpi_enreg,ndat,nnlout,&
     541       365160 :                    paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnl2,enl=rf_hamkq%e1kbsc)
     542              :      end if
     543              : 
     544       608116 :      if (usecprj==0) then
     545         7680 :        call pawcprj_free(cwaveprj_tmp)
     546        23040 :        ABI_FREE(cwaveprj_tmp)
     547              :      end if
     548       608116 :      nullify(cwaveprj_ptr)
     549              : 
     550              :    else
     551              :      ! Norm-conserving psps:
     552              :      ! Compute only derivatives due to projectors |p_i>^(1)
     553      5625277 :      cpopt=-1 ; choice=2 ; signs=2 ; paw_opt=0
     554              :      call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamkq,idir,lambda,mpi_enreg,ndat,nnlout,&
     555      5625277 :        paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnlx1_,iatom_only=ipert)
     556      5625277 :      if (sij_opt==1) then
     557            0 :        if(gs_hamkq%gpu_option/=ABI_GPU_OPENMP) then
     558              :          !$OMP PARALLEL DO
     559            0 :          do ipw=1,npw1*my_nspinor*ndat
     560            0 :            gs1c(:,ipw)=zero
     561              :          end do
     562              :        else
     563            0 :          call gpu_set_to_zero(gs1c,int(2,c_size_t)*npw1*my_nspinor*ndat)
     564              :        end if
     565              :      end if
     566              :    end if
     567              :    ABI_NVTX_END_RANGE()
     568              : 
     569              : !  k-point perturbation
     570              : !  -------------------------------------------
     571      2368078 :  else if (ipert==natom+1.and.(optnl>0.or.sij_opt/=0)) then
     572              : 
     573              :    ABI_NVTX_START_RANGE(NVTX_GETGH1_DDK)
     574              : 
     575      1437546 :    tim_nonlop=8 ; signs=2 ; choice=5
     576      1437546 :    if (gs_hamkq%usepaw==1) then
     577       258832 :      if (usecprj==1) then
     578       255376 :        cwaveprj_ptr => cwaveprj
     579              :      else
     580        24192 :        ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor*ndat))
     581         3456 :        call pawcprj_alloc(cwaveprj_tmp,1,gs_hamkq%dimcprj)
     582         3456 :        cwaveprj_ptr => cwaveprj_tmp
     583              :      end if
     584       258832 :      cpopt=-1+5*usecprj; paw_opt=1; if (sij_opt/=0) paw_opt=sij_opt+3
     585              : !    JLJ: BUG (wrong result) of H^(1) if stored cprj are used in PAW DDKs with nspinor==2 (==1 works fine).
     586              : !    To be debugged, if someone has time...
     587       258832 :      if(gs_hamkq%nspinor==2) cpopt=-1
     588       258832 :      if(associated(gs_hamkq%vectornd)) cpopt=-1
     589              :      call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,idir,lambda,mpi_enreg,ndat,nnlout,&
     590       258832 :                  paw_opt,signs,gs1c,tim_nonlop,cwave,gvnlx1_)
     591       258832 :      if (usecprj==0) then
     592         3456 :        call pawcprj_free(cwaveprj_tmp)
     593        10368 :        ABI_FREE(cwaveprj_tmp)
     594              :      end if
     595       258832 :      nullify(cwaveprj_ptr)
     596              :    else
     597      1178714 :      cpopt=-1 ; paw_opt=0
     598              :      call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamkq,idir,lambda,mpi_enreg,ndat,nnlout,&
     599      1178714 :                   paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnlx1_)
     600              :    end if
     601              : 
     602              :    ABI_NVTX_END_RANGE()
     603              : 
     604              : !DEBUG
     605              : !  gvnlx1_=zero
     606              : !ENDDEBUG
     607              : 
     608              : 
     609              : !  Electric field perturbation without Berry phase
     610              : !  -------------------------------------------
     611              :  else if (ipert==natom+2 .and. &
     612              :           (berryopt/=4 .and. berryopt/=6 .and. berryopt/=7 .and. &
     613      1441287 :           berryopt/=14 .and. berryopt/=16 .and. berryopt/=17) .and.(optnl>0.or.sij_opt/=0))then
     614              :    !  gvnlx1 was already initialized in the calling routine, by reading a ddk file. It contains |i du^(0)/dk_band>
     615              : 
     616              :    ABI_NVTX_START_RANGE(NVTX_GETGH1_DDE)
     617              : 
     618       510755 :    if (gs_hamkq%usepaw==1) then
     619       106864 :      if (usecprj==1) then
     620        89200 :        cwaveprj_ptr => cwaveprj
     621              :      else
     622       123648 :        ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor*ndat))
     623        17664 :        call pawcprj_alloc(cwaveprj_tmp,1,gs_hamkq%dimcprj)
     624        17664 :        cwaveprj_ptr => cwaveprj_tmp
     625              :      end if
     626       106864 :      if (opt_gvnlx1==2.and.optnl>=1) then
     627              : 
     628              :        ! PAW: Compute application of S^(0) to ddk WF
     629       106864 :        cpopt=-1 ; choice=1 ; paw_opt=3 ; signs=2
     630       320592 :        ABI_MALLOC(nonlop_out,(2,npw1*my_nspinor*ndat))
     631              : #ifdef HAVE_OPENMP_OFFLOAD
     632              :        if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_enter_map_alloc(nonlop_out,2*npw1*my_nspinor*ndat)
     633              : #endif
     634              :        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,0,lambda,mpi_enreg,ndat,nnlout,&
     635       106864 :                    paw_opt,signs,nonlop_out,tim_nonlop,gvnlx1_,vectout_dum)
     636       106864 :        if(gs_hamkq%gpu_option/=ABI_GPU_OPENMP) then
     637              :          !$OMP PARALLEL DO
     638     15681444 :          do ipw=1,npw1*my_nspinor*ndat
     639     77979764 :            gvnlx1_(:,ipw)=nonlop_out(:,ipw)
     640              :          end do
     641              :        else
     642              : #ifdef HAVE_OPENMP_OFFLOAD
     643              :          call gpu_copy(gvnlx1_, nonlop_out, int(2,c_size_t)*npw1*my_nspinor*ndat)
     644              : #endif
     645              :        end if
     646              : 
     647              : !      PAW: Compute part of H^(1) due to derivative of S
     648       106864 :        cpopt=4*usecprj ; choice=51 ; paw_opt=3 ; signs=2
     649              :        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,idir,lambda,mpi_enreg,ndat,nnlout,&
     650       106864 :                     paw_opt,signs,nonlop_out,tim_nonlop,cwave,vectout_dum)
     651              : 
     652       106864 :        if (gs_hamkq%gpu_option/=ABI_GPU_OPENMP) then
     653       106864 :          if(compute_conjugate) then
     654              :            !$OMP PARALLEL DO
     655            0 :            do ipw=1,npw1*my_nspinor*ndat ! Note the multiplication by -i
     656            0 :              gvnlx1_(1,ipw)=gvnlx1_(1,ipw)+nonlop_out(2,ipw)
     657            0 :              gvnlx1_(2,ipw)=gvnlx1_(2,ipw)-nonlop_out(1,ipw)
     658              :            end do
     659              :          else
     660              :            !$OMP PARALLEL DO
     661     15681444 :            do ipw=1,npw1*my_nspinor*ndat ! Note the multiplication by i
     662     15574580 :              gvnlx1_(1,ipw)=gvnlx1_(1,ipw)-nonlop_out(2,ipw)
     663     15681444 :              gvnlx1_(2,ipw)=gvnlx1_(2,ipw)+nonlop_out(1,ipw)
     664              :            end do
     665              :          end if
     666              :        else
     667              : #ifdef HAVE_OPENMP_OFFLOAD
     668              :          if(compute_conjugate) then
     669              : #ifdef HAVE_OPENMP_OFFLOAD
     670              :            !$OMP TARGET PARALLEL DO MAP(to:gvnlx1_,nonlop_out)
     671              :            do ipw=1,npw1*my_nspinor*ndat ! Note the multiplication by -i
     672              :              gvnlx1_(1,ipw)=gvnlx1_(1,ipw)+nonlop_out(2,ipw)
     673              :              gvnlx1_(2,ipw)=gvnlx1_(2,ipw)-nonlop_out(1,ipw)
     674              :            end do
     675              : #endif
     676              :          else
     677              : #ifdef HAVE_OPENMP_OFFLOAD
     678              :            !$OMP TARGET PARALLEL DO MAP(to:gvnlx1_,nonlop_out)
     679              :            do ipw=1,npw1*my_nspinor*ndat ! Note the multiplication by i
     680              :              gvnlx1_(1,ipw)=gvnlx1_(1,ipw)-nonlop_out(2,ipw)
     681              :              gvnlx1_(2,ipw)=gvnlx1_(2,ipw)+nonlop_out(1,ipw)
     682              :            end do
     683              : #endif
     684              :          end if
     685              : #endif
     686              :        end if
     687              : 
     688              :        ! PAW: Compute part of H^(1) due to derivative of electric field part of Dij
     689       106864 :        cpopt=2 ; choice=1 ; paw_opt=1 ; signs=2
     690              :        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,0,lambda,mpi_enreg,ndat,nnlout,&
     691       106864 :                    paw_opt,signs,svectout_dum,tim_nonlop,cwave,nonlop_out,enl=rf_hamkq%e1kbfr)
     692              : 
     693       106864 :        if(gs_hamkq%gpu_option/=ABI_GPU_OPENMP) then
     694              :          !$OMP PARALLEL DO
     695     15681444 :          do ipw=1,npw1*my_nspinor*ndat
     696     77979764 :            gvnlx1_(:,ipw)=gvnlx1_(:,ipw)+nonlop_out(:,ipw)
     697              :          end do
     698              :        else
     699              :          call abi_xaxpy(2*npw1*my_nspinor*ndat, cone, &
     700            0 :          &    nonlop_out, 1, gvnlx1_, 1, x_cplx=1, gpu_option=gs_hamkq%gpu_option)
     701              :        end if
     702              : #ifdef HAVE_OPENMP_OFFLOAD
     703              :        if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_exit_map_delete(nonlop_out,2*npw1*my_nspinor*ndat)
     704              : #endif
     705       106864 :        ABI_FREE(nonlop_out)
     706              : 
     707              :      end if ! opt_gvnlx1==2
     708              : 
     709              : !    PAW: Compute derivatives due to part of D_ij^(1) depending on VHxc^(1)
     710       106864 :      if (optnl>=2) then
     711       229728 :        ABI_MALLOC(gvnl2,(2,npw1*my_nspinor*ndat))
     712              : #ifdef HAVE_OPENMP_OFFLOAD
     713              :        if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_enter_map_alloc(gvnl2,2*npw1*my_nspinor*ndat)
     714              : #endif
     715        76576 :        cpopt=-1+3*usecprj;if (opt_gvnlx1==2) cpopt=2
     716        76576 :        choice=1 ; paw_opt=1 ; signs=2
     717              :        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,0,lambda,mpi_enreg,ndat,nnlout,&
     718        76576 :                    paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnl2,enl=rf_hamkq%e1kbsc)
     719              :      end if
     720              : 
     721       106864 :      if (sij_opt==1) then
     722        76576 :        if(gs_hamkq%gpu_option/=ABI_GPU_OPENMP) then
     723              :          !$OMP PARALLEL DO
     724      9716880 :          do ipw=1,npw1*my_nspinor*ndat
     725     28997488 :            gs1c(:,ipw)=zero
     726              :          end do
     727              :        else
     728            0 :          call gpu_set_to_zero(gs1c,int(2,c_size_t)*npw1*my_nspinor*ndat)
     729              :        end if
     730              :      end if
     731       106864 :      if (usecprj==0) then
     732        17664 :        call pawcprj_free(cwaveprj_tmp)
     733        52992 :        ABI_FREE(cwaveprj_tmp)
     734              :      end if
     735       106864 :      nullify(cwaveprj_ptr)
     736              :    end if  ! PAW
     737              : 
     738              :    ABI_NVTX_END_RANGE()
     739              : 
     740              : !  Electric field perturbation with Berry phase
     741              : !  -------------------------------------------
     742              :  else if (ipert==natom+2 .and. &
     743              :          (berryopt==4 .or. berryopt==6 .or. berryopt==7 .or. &
     744       419777 :          berryopt==14 .or. berryopt==16 .or. berryopt==17 ) .and.(optnl>0.or.sij_opt/=0))then
     745              : 
     746         1152 :    if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) then
     747            0 :      ABI_BUG("Not implemented for OpenMP GPU (gs_hamkq%gpu_option==2)")
     748              :    end if
     749         1152 :    if (optnl>=1) then
     750        48960 :      do ipw=1,npw1*my_nspinor*ndat
     751        47808 :        gvnlx1_(1,ipw)=-grad_berry(2,ipw)
     752        48960 :        gvnlx1_(2,ipw)= grad_berry(1,ipw)
     753              :      end do
     754              :    end if
     755         1152 :    if (sij_opt==1) then
     756            0 :      ABI_BUG("toto")
     757              : !$OMP PARALLEL DO
     758            0 :      do ipw=1,npw1*my_nspinor*ndat
     759            0 :        gs1c(:,ipw)=zero
     760              :      end do
     761              :    end if
     762              : 
     763              : !  Strain perturbation
     764              : !  -------------------------------------------
     765       418625 :  else if ((ipert==natom+3.or.ipert==natom+4).and.(optnl>0.or.sij_opt/=0)) then
     766              : 
     767              :    ABI_NVTX_START_RANGE(NVTX_GETGH1_STRAIN)
     768              : 
     769       371953 :    istr=idir;if(ipert==natom+4) istr=istr+3
     770              : 
     771              :    ! PAW:
     772       371953 :    if (gs_hamkq%usepaw==1) then
     773              : 
     774        62964 :      if (usecprj==1) then
     775        62964 :        cwaveprj_ptr => cwaveprj
     776              :      else
     777            0 :        ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor*ndat))
     778            0 :        call pawcprj_alloc(cwaveprj_tmp,1,gs_hamkq%dimcprj)
     779            0 :        cwaveprj_ptr => cwaveprj_tmp
     780              :      end if
     781              : 
     782              :      ! 1- Compute derivatives due to projectors |p_i>^(1) All atoms contribute
     783        62964 :      cpopt=-1+5*usecprj ; choice=3 ; signs=2
     784        62964 :      paw_opt=1;if (sij_opt/=0) paw_opt=sij_opt+3
     785              :      call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,istr,lambda,mpi_enreg,ndat,nnlout,&
     786        62964 :                  paw_opt,signs,gs1c,tim_nonlop,cwave,gvnlx1_)
     787              : 
     788              :      ! 2- Compute derivatives due to frozen part of D_ij^(1) (independent of VHxc^(1)). All atoms contribute
     789        62964 :      if (optnl>=1) then
     790       188892 :        ABI_MALLOC(nonlop_out,(2,npw1*my_nspinor*ndat))
     791              : #ifdef HAVE_OPENMP_OFFLOAD
     792              :        if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_enter_map_alloc(nonlop_out,2*npw1*my_nspinor*ndat)
     793              : #endif
     794        62964 :        cpopt=1+3*usecprj ; choice=1 ; signs=2 ; paw_opt=1
     795              :        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,istr,lambda,mpi_enreg,ndat,nnlout,&
     796        62964 :                     paw_opt,signs,svectout_dum,tim_nonlop,cwave,nonlop_out,enl=rf_hamkq%e1kbfr)
     797        62964 :        if(gs_hamkq%gpu_option/=ABI_GPU_OPENMP) then
     798              :          !$OMP PARALLEL DO
     799     19198804 :          do ipw=1,npw1*my_nspinor*ndat
     800     95742164 :            gvnlx1_(:,ipw)=gvnlx1_(:,ipw)+nonlop_out(:,ipw)
     801              :          end do
     802              :        else
     803            0 :          call abi_xaxpy(2*npw1*my_nspinor*ndat, cone, nonlop_out, 1, gvnlx1_, 1, x_cplx=1, gpu_option=gs_hamkq%gpu_option)
     804              :        end if
     805              : #ifdef HAVE_OPENMP_OFFLOAD
     806              :        if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_exit_map_delete(nonlop_out,2*npw1*my_nspinor*ndat)
     807              : #endif
     808        62964 :        ABI_FREE(nonlop_out)
     809              :      end if
     810              : 
     811              :      ! 3- Compute derivatives due to part of D_ij^(1) depending on VHxc^(1). All atoms contribute
     812        62964 :      if (optnl>=2) then
     813        73512 :        ABI_MALLOC(gvnl2,(2,npw1*my_nspinor*ndat))
     814              : #ifdef HAVE_OPENMP_OFFLOAD
     815              :        if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_enter_map_alloc(gvnl2,2*npw1*my_nspinor*ndat)
     816              : #endif
     817        24504 :        cpopt=4 ; choice=1 ; signs=2 ; paw_opt=1
     818              :        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,istr,lambda,mpi_enreg,ndat,nnlout,&
     819        24504 :                    paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnl2,enl=rf_hamkq%e1kbsc)
     820              :      end if
     821              : 
     822        62964 :      if (usecprj==0) then
     823            0 :        call pawcprj_free(cwaveprj_tmp)
     824            0 :        ABI_FREE(cwaveprj_tmp)
     825              :      end if
     826        62964 :      nullify(cwaveprj_ptr)
     827              : 
     828              :    else
     829              :      ! Norm-conserving psps:
     830              :      ! Compute only derivatives due to projectors |p_i>^(1)
     831       308989 :      choice=3 ; cpopt=-1 ; signs=2 ; paw_opt=0
     832              :      call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamkq,istr,(/lambda/),mpi_enreg,ndat,nnlout,&
     833       926967 :                  paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnlx1_)
     834       308989 :      if (sij_opt==1) then
     835            0 :        if(gs_hamkq%gpu_option/=ABI_GPU_OPENMP) then
     836              :          !$OMP PARALLEL DO
     837            0 :          do ipw=1,npw1*my_nspinor*ndat
     838            0 :            gs1c(:,ipw)=zero
     839              :          end do
     840              :        else
     841            0 :          call gpu_set_to_zero(gs1c,int(2,c_size_t)*npw1*my_nspinor*ndat)
     842              :        end if
     843              :      end if
     844              :    end if
     845              : 
     846              :    ABI_NVTX_END_RANGE()
     847              : 
     848              : !  No non-local part
     849              : !  -------------------------------------------
     850        46672 :  else if (usevnl>0.or.(sij_opt/=0)) then
     851              : 
     852        46488 :    if (optnl>=1) then
     853        46488 :      if(gs_hamkq%gpu_option/=ABI_GPU_OPENMP) then
     854              :        !$OMP PARALLEL DO
     855     22046312 :        do ipw=1,npw1*my_nspinor*ndat
     856     66045960 :          gvnlx1_(:,ipw)=zero
     857              :        end do
     858              :      else
     859            0 :        call gpu_set_to_zero(gvnlx1_,int(2,c_size_t)*npw1*my_nspinor*ndat)
     860              :      end if
     861              :    end if
     862        46488 :    if (sij_opt/=0) then
     863            0 :      if(gs_hamkq%gpu_option/=ABI_GPU_OPENMP) then
     864              :        !$OMP PARALLEL DO
     865            0 :        do ipw=1,npw1*my_nspinor*ndat
     866            0 :          gs1c(:,ipw)=zero
     867              :        end do
     868              :      else
     869            0 :        call gpu_set_to_zero(gs1c,int(2,c_size_t)*npw1*my_nspinor*ndat)
     870              :      end if
     871              :    end if
     872              : 
     873              :  end if
     874              : 
     875              : !======================================================================
     876              : !== Apply the 1st-order kinetic operator to the wavefunction
     877              : !== (add it to nl contribution)
     878              : !======================================================================
     879              : 
     880              : !Phonon perturbation or Electric field perturbation
     881              : !-------------------------------------------
     882              : !No kinetic contribution
     883              : 
     884              : !k-point perturbation or Strain perturbation
     885              : !-------------------------------------------
     886              : 
     887      8601471 :  usevnl2=allocated(gvnl2)
     888      8601471 :  has_kin=(ipert==natom+1.or.ipert==natom+3.or.ipert==natom+4)
     889      8601471 :  if (associated(gs_hamkq%kinpw_kp)) then
     890      8601471 :    kinpw1 => gs_hamkq%kinpw_kp
     891            0 :  else if (optnl>=1.or.usevnl2.or.has_kin) then
     892            0 :    ABI_BUG('need kinpw1 allocated!')
     893              :  end if
     894      8601471 :  if (associated(rf_hamkq%dkinpw_k)) then
     895      5622552 :    dkinpw => rf_hamkq%dkinpw_k
     896      2978919 :  else if (has_kin) then
     897            0 :    ABI_BUG('need dkinpw allocated!')
     898              :  end if
     899              : 
     900      5622552 :  if (has_kin) then
     901              : !  Remember that npw=npw1 for ddk perturbation
     902              : #ifdef HAVE_OPENMP_OFFLOAD
     903              :    !$OMP TARGET TEAMS DISTRIBUTE PRIVATE(ipws) MAP(to:cwave,gvnlx1_,dkinpw,kinpw1) &
     904              :    !$OMP&  IF(gs_hamkq%gpu_option==ABI_GPU_OPENMP)
     905              : #endif
     906      3677174 :    do ispinor=1,my_nspinor*ndat
     907              :      !$OMP PARALLEL DO PRIVATE(ipw,ipws)
     908    271039572 :      do ipw=1,npw
     909    267362398 :        ipws=ipw+npw*(ispinor-1)
     910    269230073 :        if(kinpw1(ipw)<threshold)then
     911    267362398 :          gvnlx1_(1,ipws)=gvnlx1_(1,ipws)+dkinpw(ipw)*cwave(1,ipws)
     912    267362398 :          gvnlx1_(2,ipws)=gvnlx1_(2,ipws)+dkinpw(ipw)*cwave(2,ipws)
     913              :        else
     914            0 :          gvnlx1_(1,ipws)=zero
     915            0 :          gvnlx1_(2,ipws)=zero
     916              :        end if
     917              :      end do
     918              :    end do
     919              :  end if
     920              : 
     921              : !======================================================================
     922              : !== Apply the 1st-order nuclear dipole operator to the wavefunction
     923              : !== Only coded for DDK
     924              : !== (add it to nl contribution)
     925              : !======================================================================
     926              : 
     927      8601471 :  has_nd1=( (ipert .EQ. natom+1) .AND. ASSOCIATED(rf_hamkq%vectornd) )
     928              : 
     929              :  if (has_nd1) then
     930       378864 :    ABI_MALLOC(gh1ndc,(2,npw*my_nspinor*ndat))
     931              : #ifdef HAVE_OPENMP_OFFLOAD
     932              :    if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_enter_map_alloc(gh1ndc,2*npw*my_nspinor*ndat)
     933              : #endif
     934              :    call getgh1ndc(cwave,gh1ndc,gs_hamkq%gbound_k,gs_hamkq%istwf_k,gs_hamkq%kg_k,&
     935              :      & gs_hamkq%mgfft,mpi_enreg,ndat,gs_hamkq%ngfft,npw,gs_hamkq%nvloc,&
     936              :      & gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,my_nspinor,rf_hamkq%vectornd,&
     937       126288 :      & gs_hamkq%vlocal,rf_hamkq%zora,gs_hamkq%gpu_option)
     938              : #ifdef HAVE_OPENMP_OFFLOAD
     939              :    !$OMP TARGET TEAMS DISTRIBUTE &
     940              :    !$OMP& MAP(to:gvnlx1_,gh1ndc) PRIVATE(ispinor) &
     941              :    !$OMP& IF(gs_hamkq%gpu_option==ABI_GPU_OPENMP)
     942              : #endif
     943       285600 :    do ispinor=1,my_nspinor*ndat
     944              :      !$OMP PARALLEL DO PRIVATE(ipw,ipws)
     945     26845944 :      do ipw=1,npw
     946     26560344 :        ipws=ipw+npw*(ispinor-1)
     947     26560344 :        gvnlx1_(1,ipws)=gvnlx1_(1,ipws)+gh1ndc(1,ipws)
     948     26719656 :        gvnlx1_(2,ipws)=gvnlx1_(2,ipws)+gh1ndc(2,ipws)
     949              :      end do
     950              :    end do
     951              : #ifdef HAVE_OPENMP_OFFLOAD
     952              :    if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_exit_map_delete(gh1ndc,2*npw*my_nspinor*ndat)
     953              : #endif
     954       126288 :    ABI_FREE(gh1ndc)
     955              :  end if
     956              : 
     957              : !======================================================================
     958              : !== Apply the 1st-order mGGA operator to the wavefunction
     959              : !== Only coded for DDK
     960              : !== (add it to nl contribution)
     961              : !======================================================================
     962              : 
     963      8601471 :  has_mGGA1=( (ipert .EQ. natom+1) .AND. ASSOCIATED(rf_hamkq%vxctaulocal) )
     964              : 
     965              :  if (has_mGGA1) then
     966        34560 :    ABI_MALLOC(gh1c_mGGA,(2,npw*my_nspinor*ndat))
     967              : #ifdef HAVE_OPENMP_OFFLOAD
     968              :    !$OMP TARGET UPDATE FROM(cwave) IF(gs_hamkq%gpu_option==ABI_GPU_OPENMP)
     969              : #endif
     970              :    call getgh1c_mGGA(cwave,gs_hamkq%gbound_k,gh1c_mGGA,gs_hamkq%gmet,gs_hamkq%gprimd,idir,gs_hamkq%istwf_k,&
     971              :                      gs_hamkq%kg_k,gs_hamkq%kpt_k,gs_hamkq%mgfft,mpi_enreg,my_nspinor,gs_hamkq%n4,gs_hamkq%n5,&
     972              :                      gs_hamkq%n6,ndat,gs_hamkq%ngfft,npw,gs_hamkq%nvloc,rf_hamkq%vxctaulocal,&
     973        11520 :                      gpu_option=gs_hamkq%gpu_option)
     974              : #ifdef HAVE_OPENMP_OFFLOAD
     975              :    !$OMP TARGET TEAMS DISTRIBUTE &
     976              :    !$OMP& MAP(to:gvnlx1_,gh1c_mGGA) PRIVATE(ispinor) &
     977              :    !$OMP& IF(gs_hamkq%gpu_option==ABI_GPU_OPENMP)
     978              : #endif
     979        30720 :    do ispinor=1,my_nspinor*ndat
     980              :      !$OMP PARALLEL DO PRIVATE(ipw,ipws)
     981      2838720 :      do ipw=1,npw
     982      2808000 :        ipws=ipw+npw*(ispinor-1)
     983      2808000 :        gvnlx1_(1,ipws)=gvnlx1_(1,ipws)+gh1c_mGGA(1,ipws)
     984      2827200 :        gvnlx1_(2,ipws)=gvnlx1_(2,ipws)+gh1c_mGGA(2,ipws)
     985              :      end do
     986              :    end do
     987        11520 :    ABI_FREE(gh1c_mGGA)
     988              :  end if
     989              : 
     990              : !======================================================================
     991              : !== Sum contributions to get the application of H^(1) to the wf
     992              : !======================================================================
     993              : !Also filter the wavefunctions for large modified kinetic energy
     994              : 
     995              : !Add non-local+kinetic to local part
     996      8601471 :  if (optnl>=1.or.has_kin) then
     997              : #ifdef HAVE_OPENMP_OFFLOAD
     998              :    !$OMP TARGET TEAMS DISTRIBUTE PRIVATE(ipws) MAP(to:gh1c,gvnlx1_,kinpw1) &
     999              :    !$OMP&  IF(gs_hamkq%gpu_option==ABI_GPU_OPENMP)
    1000              : #endif
    1001     17812980 :    do ispinor=1,my_nspinor*ndat
    1002      9211693 :      ipws=(ispinor-1)*npw1
    1003              :      !$OMP PARALLEL DO PRIVATE(ipw)
    1004   2535750305 :      do ipw=1+ipws,npw1+ipws
    1005   2527148834 :        if(kinpw1(ipw-ipws)<threshold)then
    1006   2517937141 :          gh1c(1,ipw)=gh1c(1,ipw)+gvnlx1_(1,ipw)
    1007   2517937141 :          gh1c(2,ipw)=gh1c(2,ipw)+gvnlx1_(2,ipw)
    1008              :        else
    1009            0 :          gh1c(1,ipw)=zero
    1010            0 :          gh1c(2,ipw)=zero
    1011              :        end if
    1012              :      end do
    1013              :    end do
    1014              :  end if
    1015              : 
    1016              : !PAW: add non-local part due to first order change of VHxc
    1017      8601471 :  if (usevnl2) then
    1018              : #ifdef HAVE_OPENMP_OFFLOAD
    1019              :    !$OMP TARGET TEAMS DISTRIBUTE PRIVATE(ipws) MAP(to:gh1c,gvnl2,kinpw1) &
    1020              :    !$OMP&  IF(gs_hamkq%gpu_option==ABI_GPU_OPENMP)
    1021              : #endif
    1022       932480 :    do ispinor=1,my_nspinor*ndat
    1023       466240 :      ipws=(ispinor-1)*npw1
    1024              :      !$OMP PARALLEL DO PRIVATE(ipw)
    1025     57029528 :      do ipw=1+ipws,npw1+ipws
    1026     56563288 :        if(kinpw1(ipw-ipws)<threshold)then
    1027     56097048 :          gh1c(1,ipw)=gh1c(1,ipw)+gvnl2(1,ipw)
    1028     56097048 :          gh1c(2,ipw)=gh1c(2,ipw)+gvnl2(2,ipw)
    1029              :        end if
    1030              :      end do
    1031              :    end do
    1032              : #ifdef HAVE_OPENMP_OFFLOAD
    1033              :    if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) call ompgpu_exit_map_delete(gvnl2,2*npw1*my_nspinor*ndat)
    1034              : #endif
    1035       466240 :    ABI_FREE(gvnl2)
    1036              :  end if
    1037              : 
    1038              : #ifdef HAVE_OPENMP_OFFLOAD
    1039              :  if(gs_hamkq%gpu_option==ABI_GPU_OPENMP) then
    1040              :    !$OMP TARGET EXIT DATA MAP(from:gh1c)  IF(map_gh1c)
    1041              :    !$OMP TARGET EXIT DATA MAP(from:gs1c)  IF(map_gs1c)
    1042              :    !$OMP TARGET EXIT DATA MAP(from:cwave) IF(map_cwave)
    1043              :    !$OMP TARGET UPDATE FROM(gvnlx1_) IF(usevnl==1 .and. gs_hamkq%gpu_option==ABI_GPU_OPENMP)
    1044              :    if(map_gvnlx1_) call ompgpu_exit_map_delete(gvnlx1_,2*npw1*my_nspinor*ndat)
    1045              :  end if
    1046              : #endif
    1047      8601471 :  if (usevnl==1) then
    1048      4665741 :    nullify(gvnlx1_)
    1049              :  else
    1050      3935730 :    ABI_FREE(gvnlx1_)
    1051              :  end if
    1052              : 
    1053              :  ABI_NVTX_END_RANGE()
    1054              : 
    1055      8601471 :  call timab(196+tim_getgh1c,2,tsec)
    1056              : 
    1057              :  DBG_EXIT("COLL")
    1058              : 
    1059              : !NOTE: These subroutines were placed here because NVHPC would cause issues when
    1060              : !      processing OpenMP directives below by creating artifacts :
    1061              : !293, Generating target enter data map(to: kinpw1$sd50(:))
    1062              : !     Generating target enter data map(create: work(:,:,:,:))
    1063              : !     Generating target enter data map(to: cwave$sd(:),dkinpw$sd46(:),gvnlx1_$sd(:))
    1064              : !
    1065              : !     Tested with NVHPC 24.3
    1066              : !     Issues occurred with arrays: work, gvnlx1, gvnl2, nonlop_out
    1067              : !     The name 'getgh1c_array' is for debugging purposes.
    1068              : 
    1069              : #ifdef HAVE_OPENMP_OFFLOAD
    1070              :  contains
    1071              :    subroutine ompgpu_enter_map_alloc(getgh1c_array,size)
    1072              :     integer,intent(in)  :: size
    1073              :     real(dp),intent(inout) :: getgh1c_array(size)
    1074              :     !$OMP TARGET ENTER DATA MAP(alloc:getgh1c_array)
    1075              :    end subroutine ompgpu_enter_map_alloc
    1076              : 
    1077              :    subroutine ompgpu_exit_map_delete(getgh1c_array,size)
    1078              :     integer,intent(in)  :: size
    1079              :     real(dp),intent(inout) :: getgh1c_array(size)
    1080              :     !$OMP TARGET EXIT DATA MAP(delete:getgh1c_array)
    1081              :    end subroutine ompgpu_exit_map_delete
    1082              : 
    1083              : #endif
    1084              : 
    1085     17202942 : end subroutine getgh1c
    1086              : !!***
    1087              : 
    1088              : !----------------------------------------------------------------------
    1089              : 
    1090              : !!****f* m_hamiltonian/rf_transgrid_and_pack
    1091              : !! NAME
    1092              : !!  rf_transgrid_and_pack
    1093              : !!
    1094              : !! FUNCTION
    1095              : !! Set up local potential vlocal1 with proper dimensioning, from vtrial1
    1096              : !! taking into account the spin. Same thing for vlocal from vtrial.
    1097              : !!
    1098              : !! INPUTS
    1099              : !!  isppol=Spin index.
    1100              : !!  nspden=Number of density components
    1101              : !!  usepaw=1 if PAW, 0 for NC.
    1102              : !!  cplex=1 if DFPT potential is real, 2 for complex
    1103              : !!  nfftf=Number of FFT points on the FINE grid treated by this processor
    1104              : !!  nfft=Number of FFT points on the COARSE grid treated by this processor
    1105              : !!  ngfft(18)=Info on the coarse grid.
    1106              : !!  pawfgr <type(pawfgr_type)>=fine grid parameters and related data
    1107              : !!  mpi_enreg=information about MPI parallelization
    1108              : !!  vtrial(nfftf,nspden)=GS Vtrial(r) on the DENSE mesh
    1109              : !!  vtrial1(cplex*nfftf,nspden)=INPUT RF Vtrial(r) on the DENSE mesh
    1110              : !!
    1111              : !! OUTPUT
    1112              : !!  vlocal(n4,n5,n6,nvloc)= GS local potential in real space, on the augmented coarse fft grid
    1113              : !!  vlocal1(cplex*n4,n5,n6,nvloc)= RF local potential in real space, on the augmented coarse fft grid
    1114              : !!
    1115              : !! SOURCE
    1116              : 
    1117       385929 : subroutine rf_transgrid_and_pack(isppol,nspden,usepaw,cplex,nfftf,nfft,ngfft,nvloc,&
    1118       385929 : &                                pawfgr,mpi_enreg,vtrial,vtrial1,vlocal,vlocal1)
    1119              : 
    1120              : !Arguments ------------------------------------
    1121              : !scalars
    1122              :  integer,intent(in) :: isppol,nspden,usepaw,cplex,nfftf,nfft,nvloc
    1123              :  type(pawfgr_type),intent(in) :: pawfgr
    1124              :  type(MPI_type),intent(in) :: mpi_enreg
    1125              : !arrays
    1126              :  integer,intent(in) :: ngfft(18)
    1127              :  real(dp),intent(in),target :: vtrial(nfftf,nspden)
    1128              :  real(dp),intent(inout),target :: vtrial1(cplex*nfftf,nspden)
    1129              :  real(dp),intent(out) :: vlocal(ngfft(4),ngfft(5),ngfft(6),nvloc)
    1130              :  real(dp),intent(out) :: vlocal1(cplex*ngfft(4),ngfft(5),ngfft(6),nvloc)
    1131              : 
    1132              : !Local variables-------------------------------
    1133              : !scalars
    1134              :  integer :: n1,n2,n3,n4,n5,n6,paral_kgb,ispden
    1135              : !arrays
    1136              :  real(dp) :: rhodum(1) !, tsec(2)
    1137       385929 :  real(dp), contiguous, pointer :: vtrial_ptr(:,:),vtrial1_ptr(:,:)
    1138       385929 :  real(dp),allocatable :: cgrvtrial(:,:),cgrvtrial1(:,:),vlocal_tmp(:,:,:),vlocal1_tmp(:,:,:)
    1139              : ! *************************************************************************
    1140              : 
    1141       385929 :  n1=ngfft(1); n2=ngfft(2); n3=ngfft(3)
    1142       385929 :  n4=ngfft(4); n5=ngfft(5); n6=ngfft(6)
    1143       385929 :  paral_kgb = mpi_enreg%paral_kgb
    1144              : 
    1145       385929 :  if (nspden/=4) then
    1146       385634 :    vtrial_ptr => vtrial
    1147       385634 :    if (usepaw==0.or.pawfgr%usefinegrid==0) then
    1148       382671 :      call fftpac(isppol,mpi_enreg,nspden,n1,n2,n3,n4,n5,n6,ngfft,vtrial_ptr,vlocal(:,:,:,1),2)
    1149       382671 :      call fftpac(isppol,mpi_enreg,nspden,cplex*n1,n2,n3,cplex*n4,n5,n6,ngfft,vtrial1,vlocal1(:,:,:,1),2)
    1150              :    else
    1151        11852 :      ABI_MALLOC(cgrvtrial,(nfft,nspden))
    1152         2963 :      call transgrid(1,mpi_enreg,nspden,-1,0,0,paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vtrial_ptr)
    1153         2963 :      call fftpac(isppol,mpi_enreg,nspden,n1,n2,n3,n4,n5,n6,ngfft,cgrvtrial,vlocal(:,:,:,1),2)
    1154        11852 :      ABI_REMALLOC(cgrvtrial, (cplex*nfft, nspden))
    1155         2963 :      call transgrid(cplex,mpi_enreg,nspden,-1,0,0,paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vtrial1)
    1156         2963 :      call fftpac(isppol,mpi_enreg,nspden,cplex*n1,n2,n3,cplex*n4,n5,n6,ngfft,cgrvtrial,vlocal1(:,:,:,1),2)
    1157         2963 :      ABI_FREE(cgrvtrial)
    1158              :    end if
    1159       385929 :    nullify(vtrial_ptr)
    1160              :  else
    1161              :    ! nspden==4 non-collinear magnetism
    1162          295 :    vtrial_ptr => vtrial
    1163          295 :    vtrial1_ptr => vtrial1
    1164         1475 :    ABI_MALLOC(vlocal_tmp,(n4,n5,n6))
    1165         1475 :    ABI_MALLOC(vlocal1_tmp,(cplex*n4,n5,n6))
    1166          295 :    if (usepaw==0.or.pawfgr%usefinegrid==0) then
    1167         1475 :      do ispden=1,nspden
    1168         1180 :        call fftpac(ispden,mpi_enreg,nspden,n1,n2,n3,n4,n5,n6,ngfft,vtrial_ptr,vlocal_tmp,2)
    1169      8572372 :        vlocal(:,:,:,ispden)=vlocal_tmp(:,:,:)
    1170         1180 :        call fftpac(ispden,mpi_enreg,nspden,cplex*n1,n2,n3,cplex*n4,n5,n6,ngfft,vtrial1_ptr,vlocal1_tmp,2)
    1171     13762427 :        vlocal1(:,:,:,ispden)=vlocal1_tmp(:,:,:)
    1172              :      end do
    1173              :    else
    1174              :      ! TODO FR EB check the correctness of the following lines for PAW calculations
    1175            0 :      ABI_MALLOC(cgrvtrial,(nfft,nspden))
    1176            0 :      ABI_MALLOC(cgrvtrial1,(nfft,nspden))
    1177            0 :      call transgrid(cplex,mpi_enreg,nspden,-1,0,0,paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vtrial_ptr)
    1178            0 :      call transgrid(cplex,mpi_enreg,nspden,-1,0,0,paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial1,vtrial1_ptr)
    1179            0 :      do ispden=1,nspden
    1180            0 :        call fftpac(ispden,mpi_enreg,nspden,n1,n2,n3,n4,n5,n6,ngfft,vtrial_ptr,vlocal_tmp,2)
    1181            0 :        vlocal(:,:,:,ispden)=vlocal_tmp(:,:,:)
    1182            0 :        call fftpac(ispden,mpi_enreg,nspden,n1,n2,n3,n4,n5,n6,ngfft,vtrial1_ptr,vlocal1_tmp,2)
    1183            0 :        vlocal1(:,:,:,ispden)=vlocal1_tmp(:,:,:)
    1184              :      end do
    1185            0 :      ABI_FREE(cgrvtrial)
    1186              :    end if
    1187          295 :    ABI_FREE(vlocal_tmp)
    1188          295 :    ABI_FREE(vlocal1_tmp)
    1189              :  end if ! nspden
    1190              : 
    1191       771858 : end subroutine rf_transgrid_and_pack
    1192              : !!***
    1193              : 
    1194              : !----------------------------------------------------------------------
    1195              : 
    1196              : !!****f* m_hamiltonian/getgh1c_setup
    1197              : !! NAME
    1198              : !!  getgh1c_setup
    1199              : !!
    1200              : !! FUNCTION
    1201              : !!
    1202              : !! INPUTS
    1203              : !!
    1204              : !! OUTPUT
    1205              : !!
    1206              : !! SOURCE
    1207              : 
    1208       916828 : subroutine getgh1c_setup(gs_hamkq, rf_hamkq, dtset, psps, kpoint, kpq, idir, ipert,&              ! In
    1209              :                          natom, rmet, gprimd, gmet, istwf_k, npw_k, npw1_k, &                     ! In
    1210       916828 :                          useylmgr1, kg_k, ylm_k, kg1_k, ylm1_k, ylmgr1_k, &                       ! In
    1211              :                          dkinpw, nkpg, nkpg1, kpg_k, kpg1_k, kinpw1, ffnlk, ffnl1, ph3d, ph3d1,&  ! Out
    1212              :                          ddkinpw, dkinpw2, rf_hamk_dir2, ffnl1_test, &                            ! Optional
    1213              :                          reuse_kpg_k, reuse_kpg1_k, reuse_ffnlk, reuse_ffnl1)                     ! Optional
    1214              : 
    1215              : !Arguments ------------------------------------
    1216              : !scalars
    1217              :  integer,intent(in) :: idir,ipert,istwf_k,npw_k,npw1_k,natom,useylmgr1
    1218              :  integer,intent(out) :: nkpg,nkpg1
    1219              :  type(gs_hamiltonian_type),intent(inout) :: gs_hamkq
    1220              :  type(rf_hamiltonian_type),intent(inout) :: rf_hamkq
    1221              :  type(rf_hamiltonian_type),intent(inout),optional :: rf_hamk_dir2
    1222              :  type(dataset_type),intent(in) :: dtset
    1223              :  type(pseudopotential_type),intent(in) :: psps
    1224              :  integer,optional,intent(in) :: reuse_kpg_k, reuse_kpg1_k, reuse_ffnlk, reuse_ffnl1
    1225              : !arrays
    1226              :  integer,intent(in) :: kg_k(3,npw_k),kg1_k(3,npw1_k)
    1227              :  real(dp),intent(in) :: kpoint(3),kpq(3),gmet(3,3),gprimd(3,3),rmet(3,3)
    1228              :  real(dp),intent(in) :: ylm_k(npw_k,psps%mpsang*psps%mpsang*psps%useylm)
    1229              :  real(dp),intent(in) :: ylmgr1_k(npw1_k,3+6*((ipert-natom)/10),psps%mpsang*psps%mpsang*psps%useylm*useylmgr1)
    1230              :  real(dp),intent(in) :: ylm1_k(npw1_k,psps%mpsang*psps%mpsang*psps%useylm)
    1231              :  real(dp),allocatable,intent(out) :: dkinpw(:),kinpw1(:)
    1232              :  real(dp),allocatable,intent(inout) :: ffnlk(:,:,:,:),ffnl1(:,:,:,:), kpg_k(:,:), kpg1_k(:,:)
    1233              :  real(dp),allocatable,intent(out),optional :: dkinpw2(:),ddkinpw(:),ffnl1_test(:,:,:,:)
    1234              :  real(dp),allocatable,intent(out) :: ph3d(:,:,:),ph3d1(:,:,:)
    1235              : 
    1236              : !Local variables-------------------------------
    1237              : !scalars
    1238              :  integer :: dimffnl1,dimffnlk,ider,idir0,idir1,idir2,istr,ntypat,print_info
    1239              :  integer :: reuse_ffnlk_, reuse_ffnl1_, reuse_kpg_k_, reuse_kpg1_k_
    1240              :  logical :: qne0
    1241              :  !real(dp) :: cpu, wall, gflops
    1242              : !arrays
    1243              :  real(dp) :: ylmgr_dum(1,1,1), tsec(2)
    1244              : ! *************************************************************************
    1245              : 
    1246              :  ! MG: This routine is called **many times** in the EPH code for phonon and DDK perturbations
    1247              :  ! Please, be extremely careful when adding extra stuff that may affect performance.
    1248              : 
    1249              :  ! Keep track of total time spent in getgh1c_setup (use 195 slot)
    1250       916828 :  call timab(195, 1, tsec)
    1251              :  !call cwtime(cpu, wall, gflops, "start")
    1252              : 
    1253       916828 :  reuse_ffnlk_ = 0; if (present(reuse_ffnlk)) reuse_ffnlk_ = reuse_ffnlk
    1254       916828 :  reuse_ffnl1_ = 0; if (present(reuse_ffnl1)) reuse_ffnl1_ = reuse_ffnl1
    1255       916828 :  reuse_kpg_k_ = 0; if (present(reuse_kpg_k)) reuse_kpg_k_ = reuse_kpg_k
    1256       916828 :  reuse_kpg1_k_ = 0; if (present(reuse_kpg1_k)) reuse_kpg1_k_ = reuse_kpg1_k
    1257              : 
    1258       916828 :  if(.not.present(ddkinpw) .and. ipert==natom+10) then
    1259            0 :    ABI_BUG("ddkinpw is not optional for ipert=natom+10.")
    1260              :  end if
    1261       916828 :  if(.not.present(dkinpw2) .and. ipert==natom+10 .and. idir>3) then
    1262            0 :    ABI_BUG("dkinpw2 is not optional for ipert=natom+10 and idir>3.")
    1263              :  end if
    1264       916828 :  if(.not.present(rf_hamk_dir2) .and. ((ipert==natom+10 .and. idir>3) .or. ipert==natom+11)) then
    1265            0 :    ABI_BUG("rf_hamk_dir2 is not optional for ipert=natom+10 (with idir>3) or ipert=natom+11.")
    1266              :  end if
    1267              : 
    1268       916828 :  ntypat = psps%ntypat
    1269       916828 :  qne0 = ((kpq(1)-kpoint(1))**2+(kpq(2)-kpoint(2))**2+(kpq(3)-kpoint(3))**2>=tol14)
    1270              : 
    1271              :  ! Compute k+G vectors
    1272       916828 :  nkpg = 0; if (ipert >= 1 .and. ipert <= natom) nkpg = 3*dtset%nloalg(3)
    1273       916828 :  if (reuse_kpg_k_ == 0) then
    1274      3667312 :    ABI_MALLOC(kpg_k, (npw_k,  nkpg))
    1275       916828 :    if (nkpg > 0) call mkkpg(kg_k, kpg_k, kpoint, nkpg, npw_k)
    1276              :  else
    1277            0 :    ABI_CHECK(all(shape(kpg_k) == [npw_k,  nkpg]), sjoin("Wrong shape in input kpg_k", ltoa(shape(kpg_k))))
    1278              :  endif
    1279              : 
    1280              :  ! Compute k+q+G vectors
    1281       916828 :  nkpg1 = 0; if (ipert >= 1 .and. ipert <= natom) nkpg1 = 3*dtset%nloalg(3)
    1282       916828 :  if (reuse_kpg1_k_ == 0) then
    1283      3667312 :    ABI_MALLOC(kpg1_k, (npw1_k, nkpg1))
    1284       916828 :    if (nkpg1 > 0) call mkkpg(kg1_k, kpg1_k, kpq(:), nkpg1, npw1_k)
    1285              :  else
    1286            0 :    ABI_CHECK(all(shape(kpg1_k) == [npw1_k,  nkpg1]), sjoin("Wrong shape in input kpg1_k:", ltoa(shape(kpg1_k))))
    1287              :  endif
    1288              : 
    1289              :  ! ===== Preparation of the non-local contributions
    1290       916828 :  dimffnlk =0; if (ipert<=natom) dimffnlk=1
    1291              : 
    1292              :  ! Compute nonlocal form factors ffnlk at (k+G)
    1293              :  ! (only for atomic displacement perturbation)
    1294       916828 :  if (reuse_ffnlk_ == 0) then
    1295      5210208 :    ABI_MALLOC(ffnlk, (npw_k, dimffnlk, psps%lmnmax, ntypat))
    1296       868368 :    if (ipert<=natom) then
    1297       510820 :      ider=0;idir0=0
    1298              :      call mkffnl(psps%dimekb,dimffnlk,psps%ekb,ffnlk,psps%ffspl,&
    1299              :        gmet,gprimd,ider,idir0,psps%indlmn,kg_k,kpg_k,kpoint,psps%lmnmax,&
    1300              :        psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,npw_k,ntypat,&
    1301       510820 :        psps%pspso,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm_k,ylmgr_dum)
    1302              :    end if
    1303              :  else
    1304       242300 :    ABI_CHECK(all(shape(ffnlk) == [npw_k, dimffnlk, psps%lmnmax, ntypat]), sjoin("Wrong shape in input ffnlk:", ltoa(shape(ffnlk))))
    1305              :  end if
    1306              : 
    1307              :  ! Compute nonlocal form factors ffnl1 at (k+q+G)
    1308              :  !-- Atomic displacement perturbation
    1309       916828 :  if (ipert<=natom) then
    1310       510820 :    ider=0;idir0=0
    1311              :  !-- k-point perturbation (1st-derivative)
    1312       406008 :  else if (ipert==natom+1) then
    1313       223022 :    ider=1;idir0=idir
    1314              :  !-- k-point perturbation (2nd-derivative)
    1315       182986 :  else if (ipert==natom+10.or.ipert==natom+11) then
    1316        14616 :    ider=2;idir0=4
    1317              :  !-- Electric field perturbation
    1318       168370 :  else if (ipert==natom+2) then
    1319        89874 :    if (psps%usepaw==1) then
    1320         8464 :      ider=1;idir0=idir
    1321              :    else
    1322        81410 :      ider=0;idir0=0
    1323              :    end if
    1324              :  !-- Strain perturbation
    1325        78496 :  else if (ipert==natom+3.or.ipert==natom+4) then
    1326        76900 :    if (ipert==natom+3) istr=idir
    1327        76900 :    if (ipert==natom+4) istr=idir+3
    1328        76900 :    ider=1;idir0=-istr
    1329              :  !-- Magnetic field perturbation ( SPr, Zeeman ) or scalar potential
    1330         1596 :  else if(ipert==natom+5.or.ipert==natom+6.or.(ipert>natom+11.and.ipert<=2*natom+11))then
    1331         1596 :    ider=0;idir0=0
    1332              :  end if
    1333              : 
    1334              :  ! Compute nonlocal form factors ffnl1 at (k+q+G), for all atoms
    1335       916828 :  dimffnl1=1+ider
    1336       916828 :  if (ider==1.and.idir0==0) dimffnl1=2+2*psps%useylm
    1337       916828 :  if (ider==2.and.idir0==4) dimffnl1=3+7*psps%useylm
    1338              : 
    1339       916828 :  if (reuse_ffnl1_ == 0) then
    1340      5210208 :    ABI_MALLOC(ffnl1, (npw1_k, dimffnl1, psps%lmnmax, ntypat))
    1341              : 
    1342              :    call mkffnl(psps%dimekb,dimffnl1,psps%ekb,ffnl1,psps%ffspl,gmet,gprimd,ider,idir0,&
    1343              :      psps%indlmn,kg1_k,kpg1_k,kpq,psps%lmnmax,psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg1,&
    1344       868368 :      npw1_k,ntypat,psps%pspso,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm1_k,ylmgr1_k)
    1345              :  else
    1346       242300 :    ABI_CHECK(all(shape(ffnl1) == [npw1_k, dimffnl1, psps%lmnmax, ntypat]), sjoin("Wrong shape in input ffnl1", ltoa(shape(ffnl1))))
    1347              :  end if
    1348              : 
    1349              :  ! Compute ffnl for nonlop with signs = 1
    1350       916828 :  print_info = 0
    1351       916828 :  if (dtset%prtvol==-19.or.dtset%prtvol==-20.or.dtset%prtvol==-21.or.dtset%nonlinear_info>=3) then
    1352          240 :    print_info = 1
    1353              :  end if
    1354       916828 :  if (present(ffnl1_test).and.print_info/=0.and.(ipert==natom+10.or.ipert==natom+11)) then
    1355         1440 :    ABI_MALLOC(ffnl1_test,(npw1_k,dimffnl1,psps%lmnmax,psps%ntypat))
    1356          240 :    idir0 = 0 ! for nonlop with signs = 1
    1357              :    call mkffnl(psps%dimekb,dimffnl1,psps%ekb,ffnl1_test,psps%ffspl,gs_hamkq%gmet,gs_hamkq%gprimd,ider,idir0,&
    1358              :      psps%indlmn,kg1_k,kpg1_k,kpq,psps%lmnmax,psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg1,&
    1359          240 :      npw1_k,psps%ntypat,psps%pspso,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm1_k,ylmgr1_k)
    1360              :  end if
    1361              : 
    1362              :  !===== Preparation of the kinetic contributions
    1363              :  ! Note that not all these arrays should be allocated in the general case when wtk_k vanishes
    1364              : 
    1365              :  ! Compute (1/2) (2 Pi)**2 (k+q+G)**2:
    1366      2750484 :  ABI_MALLOC(kinpw1, (npw1_k))
    1367    126382525 :  kinpw1(:)=zero
    1368       916828 :  call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg1_k,kinpw1,kpq,npw1_k,0,0)
    1369              : 
    1370      2750484 :  ABI_MALLOC(dkinpw,(npw_k)) ! 1st derivative (1st direction)
    1371    126374369 :  dkinpw(:)=zero
    1372       916828 :  if(ipert==natom+10 .and. idir>3) then
    1373        14112 :    ABI_MALLOC(dkinpw2,(npw_k)) ! 1st derivative (2nd directions)
    1374       990680 :    dkinpw2(:)=zero
    1375              :  end if
    1376       916828 :  if(ipert==natom+10) then
    1377        22320 :    ABI_MALLOC(ddkinpw,(npw_k)) ! 2nd derivative
    1378      1524172 :    ddkinpw(:)=zero
    1379              :  end if
    1380              : 
    1381              :  ! -- k-point perturbation (1st-derivative)
    1382       916828 :  if (ipert==natom+1) then
    1383              :    ! Compute the derivative of the kinetic operator vs k
    1384       223022 :    call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,dkinpw,kpoint,npw_k,idir,0) ! 1st derivative
    1385              :  end if
    1386              : 
    1387              :  !-- k-point perturbation (2nd-derivative)
    1388       916828 :  if (ipert==natom+10.or.ipert==natom+11) then
    1389              :    ! Compute the derivative of the kinetic operator vs k in kinpw, second and first orders
    1390        14616 :    if(ipert==natom+10 .and. idir<=3) then
    1391         4104 :      call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,dkinpw,kpoint,npw_k,idir,0) ! 1st derivative
    1392         4104 :      call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,ddkinpw,kpoint,npw_k,idir,idir) ! 2nd derivative
    1393              :    else
    1394        11072 :      select case(idir)
    1395              :      ! Diagonal terms:
    1396              :      case (1)
    1397          560 :        idir1 = 1
    1398          560 :        idir2 = 1
    1399              :      case (2)
    1400          560 :        idir1 = 2
    1401          560 :        idir2 = 2
    1402              :      case (3)
    1403           32 :        idir1 = 3
    1404           32 :        idir2 = 3
    1405              :      ! Upper triangular terms:
    1406              :      case (4)
    1407         2104 :        idir1 = 2
    1408         2104 :        idir2 = 3
    1409              :      case (5)
    1410         1048 :        idir1 = 1
    1411         1048 :        idir2 = 3
    1412              :      case (6)
    1413         2104 :        idir1 = 1
    1414         2104 :        idir2 = 2
    1415              :      ! Lower triangular terms:
    1416              :      case (7)
    1417         1544 :        idir1 = 3
    1418         1544 :        idir2 = 2
    1419              :      case (8)
    1420         1016 :        idir1 = 3
    1421         1016 :        idir2 = 1
    1422              :      case (9)
    1423         1544 :        idir1 = 2
    1424        10512 :        idir2 = 1
    1425              :      end select
    1426        10512 :      call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,dkinpw,kpoint,npw_k,idir1,0) !  1st derivative, idir1
    1427        10512 :      if(ipert==natom+10) then
    1428         7056 :        call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,dkinpw2,kpoint,npw_k,idir2,0) ! 1st derivative, idir2
    1429         7056 :        call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,ddkinpw,kpoint,npw_k,idir1,idir2) ! 2nd derivative
    1430              :      end if
    1431              :    end if
    1432              :  end if
    1433              : 
    1434              :  !-- Strain perturbation
    1435       916828 :  if (ipert==natom+3.or.ipert==natom+4) then
    1436        76900 :    if (ipert==natom+3) istr=idir
    1437        76900 :    if (ipert==natom+4) istr=idir+3
    1438              :    ! Compute the derivative of the kinetic operator vs strain
    1439        76900 :    call kpgstr(dkinpw,dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,gprimd,istr,kg_k,kpoint,npw_k)
    1440              :  end if
    1441              : 
    1442              :  !===== Load the k/k+q dependent parts of the Hamiltonian
    1443              :  ! Load k-dependent part in the Hamiltonian datastructure
    1444      3667312 :  ABI_MALLOC(ph3d, (2,npw_k,gs_hamkq%matblk))
    1445              :  call gs_hamkq%load_k(kpt_k=kpoint, npw_k=npw_k, istwf_k=istwf_k, kg_k=kg_k, kpg_k=kpg_k,&
    1446       916828 :                       ph3d_k=ph3d, compute_ph3d=.true., compute_gbound=.true.)
    1447              : 
    1448      4584140 :  if (size(ffnlk)>0) then
    1449       510820 :    call gs_hamkq%load_k(ffnl_k=ffnlk)
    1450              :  else
    1451       406008 :    call gs_hamkq%load_k(ffnl_k=ffnl1)
    1452              :  end if
    1453              : 
    1454              :  ! Load k+q-dependent part in the Hamiltonian datastructure
    1455              :  ! Note: istwf_k is imposed to 1 for RF calculations (should use istwf_kq instead)
    1456              :  call gs_hamkq%load_kprime(kpt_kp=kpq,npw_kp=npw1_k,istwf_kp=istwf_k,&
    1457       916828 :    kinpw_kp=kinpw1,kg_kp=kg1_k,kpg_kp=kpg1_k,ffnl_kp=ffnl1,compute_gbound=.true.)
    1458              : 
    1459       916828 :  if (qne0) then
    1460      1639484 :    ABI_MALLOC(ph3d1,(2,npw1_k,gs_hamkq%matblk))
    1461       409871 :    call gs_hamkq%load_kprime(ph3d_kp=ph3d1,compute_ph3d=.true.)
    1462              :  end if
    1463              : 
    1464              :  ! Load k-dependent part in the 1st-order Hamiltonian datastructure
    1465       916828 :  call rf_hamkq%load_k(npw_k=npw_k,dkinpw_k=dkinpw)
    1466              : 
    1467       916828 :  if (ipert==natom+10) then
    1468        11160 :    call rf_hamkq%load_k(ddkinpw_k=ddkinpw)
    1469        11160 :    if (idir>3) call rf_hamk_dir2%load_k(dkinpw_k=dkinpw2,ddkinpw_k=ddkinpw)
    1470              :  end if
    1471              : 
    1472       916828 :  call timab(195, 2, tsec)
    1473              : 
    1474       916828 : end subroutine getgh1c_setup
    1475              : !!***
    1476              : 
    1477              : !!****f* ABINIT/getdc1
    1478              : !!
    1479              : !! NAME
    1480              : !! getdc1
    1481              : !!
    1482              : !! FUNCTION
    1483              : !! Compute |delta_C^(1)> from one wave function C - PAW ONLY
    1484              : !! Compute <G|delta_C^(1)> (dcwavef) and eventually <P_i| delta_C^(1)> (dcwaveprj) where P_i= non-local projector
    1485              : !! delta_C^(1) is the variation of wavefunction only due to variation of overlap operator S.
    1486              : !! delta_C^(1)=-1/2.Sum_j [ <C_j|S^(1)|C>.C_j
    1487              : !!         see PRB 78, 035105 (2008) [[cite:Audouze2008]], Eq. (42 and 40, term 2)
    1488              : !!
    1489              : !! INPUTS
    1490              : !!  cgq(2,mcgq)=wavefunction coefficients for all bands j on present processor, at k+Q: cgq=< G |Cnk+q>
    1491              : !!  cprjq(natom,mcprjq)= wave functions j at k+q projected with non-local projectors: cprjq=<P_i|Cnk+q>
    1492              : !!  ibgq=shift to be applied on the location of data in the array cprjq
    1493              : !!  icgq=shift to be applied on the location of data in the array cgq
    1494              : !!  istwfk=option parameter that describes the storage of wfs
    1495              : !!  mcgq=second dimension of the cgq array
    1496              : !!  mcprjq=second dimension of the cprjq array
    1497              : !!  mpi_enreg=information about MPI parallelization
    1498              : !!  ndat=number of bands to compute in parallel
    1499              : !!  natom= number of atoms in cell
    1500              : !!  nband=number of bands
    1501              : !!  npw1=number of planewaves in basis sphere at k+Q
    1502              : !!  nspinor=number of spinorial components of the wavefunctions
    1503              : !!  opt_cprj=flag governing the computation of <P_i|delta_C^(1)> (P_i= non-local projector)
    1504              : !!  s1cwave0(2,npw1*nspinor)=<G|S^(1)|C> where S^(1) is the first-order overlap operator
    1505              : !!
    1506              : !! OUTPUT
    1507              : !!  dcwavef(2,npw1*nspinor)=change of wavefunction due to change of overlap PROJECTED ON PLANE-WAVES:
    1508              : !!         dcwavef is delta_C(1)=-1/2.Sum_{j}[<C0_k+q_j|S(1)|C0_k_i>.|C0_k+q_j>]
    1509              : !!  === if optcprj=1 ===
    1510              : !!  dcwaveprj(natom,nspinor*optcprj)=change of wavefunction due to change of overlap PROJECTED ON NL-PROJECTORS:
    1511              : !!
    1512              : !! SOURCE
    1513              : 
    1514       816088 : subroutine getdc1(band,band_procs,bands_treated_now,cgq,cprjq,dcwavef,dcwaveprj,&
    1515              : &                 ibgq,icgq,istwfk,mcgq,mcprjq,&
    1516       816088 : &                 mpi_enreg,ndat,natom,nband,nband_me,npw1,nspinor,optcprj,s1cwave0,&
    1517              : &                 gpu_option)
    1518              : 
    1519              : !Arguments ------------------------------------
    1520              : !scalars
    1521              :  integer,intent(in) :: ibgq,icgq,istwfk,mcgq,mcprjq,natom,nband,npw1,nspinor,optcprj
    1522              :  integer,intent(in) :: band, nband_me, ndat
    1523              :  type(MPI_type),intent(in) :: mpi_enreg
    1524              :  integer,optional,intent(in) :: gpu_option
    1525              : !arrays
    1526              :  integer,intent(in) :: band_procs(nband),bands_treated_now(nband,ndat)
    1527              :  real(dp),intent(in) :: cgq(2,mcgq),s1cwave0(2,npw1*nspinor*ndat)
    1528              :  real(dp),intent(out) :: dcwavef(2,npw1*nspinor*ndat)
    1529              :  type(pawcprj_type),intent(in) :: cprjq(natom,mcprjq)
    1530              :  type(pawcprj_type),intent(inout) :: dcwaveprj(natom,nspinor*ndat*optcprj)
    1531              : 
    1532              : !Local variables-------------------------------
    1533              : !scalars
    1534              :  integer, parameter :: tim_projbd=0
    1535              :  integer :: ipw, idat
    1536              :  integer :: band_, ierr, nproc_band
    1537              :  integer :: l_gpu_option
    1538              :  real(dp),parameter :: scal=-half
    1539              : !arrays
    1540       816088 :  integer, allocatable :: nlmn(:)
    1541       816088 :  real(dp), allocatable :: dummy(:,:),scprod(:,:,:)
    1542              :  real(dp), allocatable :: dcwavef_tmp(:,:)
    1543       816088 :  type(pawcprj_type),allocatable :: dcwaveprj_tmp(:,:)
    1544              : ! *********************************************************************
    1545              : 
    1546              :  DBG_ENTER("COLL")
    1547              : 
    1548       816088 :  l_gpu_option = ABI_GPU_DISABLED; if (present(gpu_option))  l_gpu_option  = gpu_option
    1549       816088 :  nproc_band=mpi_enreg%nproc_band
    1550              : 
    1551       816088 :  ABI_MALLOC(dummy,(0,0))
    1552      3264352 :  ABI_MALLOC(scprod,(2,nband_me,ndat))
    1553      2448264 :  ABI_MALLOC(dcwavef_tmp,(2,npw1*nspinor*ndat))
    1554              : #ifdef HAVE_OPENMP_OFFLOAD
    1555              :  !$OMP TARGET ENTER DATA MAP(alloc:dcwavef_tmp,scprod) IF(l_gpu_option==ABI_GPU_OPENMP)
    1556              : #endif
    1557       816088 :  if (optcprj == 1) then
    1558       844092 :    ABI_MALLOC(nlmn,(natom))
    1559      2100264 :    ABI_MALLOC(dcwaveprj_tmp,(natom,nspinor*ndat*optcprj))
    1560       974808 :    nlmn(:)=dcwaveprj(:,1)%nlmn
    1561       281364 :    call pawcprj_alloc(dcwaveprj_tmp, 0, nlmn)
    1562       281364 :    ABI_FREE(nlmn)
    1563              :  end if
    1564              : 
    1565              : !=== 1- COMPUTE: <G|S^(1)|C_k> - Sum_j [<C_k+q,j|S^(1)|C_k>.<G|C_k+q,j>]
    1566              : !!               using the projb routine
    1567              : !Note the subtlety: projbd is called with useoverlap=0 and s1cwave0
    1568              : !in order to get Sum[<cgq|s1|c>|cgq>]=Sum[<cgq|gs1>|cgq>]
    1569              : 
    1570              : ! run over procs in my pool which have a dcwavef to projbd
    1571      6301096 :  do band_ = 1, nband, ndat
    1572      5485008 :    if (bands_treated_now(band_, 1) == 0) cycle
    1573       825088 :    if(l_gpu_option==ABI_GPU_DISABLED) then
    1574    411686110 :      dcwavef_tmp = zero
    1575            0 :    else if(l_gpu_option==ABI_GPU_OPENMP) then
    1576            0 :      call gpu_set_to_zero(dcwavef_tmp,int(2,c_size_t)*npw1*nspinor*ndat)
    1577              :    end if
    1578              : 
    1579              : ! distribute dcwavef_tmp to my band pool
    1580              : ! everyone works on a single band s1cwave0 = <G|S^(1)|C_k>
    1581       825088 :    if (band_ == band) then
    1582       816088 :      if(l_gpu_option==ABI_GPU_DISABLED) then
    1583              :        !$OMP PARALLEL DO
    1584    124296762 :        do ipw=1,npw1*nspinor*ndat
    1585    371258110 :          dcwavef_tmp(1:2,ipw)=s1cwave0(1:2,ipw)
    1586              :        end do
    1587              :      else if(l_gpu_option==ABI_GPU_OPENMP) then
    1588              : #ifdef HAVE_OPENMP_OFFLOAD
    1589              :        call gpu_copy(dcwavef_tmp, s1cwave0, int(2,c_size_t)*npw1*nspinor*ndat)
    1590              : #endif
    1591              :      end if
    1592              :    end if
    1593              : #ifdef HAVE_OPENMP_OFFLOAD
    1594              :    !$OMP TARGET UPDATE FROM (dcwavef_tmp) IF(l_gpu_option==ABI_GPU_OPENMP)
    1595              : #endif
    1596       825088 :    call xmpi_bcast(dcwavef_tmp,band_procs(band_),mpi_enreg%comm_band,ierr)
    1597              : #ifdef HAVE_OPENMP_OFFLOAD
    1598              :    !$OMP TARGET UPDATE TO (dcwavef_tmp) IF(l_gpu_option==ABI_GPU_OPENMP)
    1599              : #endif
    1600              : 
    1601              : ! get the projbd onto my processor's bands dcwavef = dcwavef - <cgq|dcwavef>|cgq>
    1602              : ! dcwavef = <G|S^(1)|C_k> - Sum_{MYj} [<C_k+q,j|S^(1)|C_k>.<G|C_k+q,j>]
    1603              : ! scprod  =                            <C_k+q,j|S^(1)|C_k> for {MYj}
    1604      1650176 :    do idat=1,ndat
    1605              :      call projbd(cgq,dcwavef_tmp(:,1+(idat-1)*npw1*nspinor:idat*npw1*nspinor),-1,&
    1606              : &       icgq,0,istwfk,mcgq,0,nband_me,npw1,nspinor,&
    1607              : &       dummy,scprod(:,:,idat),0,tim_projbd,0,mpi_enreg%me_g0,mpi_enreg%comm_fft,&
    1608      1650176 : &       gpu_option=l_gpu_option)
    1609              :    end do
    1610              : #ifdef HAVE_OPENMP_OFFLOAD
    1611              :    !$OMP TARGET UPDATE FROM (scprod) IF(l_gpu_option==ABI_GPU_OPENMP)
    1612              : #endif
    1613              : 
    1614              : 
    1615              : ! sum all of the corrections
    1616              : ! dcwavef = Nprocband * <G|S^(1)|C_k> - Sum_{ALLj} [<C_k+q,j|S^(1)|C_k>.<G|C_k+q,j>]
    1617       825088 :    call xmpi_sum(dcwavef_tmp,mpi_enreg%comm_band,ierr,use_omp_map=(l_gpu_option==ABI_GPU_OPENMP))
    1618              : 
    1619              : ! save to my proc if it is my turn, and subtract Ntuple counted dcwavef
    1620       825088 :    if (band_ == band) then
    1621              : !=== 2- COMPUTE: <G|delta_C^(1)> = -1/2.Sum_j [<C_k+q,j|S^(1)|C_k>.<G|C_k+q,j>] by subtraction
    1622              : ! tested this is equivalent to previous coding to within 1.e-18 accumulated error (probably in favor of this coding)
    1623       816088 :      if(l_gpu_option==ABI_GPU_DISABLED) then
    1624              :        !$OMP PARALLEL DO PRIVATE(ipw) SHARED(dcwavef,s1cwave0,dcwavef_tmp,npw1,nspinor)
    1625    124296762 :        do ipw=1,npw1*nspinor*ndat
    1626    371258110 :          dcwavef(1:2,ipw)= scal*(nproc_band*s1cwave0(1:2,ipw)-dcwavef_tmp(1:2,ipw))
    1627              :        end do
    1628              :      else if(l_gpu_option==ABI_GPU_OPENMP) then
    1629              : #ifdef HAVE_OPENMP_OFFLOAD
    1630              :        !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO PRIVATE(ipw) MAP(to:dcwavef,s1cwave0,dcwavef_tmp)
    1631              :        do ipw=1,npw1*nspinor*ndat
    1632              :          dcwavef(1,ipw)= scal*(nproc_band*s1cwave0(1,ipw)-dcwavef_tmp(1,ipw))
    1633              :          dcwavef(2,ipw)= scal*(nproc_band*s1cwave0(2,ipw)-dcwavef_tmp(2,ipw))
    1634              :        end do
    1635              : #endif
    1636              :      end if
    1637              :    end if
    1638              :    !print*,"dcwavef ", dcwavef(1,1)
    1639              : 
    1640              : !=== 3- COMPUTE: <P_i|delta_C^(1)> = -1/2.Sum_j [<C_k+q,j|S^(1)|C_k>.<P_i|C_k+q,j>]
    1641              : ! as above everyone has to operate on each band band_
    1642      2466264 :    if (optcprj==1.and.mcprjq>0) then
    1643              : !   cprjq         =                               <P_i|C_k+q,j>  for MYj
    1644              : !   dcwaveprj_tmp =  Sum_MYj [<C_k+q,j|S^(1)|C_k>.<P_i|C_k+q,j>]
    1645       574392 :      do idat=1,ndat
    1646       574392 :        call pawcprj_lincom(scprod(:,:,idat),cprjq(:,ibgq+1:ibgq+nspinor*nband_me),dcwaveprj_tmp(:,1+(idat-1)*nspinor:idat*nspinor),nband_me)
    1647              :      end do
    1648              : 
    1649              : ! still need to mpisum the dcwaveprj to get linear combination of all bands, not just mine
    1650              : !   dcwaveprj =  Sum_ALLj [<C_k+q,j|S^(1)|C_k,i>.<P_i|C_k+q,j>]
    1651       287196 :      call pawcprj_mpi_sum(dcwaveprj_tmp,mpi_enreg%comm_band,ierr)
    1652              : 
    1653       287196 :      if (band_ == band) then
    1654              : ! dcwaveprj =  -1/2 dcwaveprj_tmp
    1655              : !TODO: check the correct order of scal and zero (alpha / beta) coefficients.
    1656              : !  Here dcwaveprj is squashed by the _tmp variable which is used in parallel
    1657       281364 :        call pawcprj_axpby(scal,zero,dcwaveprj_tmp,dcwaveprj)
    1658              :      end if
    1659              :    end if
    1660              : 
    1661              :  end do ! procs in my band pool
    1662              : 
    1663              : #ifdef HAVE_OPENMP_OFFLOAD
    1664              :  !$OMP TARGET EXIT DATA MAP(delete:dcwavef_tmp,scprod) IF(l_gpu_option==ABI_GPU_OPENMP)
    1665              : #endif
    1666              : 
    1667       816088 :  ABI_FREE(dummy)
    1668       816088 :  ABI_FREE(scprod)
    1669       816088 :  ABI_FREE(dcwavef_tmp)
    1670       816088 :  if (optcprj == 1) then
    1671       281364 :    call pawcprj_free(dcwaveprj_tmp)
    1672       974808 :    ABI_FREE(dcwaveprj_tmp)
    1673              :  end if
    1674              : 
    1675              :  DBG_EXIT("COLL")
    1676              : 
    1677       816088 : end subroutine getdc1
    1678              : !!***
    1679              : 
    1680              : !!****f* ABINIT/getgh1dqc
    1681              : !! NAME
    1682              : !!  getgh1dqc
    1683              : !!
    1684              : !! FUNCTION
    1685              : !! Computes <G|dH^(1)/dq_{gamma}|C> or <G|d^2H^(1)/dq_{gamma}dq_{delta}|C>
    1686              : !! for input vector |C> expressed in reciprocal space.
    1687              : !! dH^(1)/dq_{gamma} and d^2H^(1)/dq_{gamma}dq_{delta} are the first
    1688              : !! and second q-gradient (at q=0) of the 1st-order perturbed Hamiltonian.
    1689              : !! The first (second) derivative direction is inferred from idir (qdir1).
    1690              : !!
    1691              : !! INPUTS
    1692              : !!  cwave(2,npw*nspinor)=input wavefunction, in reciprocal space
    1693              : !!  cwaveprj(natom,nspinor*usecprj)=<p_lmn|C> coefficients for wavefunction |C> (and 1st derivatives)
    1694              : !!     if not allocated or size=0, they are locally computed (and not sorted)
    1695              : !!  gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k+q
    1696              : !!  idir=first index of the perturbation
    1697              : !!  ipert=type of the perturbation
    1698              : !!  mpi_enreg=information about MPI parallelization
    1699              : !!  npw=number of planewaves in basis sphere at given k.
    1700              : !!  npw1=number of planewaves in basis sphere at k+q
    1701              : !!  optlocal=0: local part of H^(1) is not computed
    1702              : !!           1: local part of H^(1) is computed in gvloc1dqc
    1703              : !!  optnl=0: non-local part of H^(1) is not computed
    1704              : !!        1: non-local part of H^(1) depending on VHxc^(1) is not computed in gvloc1dqc
    1705              : !!        2: non-local part of H^(1) is totally computed in gvloc1dqc
    1706              : !!  qdir1= direction of the 1st q-gradient
    1707              : !!  rf_hamkq <type(rf_hamiltonian_type)>=all data for the 1st-order Hamiltonian at k,k+q
    1708              : !!  qdir2= (optional) direction of the 2nd q-gradient
    1709              : !!
    1710              : !! OUTPUT
    1711              : !!  gh1dqc(2,npw1*nspinor)= <G|dH^(1)/dq_{\gamma}|C> on the k+q sphere
    1712              : !!  gvloc1dqc(2,npw1*nspinor)= local potential part of gh1dqc
    1713              : !!  gvnl1dqc(2,npw1*nspinor)= non local potential part of gh1dqc
    1714              : !!
    1715              : !! NOTES
    1716              : !!  Currently two Hamiltonian gradients at (q=0) are implemented:
    1717              : !!     ipert<=natom ->            first q-derivative along reduced coordinates directions
    1718              : !!                              of the atomic displacement perturbation hamiltonian
    1719              : !!     ipert==natom+3 or natom+4 -> second q-derivative along cartesian coordinates
    1720              : !!                                  of the metric perturbation hamiltonian.
    1721              : !!     Which is equivalent (except for an i factor) to the first
    1722              : !!                                  q-derivative along cartesian coordinates of the strain
    1723              : !!                                  perturbation hamiltonian.
    1724              : !!
    1725              : !! SOURCE
    1726              : 
    1727      1002208 : subroutine getgh1dqc(cwave,cwaveprj,gh1dqc,gvloc1dqc,gvnl1dqc,gs_hamkq,&
    1728              : &          idir,ipert,mpi_enreg,optlocal,optnl,qdir1,rf_hamkq,&
    1729              : &          qdir2)                                                        !optional
    1730              : 
    1731              : !Arguments ------------------------------------
    1732              : !scalars
    1733              :  integer,intent(in) :: idir,ipert,optlocal,optnl,qdir1
    1734              :  integer,intent(in),optional :: qdir2
    1735              :  type(MPI_type),intent(in) :: mpi_enreg
    1736              :  type(gs_hamiltonian_type),intent(inout),target :: gs_hamkq
    1737              :  type(rf_hamiltonian_type),intent(inout),target :: rf_hamkq
    1738              : 
    1739              : !arrays
    1740              :  real(dp),intent(inout) :: cwave(2,gs_hamkq%npw_k*gs_hamkq%nspinor)
    1741              :  real(dp),intent(out) :: gh1dqc(2,gs_hamkq%npw_kp*gs_hamkq%nspinor)
    1742              :  real(dp),intent(out) :: gvloc1dqc(2,gs_hamkq%npw_kp*gs_hamkq%nspinor)
    1743              :  real(dp),intent(out) :: gvnl1dqc(2,gs_hamkq%npw_kp*gs_hamkq%nspinor)
    1744      1002208 :  real(dp),contiguous, pointer :: dqdqkinpw(:),kinpw1(:)
    1745              :  type(pawcprj_type),intent(inout),target :: cwaveprj(:,:)
    1746              : 
    1747              : !Local variables-------------------------------
    1748              : !scalars
    1749              :  integer :: choice,cpopt,iidir,ipw,ipws,ispinor,my_nspinor,natom,nnlout
    1750              :  integer :: npw,npw1,paw_opt,signs,tim_fourwf,tim_nonlop
    1751              :  logical :: has_kin
    1752              :  !character(len=500) :: msg
    1753              :  real(dp) :: lambda,weight
    1754              : 
    1755              : !arrays
    1756              :  integer,parameter :: ngamma(3,3)=reshape((/1,6,5,9,2,4,8,7,3/),(/3,3/))
    1757              :  real(dp) :: enlout(1),svectout_dum(1,1)
    1758      1002208 :  real(dp),contiguous, pointer :: gvnl1dqc_(:,:)
    1759      1002208 :  real(dp), allocatable :: work(:,:,:,:)
    1760              : ! *************************************************************************
    1761              : 
    1762              :  DBG_ENTER("COLL")
    1763              : 
    1764              : !======================================================================
    1765              : !== Initialisations and compatibility tests
    1766              : !======================================================================
    1767              : 
    1768      1002208 :  npw  =gs_hamkq%npw_k
    1769      1002208 :  npw1 =gs_hamkq%npw_kp
    1770      1002208 :  natom=gs_hamkq%natom
    1771              : 
    1772              : !Compatibility tests
    1773      1002208 :  if (mpi_enreg%paral_spinor==1) then
    1774            0 :    ABI_BUG('Not compatible with parallelization over spinor components !')
    1775              :  end if
    1776              : 
    1777              : !Check sizes
    1778      1002208 :  my_nspinor=max(1,gs_hamkq%nspinor/mpi_enreg%nproc_spinor)
    1779      3006624 :  if (size(cwave)<2*npw*my_nspinor) then
    1780            0 :    ABI_BUG('wrong size for cwave!')
    1781              :  end if
    1782      3006624 :  if (size(gh1dqc)<2*npw1*my_nspinor) then
    1783            0 :    ABI_BUG('wrong size for gh1dqc!')
    1784              :  end if
    1785              : 
    1786              : !=============================================================================
    1787              : !== Apply the q-gradients of the 1st-order local potential to the wavefunction
    1788              : !=============================================================================
    1789              : 
    1790              : !Phonon and metric (strain) perturbation
    1791      1002208 :  if (ipert<=natom+6.and.ipert/=natom+1.and.ipert/=natom+2.and.optlocal>0) then
    1792              : 
    1793      5011040 :    ABI_MALLOC(work,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
    1794              : 
    1795      1002208 :    weight=one ; tim_fourwf=4
    1796              :    call fourwf(rf_hamkq%cplex,rf_hamkq%vlocal1,cwave,gvloc1dqc,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
    1797              :  & gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
    1798              :  & npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight,&
    1799      1002208 :  & gpu_option=gs_hamkq%gpu_option)
    1800              : 
    1801      1002208 :    ABI_FREE(work)
    1802              : 
    1803              :  else
    1804              : 
    1805              : !$OMP PARALLEL DO
    1806            0 :    do ipw=1,npw1*my_nspinor
    1807            0 :      gvloc1dqc(:,ipw)=zero
    1808              :    end do
    1809              : 
    1810              :  end if
    1811              : 
    1812              : !================================================================================
    1813              : !== Apply the q-gradients of the 1st-order non-local potential to the wavefunction
    1814              : !================================================================================
    1815              : 
    1816              : !Initializations
    1817      1002208 : lambda=zero
    1818      1002208 : nnlout=1
    1819      1002208 : tim_nonlop=0
    1820              : 
    1821              : !Allocations
    1822      3006624 : ABI_MALLOC(gvnl1dqc_,(2,npw1*my_nspinor))
    1823              : 
    1824              : !Phonon perturbation
    1825              : !-------------------------------------------
    1826              :  !1st q-gradient
    1827      1002208 :  if (ipert<=natom.and..not.present(qdir2).and.optnl>0) then
    1828       380128 :    cpopt=-1 ; choice=22 ; signs=2 ; paw_opt=0
    1829              :    call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamkq,idir,(/lambda/),mpi_enreg,1,nnlout,&
    1830       760256 : &  paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnl1dqc_,iatom_only=ipert,qdir=qdir1)
    1831              : 
    1832              : !$OMP PARALLEL DO
    1833     39529196 :    do ipw=1,npw1*my_nspinor
    1834     39149068 :      gvnl1dqc(1,ipw)=gvnl1dqc_(1,ipw)
    1835     39529196 :      gvnl1dqc(2,ipw)=gvnl1dqc_(2,ipw)
    1836              :    end do
    1837              : 
    1838              :  !2nd q-gradient
    1839       622080 :  else if (ipert<=natom.and.present(qdir2).and.optnl>0) then
    1840       248832 :    iidir=ngamma(idir,qdir2)
    1841       248832 :    cpopt=-1 ; choice=25 ; signs=2 ; paw_opt=0
    1842              :    call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamkq,iidir,(/lambda/),mpi_enreg,1,nnlout,&
    1843       497664 : &  paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnl1dqc_,iatom_only=ipert,qdir=qdir1)
    1844              : 
    1845              : !$OMP PARALLEL DO
    1846     24828768 :    do ipw=1,npw1*my_nspinor
    1847     24579936 :      gvnl1dqc(1,ipw)=gvnl1dqc_(1,ipw)
    1848     24828768 :      gvnl1dqc(2,ipw)=gvnl1dqc_(2,ipw)
    1849              :    end do
    1850              : 
    1851              : !Metric (strain) perturbation
    1852              : !-------------------------------------------
    1853       373248 :  else if ((ipert==natom+3.or.ipert==natom+4).and.optnl>0) then
    1854       373248 :    cpopt=-1 ; choice=33 ; signs=2 ; paw_opt=0
    1855              :    call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamkq,idir,(/lambda/),mpi_enreg,1,nnlout,&
    1856       746496 : &  paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnl1dqc_,qdir=qdir1)
    1857              : 
    1858              : !$OMP PARALLEL DO
    1859     37243152 :    do ipw=1,npw1*my_nspinor
    1860     36869904 :      gvnl1dqc(1,ipw)=gvnl1dqc_(1,ipw)
    1861     37243152 :      gvnl1dqc(2,ipw)=gvnl1dqc_(2,ipw)
    1862              :    end do
    1863              : 
    1864              :  else
    1865              : 
    1866              : !$OMP PARALLEL DO
    1867            0 :    do ipw=1,npw1*my_nspinor
    1868            0 :      gvnl1dqc(:,ipw)=zero
    1869              :    end do
    1870              : 
    1871              :  end if
    1872              : 
    1873              : !==============================================================================
    1874              : !== Apply the q-gradients of the 1st-order kinetic operator to the wavefunction
    1875              : !== (add it to nl contribution)
    1876              : !==============================================================================
    1877              : 
    1878              : !Strain (metric) perturbation
    1879              : !-------------------------------------------
    1880      1002208 :  has_kin=(ipert==natom+3.or.ipert==natom+4)
    1881      1002208 :  if (associated(gs_hamkq%kinpw_kp)) then
    1882      1002208 :    kinpw1 => gs_hamkq%kinpw_kp
    1883            0 :  else if (has_kin) then
    1884            0 :    ABI_BUG('need kinpw1 allocated!')
    1885              :  end if
    1886      1002208 :  if (associated(rf_hamkq%dkinpw_k)) then
    1887      1002208 :    dqdqkinpw => rf_hamkq%dkinpw_k
    1888            0 :  else if (has_kin) then
    1889            0 :    ABI_BUG('need dqdqkinpw allocated!')
    1890              :  end if
    1891              : 
    1892      1002208 :  if (has_kin) then
    1893              : !  Remember that npw=npw1
    1894       746496 :    do ispinor=1,my_nspinor
    1895              : !$OMP PARALLEL DO PRIVATE(ipw,ipws) SHARED(cwave,ispinor,gvnl1dqc,dqdqkinpw,kinpw1,npw,my_nspinor)
    1896     37616400 :      do ipw=1,npw
    1897     36869904 :        ipws=ipw+npw*(ispinor-1)
    1898     37243152 :        if(kinpw1(ipw)<huge(zero)*1.d-11)then
    1899     36869904 :          gvnl1dqc(1,ipws)=gvnl1dqc(1,ipws)+dqdqkinpw(ipw)*cwave(1,ipws)
    1900     36869904 :          gvnl1dqc(2,ipws)=gvnl1dqc(2,ipws)+dqdqkinpw(ipw)*cwave(2,ipws)
    1901              :        else
    1902            0 :          gvnl1dqc(1,ipws)=zero
    1903            0 :          gvnl1dqc(2,ipws)=zero
    1904              :        end if
    1905              :      end do
    1906              :    end do
    1907              :  end if
    1908              : 
    1909              : !===================================================================================
    1910              : !== Sum contributions to get the application of dH^(1)/dq or d^2H^(1)/dqdq to the wf
    1911              : !===================================================================================
    1912              : 
    1913      2004416 :  do ispinor=1,my_nspinor
    1914      1002208 :    ipws=(ispinor-1)*npw1
    1915              : !$OMP PARALLEL DO PRIVATE(ipw) SHARED(gh1dqc,gvnl1dqc,kinpw1,ipws,npw1)
    1916    102603324 :    do ipw=1+ipws,npw1+ipws
    1917    101601116 :      if(kinpw1(ipw-ipws)<huge(zero)*1.d-11)then
    1918    100598908 :        gh1dqc(1,ipw)=gvloc1dqc(1,ipw)+gvnl1dqc(1,ipw)
    1919    100598908 :        gh1dqc(2,ipw)=gvloc1dqc(2,ipw)+gvnl1dqc(2,ipw)
    1920              :      else
    1921            0 :        gh1dqc(1,ipw)=zero
    1922            0 :        gh1dqc(2,ipw)=zero
    1923              :      end if
    1924              :    end do
    1925              :  end do
    1926              : 
    1927      1002208 :  ABI_FREE(gvnl1dqc_)
    1928              :  DBG_EXIT("COLL")
    1929              : 
    1930      1002208 : end subroutine getgh1dqc
    1931              : !!***
    1932              : 
    1933              : !!****f* m_hamiltonian/getgh1dqc_setup
    1934              : !! NAME
    1935              : !!  getgh1dqc_setup
    1936              : !!
    1937              : !! FUNCTION
    1938              : !!
    1939              : !! INPUTS
    1940              : !!
    1941              : !!
    1942              : !! OUTPUT
    1943              : !!
    1944              : !! SOURCE
    1945              : 
    1946       250168 : subroutine getgh1dqc_setup(gs_hamkq,rf_hamkq,dtset,psps,kpoint,kpq,idir,ipert,qdir1,&    ! In
    1947              : &                natom,rmet,rprimd,gprimd,gmet,istwf_k,npw_k,npw1_k,nylmgr,&             ! In
    1948       250168 : &                useylmgr1,kg_k,ylm_k,kg1_k,ylm1_k,ylmgr1_k,&                            ! In
    1949              : &                nkpg,nkpg1,kpg_k,kpg1_k,dqdqkinpw,kinpw1,ffnlk,ffnl1,ph3d,ph3d1,&       ! Out
    1950              : &                reuse_ffnlk,reuse_ffnl1,qdir2)                                          ! Optional
    1951              : 
    1952              : !Arguments ------------------------------------
    1953              : !scalars
    1954              :  integer,intent(in) :: idir,ipert,istwf_k,natom,npw_k,npw1_k,nylmgr,qdir1,useylmgr1
    1955              :  integer,intent(in),optional :: reuse_ffnlk,reuse_ffnl1,qdir2
    1956              :  integer,intent(out) :: nkpg,nkpg1
    1957              :  type(gs_hamiltonian_type),intent(inout) :: gs_hamkq
    1958              :  type(rf_hamiltonian_type),intent(inout) :: rf_hamkq
    1959              :  type(dataset_type),intent(in) :: dtset
    1960              :  type(pseudopotential_type),intent(in) :: psps
    1961              : !arrays
    1962              :  integer,intent(in) :: kg_k(3,npw_k),kg1_k(3,npw1_k)
    1963              :  real(dp),intent(in) :: kpoint(3),kpq(3),gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3)
    1964              :  real(dp),intent(in) :: ylm_k(npw_k,psps%mpsang*psps%mpsang*psps%useylm)
    1965              : ! real(dp),intent(in) :: ylmgr1_k(npw1_k,3+6*((ipert-natom)/10),psps%mpsang*psps%mpsang*psps%useylm*useylmgr1)
    1966              :  real(dp),intent(in) :: ylmgr1_k(npw1_k,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr1)
    1967              :  real(dp),intent(in) :: ylm1_k(npw1_k,psps%mpsang*psps%mpsang*psps%useylm)
    1968              :  real(dp),allocatable,intent(out) :: dqdqkinpw(:),kinpw1(:)
    1969              :  real(dp),allocatable,intent(inout) :: ffnlk(:,:,:,:),ffnl1(:,:,:,:)
    1970              :  real(dp),allocatable,intent(out) :: kpg_k(:,:),kpg1_k(:,:),ph3d(:,:,:),ph3d1(:,:,:)
    1971              : 
    1972              : !Local variables-------------------------------
    1973              : !scalars
    1974              :  integer :: dimffnl1,dimffnlk,ider,idir0,ig,mu,mua,mub,ntypat
    1975              :  integer :: nu,nua,nub
    1976              :  integer :: reuse_ffnlk_,reuse_ffnl1_
    1977              :  logical :: qne0
    1978              : !arrays
    1979              :  integer,parameter :: alpha(6)=(/1,2,3,3,3,2/),beta(6)=(/1,2,3,2,1,1/)
    1980              :  integer,parameter :: gamma(3,3)=reshape((/1,6,5,6,2,4,5,4,3/),(/3,3/))
    1981              :  real(dp) :: ylmgr_dum(1,1,1)
    1982       250168 :  real(dp),allocatable :: ffnl1_tmp(:,:,:,:)
    1983              : ! *************************************************************************
    1984              : 
    1985       250168 :  reuse_ffnlk_ = 0; if (present(reuse_ffnlk)) reuse_ffnlk_ = reuse_ffnlk
    1986       250168 :  reuse_ffnl1_ = 0; if (present(reuse_ffnl1)) reuse_ffnl1_ = reuse_ffnl1
    1987              : 
    1988       250168 :  ntypat = psps%ntypat
    1989       250168 :  qne0=((kpq(1)-kpoint(1))**2+(kpq(2)-kpoint(2))**2+(kpq(3)-kpoint(3))**2>=tol14)
    1990              : 
    1991              : !Compute (k+G) vectors
    1992       250168 :  nkpg=0;if(ipert>=1.and.ipert<=natom) nkpg=3*dtset%nloalg(3)
    1993      1000672 :  ABI_MALLOC(kpg_k,(npw_k,nkpg))
    1994       250168 :  if (nkpg>0) then
    1995            0 :    call mkkpg(kg_k,kpg_k,kpoint,nkpg,npw_k)
    1996              :  end if
    1997              : 
    1998              : !Compute (k+q+G) vectors
    1999       250168 :  nkpg1=0;if(ipert>=1.and.ipert<=natom) nkpg1=3*dtset%nloalg(3)
    2000      1000672 :  ABI_MALLOC(kpg1_k,(npw1_k,nkpg1))
    2001       250168 :  if (nkpg1>0) then
    2002            0 :    call mkkpg(kg1_k,kpg1_k,kpq(:),nkpg1,npw1_k)
    2003              :  end if
    2004              : 
    2005              : !===== Preparation of the non-local contributions
    2006              : 
    2007       250168 :  dimffnlk=0;if (ipert<=natom) dimffnlk=1
    2008              : 
    2009              : !Compute nonlocal form factors ffnlk at (k+G)
    2010       250168 :  if (reuse_ffnlk_ == 0) then
    2011       493056 :    ABI_MALLOC(ffnlk,(npw_k,dimffnlk,psps%lmnmax,ntypat))
    2012        82176 :    if (ipert<=natom) then
    2013        51072 :      ider=0;idir0=0
    2014              :      call mkffnl(psps%dimekb,dimffnlk,psps%ekb,ffnlk,psps%ffspl,&
    2015              :       gmet,gprimd,ider,idir0,psps%indlmn,kg_k,kpg_k,kpoint,psps%lmnmax,&
    2016              :       psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,npw_k,ntypat,&
    2017        51072 :       psps%pspso,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm_k,ylmgr_dum)
    2018              :    end if
    2019              :  else
    2020       839960 :    ABI_CHECK(all(shape(ffnlk) == [npw_k, dimffnlk, psps%lmnmax, ntypat]), "Wrong shape in input ffnlk")
    2021              :  end if
    2022              : 
    2023              : !Compute nonlocal form factors ffnl1 at (k+q+G)
    2024              : !TODO: For the second order gradients, this routine is called for each 3 directions of the
    2025              : !derivative and every time it calculates all the form factors derivatives. This could be
    2026              : !done just once.
    2027              :  !-- 1st q-grad of atomic displacement perturbation
    2028       250168 :  if (ipert<=natom.and..not.present(qdir2)) then
    2029        94648 :    ider=1;idir0=qdir1
    2030              :  !-- 2nd q-grad of atomic displacement perturbation
    2031       155520 :  else if (ipert<=natom.and.present(qdir2)) then
    2032        62208 :    ider=2;idir0=4
    2033              :  !-- 2nd q-grad of metric (1st q-grad of strain) perturbation
    2034        93312 :  else if (ipert==natom+3.or.ipert==natom+4) then
    2035        93312 :    ider=2;idir0=4
    2036              :  end if
    2037              : 
    2038              : !Compute nonlocal form factors ffnl1 at (k+q+G), for all atoms
    2039       250168 :  dimffnl1=1+ider
    2040       250168 :  if (ider==2.and.(idir0==0.or.idir0==4)) dimffnl1=3+7*psps%useylm
    2041              : 
    2042       250168 :  if (reuse_ffnl1_ == 0) then
    2043       493056 :    ABI_MALLOC(ffnl1,(npw1_k,dimffnl1,psps%lmnmax,ntypat))
    2044              :    call mkffnl(psps%dimekb,dimffnl1,psps%ekb,ffnl1,psps%ffspl,gmet,gprimd,ider,idir0,&
    2045              :     psps%indlmn,kg1_k,kpg1_k,kpq,psps%lmnmax,psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg1,&
    2046        82176 :     npw1_k,ntypat,psps%pspso,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm1_k,ylmgr1_k)
    2047              :  else
    2048       839960 :    ABI_CHECK(all(shape(ffnl1) == [npw1_k, dimffnl1, psps%lmnmax, ntypat]), "Wrong shape in input ffnl1")
    2049              :  end if
    2050              : 
    2051              : 
    2052              : !Convert nonlocal form factors to cartesian coordinates.
    2053              : !For metric (strain) perturbation only.
    2054       250168 :  if (ipert==natom+3.or.ipert==natom+4) then
    2055       559872 :    ABI_MALLOC(ffnl1_tmp,(npw1_k,dimffnl1,psps%lmnmax,ntypat))
    2056   1118694240 :    ffnl1_tmp=ffnl1
    2057              : 
    2058              :    !First q-derivative
    2059    336494736 :    ffnl1(:,2:4,:,:)=zero
    2060       373248 :    do mu=1,3
    2061     28025676 :      do ig=1,npw1_k
    2062    110889648 :        do nu=1,3
    2063   1189054404 :          ffnl1(ig,1+mu,:,:)=ffnl1(ig,1+mu,:,:)+ffnl1_tmp(ig,1+nu,:,:)*rprimd(mu,nu)
    2064              :        end do
    2065              :      end do
    2066              :    end do
    2067              : 
    2068              :    !Second q-derivative
    2069    671683104 :    ffnl1(:,5:10,:,:)=zero
    2070       653184 :    do mu=1,6
    2071       559872 :      mua=alpha(mu);mub=beta(mu)
    2072     55958040 :      do ig=1,npw1_k
    2073    221779296 :        do nua=1,3
    2074    718963128 :          do nub=1,3
    2075    497743704 :            nu=gamma(nua,nub)
    2076              :            ffnl1(ig,4+mu,:,:)=ffnl1(ig,4+mu,:,:)+ &
    2077   7134326424 :          & ffnl1_tmp(ig,4+nu,:,:)*rprimd(mua,nua)*rprimd(mub,nub)
    2078              :          end do
    2079              :        end do
    2080              :      end do
    2081              :    end do
    2082              : 
    2083        93312 :    ABI_FREE(ffnl1_tmp)
    2084              :  end if
    2085              : 
    2086              : !===== Preparation of the kinetic contributions
    2087              : ! Compute (1/2) (2 Pi)**2 (k+q+G)**2:
    2088       750504 :  ABI_MALLOC(kinpw1,(npw1_k))
    2089     25316567 :  kinpw1(:)=zero
    2090       250168 :  call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg1_k,kinpw1,kpq,npw1_k,0,0)
    2091              : 
    2092       750504 :  ABI_MALLOC(dqdqkinpw,(npw_k))
    2093              :  !-- Metric (strain) perturbation
    2094       250168 :  if (ipert==natom+3.or.ipert==natom+4) then
    2095        93312 :    call mkkin_metdqdq(dqdqkinpw,dtset%effmass_free,gprimd,idir,kg_k,kpoint,npw_k,qdir1)
    2096              :  else
    2097     16005779 :    dqdqkinpw(:)=zero
    2098              :  end if
    2099              : 
    2100              : !===== Load the k/k+q dependent parts of the Hamiltonian
    2101              : 
    2102              : !Load k-dependent part in the Hamiltonian datastructure
    2103      1000672 :  ABI_MALLOC(ph3d,(2,npw_k,gs_hamkq%matblk))
    2104              :  call gs_hamkq%load_k(kpt_k=kpoint,npw_k=npw_k,istwf_k=istwf_k,kg_k=kg_k,kpg_k=kpg_k,&
    2105       250168 : & ph3d_k=ph3d,compute_ph3d=.true.,compute_gbound=.true.)
    2106              : 
    2107      1250840 :  if (size(ffnlk)>0) then
    2108       156856 :    call gs_hamkq%load_k(ffnl_k=ffnlk)
    2109              :  else
    2110        93312 :    call gs_hamkq%load_k(ffnl_k=ffnl1)
    2111              :  end if
    2112              : 
    2113              : !Load k+q-dependent part in the Hamiltonian datastructure
    2114              : !    Note: istwf_k is imposed to 1 for RF calculations (should use istwf_kq instead)
    2115              :  call gs_hamkq%load_kprime(kpt_kp=kpq,npw_kp=npw1_k,istwf_kp=istwf_k,&
    2116              : & kinpw_kp=kinpw1,kg_kp=kg1_k,kpg_kp=kpg1_k,ffnl_kp=ffnl1,&
    2117       250168 : & compute_gbound=.true.)
    2118              : 
    2119       250168 :  if (qne0) then
    2120            0 :    ABI_MALLOC(ph3d1,(2,npw1_k,gs_hamkq%matblk))
    2121            0 :    call gs_hamkq%load_kprime(ph3d_kp=ph3d1,compute_ph3d=.true.)
    2122              :  end if
    2123              : 
    2124              : !Load k-dependent part in the 1st-order Hamiltonian datastructure
    2125       250168 :  call rf_hamkq%load_k(npw_k=npw_k,dkinpw_k=dqdqkinpw)
    2126              : 
    2127       250168 : end subroutine getgh1dqc_setup
    2128              : !!***
    2129              : 
    2130              : !----------------------------------------------------------------------
    2131              : 
    2132              : !!****f* ABINIT/getgh1ndc
    2133              : !!
    2134              : !! NAME
    2135              : !! getgh1ndc
    2136              : !!
    2137              : !! FUNCTION
    2138              : !! Compute 1st order magnetic nuclear dipole moment contribution to <G|H|C>
    2139              : !! for input vector |C> expressed in reciprocal space.
    2140              : !! Only for DDK perturbation
    2141              : !!
    2142              : !! INPUTS
    2143              : !!
    2144              : !! OUTPUT
    2145              : !!  gh1ndc(2,npw_k*my_nspinor*ndat)=1st order A.p contribution to <G|H|C> for array of nuclear dipoles
    2146              : !!
    2147              : !! NOTES
    2148              : !! This codes only the DDK response for A.p, so effectively A_ipert|C>. The nuclear dipole Hamiltonian
    2149              : !! (to first order in the nuclear dipole strength) is A.p where in atomic units
    2150              : !! A.p=\alpha^2 m x (r-R)/(r-R)^3 . p. Here the components of A have been precomputed in real space
    2151              : !! by make_vectornd. The first-order DDK contribution is i[A.p,r] = A_idir where idir is the
    2152              : !! direction of the DDK perturbation, or 2\pi A_idir when A, p, and r are in reduced coords
    2153              : !!
    2154              : !! SOURCE
    2155              : 
    2156       200556 : subroutine getgh1ndc(cwavein,gh1ndc,gbound_k,istwf_k,kg_k,mgfft,mpi_enreg,&
    2157              : &                      ndat,ngfft,npw_k,nvloc,n4,n5,n6,my_nspinor,&
    2158       200556 : &                      vectornd,vlocal,zora,gpu_option)
    2159              : 
    2160              : !Arguments ------------------------------------
    2161              : !scalars
    2162              :  integer,intent(in) :: istwf_k,mgfft,my_nspinor,ndat,npw_k,nvloc,n4,n5,n6,zora
    2163              :  integer,intent(in) :: gpu_option
    2164              :  type(MPI_type),intent(in) :: mpi_enreg
    2165              : !arrays
    2166              :  integer,intent(in) :: gbound_k(2*mgfft+4),kg_k(3,npw_k),ngfft(18)
    2167              :  real(dp),intent(inout) :: cwavein(2,npw_k*my_nspinor*ndat)
    2168              :  real(dp),intent(inout) :: gh1ndc(2,npw_k*my_nspinor*ndat)
    2169              :  real(dp),intent(inout) :: vectornd(n4,n5,n6,nvloc),vlocal(n4,n5,n6,nvloc)
    2170              : 
    2171              : !Local variables-------------------------------
    2172              : !scalars
    2173              :  integer,parameter :: tim_fourwf=1
    2174              :  integer :: idat,ipw,iv1,iv2,nspinortot,shift
    2175              :  logical :: nspinor1TreatedByThisProc,nspinor2TreatedByThisProc,usezora
    2176              :  real(dp) :: weight=one
    2177              :  real(dp), parameter :: HalfFineStruct2=half/InvFineStruct**2
    2178              :  !arrays
    2179       200556 :  real(dp),allocatable :: cwavein1(:,:),cwavein2(:,:)
    2180       200556 :  real(dp),allocatable :: ghc1(:,:),ghc2(:,:)
    2181       200556 :  real(dp),allocatable :: vectornd_dir(:,:,:,:),work(:,:,:,:),zk(:,:,:)
    2182              : ! *********************************************************************
    2183              : 
    2184    129621024 :  gh1ndc(:,:)=zero
    2185       200556 :  if (nvloc/=1) return
    2186              : 
    2187       200556 :  nspinortot=min(2,(1+mpi_enreg%paral_spinor)*my_nspinor)
    2188       200556 :  if (mpi_enreg%paral_spinor==0) then
    2189       200556 :    shift=npw_k
    2190       200556 :    nspinor1TreatedByThisProc=.true.
    2191       200556 :    nspinor2TreatedByThisProc=(nspinortot==2)
    2192              :  else
    2193            0 :    shift=0
    2194            0 :    nspinor1TreatedByThisProc=(mpi_enreg%me_spinor==0)
    2195            0 :    nspinor2TreatedByThisProc=(mpi_enreg%me_spinor==1)
    2196              :  end if
    2197              : 
    2198       200556 :  usezora=((zora.EQ.1).OR.(zora.EQ.3))
    2199       200556 :  if(usezora) then
    2200            0 :    ABI_MALLOC(zk,(n4,n5,n6))
    2201            0 :    zk(1:n4,1:1:n5,1:n6)=1.0/(1.0-HalfFineStruct2*vlocal(1:n4,1:n5,1:n6,nvloc))
    2202              :  end if
    2203              : 
    2204      1002780 :  ABI_MALLOC(work,(2,n4,n5,n6*ndat))
    2205              : 
    2206       200556 :  if (nspinortot==1) then
    2207              : 
    2208       431172 :    ABI_MALLOC(ghc1,(2,npw_k*ndat))
    2209              : #ifdef HAVE_OPENMP_OFFLOAD
    2210              :    !$OMP TARGET ENTER DATA MAP(alloc:ghc1) IF(gpu_option==ABI_GPU_OPENMP)
    2211              : #endif
    2212              : 
    2213       862344 :    ABI_MALLOC(vectornd_dir,(n4,n5,n6,nvloc))
    2214       143724 :    if (usezora) then
    2215            0 :      vectornd_dir(1:n4,1:n5,1:n6,nvloc)=zk(1:n4,1:n5,1:n6)*vectornd(1:n4,1:n5,1:n6,nvloc)
    2216              :    else
    2217    809155404 :      vectornd_dir(1:n4,1:n5,1:n6,nvloc)=vectornd(1:n4,1:n5,1:n6,nvloc)
    2218              :    end if
    2219              :    ! apply vector potential in direction ipert to input wavefunction
    2220              :    call fourwf(1,vectornd_dir,cwavein,ghc1,work,gbound_k,gbound_k,&
    2221              :      & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
    2222       143724 :      & tim_fourwf,weight,weight,gpu_option=gpu_option)
    2223       143724 :    ABI_FREE(vectornd_dir)
    2224              : 
    2225              :    ! scale by 2\pi
    2226       143724 :    if(gpu_option==ABI_GPU_DISABLED) then
    2227     79694112 :      gh1ndc=two_pi*ghc1
    2228              :    else if(gpu_option==ABI_GPU_OPENMP) then
    2229              : #ifdef HAVE_OPENMP_OFFLOAD
    2230              :      !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO MAP(to:gh1ndc,ghc1) PRIVATE(ipw)
    2231              :      do ipw=1,npw_k*ndat
    2232              :        gh1ndc(1,ipw)=two_pi*ghc1(1,ipw)
    2233              :        gh1ndc(2,ipw)=two_pi*ghc1(2,ipw)
    2234              :      end do
    2235              : #endif
    2236              :    end if
    2237              : 
    2238              : #ifdef HAVE_OPENMP_OFFLOAD
    2239              :    !$OMP TARGET EXIT DATA MAP(delete:ghc1) IF(gpu_option==ABI_GPU_OPENMP)
    2240              : #endif
    2241       143724 :    ABI_FREE(ghc1)
    2242              : 
    2243              :  else ! nspinortot==2
    2244              : 
    2245        56832 :    if (nspinor1TreatedByThisProc) then
    2246              : 
    2247       170496 :      ABI_MALLOC(cwavein1,(2,npw_k*ndat))
    2248       113664 :      ABI_MALLOC(ghc1,(2,npw_k*ndat))
    2249              : #ifdef HAVE_OPENMP_OFFLOAD
    2250              :      !$OMP TARGET ENTER DATA MAP(alloc:ghc1,cwavein1) IF(gpu_option==ABI_GPU_OPENMP)
    2251              : #endif
    2252              : 
    2253        56832 :      if(gpu_option==ABI_GPU_DISABLED) then
    2254       113664 :        do idat=1,ndat
    2255      8425344 :          do ipw=1,npw_k
    2256     24991872 :            cwavein1(1:2,ipw+(idat-1)*npw_k)=cwavein(1:2,ipw+(idat-1)*my_nspinor*npw_k)
    2257              :          end do
    2258              :        end do
    2259              :      else if(gpu_option==ABI_GPU_OPENMP) then
    2260              : #ifdef HAVE_OPENMP_OFFLOAD
    2261              :        !$OMP TARGET TEAMS DISTRIBUTE MAP(to:cwavein1,cwavein) PRIVATE(idat)
    2262              :        do idat=1,ndat
    2263              :          !$OMP PARALLEL DO PRIVATE(ipw)
    2264              :          do ipw=1,npw_k
    2265              :            cwavein1(1,ipw+(idat-1)*npw_k)=cwavein(1,ipw+(idat-1)*my_nspinor*npw_k)
    2266              :            cwavein1(2,ipw+(idat-1)*npw_k)=cwavein(2,ipw+(idat-1)*my_nspinor*npw_k)
    2267              :          end do
    2268              :        end do
    2269              : #endif
    2270              :      end if
    2271              : 
    2272       340992 :      ABI_MALLOC(vectornd_dir,(n4,n5,n6,nvloc))
    2273        56832 :      if (usezora) then
    2274            0 :        vectornd_dir(1:n4,1:n5,1:n6,nvloc)=zk(1:n4,1:n5,1:n6)*vectornd(1:n4,1:n5,1:n6,nvloc)
    2275              :      else
    2276    279215616 :        vectornd_dir(1:n4,1:n5,1:n6,nvloc)=vectornd(1:n4,1:n5,1:n6,nvloc)
    2277              :      end if
    2278              :      call fourwf(1,vectornd_dir,cwavein1,ghc1,work,gbound_k,gbound_k,&
    2279              :        & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
    2280        56832 :        & tim_fourwf,weight,weight,gpu_option=gpu_option)
    2281        56832 :      ABI_FREE(vectornd_dir)
    2282              : 
    2283        56832 :      if(gpu_option==ABI_GPU_DISABLED) then
    2284       113664 :        do idat=1,ndat
    2285        56832 :          iv1=1+(idat-1)*npw_k; iv2=npw_k+(idat-1)*npw_k
    2286     25048704 :          gh1ndc(1:2,iv1:iv2)=two_pi*ghc1(1:2,iv1:iv2)
    2287              :        end do
    2288              :      else if(gpu_option==ABI_GPU_OPENMP) then
    2289              : #ifdef HAVE_OPENMP_OFFLOAD
    2290              :        !$OMP TARGET TEAMS DISTRIBUTE MAP(to:gh1ndc,ghc1) PRIVATE(idat)
    2291              :        do idat=1,ndat
    2292              :          !$OMP PARALLEL DO PRIVATE(ipw)
    2293              :          do ipw=1,npw_k
    2294              :            gh1ndc(1,ipw+(idat-1)*npw_k)=two_pi*ghc1(1,ipw+(idat-1)*npw_k)
    2295              :            gh1ndc(2,ipw+(idat-1)*npw_k)=two_pi*ghc1(2,ipw+(idat-1)*npw_k)
    2296              :          end do
    2297              :        end do
    2298              : #endif
    2299              :      end if
    2300              : 
    2301              : #ifdef HAVE_OPENMP_OFFLOAD
    2302              :      !$OMP TARGET EXIT DATA MAP(delete:ghc1,cwavein1) IF(gpu_option==ABI_GPU_OPENMP)
    2303              : #endif
    2304        56832 :      ABI_FREE(ghc1)
    2305        56832 :      ABI_FREE(cwavein1)
    2306              : 
    2307              :    end if ! end spinor 1
    2308              : 
    2309        56832 :    if (nspinor2TreatedByThisProc) then
    2310              : 
    2311       170496 :      ABI_MALLOC(cwavein2,(2,npw_k*ndat))
    2312       113664 :      ABI_MALLOC(ghc2,(2,npw_k*ndat))
    2313              : #ifdef HAVE_OPENMP_OFFLOAD
    2314              :      !$OMP TARGET ENTER DATA MAP(alloc:ghc2,cwavein2) IF(gpu_option==ABI_GPU_OPENMP)
    2315              : #endif
    2316              : 
    2317        56832 :      if(gpu_option==ABI_GPU_DISABLED) then
    2318       113664 :        do idat=1,ndat
    2319      8425344 :          do ipw=1,npw_k
    2320     24991872 :            cwavein2(1:2,ipw+(idat-1)*npw_k)=cwavein(1:2,ipw+(idat-1)*my_nspinor*npw_k+shift)
    2321              :          end do
    2322              :        end do
    2323              :      else if(gpu_option==ABI_GPU_OPENMP) then
    2324              : #ifdef HAVE_OPENMP_OFFLOAD
    2325              :        !$OMP TARGET TEAMS DISTRIBUTE MAP(to:cwavein2,cwavein) PRIVATE(idat)
    2326              :        do idat=1,ndat
    2327              :          !$OMP PARALLEL DO PRIVATE(ipw)
    2328              :          do ipw=1,npw_k
    2329              :            cwavein2(1,ipw+(idat-1)*npw_k)=cwavein(1,ipw+(idat-1)*my_nspinor*npw_k+shift)
    2330              :            cwavein2(2,ipw+(idat-1)*npw_k)=cwavein(2,ipw+(idat-1)*my_nspinor*npw_k+shift)
    2331              :          end do
    2332              :        end do
    2333              : #endif
    2334              :      end if
    2335              : 
    2336       340992 :      ABI_MALLOC(vectornd_dir,(n4,n5,n6,nvloc))
    2337        56832 :      if (usezora) then
    2338            0 :        vectornd_dir(1:n4,1:n5,1:n6,nvloc)=zk(1:n4,1:n5,1:n6)*vectornd(1:n4,1:n5,1:n6,nvloc)
    2339              :      else
    2340    279215616 :        vectornd_dir(1:n4,1:n5,1:n6,nvloc)=vectornd(1:n4,1:n5,1:n6,nvloc)
    2341              :      end if
    2342              :      call fourwf(1,vectornd_dir,cwavein2,ghc2,work,gbound_k,gbound_k,&
    2343              :        & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
    2344        56832 :        & tim_fourwf,weight,weight,gpu_option=gpu_option)
    2345        56832 :      ABI_FREE(vectornd_dir)
    2346              : 
    2347        56832 :      if(gpu_option==ABI_GPU_DISABLED) then
    2348       113664 :        do idat=1,ndat
    2349        56832 :          iv1=1+(idat-1)*npw_k; iv2=npw_k+(idat-1)*npw_k
    2350     25048704 :          gh1ndc(1:2,iv1+shift:iv2+shift)=two_pi*ghc2(1:2,iv1:iv2)
    2351              :        end do
    2352              :      else if(gpu_option==ABI_GPU_OPENMP) then
    2353              : #ifdef HAVE_OPENMP_OFFLOAD
    2354              :        !$OMP TARGET TEAMS DISTRIBUTE MAP(to:gh1ndc,ghc2) PRIVATE(idat)
    2355              :        do idat=1,ndat
    2356              :          !$OMP PARALLEL DO PRIVATE(ipw)
    2357              :          do ipw=1,npw_k
    2358              :            gh1ndc(1,ipw+(idat-1)*npw_k+shift)=two_pi*ghc2(1,ipw+(idat-1)*npw_k)
    2359              :            gh1ndc(2,ipw+(idat-1)*npw_k+shift)=two_pi*ghc2(2,ipw+(idat-1)*npw_k)
    2360              :          end do
    2361              :        end do
    2362              : #endif
    2363              :      end if
    2364              : 
    2365              : #ifdef HAVE_OPENMP_OFFLOAD
    2366              :      !$OMP TARGET EXIT DATA MAP(delete:ghc2,cwavein2) IF(gpu_option==ABI_GPU_OPENMP)
    2367              : #endif
    2368        56832 :      ABI_FREE(ghc2)
    2369        56832 :      ABI_FREE(cwavein2)
    2370              : 
    2371              :    end if ! end spinor 2
    2372              : 
    2373              :  end if ! nspinortot
    2374              : 
    2375       200556 :  ABI_FREE(work)
    2376       200556 :  if (usezora) then
    2377            0 :    ABI_FREE(zk)
    2378              :  end if
    2379              : 
    2380       200556 : end subroutine getgh1ndc
    2381              : !!***
    2382              : 
    2383              : !!****f* ABINIT/getgh1c_mGGA
    2384              : !!
    2385              : !! NAME
    2386              : !! getgh1c_mGGA
    2387              : !!
    2388              : !! FUNCTION
    2389              : !! Compute first order metaGGA contribution to <G|H|C> for input vector |C> expressed in reciprocal space.
    2390              : !! ONLY FOR DDK PERTURBATION
    2391              : !!
    2392              : !! INPUTS
    2393              : !!
    2394              : !! OUTPUT
    2395              : !!  gh1c_mGGA(2,npw_k*my_nspinor*ndat)=metaGGA contribution to <G|H1|C>
    2396              : !!
    2397              : !! SIDE EFFECTS
    2398              : !!
    2399              : !! SOURCE
    2400              : 
    2401        19584 : subroutine getgh1c_mGGA(cwavein,gbound_k,gh1c_mGGA,gmet,gprimd,idir,istwf_k,kg_k,&
    2402        19584 :      & kpt,mgfft,mpi_enreg,my_nspinor,n4,n5,n6,ndat,ngfft,npw_k,nvloc,vxctaulocal,gpu_option)
    2403              : 
    2404              : !Arguments ------------------------------------
    2405              : !scalars
    2406              :  integer,intent(in) :: idir,istwf_k,mgfft,my_nspinor,n4,n5,n6,ndat,npw_k,nvloc
    2407              :  integer,intent(in),optional :: gpu_option
    2408              :  type(MPI_type),intent(in) :: mpi_enreg
    2409              : !arrays
    2410              :  integer,intent(in) :: gbound_k(2*mgfft+4),kg_k(3,npw_k),ngfft(18)
    2411              :  real(dp),intent(in) :: gmet(3,3),gprimd(3,3),kpt(3)
    2412              :  real(dp),intent(inout) :: cwavein(2,npw_k*my_nspinor*ndat)
    2413              :  real(dp),intent(inout) :: gh1c_mGGA(2,npw_k*my_nspinor*ndat)
    2414              :  real(dp),intent(inout) :: vxctaulocal(n4,n5,n6,nvloc,4)
    2415              : 
    2416              : !Local variables-------------------------------
    2417              :  !scalars
    2418              :  integer :: idat,ii,ipw,nspinortot,shift,gpu_option_
    2419              :  integer,parameter :: tim_fourwf=1
    2420              :  real(dp) :: weight=one
    2421              :  logical :: nspinor1TreatedByThisProc,nspinor2TreatedByThisProc
    2422              :  !arrays
    2423        19584 :  real(dp),allocatable :: cwavein1(:,:),cwavein2(:,:),dgcwavef(:,:,:),dlcwavef(:,:)
    2424        19584 :  real(dp),allocatable :: ghc1(:,:),ghc2(:,:),work(:,:,:,:)
    2425              : 
    2426              :  if(present(gpu_option)) then
    2427              :     gpu_option_=gpu_option
    2428              :  else
    2429              :     gpu_option_=0
    2430              :  end if
    2431              : 
    2432     14340384 :  gh1c_mGGA(:,:)=zero
    2433              : 
    2434        19584 :  if (nvloc/=1) return
    2435              : 
    2436        19584 :  nspinortot=min(2,(1+mpi_enreg%paral_spinor)*my_nspinor)
    2437        19584 :  if (mpi_enreg%paral_spinor==0) then
    2438        19584 :    shift=npw_k
    2439        19584 :    nspinor1TreatedByThisProc=.true.
    2440        19584 :    nspinor2TreatedByThisProc=(nspinortot==2)
    2441              :  else
    2442            0 :    shift=0
    2443            0 :    nspinor1TreatedByThisProc=(mpi_enreg%me_spinor==0)
    2444            0 :    nspinor2TreatedByThisProc=(mpi_enreg%me_spinor==1)
    2445              :  end if
    2446              : 
    2447        97920 :  ABI_MALLOC(work,(2,n4,n5,n6*ndat))
    2448              : 
    2449        19584 :  if (nspinortot==1) then
    2450              : 
    2451        19584 :    ABI_MALLOC(ghc1,(2,npw_k*ndat))
    2452        26112 :    ABI_MALLOC(dgcwavef,(2,npw_k*ndat,3))
    2453        13056 :    ABI_MALLOC(dlcwavef,(2,npw_k*ndat))
    2454              : 
    2455              : !!$OMP PARALLEL DO
    2456     11482752 :    dgcwavef = zero; dlcwavef = zero
    2457        13056 :    do idat=1,ndat
    2458       967776 :      do ipw=1,npw_k
    2459      3818880 :        dgcwavef(1,ipw+(idat-1)*npw_k,1:3)=+half*gprimd(idir,1:3)*cwavein(2,ipw+(idat-1)*npw_k)
    2460      3818880 :        dgcwavef(2,ipw+(idat-1)*npw_k,1:3)=-half*gprimd(idir,1:3)*cwavein(1,ipw+(idat-1)*npw_k)
    2461              :        dlcwavef(1:2,ipw+(idat-1)*npw_k)=two_pi*two_pi*DOT_PRODUCT(gmet(idir,:),(kpt(:)+kg_k(:,ipw)))*&
    2462      5734848 :          &cwavein(1:2,ipw+(idat-1)*npw_k)
    2463              :      end do
    2464              :    end do
    2465              : !  STEP2: Compute (vxctaulocal)*(Laplacian of cwavef) and add it to ghc
    2466      2870688 :    ghc1=zero
    2467              :    call fourwf(1,vxctaulocal(:,:,:,:,1),dlcwavef,ghc1,work,gbound_k,gbound_k,&
    2468              : &   istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
    2469         6528 : &   tim_fourwf,weight,weight,gpu_option=gpu_option)
    2470              : !!$OMP PARALLEL DO
    2471        13056 :    do idat=1,ndat
    2472       967776 :      do ipw=1,npw_k
    2473      2870688 :        gh1c_mGGA(:,ipw+(idat-1)*npw_k)=gh1c_mGGA(:,ipw+(idat-1)*npw_k)+ghc1(:,ipw+(idat-1)*npw_k)
    2474              :      end do
    2475              :    end do
    2476              : !  STEP3: Compute sum of (grad components of vxctaulocal)*(grad components of cwavef)
    2477        26112 :    do ii=1,3
    2478      8612064 :      ghc1=zero
    2479              :      call fourwf(1,vxctaulocal(:,:,:,:,1+ii),dgcwavef(:,:,ii),ghc1,work,gbound_k,gbound_k,&
    2480              :      istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
    2481        19584 : &      tim_fourwf,weight,weight,gpu_option=gpu_option)
    2482              : !!$OMP PARALLEL DO
    2483        45696 :      do idat=1,ndat
    2484      2903328 :        do ipw=1,npw_k
    2485      8612064 :          gh1c_mGGA(:,ipw+(idat-1)*npw_k)=gh1c_mGGA(:,ipw+(idat-1)*npw_k)+ghc1(:,ipw+(idat-1)*npw_k)
    2486              :        end do
    2487              :      end do
    2488              :    end do ! ii
    2489         6528 :    ABI_FREE(dgcwavef)
    2490         6528 :    ABI_FREE(dlcwavef)
    2491         6528 :    ABI_FREE(ghc1)
    2492              : 
    2493              :  else ! nspinortot==2
    2494              : 
    2495        39168 :    ABI_MALLOC(cwavein1,(2,npw_k*ndat))
    2496        26112 :    ABI_MALLOC(cwavein2,(2,npw_k*ndat))
    2497        26112 :    do idat=1,ndat
    2498      1935552 :      do ipw=1,npw_k
    2499      5728320 :        cwavein1(1:2,ipw+(idat-1)*npw_k)=cwavein(1:2,ipw+(idat-1)*my_nspinor*npw_k)
    2500      5741376 :        cwavein2(1:2,ipw+(idat-1)*npw_k)=cwavein(1:2,ipw+(idat-1)*my_nspinor*npw_k+shift)
    2501              :      end do
    2502              :    end do
    2503              : 
    2504        13056 :    if (nspinor1TreatedByThisProc) then
    2505        26112 :      ABI_MALLOC(ghc1,(2,npw_k*ndat))
    2506        52224 :      ABI_MALLOC(dgcwavef,(2,npw_k*ndat,3))
    2507        26112 :      ABI_MALLOC(dlcwavef,(2,npw_k*ndat))
    2508              : 
    2509     22965504 :      dgcwavef = zero; dlcwavef = zero
    2510        26112 :      do idat=1,ndat
    2511      1935552 :        do ipw=1,npw_k
    2512      7637760 :          dgcwavef(1,ipw+(idat-1)*npw_k,1:3)=+half*gprimd(idir,1:3)*cwavein1(2,ipw+(idat-1)*npw_k)
    2513      7637760 :          dgcwavef(2,ipw+(idat-1)*npw_k,1:3)=-half*gprimd(idir,1:3)*cwavein1(1,ipw+(idat-1)*npw_k)
    2514              :          dlcwavef(1:2,ipw+(idat-1)*npw_k)=two_pi*two_pi*DOT_PRODUCT(gmet(idir,:),(kpt(:)+kg_k(:,ipw)))*&
    2515     11469696 :            &cwavein1(1:2,ipw+(idat-1)*npw_k)
    2516              :        end do
    2517              :      end do
    2518              : !    STEP2: Compute (vxctaulocal)*(Laplacian of cwavef) and add it to ghc
    2519      5741376 :      ghc1=zero
    2520              :      call fourwf(1,vxctaulocal(:,:,:,:,1),dlcwavef,ghc1,work,gbound_k,gbound_k,&
    2521              : &      istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
    2522        13056 : &      tim_fourwf,weight,weight,gpu_option=gpu_option)
    2523        26112 :      do idat=1,ndat
    2524      1935552 :        do ipw=1,npw_k
    2525      5741376 :          gh1c_mGGA(:,ipw+(idat-1)*my_nspinor*npw_k)=gh1c_mGGA(:,ipw+(idat-1)*my_nspinor*npw_k)+ghc1(:,ipw+(idat-1)*npw_k)
    2526              :        end do
    2527              :      end do
    2528              : !    STEP3: Compute sum of (grad components of vxctaulocal)*(grad components of cwavef)
    2529        52224 :      do ii=1,3
    2530     17224128 :        ghc1=zero
    2531              :        call fourwf(1,vxctaulocal(:,:,:,:,1+ii),dgcwavef(:,:,ii),ghc1,work,gbound_k,gbound_k,&
    2532              :        istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
    2533        39168 : &        tim_fourwf,weight,weight,gpu_option=gpu_option)
    2534        91392 :        do idat=1,ndat
    2535      5806656 :          do ipw=1,npw_k
    2536     17224128 :            gh1c_mGGA(:,ipw+(idat-1)*my_nspinor*npw_k)=gh1c_mGGA(:,ipw+(idat-1)*my_nspinor*npw_k)+ghc1(:,ipw+(idat-1)*npw_k)
    2537              :          end do
    2538              :        end do
    2539              :      end do ! ii
    2540        13056 :      ABI_FREE(dgcwavef)
    2541        13056 :      ABI_FREE(dlcwavef)
    2542              : 
    2543        13056 :      ABI_FREE(ghc1)
    2544              :    end if ! end spinor 1
    2545              : 
    2546        13056 :    if (nspinor2TreatedByThisProc) then
    2547        26112 :      ABI_MALLOC(ghc2,(2,npw_k*ndat))
    2548        52224 :      ABI_MALLOC(dgcwavef,(2,npw_k*ndat,3))
    2549        26112 :      ABI_MALLOC(dlcwavef,(2,npw_k*ndat))
    2550              : 
    2551     22965504 :      dgcwavef = zero; dlcwavef = zero
    2552        26112 :      do idat=1,ndat
    2553      1935552 :        do ipw=1,npw_k
    2554      7637760 :          dgcwavef(1,ipw+(idat-1)*npw_k,1:3)=+half*gprimd(idir,1:3)*cwavein2(2,ipw+(idat-1)*npw_k)
    2555      7637760 :          dgcwavef(2,ipw+(idat-1)*npw_k,1:3)=-half*gprimd(idir,1:3)*cwavein2(1,ipw+(idat-1)*npw_k)
    2556              :          dlcwavef(1:2,ipw+(idat-1)*npw_k)=two_pi*two_pi*DOT_PRODUCT(gmet(idir,:),(kpt(:)+kg_k(:,ipw)))*&
    2557     11469696 :            &cwavein2(1:2,ipw+(idat-1)*npw_k)
    2558              :        end do
    2559              :      end do
    2560              : !    STEP2: Compute (vxctaulocal)*(Laplacian of cwavef) and add it to ghc
    2561      5741376 :      ghc2=zero
    2562              :      call fourwf(1,vxctaulocal(:,:,:,:,1),dlcwavef,ghc2,work,gbound_k,gbound_k,&
    2563              : &      istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
    2564        13056 : &      tim_fourwf,weight,weight,gpu_option=gpu_option)
    2565        26112 :      do idat=1,ndat
    2566      1935552 :        do ipw=1,npw_k
    2567              :          gh1c_mGGA(:,ipw+(idat-1)*my_nspinor*npw_k+shift)=gh1c_mGGA(:,ipw+(idat-1)*my_nspinor*npw_k+shift)+&
    2568      5741376 :            & ghc2(:,ipw+(idat-1)*npw_k)
    2569              :        end do
    2570              :      end do
    2571              : !    STEP3: Compute sum of (grad components of vxctaulocal)*(grad components of cwavef)
    2572        52224 :      do ii=1,3
    2573     17224128 :        ghc2=zero
    2574              :        call fourwf(1,vxctaulocal(:,:,:,:,1+ii),dgcwavef(:,:,ii),ghc2,work,gbound_k,gbound_k,&
    2575              :        istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
    2576        39168 : &        tim_fourwf,weight,weight,gpu_option=gpu_option)
    2577        91392 :        do idat=1,ndat
    2578      5806656 :          do ipw=1,npw_k
    2579              :            gh1c_mGGA(:,ipw+(idat-1)*my_nspinor*npw_k+shift)=gh1c_mGGA(:,ipw+(idat-1)*my_nspinor*npw_k+shift)+&
    2580     17224128 :              & ghc2(:,ipw+(idat-1)*npw_k)
    2581              :          end do
    2582              :        end do
    2583              :      end do ! ii
    2584        13056 :      ABI_FREE(dgcwavef)
    2585        13056 :      ABI_FREE(dlcwavef)
    2586              : 
    2587        13056 :      ABI_FREE(ghc2)
    2588              :    end if ! end spinor 2
    2589              : 
    2590        13056 :    ABI_FREE(cwavein1)
    2591        13056 :    ABI_FREE(cwavein2)
    2592              : 
    2593              :  end if ! nspinortot
    2594              : 
    2595        19584 :  ABI_FREE(work)
    2596              : 
    2597              : end subroutine getgh1c_mGGA
    2598              : !!***
    2599              : 
    2600              : end module m_getgh1c
    2601              : !!***
        

Generated by: LCOV version 2.3-1