LCOV - code coverage report
Current view: top level - src/72_response - m_dfpt_mkrho.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 69.3 % 374 259
Test Date: 2026-09-19 17:42:43 Functions: 100.0 % 4 4

            Line data    Source code
       1              : !!****m* ABINIT/m_dfpt_mkrho
       2              : !! NAME
       3              : !!  m_dfpt_mkrho
       4              : !!
       5              : !! FUNCTION
       6              : !! Compute RF charge density rho1(r) and rho1(G) in electrons/bohr**3
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, LSI, AR, MB, 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_dfpt_mkrho
      26              : 
      27              :  use defs_basis
      28              :  use m_abicore
      29              :  use m_errors
      30              :  use m_cgtools
      31              :  use m_xmpi
      32              : 
      33              :  use defs_abitypes, only : MPI_type
      34              :  use m_time,            only : timab
      35              :  use m_io_tools,        only : get_unit, iomode_from_fname
      36              :  use m_fftcore,         only : sphereboundary
      37              :  use m_fft,             only : fftpac, fourwf
      38              :  use m_spacepar,        only : symrhg
      39              :  use m_hamiltonian,     only : gs_hamiltonian_type
      40              :  use m_pawrhoij,        only : pawrhoij_type
      41              :  use m_pawcprj,         only : pawcprj_type, pawcprj_alloc, pawcprj_free
      42              :  use m_paw_occupancies, only : pawaccrhoij
      43              :  use m_paral_atom,      only : get_my_atmtab
      44              :  use m_mpinfo,          only : proc_distrb_cycle
      45              :  use m_cgprj,           only : getcprj
      46              : 
      47              : #if defined(HAVE_GPU_MARKERS)
      48              :  use m_nvtx_data
      49              : #endif
      50              : 
      51              :  implicit none
      52              : 
      53              :  private
      54              : !!***
      55              : 
      56              :  public :: dfpt_mkrho
      57              :  public :: dfpt_accrho
      58              : !!***
      59              : 
      60              : contains
      61              : !!***
      62              : 
      63              : !!****f* ABINIT/dfpt_mkrho
      64              : !! NAME
      65              : !! dfpt_mkrho
      66              : !!
      67              : !! FUNCTION
      68              : !! Compute RF charge density rho1(r) and rho1(G) in electrons/bohr**3
      69              : !! from input RF and GS wavefunctions, band occupations, and k point weights.
      70              : !!
      71              : !! INPUTS
      72              : !!  cg(2,mpw*nspinor*mband*mkmem*nsppol)=wf in G space
      73              : !!  cg1(2,mpw1*nspinor*mband*mk1mem*nsppol)=first-order wf in G space
      74              : !!  cplex=1 if rhor1 is real, 2 if rhor1 is complex
      75              : !!  gprimd(3,3)=dimensional reciprocal space primitive translations
      76              : !!  irrzon(nfft**(1-1/nsym),2,(nspden/nsppol)-3*(nspden/4))=irreducible zone data
      77              : !!  istwfk_rbz(nkpt_rbz)=input option parameter that describes the storage of wfs
      78              : !!  kg(3,mpw*mkmem)=reduced planewave coordinates, GS data.
      79              : !!  kg1(3,mpw1*mkmem1)=reduced planewave coordinates, RF data.
      80              : !!  mband=maximum number of bands
      81              : !!  mgfft=maximum size of 1D FFTs
      82              : !!  mkmem=Number of k points treated by this node (GS data)
      83              : !!  mk1mem=Number of k points treated by this node (RF data)
      84              : !!  mpi_enreg=information about MPI parallelization
      85              : !!  mpw=maximum allowed value for npw (GS wfs)
      86              : !!  mpw1=maximum allowed value for npw1 (RF data)
      87              : !!  nband_rbz(nkpt_rbz*nsppol)=number of bands to be included in summation
      88              : !!   at each k point for each spin channel.
      89              : !!  nfft=(effective) number of FFT grid points (for this processor)
      90              : !!  ngfft(18)=contain all needed information about 3D FFT,
      91              : !!    see ~abinit/doc/variables/vargs.htm#ngfft
      92              : !!  nkpt_rbz=number of k points in the reduced Brillouin zone
      93              : !!  npwarr(nkpt_rbz)=number of planewaves and boundary planewaves at k points
      94              : !!  npwar1(nkpt_rbz)=number of planewaves and boundary planewaves at k+q points
      95              : !!  nspden=number of spin-density components
      96              : !!  nspinor=number of spinorial components of the wavefunctions
      97              : !!  nsppol=1 for unpolarized, 2 for spin-polarized
      98              : !!  nsym=number of symmetry elements in group (at least 1 for identity)
      99              : !!  occ_rbz(mband*nkpt_rbz*nsppol)=occupation numbers for each band
     100              : !!   (usually 2.0) at each k point of the reduced Brillouin zone
     101              : !!  phnons(2,nfft**(1-1/nsym),(nspden/nsppol)-3*(nspden/4))=nonsymmorphic translation phases
     102              : !!  rprimd(3,3)=dimensional real space primitive translations
     103              : !!  symafm(nsym)=(anti)ferromagnetic part of symmetry operations
     104              : !!  symrel(3,3,nsym)=symmetry matrices in real space (integers)
     105              : !!  ucvol=unit cell volume (Bohr**3)
     106              : !!  wtk_rbz(nkpt_rbz)=k point weights (they sum to 1.0).
     107              : !!
     108              : !! OUTPUT
     109              : !!  rhog1(2,nfft)=total electron density in G space
     110              : !!  rhor1(cplex*nfft,nspden)=electron density in r space
     111              : !!   (if spin polarized, array contains total density in first half and
     112              : !!    spin-up density in second half)
     113              : !!
     114              : !! SOURCE
     115              : 
     116            8 : subroutine dfpt_mkrho(cg,cg1,cplex,gprimd,irrzon,istwfk_rbz,&
     117            8 : & kg,kg1,mband,mband_mem,mgfft,mkmem,mk1mem,mpi_enreg,mpw,mpw1,nband_rbz,&
     118            8 : & nfft,ngfft,nkpt_rbz,npwarr,npwar1,nspden,nspinor,nsppol,nsym,&
     119            8 : & occ_rbz,phnons,rhog1,rhor1,rprimd,symafm,symrel,tnons,ucvol,wtk_rbz)
     120              : 
     121              : !Arguments ------------------------------------
     122              : !scalars
     123              :  integer,intent(in) :: cplex,mband,mband_mem,mgfft,mk1mem,mkmem,mpw,mpw1,nfft,nkpt_rbz
     124              :  integer,intent(in) :: nspden,nspinor,nsppol,nsym
     125              :  real(dp),intent(in) :: ucvol
     126              :  type(MPI_type),intent(in) :: mpi_enreg
     127              : !arrays
     128              :  integer,intent(in) :: irrzon(nfft**(1-1/nsym),2,(nspden/nsppol)-3*(nspden/4))
     129              :  integer,intent(in) :: istwfk_rbz(nkpt_rbz),kg(3,mpw*mkmem),kg1(3,mpw1*mk1mem)
     130              :  integer,intent(in) :: nband_rbz(nkpt_rbz*nsppol),ngfft(18),npwar1(nkpt_rbz)
     131              :  integer,intent(in) :: npwarr(nkpt_rbz),symafm(nsym),symrel(3,3,nsym)
     132              :  real(dp),intent(in) :: cg(2,mpw*nspinor*mband_mem*mkmem*nsppol)
     133              :  real(dp),intent(in) :: cg1(2,mpw1*nspinor*mband_mem*mk1mem*nsppol),gprimd(3,3)
     134              :  real(dp),intent(in) :: occ_rbz(mband*nkpt_rbz*nsppol)
     135              :  real(dp),intent(in) :: phnons(2,nfft**(1-1/nsym),(nspden/nsppol)-3*(nspden/4))
     136              :  real(dp),intent(in) :: rprimd(3,3),tnons(3,nsym)
     137              :  real(dp),intent(in) :: wtk_rbz(nkpt_rbz)
     138              :  real(dp),intent(out) :: rhog1(2,nfft),rhor1(cplex*nfft,nspden)
     139              : 
     140              : !Local variables-------------------------------
     141              : !scalars
     142              :  integer,parameter :: tim_fourwf7=7,tim_rwwf15=15
     143              :  integer,save :: nskip=0
     144              :  integer :: bdtot_index,i1,i2,i3,iband,icg,icg1,ierr,ifft,ikg,ptr
     145              :  integer :: iband_me
     146              :  integer :: ikg1,ikpt,ispden,ispinor,isppol,istwf_k,ptr1,ptr2
     147              :  integer :: me,n1,n2,n3,n4,n5,n6,nband_k,npw1_k
     148              :  integer :: npw_k,spaceworld
     149              :  real(dp) :: im0,im1,re0,re1,weight
     150              :  real(dp) :: im0_up,im1_up,re0_up,re1_up,im0_down,im1_down,re0_down,re1_down
     151              :  character(len=500) :: message
     152              : !arrays
     153            8 :  integer,allocatable :: gbound(:,:),gbound1(:,:),kg1_k(:,:)
     154            8 :  integer,allocatable :: kg_k(:,:)
     155              :  real(dp) :: tsec(2)
     156            8 :  real(dp),allocatable,target :: cwavef(:,:),cwavef1(:,:)
     157            8 :  real(dp),allocatable :: dummy(:,:),rhoaug(:,:,:,:)
     158            8 :  real(dp),allocatable :: rhoaug1(:,:,:,:),wfraug(:,:,:,:),wfraug1(:,:,:,:)
     159            8 :  real(dp),allocatable :: wfraug1_up(:,:,:,:),wfraug1_down(:,:,:,:)
     160            8 :  real(dp),allocatable :: wfraug_up(:,:,:,:),wfraug_down(:,:,:,:)
     161            8 :  real(dp),allocatable :: cwave0_up(:,:),cwave0_down(:,:),cwave1_up(:,:),cwave1_down(:,:)
     162              : 
     163              : ! *************************************************************************
     164              : 
     165              : !DBG_ENTER("COLL")
     166              :  ABI_NVTX_START_RANGE(NVTX_DFPT_MKRHO)
     167              : 
     168            8 :  if(nspden==4)then
     169              : !  NOTE: see mkrho for the modifications needed for non-collinear treatment
     170              :    write(message, '(3a)' )&
     171            0 :     ' Linear-response calculations are under construction with nspden=4',ch10,&
     172            0 :     ' Action: modify value of nspden in input file unless you know what you are doing.'
     173            0 :    ABI_WARNING(message)
     174              :  end if
     175              : 
     176              : !Init spaceworld
     177            8 :  spaceworld=mpi_enreg%comm_cell
     178            8 :  me=mpi_enreg%me_kpt
     179              : 
     180              : !zero the charge density array in real space
     181              : !$OMP PARALLEL DO
     182           16 :  do ispden=1,nspden
     183        28976 :    do ifft=1,cplex*nfft
     184        28968 :      rhor1(ifft,ispden)=zero
     185              :    end do
     186              :  end do
     187              : 
     188              : !start loop over spin and k points
     189            8 :  bdtot_index=0; icg=0; icg1=0
     190              : 
     191            8 :  n1=ngfft(1); n2=ngfft(2); n3=ngfft(3)
     192            8 :  n4=ngfft(4); n5=ngfft(5); n6=ngfft(6) !n4,n5,n6 are FFT dimensions, modified to avoid cache trashing
     193              : 
     194              : !Note that the dimensioning of cwavef and cwavef1 does not include nspinor
     195           24 :  ABI_MALLOC(cwavef,(2,mpw))
     196           24 :  ABI_MALLOC(cwavef1,(2,mpw1))
     197              : !Actually, rhoaug is not needed, except for strong dimensioning requirement
     198            8 :  ABI_MALLOC(dummy,(2,1))
     199           48 :  ABI_MALLOC(rhoaug,(n4,n5,n6,nspinor**2))
     200           48 :  ABI_MALLOC(rhoaug1,(cplex*n4,n5,n6,nspinor**2))
     201           40 :  ABI_MALLOC(wfraug,(2,n4,n5,n6))
     202           32 :  ABI_MALLOC(wfraug1,(2,n4,n5,n6))
     203              : 
     204              : ! EB FR Separate collinear and non-collinear magnetism
     205            8 :  if (nspden /= 4) then  ! EB FR nspden check
     206           16 :    do isppol=1,nsppol
     207              : 
     208           16 :      ikg=0; ikg1=0
     209              : 
     210        34544 :      rhoaug1(:,:,:,:)=zero
     211              : 
     212          370 :      do ikpt=1,nkpt_rbz
     213              : 
     214          362 :        nband_k=nband_rbz(ikpt+(isppol-1)*nkpt_rbz)
     215          362 :        istwf_k=istwfk_rbz(ikpt)
     216          362 :        npw_k=npwarr(ikpt)
     217          362 :        npw1_k=npwar1(ikpt)
     218              : 
     219          362 :        if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me)) then
     220          216 :          bdtot_index=bdtot_index+nband_k
     221          216 :          cycle
     222              :        end if
     223              : 
     224          584 :        ABI_MALLOC(gbound,(2*mgfft+8,2))
     225          438 :        ABI_MALLOC(kg_k,(3,npw_k))
     226          292 :        ABI_MALLOC(gbound1,(2*mgfft+8,2))
     227          438 :        ABI_MALLOC(kg1_k,(3,npw1_k))
     228              : 
     229        73582 :        kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
     230          146 :        call sphereboundary(gbound,istwf_k,kg_k,mgfft,npw_k)
     231              : 
     232        73582 :        kg1_k(:,1:npw1_k)=kg1(:,1+ikg1:npw1_k+ikg1)
     233          146 :        call sphereboundary(gbound1,istwf_k,kg1_k,mgfft,npw1_k)
     234              : 
     235              : !    Loop over bands to fft and square for rho(r)
     236          146 :        iband_me = 0
     237         1306 :        do iband=1,nband_k
     238         1160 :          if (mpi_enreg%proc_distrb(ikpt,iband,isppol)/=me) cycle
     239         1160 :          iband_me = iband_me + 1
     240              : !      Only treat occupied states
     241         1306 :          if (abs(occ_rbz(iband+bdtot_index))>tol8) then
     242              : !        Treat separately the two spinor components
     243         1168 :            do ispinor=1,nspinor
     244              : !          Obtain Fourier transform in fft box and accumulate the density
     245          584 :              ptr = 1 + (ispinor-1)*npw_k + (iband_me-1)*npw_k*nspinor + icg
     246          584 :              call cg_zcopy(npw_k, cg(1,ptr), cwavef)
     247              : 
     248              : !      In these two calls, rhoaug, rhoaug1 and weight are dummy variables, and are not modified
     249              :              call fourwf(1,rhoaug,cwavef,dummy,wfraug,gbound,gbound,&
     250          584 : &             istwf_k,kg_k,kg_k,mgfft,mpi_enreg,1,ngfft,npw_k,1,n4,n5,n6,0,tim_fourwf7,weight,weight)
     251              : 
     252              : ! TODO: here ispinor should be ispinorp to get full matrix and nspden 4
     253          584 :              ptr = 1 + (ispinor-1)*npw1_k + (iband_me-1)*npw1_k*nspinor + icg1
     254          584 :              call cg_zcopy(npw1_k, cg1(1,ptr), cwavef1)
     255              : 
     256              :              call fourwf(cplex,rhoaug1,cwavef1,dummy,wfraug1,gbound1,gbound1,&
     257              : &             istwf_k,kg1_k,kg1_k,mgfft,mpi_enreg,1,ngfft,npw1_k,1,n4,n5,n6,0,&
     258          584 : &             tim_fourwf7,weight,weight)
     259              : 
     260              : !          Compute the weight, note that the factor 2 is
     261              : !          not the spin factor (see Eq.44 of PRB55,10337 (1997) [[cite:Gonze1997]])
     262          584 :              weight=two*occ_rbz(iband+bdtot_index)*wtk_rbz(ikpt)/ucvol
     263              : 
     264              : !          Accumulate density
     265         1168 :              if(cplex==2)then
     266              : !$OMP PARALLEL DO PRIVATE(im0,im1,re0,re1)
     267            0 :                do i3=1,n3
     268            0 :                  do i2=1,n2
     269            0 :                    do i1=1,n1
     270            0 :                      re0=wfraug(1,i1,i2,i3) ; im0=wfraug(2,i1,i2,i3)
     271            0 :                      re1=wfraug1(1,i1,i2,i3); im1=wfraug1(2,i1,i2,i3)
     272            0 :                      rhoaug1(2*i1-1,i2,i3,1)=rhoaug1(2*i1-1,i2,i3,1)+weight*(re0*re1+im0*im1)
     273            0 :                      rhoaug1(2*i1  ,i2,i3,1)=rhoaug1(2*i1  ,i2,i3,1)+weight*(re0*im1-im0*re1)
     274              :                    end do
     275              :                  end do
     276              :                end do
     277              :              else
     278              : !$OMP PARALLEL DO
     279         8200 :                do i3=1,n3
     280       121992 :                  do i2=1,n2
     281      1981248 :                    do i1=1,n1
     282              :                      rhoaug1(i1,i2,i3,1)=rhoaug1(i1,i2,i3,1)+&
     283      1973632 : &                     weight*( wfraug(1,i1,i2,i3)*wfraug1(1,i1,i2,i3) + wfraug(2,i1,i2,i3)*wfraug1(2,i1,i2,i3)  )
     284              :                    end do
     285              :                  end do
     286              :                end do
     287              :              end if ! cplex
     288              :            end do ! ispinor
     289              :          else !abs(occ_rbz(iband+bdtot_index))>tol8
     290          576 :            nskip=nskip+1  ! if the state is not occupied. Accumulate the number of one-way 3D ffts skipped
     291              :          end if ! abs(occ_rbz(iband+bdtot_index))>tol8
     292              : 
     293              :        end do ! iband
     294              : 
     295          146 :        ABI_FREE(gbound)
     296          146 :        ABI_FREE(kg_k)
     297          146 :        ABI_FREE(gbound1)
     298          146 :        ABI_FREE(kg1_k)
     299              : 
     300          146 :        bdtot_index=bdtot_index+nband_k
     301              : 
     302              : ! only increase indices for my bands on my proc
     303          146 :        icg=icg+npw_k*mband_mem*nspinor
     304          146 :        ikg=ikg+npw_k
     305              : 
     306          146 :        icg1=icg1+npw1_k*mband_mem*nspinor
     307          154 :        ikg1=ikg1+npw1_k
     308              : 
     309              :      end do ! ikpt
     310              : 
     311              :      if (xmpi_paral==0) then !  Write the number of one-way 3D ffts skipped until now
     312              :        write(message,'(a,i8)')' mkrho3 : number of one-way 3D ffts skipped in mkrho3 until now =',nskip
     313              :        call wrtout(std_out,message,'PERS')
     314              :      end if
     315              : 
     316              : !  Transfer density on augmented fft grid to normal fft grid in real space
     317              : !  Take also into account the spin, to place it correctly in rhor1.
     318              : !  Note the use of cplex
     319           16 :      call fftpac(isppol,mpi_enreg,nspden,cplex*n1,n2,n3,cplex*n4,n5,n6,ngfft,rhor1,rhoaug1,1)
     320              : 
     321              :    end do ! loop over isppol spins
     322              : 
     323              :  else ! nspden = 4
     324              : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     325              : ! Part added for the non collinear magnetism
     326              : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     327              : ! The same lines of code are in 72_response/accrho3.F90
     328              : ! TODO: merge these lines in a single routine??!!
     329              : !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     330              : 
     331            0 :    ikg=0; ikg1=0
     332              : 
     333            0 :    rhoaug1(:,:,:,:)=zero
     334              : 
     335            0 :    do ikpt=1,nkpt_rbz
     336              : 
     337            0 :      nband_k=nband_rbz(ikpt)
     338            0 :      istwf_k=istwfk_rbz(ikpt)
     339            0 :      npw_k=npwarr(ikpt)
     340            0 :      npw1_k=npwar1(ikpt)
     341              : 
     342            0 :      if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,1,me)) then
     343            0 :        bdtot_index=bdtot_index+nband_k
     344            0 :        cycle
     345              :      end if
     346              : 
     347            0 :      ABI_MALLOC(gbound,(2*mgfft+8,2))
     348            0 :      ABI_MALLOC(kg_k,(3,npw_k))
     349            0 :      ABI_MALLOC(gbound1,(2*mgfft+8,2))
     350            0 :      ABI_MALLOC(kg1_k,(3,npw1_k))
     351              : 
     352            0 :      kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
     353            0 :      call sphereboundary(gbound,istwf_k,kg_k,mgfft,npw_k)
     354              : 
     355            0 :      kg1_k(:,1:npw1_k)=kg1(:,1+ikg1:npw1_k+ikg1)
     356            0 :      call sphereboundary(gbound1,istwf_k,kg1_k,mgfft,npw1_k)
     357              : 
     358              : !    Loop over bands to fft and square for rho(r)
     359            0 :      iband_me = 0
     360            0 :      do iband=1,nband_k
     361              : 
     362            0 :        if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,iband,iband,1,me)) cycle
     363            0 :        iband_me = iband_me + 1
     364              : 
     365              : !      Only treat occupied states
     366            0 :        if (abs(occ_rbz(iband+bdtot_index))>tol8) then
     367              : 
     368              : ! Build the four components of rho. We use only norm quantities and, so fourwf.
     369              : 
     370            0 :          ABI_MALLOC(wfraug_up,(2,n4,n5,n6))
     371            0 :          ABI_MALLOC(wfraug_down,(2,n4,n5,n6))
     372            0 :          ABI_MALLOC(wfraug1_up,(2,n4,n5,n6))
     373            0 :          ABI_MALLOC(wfraug1_down,(2,n4,n5,n6))
     374            0 :          ABI_MALLOC(cwave0_up,(2,npw_k))
     375            0 :          ABI_MALLOC(cwave0_down,(2,npw_k))
     376            0 :          ABI_MALLOC(cwave1_up,(2,npw1_k))
     377            0 :          ABI_MALLOC(cwave1_down,(2,npw1_k))
     378              : 
     379              : ! EB FR build spinorial wavefunctions
     380              : ! Obtain Fourier transform in fft box and accumulate the density
     381              : ! zero order up and down spins
     382            0 :          ptr1 = 1 + (iband_me-1)*npw_k*nspinor + icg
     383            0 :          call cg_zcopy(npw_k, cg(1,ptr1), cwave0_up)
     384            0 :          ptr2 = 1 + npw_k + (iband_me-1)*npw_k*nspinor + icg
     385            0 :          call cg_zcopy(npw_k, cg(1,ptr2), cwave0_down)
     386              : ! first order up and down spins
     387            0 :          ptr1 = 1 + (iband_me-1)*npw1_k*nspinor + icg1
     388            0 :          call cg_zcopy(npw1_k, cg1(1,ptr1), cwave1_up)
     389            0 :          ptr2 = 1 + npw1_k + (iband_me-1)*npw1_k*nspinor + icg1
     390            0 :          call cg_zcopy(npw1_k, cg1(1,ptr2), cwave1_down)
     391              : 
     392              : !density components
     393              : !GS wfk Fourrier Tranform
     394              :          call fourwf(1,rhoaug(:,:,:,2),cwave0_up,dummy,wfraug_up,gbound,gbound,istwf_k,kg_k,kg_k,&
     395              : &         mgfft,mpi_enreg,1,ngfft,npw_k,1,n4,n5,n6,&
     396            0 : &         0,tim_fourwf7,weight,weight)
     397              :          call fourwf(1,rhoaug(:,:,:,2),cwave0_down,dummy,wfraug_down,gbound,gbound,istwf_k,kg_k,kg_k,&
     398              : &         mgfft,mpi_enreg,1,ngfft,npw_k,1,n4,n5,n6,&
     399            0 : &         0,tim_fourwf7,weight,weight)
     400              : !1st order wfk Fourrier Transform
     401              :          call fourwf(cplex,rhoaug(:,:,:,1),cwave1_up,dummy,wfraug1_up,gbound1,gbound1,istwf_k,kg1_k,kg1_k,&
     402            0 : &         mgfft,mpi_enreg,1,ngfft,npw1_k,1,n4,n5,n6,0,tim_fourwf7,weight,weight)
     403              :          call fourwf(cplex,rhoaug(:,:,:,1),cwave1_down,dummy,wfraug1_down,gbound1,gbound1,istwf_k,kg1_k,kg1_k,&
     404            0 : &         mgfft,mpi_enreg,1,ngfft,npw1_k,1,n4,n5,n6,0,tim_fourwf7,weight,weight)
     405              : 
     406              : !    The factor 2 is not the spin factor (see Eq.44 of PRB55,10337 (1997) ?? [[cite:Gonze1997]])
     407            0 :          weight=two*occ_rbz(iband+bdtot_index)*wtk_rbz(ikpt)/ucvol
     408              : 
     409              : !    Accumulate 1st-order density (x component)
     410            0 :          if (cplex==2) then
     411            0 :            do i3=1,n3
     412            0 :              do i2=1,n2
     413            0 :                do i1=1,n1
     414            0 :                  re0_up=wfraug_up(1,i1,i2,i3)  ;     im0_up=wfraug_up(2,i1,i2,i3)
     415            0 :                  re1_up=wfraug1_up(1,i1,i2,i3) ;     im1_up=wfraug1_up(2,i1,i2,i3)
     416            0 :                  re0_down=wfraug_down(1,i1,i2,i3)  ; im0_down=wfraug_down(2,i1,i2,i3)
     417            0 :                  re1_down=wfraug1_down(1,i1,i2,i3) ; im1_down=wfraug1_down(2,i1,i2,i3)
     418            0 :                  rhoaug1(2*i1-1,i2,i3,1)=rhoaug1(2*i1-1,i2,i3,1)+weight*(re0_up*re1_up+im0_up*im1_up) !n_upup
     419            0 :                  rhoaug1(2*i1  ,i2,i3,1)=rhoaug1(2*i1  ,i2,i3,1)+weight*(re0_up*im1_up-im0_up*re1_up)
     420            0 :                  rhoaug1(2*i1-1,i2,i3,4)=rhoaug1(2*i1-1,i2,i3,4)+weight*(re0_down*re1_down+im0_down*im1_down) ! n_dndn
     421            0 :                  rhoaug1(2*i1  ,i2,i3,4)=rhoaug1(2*i1  ,i2,i3,4)+weight*(re0_down*im1_down-im0_down*re1_down)
     422              : 
     423              :                  rhoaug1(2*i1-1,i2,i3,2)=rhoaug1(2*i1-1,i2,i3,2)+weight*(re1_up*re0_down+im1_up*im0_down)& !Re[m1x]
     424            0 : &                +weight*(re1_down*re0_up+im1_down*im0_up)
     425              :                  rhoaug1(2*i1  ,i2,i3,2)=rhoaug1(2*i1  ,i2,i3,2)+weight*(-re1_up*im0_down+im1_up*re0_down)& !Im[m1x]
     426            0 : &                +weight*(-re1_down*im0_up+im1_down*re0_up)
     427              : 
     428              :                  rhoaug1(2*i1-1,i2,i3,3)=rhoaug1(2*i1-1,i2,i3,3)+weight*(+re1_up*im0_down-im1_up*re0_down)& !Re[m1y]
     429            0 : &                +weight*(-re1_down*im0_up+im1_down*re0_up)
     430              :                  rhoaug1(2*i1  ,i2,i3,3)=rhoaug1(2*i1  ,i2,i3,3)+weight*(+re1_up*re0_down+im1_up*im0_down)& !Im[m1y]
     431            0 : &                +weight*(-re1_down*re0_up-im1_down*im0_up)
     432              :                end do
     433              :              end do
     434              :            end do
     435              :          else
     436            0 :            re0_up=zero;im0_up=zero;re1_up=zero;im1_up=zero;re0_down=zero;im0_down=zero
     437            0 :            re1_down=zero;im1_down=zero
     438            0 :            do i3=1,n3
     439            0 :              do i2=1,n2
     440            0 :                do i1=1,n1
     441            0 :                  re0_up=wfraug_up(1,i1,i2,i3)  ;     im0_up=wfraug_up(2,i1,i2,i3)
     442            0 :                  re1_up=wfraug1_up(1,i1,i2,i3) ;     im1_up=wfraug1_up(2,i1,i2,i3)
     443            0 :                  re0_down=wfraug_down(1,i1,i2,i3)  ; im0_down=wfraug_down(2,i1,i2,i3)
     444            0 :                  re1_down=wfraug1_down(1,i1,i2,i3) ; im1_down=wfraug1_down(2,i1,i2,i3)
     445            0 :                  rhoaug1(i1,i2,i3,1)=rhoaug1(i1,i2,i3,1)+weight*(re0_up*re1_up+im0_up*im1_up) ! n_upup
     446            0 :                  rhoaug1(i1,i2,i3,4)=rhoaug1(i1,i2,i3,4)+weight*(re0_down*re1_down+im0_down*im1_down) ! n_dndn
     447              :                  rhoaug1(i1,i2,i3,2)=rhoaug1(i1,i2,i3,2)+weight*(re1_up*re0_down+re0_up*re1_down &
     448            0 : &                 +im0_up*im1_down+im0_down*im1_up) !mx; the factor two is inside weight
     449              :                  rhoaug1(i1,i2,i3,3)=rhoaug1(i1,i2,i3,3)+weight*(re1_up*im0_down-im1_up*re0_down &
     450            0 : &                 +re0_up*im1_down-im0_up*re1_down) !my; the factor two is inside weight
     451              :                end do
     452              :              end do
     453              :            end do
     454              :          end if
     455            0 :          ABI_FREE(wfraug_up)
     456            0 :          ABI_FREE(wfraug_down)
     457            0 :          ABI_FREE(wfraug1_up)
     458            0 :          ABI_FREE(wfraug1_down)
     459            0 :          ABI_FREE(cwave0_up)
     460            0 :          ABI_FREE(cwave0_down)
     461            0 :          ABI_FREE(cwave1_up)
     462            0 :          ABI_FREE(cwave1_down)
     463              : 
     464              :        end if ! occupied states
     465              :      end do ! End loop on iband
     466              : 
     467            0 :      ABI_FREE(gbound)
     468            0 :      ABI_FREE(kg_k)
     469            0 :      ABI_FREE(gbound1)
     470            0 :      ABI_FREE(kg1_k)
     471              : 
     472            0 :      bdtot_index=bdtot_index+nband_k
     473              : 
     474              : ! only increase indices for my bands on my proc
     475            0 :        icg=icg+npw_k*mband_mem*nspinor
     476            0 :        ikg=ikg+npw_k
     477              : 
     478            0 :        icg1=icg1+npw1_k*mband_mem*nspinor
     479            0 :        ikg1=ikg1+npw1_k
     480              : 
     481              :    end do ! End loop on ikpt
     482              : 
     483              : 
     484              :    if (xmpi_paral==0) then !  Write the number of one-way 3D ffts skipped until now
     485              :      write(message,'(a,i8)')' dfpt_mkrho : number of one-way 3D ffts skipped in mkrho3 until now =',nskip
     486              :      call wrtout(std_out,message,'PERS')
     487              :    end if
     488              : 
     489              : !  Transfer density on augmented fft grid to normal fft grid in real space
     490              : !  Take also into account the spin, to place it correctly in rhor1.
     491            0 :    call fftpac(1,mpi_enreg,nspden,cplex*n1,n2,n3,cplex*n4,n5,n6,ngfft,rhor1,rhoaug1(:,:,:,1),1)
     492            0 :    do ispden=2,4
     493            0 :      call fftpac(ispden,mpi_enreg,nspden,cplex*n1,n2,n3,cplex*n4,n5,n6,ngfft,rhor1,rhoaug1(:,:,:,ispden),1)
     494              :    end do
     495              : 
     496              :  end if ! nspden /= 4
     497              : 
     498              : !if (xmpi_paral==1) then
     499              : !call timab(63,1,tsec)
     500              : !call wrtout(std_out,'dfpt_mkrho: loop on k-points and spins done in parallel','COLL')
     501              : !call xmpi_barrier(spaceworld)
     502              : !call timab(63,2,tsec)
     503              : !end if
     504              : 
     505            8 :  ABI_FREE(cwavef)
     506            8 :  ABI_FREE(cwavef1)
     507            8 :  ABI_FREE(dummy)
     508            8 :  ABI_FREE(rhoaug)
     509            8 :  ABI_FREE(rhoaug1)
     510            8 :  ABI_FREE(wfraug)
     511            8 :  ABI_FREE(wfraug1)
     512              : 
     513              : !Recreate full rhor1 on all proc.
     514              : !TODO : check this sums correctly on bands as well as k
     515            8 :  call timab(48,1,tsec)
     516            8 :  call timab(71,1,tsec)
     517            8 :  call xmpi_sum(rhor1,spaceworld,ierr)
     518            8 :  call timab(71,2,tsec)
     519            8 :  call timab(48,2,tsec)
     520              : 
     521              :  !This rotation is managed by symrhg
     522            8 :  if (nspden==4) then
     523            0 :   rhor1(:,2) = rhor1(:,2) + (rhor1(:,1) + rhor1(:,4))
     524            0 :   rhor1(:,3) = rhor1(:,3) + (rhor1(:,1) + rhor1(:,4))
     525              :  end if
     526              : 
     527              :  call symrhg(cplex,gprimd,irrzon,mpi_enreg,nfft,nfft,ngfft,nspden,nsppol,nsym,phnons,&
     528            8 :              rhog1,rhor1,rprimd,symafm,symrel,tnons)
     529              : 
     530              : !We now have both rho(r) and rho(G), symmetrized, and if nsppol=2
     531              : !we also have the spin-up density, symmetrized, in rhor1(:,2).
     532              : 
     533              :  ABI_NVTX_END_RANGE()
     534              : !DBG_EXIT("COLL")
     535              : 
     536            8 : end subroutine dfpt_mkrho
     537              : !!***
     538              : 
     539              : !!****f* ABINIT/dfpt_accrho
     540              : !! NAME
     541              : !! dfpt_accrho
     542              : !!
     543              : !! FUNCTION
     544              : !! Response function calculation only:
     545              : !!  Accumulate contribution to first-order density due to current (k,band)
     546              : !!  Also accumulate zero-order potential part of the 2nd-order total energy (if needed)
     547              : !!
     548              : !! INPUTS
     549              : !!  cplex=1 if 1st-order density is real, 2 if 1st-order density is complex
     550              : !!  cwave0(2,npw*nspinor)=GS wavefunction at k, in reciprocal space
     551              : !!  cwave1(2,npw1*nspinor)=1st-order wavefunction at k,q, in reciprocal space
     552              : !!  cwavef(2,npw1*nspinor)=1st-order wavefunction at k,q, in reciprocal space, without correction due to occupation change
     553              : !!  cwaveprj0(natom,nspinor*usecprj)= GS wave function at k projected with nl projectors
     554              : !!  cwaveprj1(natom,nspinor*usecprj)= 1st-order wave function at k,q projected with nl projectors
     555              : !!  gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k+q
     556              : !!  iband=index of current band
     557              : !!  idir=direction of the current perturbation
     558              : !!  ipert=type of the perturbation
     559              : !!  isppol=1 index of current spin component
     560              : !!  kptopt=option for the generation of k points
     561              : !!  mpi_atmtab(:)=--optional-- indexes of the atoms treated by current proc
     562              : !!  comm_atom=--optional-- MPI communicator over atoms
     563              : !!  mpi_enreg=information about MPI parallelization
     564              : !!  natom=number of atoms in cell
     565              : !!  nband_k=number of bands at this k point for that spin polarization
     566              : !!  ncpgr=number of gradients stored in cprj array (cprj=<p_i|Cnk>)
     567              : !!  npw_k=number of planewaves in basis sphere at k
     568              : !!  npw1_k=number of planewaves in basis sphere at k+q
     569              : !!  nspinor=number of spinorial components of the wavefunctions
     570              : !!  occ_k(nband_k)=occupation number for each band (usually 2) for each k.
     571              : !!  option= 1: accumulate 1st-order density,
     572              : !!          2: accumulate 0-order potential part of the 2nd-order total energy
     573              : !!          3: accumulate both
     574              : !!  tim_fourwf= timing code for fourwf (5 from dfpt_vtowfk, 18 from dfpt_nstwf)
     575              : !!  wf_corrected=flag put to 1 if cwave1 is different from cwavef (if there is a contribution from occ. change)
     576              : !!  wtk_k=weight assigned to the k point.
     577              : !!
     578              : !! OUTPUT
     579              : !!  ====== if option=2 or option=3 =====
     580              : !!  eloc0_k=zero-order local contribution to 2nd-order total energy for current band and k
     581              : !!
     582              : !! SIDE EFFECTS
     583              : !!  ====== if option=1 or option=3 =====
     584              : !!    rhoaug1(cplex*n4,n5,n6,nvloc)= density in electrons/bohr**3,
     585              : !!    ==== if gs_hamkq%usepaw=1 =====
     586              : !!    pawrhoij1(natom) <type(pawrhoij_type)>= 1st-order paw rhoij occupancies and related data
     587              : !!                                            (cumulative, so input as well as output)
     588              : !!
     589              : !! NOTES
     590              : !!  In this part of the treatment of one band, one has to
     591              : !!  perform Fourier transforms, and to treat separately the
     592              : !!  two spinorial components of the wavefunction.
     593              : !!  Was part of dfpt_vtowfk before.
     594              : !!
     595              : !! SOURCE
     596              : 
     597      7238222 : subroutine dfpt_accrho(cplex,cwave0,cwave1,cwavef,cwaveprj0,cwaveprj1,&
     598      3619111 : &                  eloc0_k,gs_hamkq,iband,idir,ipert,isppol,kptopt,&
     599      3619111 : &                  mpi_enreg,ndat,natom,nband_k,ncpgr,npw_k,npw1_k,nspinor,occ_k,&
     600      3619111 : &                  option,pawrhoij1,rhoaug1,tim_fourwf,wf_corrected,&
     601      3619111 : &                  wtk_k,comm_atom,mpi_atmtab)
     602              : 
     603              : !Arguments ------------------------------------
     604              : !scalars
     605              :  integer,intent(in) :: cplex,iband,idir,ipert,isppol,kptopt,natom,nband_k,ndat
     606              :  integer,intent(in) :: ncpgr,npw_k,npw1_k,nspinor,option,tim_fourwf,wf_corrected
     607              :  integer,optional,intent(in) :: comm_atom
     608              :  integer,optional,target,intent(in) :: mpi_atmtab(:)
     609              :  real(dp),intent(in) :: wtk_k
     610              :  real(dp),intent(out) :: eloc0_k(ndat)
     611              :  type(gs_hamiltonian_type),intent(inout),target :: gs_hamkq
     612              :  type(MPI_type),intent(in) :: mpi_enreg
     613              : !arrays
     614              :  real(dp),intent(in),target :: cwave0(2,npw_k*nspinor*ndat),cwave1(2,npw1_k*nspinor*ndat),cwavef(2,npw1_k*nspinor*ndat)
     615              :  real(dp),intent(in) :: occ_k(nband_k)
     616              :  real(dp),intent(inout) :: rhoaug1(cplex*gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,gs_hamkq%nvloc)
     617              :  type(pawcprj_type),intent(in) :: cwaveprj0(natom,nspinor*ndat*gs_hamkq%usecprj)
     618              :  type(pawcprj_type),intent(in) :: cwaveprj1(natom,nspinor*ndat*gs_hamkq%usepaw)
     619              :  type(pawrhoij_type),intent(inout) :: pawrhoij1(:)
     620              : 
     621              : !Local variables-------------------------------
     622              : !scalars
     623              :  integer,parameter :: level=14
     624              :  integer :: choice,cplex_cprj,i1,i2,i3,idat,ispinor,my_comm_atom,my_natom,n1,n2,n3,option_rhoij,gpu_option
     625              :  logical :: my_atmtab_allocated,paral_atom
     626              :  logical :: use_timerev,use_zeromag
     627              :  real(dp) :: valuer,diag,offdiag,weight
     628              :  real(dp) :: im0_up,im1_up,re0_up,re1_up,im0_down,im1_down,re0_down,re1_down
     629              : !arrays
     630      3619111 :  integer,pointer :: my_atmtab(:)
     631              :  real(dp) :: dummy(2,1)
     632      3619111 :  real(dp),allocatable :: rhoaug(:,:,:,:),wfraug(:,:,:,:),wfraug1(:,:,:,:)
     633      3619111 :  real(dp),allocatable :: wfraug1_up(:,:,:,:),wfraug1_down(:,:,:,:)
     634      3619111 :  real(dp),allocatable :: wfraug_up(:,:,:,:),wfraug_down(:,:,:,:)
     635      3619111 :  real(dp),pointer :: cwavef_sp(:,:),cwavef_up(:,:),cwavef_down(:,:)
     636      3619111 :  real(dp),pointer :: cwave0_up(:,:),cwave0_down(:,:),cwave1_up(:,:),cwave1_down(:,:)
     637              :  real(dp), ABI_CONTIGUOUS pointer :: vlocal(:,:,:,:)=>null()
     638      3619111 :  type(pawcprj_type),allocatable :: cwaveprj_tmp(:,:)
     639              : 
     640              : ! *********************************************************************
     641              :  DBG_ENTER("COLL")
     642              :  ABI_NVTX_START_RANGE(NVTX_DFPT_ACCRHO)
     643              : 
     644       102656 :  if (gs_hamkq%nvloc==4 .and. ndat>1) then
     645            0 :    ABI_ERROR("nvloc==4 isn't supported with ndat~bandpp > 1 !")
     646              :  end if
     647              : 
     648      3619111 :  if (option/=1.and.option/=2.and.option/=3) return
     649      3619111 :  gpu_option=gs_hamkq%gpu_option
     650              : 
     651              : !Initializations
     652     21714666 :  ABI_MALLOC(rhoaug,(cplex*gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,gs_hamkq%nvloc))
     653      3619111 :  n1=gs_hamkq%ngfft(1);n2=gs_hamkq%ngfft(2);n3=gs_hamkq%ngfft(3)
     654      6985356 :  if (option==2.or.option==3) eloc0_k=zero
     655      3619111 :  if (option==2.or.option==3) then
     656              : !  XG20241028 This coding confuses the gnu 8.5 compiler, wrt the CONTIGUOUS character of the pointer.
     657              : !  So, make a simple copy. This is not optimal, though...
     658              : !  Original ---
     659              : !  vlocal => gs_hamkq%vlocal
     660              : !  New ---
     661     20197470 :    ABI_MALLOC(vlocal, (size(gs_hamkq%vlocal,1),size(gs_hamkq%vlocal,2),size(gs_hamkq%vlocal,3),size(gs_hamkq%vlocal,4)) )
     662  16983811232 :    vlocal=gs_hamkq%vlocal
     663              : !  END XG20241028
     664              :  endif
     665              : 
     666              : !Loop on spinorial components
     667              : ! TODO : double loop on spinors for full rhoaug1 matrix if nspden =4
     668      3619111 :  if (gs_hamkq%nvloc/=4) then  ! see later EB FR
     669     17582275 :    ABI_MALLOC(wfraug1,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6*ndat))
     670              : #ifdef HAVE_OPENMP_OFFLOAD
     671              :    !$OMP TARGET ENTER DATA MAP(alloc:wfraug1) IF(gpu_option==ABI_GPU_OPENMP)
     672              :    !$OMP TARGET ENTER DATA MAP(to:rhoaug1) IF(gpu_option==ABI_GPU_OPENMP)
     673              : #endif
     674              : 
     675      7069448 :    do ispinor=1,nspinor
     676              : 
     677              : !  Part devoted to the accumulation of the 0-order potential part of the 2nd-order total energy
     678              : !  --------------------------------------------------------------------------------------------
     679              : 
     680              : !  Fourier transform of cwavef. Here, rhoaug is a dummy variable.
     681      3552993 :      if (wf_corrected==0.or.option==2.or.option==3) then
     682      3552993 :        if (ispinor==1) then
     683      3516455 :          cwavef_sp => cwavef(:,1:npw1_k*ndat)
     684              :        else
     685        36538 :          cwavef_sp => cwavef(:,1+npw1_k*ndat:2*npw1_k*ndat)
     686              :        end if
     687              :        !make an inverse FFT from cwavef_sp to wfraug1
     688              :        call fourwf(cplex,rhoaug,cwavef_sp,dummy,wfraug1,gs_hamkq%gbound_kp,gs_hamkq%gbound_kp,&
     689              : &       gs_hamkq%istwf_k,gs_hamkq%kg_kp,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,ndat,gs_hamkq%ngfft,&
     690              : &       gs_hamkq%npw_kp,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
     691      3552993 : &       weight,weight,gpu_option=gpu_option)
     692      3552993 :        nullify(cwavef_sp)
     693              : 
     694              :      end if
     695              : 
     696              : !  Compute contribution of bands in ndat to zero-order potential part of the 2nd-order total energy
     697              : !  NB: this is spinor diagonal
     698      3552993 :      if (option==2.or.option==3) then
     699              :        call update_potential_contrib(eloc0_k,wfraug1,vlocal,&
     700      3300127 :        &    n1,n2,n3,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,gs_hamkq%nvloc,gs_hamkq%nfft,ndat,gpu_option)
     701              :      end if ! option
     702              : 
     703              : !  Part devoted to the accumulation of the 1st-order density
     704              : !  ---------------------------------------------------------
     705      7069448 :      if (option==1.or.option==3) then
     706              : 
     707              : !    Compute 1st-order WF in real space
     708              : !    One needs the Fourier transform of cwave1. However, only the one of
     709              : !    cwavef is available. If cwavef and cwave1 differs, this Fourier
     710              : !    transform must be computed. In both case the result is in wfraug1.
     711      2768380 :        if (wf_corrected==1) then
     712       555455 :          if (ispinor==1) then
     713       555455 :            cwavef_sp => cwave1(:,1:npw1_k*ndat)
     714              :          else
     715            0 :            cwavef_sp => cwave1(:,1+npw1_k*ndat:2*npw1_k*ndat)
     716              :          end if
     717              :          call fourwf(cplex,rhoaug,cwavef_sp,dummy,wfraug1,gs_hamkq%gbound_kp,gs_hamkq%gbound_kp,&
     718              : &         gs_hamkq%istwf_k,gs_hamkq%kg_kp,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,ndat,gs_hamkq%ngfft,&
     719              : &         gs_hamkq%npw_kp,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
     720       555455 : &         weight,weight,gpu_option=gpu_option)
     721       555455 :          nullify(cwavef_sp)
     722              :        end if
     723              : 
     724              : !    Compute 0-order WF in real space
     725              : ! TODO: add loop over ispinor_prime here
     726     13841900 :        ABI_MALLOC(wfraug,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6*ndat))
     727              : #ifdef HAVE_OPENMP_OFFLOAD
     728              :    !$OMP TARGET ENTER DATA MAP(alloc:wfraug) IF(gpu_option==ABI_GPU_OPENMP)
     729              : #endif
     730      2768380 :        if (ispinor==1) then
     731      2761554 :          cwavef_sp => cwave0(:,1:npw_k*ndat)
     732              :        else
     733         6826 :          cwavef_sp => cwave0(:,1+npw_k*ndat:2*npw_k*ndat)
     734              :        end if
     735              :        call fourwf(1,rhoaug,cwavef_sp,dummy,wfraug,gs_hamkq%gbound_k,gs_hamkq%gbound_k,&
     736              : &       gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_k,gs_hamkq%mgfft,mpi_enreg,ndat,gs_hamkq%ngfft,&
     737              : &       gs_hamkq%npw_k,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
     738      2768380 : &       weight,weight,gpu_option=gpu_option)
     739      2768380 :        nullify(cwavef_sp)
     740              : 
     741              : !    The factor 2 is not the spin factor (see Eq.44 of PRB55,10337 (1997) [[cite:Gonze1997]])
     742              : !    Accumulate 1st-order density
     743              : 
     744              :      call accumulate_1st_order_density(rhoaug1,wfraug,wfraug1,&
     745              :      &    cplex,n1,n2,n3,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,gs_hamkq%nvloc,&
     746      2768380 :      &    ndat,nband_k,iband,gs_hamkq%ucvol,wtk_k,occ_k,gpu_option)
     747              : 
     748              : #ifdef HAVE_OPENMP_OFFLOAD
     749              :        !$OMP TARGET EXIT DATA MAP(delete:wfraug) IF(gpu_option==ABI_GPU_OPENMP)
     750              : #endif
     751      2768380 :        ABI_FREE(wfraug)
     752              :      end if ! option
     753              : 
     754              : 
     755              :    end do ! Loop on spinorial components if nspden=1 or 2
     756              : 
     757              : #ifdef HAVE_OPENMP_OFFLOAD
     758              :    !$OMP TARGET EXIT DATA MAP(delete:wfraug1) IF(gpu_option==ABI_GPU_OPENMP)
     759              :    !$OMP TARGET EXIT DATA MAP(from:rhoaug1)   IF(gpu_option==ABI_GPU_OPENMP)
     760              : #endif
     761      3516455 :    ABI_FREE(wfraug1)
     762              :  else ! nvloc = 4
     763              : ! The same lines of code are in 72_response/dfpt_mkrho.F90
     764              : ! TODO merge these lines in a single routine??!!
     765       513280 :    ABI_MALLOC(wfraug1_up,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
     766       410624 :    ABI_MALLOC(wfraug1_down,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
     767              : 
     768   1517385680 :    wfraug1_up(:,:,:,:)=zero
     769   1517385680 :    wfraug1_down(:,:,:,:)=zero
     770              : 
     771              : !  Part devoted to the accumulation of the 0-order potential part of the 2nd-order total energy
     772              : !  --------------------------------------------------------------------------------------------
     773              : 
     774              : !  Fourier transform of cwavef. Here, rhoaug is a dummy variable.
     775       102656 :    if (wf_corrected==0.or.option==2.or.option==3) then
     776       102656 :      cwavef_up => cwavef(:,1:npw1_k) ! wfs up spin-polarized
     777              :      call fourwf(cplex,rhoaug(:,:,:,1),cwavef_up,dummy,wfraug1_up,gs_hamkq%gbound_kp,gs_hamkq%gbound_kp,&
     778              : &     gs_hamkq%istwf_k,gs_hamkq%kg_kp,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
     779              : &     gs_hamkq%npw_kp,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
     780       102656 : &     weight,weight,gpu_option=gpu_option)
     781       102656 :      nullify(cwavef_up)
     782              : 
     783       102656 :      cwavef_down => cwavef(:,1+npw1_k:2*npw1_k) ! wfs down spin-polarized
     784              :      call fourwf(cplex,rhoaug(:,:,:,1),cwavef_down,dummy,wfraug1_down,gs_hamkq%gbound_kp,gs_hamkq%gbound_kp,&
     785              : &     gs_hamkq%istwf_k,gs_hamkq%kg_kp,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
     786              : &     gs_hamkq%npw_kp,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
     787       102656 : &     weight,weight,gpu_option=gpu_option)
     788       102656 :      nullify(cwavef_down)
     789              :    end if
     790       102656 :    if (option==2.or.option==3) then
     791              :      valuer=zero
     792      1855760 :      diag=zero
     793      1855760 :      offdiag=zero
     794              :    ! EB FR 2nd term in Eq. 91 PRB52,1096 [[cite:Gonze1995]] for non-collinear magnetism
     795      1855760 :      do i3=1,n3
     796     30152912 :        do i2=1,n2
     797    497562384 :          do i1=1,n1
     798              :            diag=vlocal(i1,i2,i3,1)*(wfraug1_up(1,i1,i2,i3)**2+wfraug1_up(2,i1,i2,i3)**2)&
     799    467512128 : &           +vlocal(i1,i2,i3,2)*(wfraug1_down(1,i1,i2,i3)**2+wfraug1_down(2,i1,i2,i3)**2)
     800              :            offdiag=(two*vlocal(i1,i2,i3,3)*((wfraug1_up(1,i1,i2,i3)*wfraug1_down(1,i1,i2,i3))+&
     801              : &           (wfraug1_up(2,i1,i2,i3)*wfraug1_down(2,i1,i2,i3))))+&
     802              : &           (two*vlocal(i1,i2,i3,4)*((-wfraug1_down(2,i1,i2,i3)*wfraug1_up(1,i1,i2,i3))+&
     803    467512128 : &           (wfraug1_down(1,i1,i2,i3)*wfraug1_up(2,i1,i2,i3))))
     804    495809280 :            valuer=valuer+diag+offdiag
     805              :          end do
     806              :        end do
     807              :      end do
     808              : !    Local potential energy of this band
     809       205312 :      eloc0_k=eloc0_k+two*valuer/dble(gs_hamkq%nfft)
     810              :    end if ! option
     811              : 
     812              : !  Part devoted to the accumulation of the 1st-order density
     813              : !  ---------------------------------------------------------
     814              : 
     815              : ! first order
     816              : !
     817       102656 :    if (option==1.or.option==3) then
     818              : 
     819              :      !SPr: condition on wf_corrected not to do FFTs of the same Bloch functions
     820        86528 :      if (wf_corrected==1) then
     821         6392 :        cwave1_up => cwave1(:,1:npw1_k)
     822         6392 :        cwave1_down => cwave1(:,1+npw1_k:2*npw1_k)
     823    291635000 :        wfraug1_up(:,:,:,:)=zero
     824    291635000 :        wfraug1_down(:,:,:,:)=zero
     825              : 
     826              :        call fourwf(cplex,rhoaug(:,:,:,1),cwave1_up,dummy,wfraug1_up,gs_hamkq%gbound_kp,gs_hamkq%gbound_kp,&
     827              : &       gs_hamkq%istwf_k,gs_hamkq%kg_kp,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
     828              : &       gs_hamkq%npw_kp,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
     829         6392 : &       weight,weight,gpu_option=gpu_option)
     830         6392 :        nullify(cwave1_up)
     831              : 
     832              :        call fourwf(cplex,rhoaug(:,:,:,1),cwave1_down,dummy,wfraug1_down,gs_hamkq%gbound_kp,gs_hamkq%gbound_kp,&
     833              : &       gs_hamkq%istwf_k,gs_hamkq%kg_kp,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
     834              : &       gs_hamkq%npw_kp,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
     835         6392 : &       weight,weight,gpu_option=gpu_option)
     836         6392 :        nullify(cwave1_down)
     837              :      end if
     838              : 
     839              : 
     840              : ! EB FR build spinorial wavefunctions
     841              : ! zero order
     842        86528 :      cwave0_up => cwave0(:,1:npw_k*ndat)
     843        86528 :      cwave0_down => cwave0(:,1+npw_k*ndat:2*npw_k*ndat)
     844       432640 :      ABI_MALLOC(wfraug_up,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
     845       346112 :      ABI_MALLOC(wfraug_down,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
     846   1275782192 :      wfraug_up(:,:,:,:)=zero
     847   1275782192 :      wfraug_down(:,:,:,:)=zero
     848              : !
     849              :      !density components
     850              :      !GS wfk Fourrier Tranform
     851              :      ! EB FR in the fourwf calls rhoaug(:,:,:,2) is a dummy argument
     852              :      call fourwf(1,rhoaug(:,:,:,2),cwave0_up,dummy,wfraug_up,gs_hamkq%gbound_k,gs_hamkq%gbound_k,&
     853              : &     gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_k,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
     854              : &     gs_hamkq%npw_k,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
     855        86528 : &     weight,weight,gpu_option=gpu_option)
     856        86528 :      nullify(cwave0_up)
     857              :      call fourwf(1,rhoaug(:,:,:,2),cwave0_down,dummy,wfraug_down,gs_hamkq%gbound_k,gs_hamkq%gbound_k,&
     858              : &     gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_k,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
     859              : &     gs_hamkq%npw_k,1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,0,tim_fourwf,&
     860        86528 : &     weight,weight,gpu_option=gpu_option)
     861        86528 :      nullify(cwave0_down)
     862              : !    Accumulate 1st-order density (x component)
     863        86528 :      re0_up=zero;im0_up=zero;re1_up=zero;im1_up=zero;re0_down=zero;im0_down=zero
     864        86528 :      re1_down=zero;im1_down=zero
     865              : !    The factor 2 is not the spin factor (see Eq.44 of PRB55,10337 (1997) [[cite:Gonze1997]])
     866              : !    SPr: the following treatment with factor=2 is ok for perturbations not breaking the
     867              : !         time reversal symmetry of the Hamiltonian (due to Kramer's degeneracy) hence
     868              : !         not applicable for magnetic field perturbation (for phonons with SOC, H^(0) has
     869              : !         time reversal symmetry though). The formulas below are rectified in dfpt_scfcv
     870              : !         in case of broken time-reversal upon reconstructing rhor1_pq and rhor1_mq.
     871        86528 :      weight=two*occ_k(iband)*wtk_k/gs_hamkq%ucvol
     872        86528 :      if (cplex==2) then
     873       690008 :        do i3=1,n3
     874     12113240 :          do i2=1,n2
     875    224286528 :            do i1=1,n1
     876    212226048 :              re0_up=wfraug_up(1,i1,i2,i3)  ;     im0_up=wfraug_up(2,i1,i2,i3)
     877    212226048 :              re1_up=wfraug1_up(1,i1,i2,i3) ;     im1_up=wfraug1_up(2,i1,i2,i3)
     878    212226048 :              re0_down=wfraug_down(1,i1,i2,i3)  ; im0_down=wfraug_down(2,i1,i2,i3)
     879    212226048 :              re1_down=wfraug1_down(1,i1,i2,i3) ; im1_down=wfraug1_down(2,i1,i2,i3)
     880              :              !SPr: in case of +q/-q calculation, the factor will be corrected later from dfpt_scfcv level
     881              :              !     along with the reconstruction of correct rhor1_{+q} and rhor1_{-q}
     882              :              !     here, rhoaug1_{sigma,sigma'} = \sum_{n,k} u1_{sigma} u0*_{sigma'} independent of the sign of q
     883    212226048 :              rhoaug1(2*i1-1,i2,i3,1)=rhoaug1(2*i1-1,i2,i3,1)+weight*(re0_up*re1_up+im0_up*im1_up) !n_upup
     884    212226048 :              rhoaug1(2*i1  ,i2,i3,1)=rhoaug1(2*i1  ,i2,i3,1)+weight*(re0_up*im1_up-im0_up*re1_up)
     885    212226048 :              rhoaug1(2*i1-1,i2,i3,4)=rhoaug1(2*i1-1,i2,i3,4)+weight*(re0_down*re1_down+im0_down*im1_down) ! n_dndn
     886    212226048 :              rhoaug1(2*i1  ,i2,i3,4)=rhoaug1(2*i1  ,i2,i3,4)+weight*(re0_down*im1_down-im0_down*re1_down)
     887              : 
     888              :              rhoaug1(2*i1-1,i2,i3,2)=rhoaug1(2*i1-1,i2,i3,2)+weight*(re1_up*re0_down+im1_up*im0_down)& !Re[m1x]
     889    212226048 : &            +weight*(re1_down*re0_up+im1_down*im0_up)
     890              :              rhoaug1(2*i1  ,i2,i3,2)=rhoaug1(2*i1  ,i2,i3,2)+weight*(-re1_up*im0_down+im1_up*re0_down)& !Im[m1x]
     891    212226048 : &            +weight*(-re1_down*im0_up+im1_down*re0_up)
     892              : 
     893              :              rhoaug1(2*i1-1,i2,i3,3)=rhoaug1(2*i1-1,i2,i3,3)+weight*(+re1_up*im0_down-im1_up*re0_down)& !Re[m1y]
     894    212226048 : &            +weight*(-re1_down*im0_up+im1_down*re0_up)
     895              :              rhoaug1(2*i1  ,i2,i3,3)=rhoaug1(2*i1  ,i2,i3,3)+weight*(+re1_up*re0_down+im1_up*im0_down)& !Im[m1y]
     896    223649280 : &            +weight*(-re1_down*re0_up-im1_down*im0_up)
     897              :            end do
     898              :          end do
     899              :        end do
     900              :      else !cplex
     901       816984 :        re0_up=zero;im0_up=zero;re1_up=zero;im1_up=zero;re0_down=zero;im0_down=zero
     902       816984 :        re1_down=zero;im1_down=zero
     903       816984 :        do i3=1,n3
     904     12640824 :          do i2=1,n2
     905    191174256 :            do i1=1,n1
     906    178567200 :              re0_up=wfraug_up(1,i1,i2,i3)  ;     im0_up=wfraug_up(2,i1,i2,i3)
     907    178567200 :              re1_up=wfraug1_up(1,i1,i2,i3) ;     im1_up=wfraug1_up(2,i1,i2,i3)
     908    178567200 :              re0_down=wfraug_down(1,i1,i2,i3)  ; im0_down=wfraug_down(2,i1,i2,i3)
     909    178567200 :              re1_down=wfraug1_down(1,i1,i2,i3) ; im1_down=wfraug1_down(2,i1,i2,i3)
     910              : 
     911    178567200 :              rhoaug1(i1,i2,i3,1)=rhoaug1(i1,i2,i3,1)+weight*(re0_up*re1_up+im0_up*im1_up) ! n_upup
     912    178567200 :              rhoaug1(i1,i2,i3,4)=rhoaug1(i1,i2,i3,4)+weight*(re0_down*re1_down+im0_down*im1_down) ! n_dndn
     913              :              rhoaug1(i1,i2,i3,2)=rhoaug1(i1,i2,i3,2)+weight*(re1_up*re0_down+re0_up*re1_down &
     914    178567200 : &             +im0_up*im1_down+im0_down*im1_up) !mx; the factor two is inside weight
     915              :              rhoaug1(i1,i2,i3,3)=rhoaug1(i1,i2,i3,3)+weight*(re1_up*im0_down-im1_up*re0_down &
     916    190391040 : &             +re0_up*im1_down-im0_up*re1_down) !my; the factor two is inside weight
     917              :            end do
     918              :          end do
     919              :        end do
     920              :      end if !cplex
     921              : 
     922        86528 :      ABI_FREE(wfraug_up)
     923        86528 :      ABI_FREE(wfraug_down)
     924              : 
     925              :    end if ! option
     926              : 
     927       102656 :    ABI_FREE(wfraug1_up)
     928       102656 :    ABI_FREE(wfraug1_down)
     929              : 
     930              :  end if ! nvloc /= 4
     931              : 
     932      3619111 :  ABI_FREE(rhoaug)
     933              : 
     934              : !XG20241028 See above
     935              : !New ---
     936      3619111 :  if (option==2.or.option==3) then
     937      3366245 :    ABI_FREE(vlocal)
     938              :  endif
     939              :  !END XG20241028
     940              : 
     941              : !Part devoted to the accumulation of the 1st-order occupation matrix in PAW case
     942              : ! TODO: parse for more nspden 4 dependencies on spinors
     943              : ! EB FR CHECK: to be modified for non-collinear?????
     944              : !-------------------------------------------------------------------------------
     945              : 
     946     10857333 :  if ((option==1.or.option==3).and.gs_hamkq%usepaw==1) then
     947              : 
     948              : !  Set up parallelism over atoms
     949       617397 :    my_natom=natom; if(gs_hamkq%usepaw==1) my_natom=size(pawrhoij1)
     950       617397 :    paral_atom=(present(comm_atom).and.(my_natom/=natom))
     951       617397 :    my_comm_atom=xmpi_comm_self;if (present(comm_atom)) my_comm_atom=comm_atom
     952       617397 :    nullify(my_atmtab);if (present(mpi_atmtab)) my_atmtab => mpi_atmtab
     953       617397 :    call get_my_atmtab(my_comm_atom,my_atmtab,my_atmtab_allocated,paral_atom,natom,my_natom_ref=my_natom)
     954              : 
     955       617397 :    cplex_cprj=2;if (gs_hamkq%istwf_k>1) cplex_cprj=1
     956       617397 :    option_rhoij=2
     957       617397 :    use_timerev=(kptopt>0.and.kptopt<3)
     958      1234794 :    use_zeromag=.false.;if (my_natom>0) use_zeromag=(pawrhoij1(1)%nspden==4.and.gs_hamkq%nvloc==1)
     959              : 
     960       617397 :    if (gs_hamkq%usecprj==1) then
     961      1234794 :      do idat=1,ndat
     962              :        call pawaccrhoij(gs_hamkq%atindx,cplex_cprj,cwaveprj0(:,1+(idat-1)*nspinor:idat*nspinor),&
     963              :   &     cwaveprj1(:,1+(idat-1)*nspinor:idat*nspinor),ipert,isppol,my_natom,&
     964              :   &     natom,nspinor,occ_k(iband+idat-1),option_rhoij,pawrhoij1,use_timerev,use_zeromag,wtk_k,&
     965      1234794 :   &     comm_atom=my_comm_atom,mpi_atmtab=my_atmtab)
     966              :      end do
     967              :    else
     968            0 :        ABI_BUG("toto")
     969            0 :      ABI_MALLOC(cwaveprj_tmp,(natom,nspinor*ndat))
     970            0 :      call pawcprj_alloc(cwaveprj_tmp,ncpgr,gs_hamkq%dimcprj)
     971            0 :      choice=2
     972              :      call getcprj(choice,0,cwave0,cwaveprj_tmp,&
     973              : &     gs_hamkq%ffnl_k,idir,gs_hamkq%indlmn,gs_hamkq%istwf_k,&
     974              : &     gs_hamkq%kg_k,gs_hamkq%kpg_k,gs_hamkq%kpt_k,gs_hamkq%lmnmax,&
     975              : &     gs_hamkq%mgfft,mpi_enreg,ndat,gs_hamkq%natom,gs_hamkq%nattyp,gs_hamkq%ngfft,&
     976              : &     gs_hamkq%nloalg,gs_hamkq%npw_k,gs_hamkq%nspinor,gs_hamkq%ntypat,gs_hamkq%phkxred,&
     977            0 : &     gs_hamkq%ph1d,gs_hamkq%ph3d_k,gs_hamkq%ucvol,gs_hamkq%useylm)
     978              :      call pawaccrhoij(gs_hamkq%atindx,cplex_cprj,cwaveprj_tmp,cwaveprj1,ipert,isppol,my_natom,&
     979              : &     gs_hamkq%natom,nspinor,occ_k(iband),option_rhoij,pawrhoij1,use_timerev,use_zeromag,wtk_k, &
     980            0 : &     comm_atom=my_comm_atom,mpi_atmtab=my_atmtab)
     981            0 :      call pawcprj_free(cwaveprj_tmp)
     982            0 :      ABI_FREE(cwaveprj_tmp)
     983              :    end if
     984              : 
     985              :  end if
     986              : 
     987              :  ABI_NVTX_END_RANGE()
     988              :  DBG_EXIT("COLL")
     989              : 
     990              :  contains
     991              : 
     992              :    !  Compute contribution of bands in ndat to zero-order potential part of the 2nd-order total energy
     993              :    !  This routine was separated from main code to accomodate OpenMP offloading with NVHPC
     994      3300127 :    subroutine update_potential_contrib(eloc0_k,wfraug1,vlocal,n1,n2,n3,n4,n5,n6,nvloc,nfft,ndat,gpu_option)
     995              :      integer,intent(in) :: n1,n2,n3,n4,n5,n6,nvloc,ndat,nfft,gpu_option
     996              :      real(dp),intent(in) :: wfraug1(2,n4,n5,n6*ndat),vlocal(n4,n5,n6,nvloc)
     997              :      real(dp),intent(inout) :: eloc0_k(ndat)
     998              :      integer :: idat,i1,i2,i3
     999              :      real(dp) :: valuer,nfft_r
    1000              : 
    1001      3300127 :      nfft_r=dble(nfft)
    1002              : #ifdef HAVE_OPENMP_OFFLOAD
    1003              :      !$OMP TARGET TEAMS DISTRIBUTE &
    1004              :      !$OMP& MAP(to:wfraug1,vlocal) MAP(tofrom:eloc0_k) PRIVATE(idat,valuer) &
    1005              :      !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1006              : #endif
    1007      6600254 :      do idat=1,ndat
    1008      3300127 :        valuer=zero
    1009              :        !$OMP PARALLEL DO COLLAPSE(3) PRIVATE(i1,i2,i3) REDUCTION(+:valuer)
    1010     54323219 :        do i3=1,n3
    1011    825793401 :          do i2=1,n2
    1012  13824709538 :            do i1=1,n1
    1013  13773686446 :              valuer=valuer+vlocal(i1,i2,i3,1)*(wfraug1(1,i1,i2,i3+n3*(idat-1))**2+wfraug1(2,i1,i2,i3+n3*(idat-1))**2)
    1014              :            end do
    1015              :          end do
    1016              :        end do
    1017              :        !    Local potential energy of this band
    1018      6600254 :        eloc0_k(idat)=eloc0_k(idat)+two*valuer/nfft_r
    1019              :      end do
    1020              : 
    1021              : #ifndef HAVE_OPENMP_OFFLOAD
    1022              :      ! Make testfarm happy
    1023              :      ABI_UNUSED((/gpu_option/))
    1024              : #endif
    1025      3300127 :    end subroutine update_potential_contrib
    1026              : 
    1027              :    !  Accumulate 1st-order density
    1028              :    !  This routine was separated from main code to accomodate OpenMP offloading with NVHPC
    1029      2768380 :    subroutine accumulate_1st_order_density(rhoaug1,wfraug,wfraug1,&
    1030      2768380 :    &    cplex,n1,n2,n3,n4,n5,n6,nvloc,ndat,nband_k,iband,ucvol,wtk_k,occ_k,gpu_option)
    1031              :      integer,intent(in)  :: cplex,n1,n2,n3,n4,n5,n6,nvloc,ndat,nband_k,iband,gpu_option
    1032              :      real(dp),intent(in) :: ucvol,wtk_k
    1033              :      real(dp),intent(inout) :: rhoaug1(cplex*n4,n5,n6,nvloc)
    1034              :      real(dp),intent(in) :: wfraug(2,n4,n5,n6*ndat),wfraug1(2,n4,n5,n6*ndat),occ_k(nband_k)
    1035              : 
    1036              :      integer  :: i1,i2,i3,idat
    1037              :      real(dp) :: weight
    1038              : 
    1039      2768380 :      if (cplex==2) then
    1040      3126744 :        do idat=1,ndat
    1041      1563372 :          weight=two*occ_k(iband+idat-1)*wtk_k/ucvol
    1042              : #ifdef HAVE_OPENMP_OFFLOAD
    1043              :          !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(3) &
    1044              :          !$OMP& MAP(to:wfraug1,wfraug,rhoaug1) PRIVATE(i3,i2,i1) &
    1045              :          !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1046              : #endif
    1047     26921180 :          do i3=1,n3
    1048    373375940 :            do i2=1,n2
    1049   5922995620 :              do i1=1,n1
    1050              : ! TODO: check which terms (ispinor ispinorp) enter a given element of rhoaug1
    1051              :                rhoaug1(2*i1-1,i2,i3,1)=rhoaug1(2*i1-1,i2,i3,1) &
    1052              : &               +weight*(wfraug(1,i1,i2,i3+n6*(idat-1))*wfraug1(1,i1,i2,i3+n6*(idat-1)) &
    1053   5551183052 : &               +wfraug(2,i1,i2,i3+n6*(idat-1))*wfraug1(2,i1,i2,i3+n6*(idat-1)))
    1054              :                rhoaug1(2*i1  ,i2,i3,1)=rhoaug1(2*i1  ,i2,i3,1) &
    1055              : &               +weight*(wfraug(1,i1,i2,i3+n6*(idat-1))*wfraug1(2,i1,i2,i3+n6*(idat-1)) &
    1056   5899201184 : &               -wfraug(2,i1,i2,i3+n6*(idat-1))*wfraug1(1,i1,i2,i3+n6*(idat-1)))
    1057              :              end do
    1058              :            end do
    1059              :          end do
    1060              :        end do
    1061              :      else
    1062      2410016 :        do idat=1,ndat
    1063      1205008 :          weight=two*occ_k(iband+idat-1)*wtk_k/ucvol
    1064              : #ifdef HAVE_OPENMP_OFFLOAD
    1065              :          !$OMP TARGET TEAMS DISTRIBUTE PARALLEL DO COLLAPSE(3) &
    1066              :          !$OMP& MAP(to:wfraug1,wfraug,rhoaug1) PRIVATE(i3,i2,i1) &
    1067              :          !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1068              : #endif
    1069     21645661 :          do i3=1,n3
    1070    312579704 :            do i2=1,n2
    1071   5176534063 :              do i1=1,n1
    1072              :                rhoaug1(i1,i2,i3,1)=rhoaug1(i1,i2,i3,1) &
    1073              : &               +weight*(wfraug(1,i1,i2,i3+n6*(idat-1))*wfraug1(1,i1,i2,i3+n6*(idat-1)) &
    1074   5157298418 : &               +wfraug(2,i1,i2,i3+n6*(idat-1))*wfraug1(2,i1,i2,i3+n6*(idat-1)))
    1075              :              end do
    1076              :            end do
    1077              :          end do
    1078              :        end do
    1079              :      end if
    1080              : 
    1081              : #ifndef HAVE_OPENMP_OFFLOAD
    1082              :      ! Make testfarm happy
    1083              :      ABI_UNUSED((/gpu_option/))
    1084              : #endif
    1085      2768380 :    end subroutine accumulate_1st_order_density
    1086              : 
    1087              : end subroutine dfpt_accrho
    1088              : !!***
    1089              : 
    1090              : end module m_dfpt_mkrho
    1091              : !!***
        

Generated by: LCOV version 2.3-1