LCOV - code coverage report
Current view: top level - src/66_nonlocal - m_cgprj.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 73.3 % 570 418
Test Date: 2026-09-21 19:39:32 Functions: 75.0 % 4 3

            Line data    Source code
       1              : !!****m* ABINIT/m_cgprj
       2              : !! NAME
       3              : !!  m_cgprj
       4              : !!
       5              : !! FUNCTION
       6              : !!   Routines to compute <Proj_i|Cnk> with |Cnk> expressed in reciprocal space.
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 1998-2026 ABINIT group (MT)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~abinit/COPYING
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! SOURCE
      15              : 
      16              : #if defined HAVE_CONFIG_H
      17              : #include "config.h"
      18              : #endif
      19              : 
      20              : #include "abi_common.h"
      21              : 
      22              : module m_cgprj
      23              : 
      24              :  use defs_basis
      25              :  use m_abicore
      26              :  use m_errors
      27              :  use m_xmpi
      28              : 
      29              :  use defs_abitypes, only : MPI_type
      30              :  use defs_datatypes, only : pseudopotential_type
      31              :  use m_fstrings, only : itoa, sjoin
      32              :  use m_kg,       only : ph1d3d, mkkpg
      33              :  use m_geometry, only : strconv
      34              :  use m_mkffnl,   only : mkffnl
      35              :  use m_mpinfo,   only : proc_distrb_cycle
      36              :  use m_pawcprj,  only : pawcprj_type, pawcprj_alloc, pawcprj_put, pawcprj_free, &
      37              :                         pawcprj_set_zero, pawcprj_mpi_sum, pawcprj_copy, pawcprj_lincom
      38              :  use m_opernla_ylm, only : opernla_ylm
      39              :  use m_opernla_ylm_mv, only : opernla_ylm_mv
      40              :  use m_opernla_gemm,   only : opernla_gemm
      41              :  use m_gemm_nonlop_projectors
      42              :  use m_time,           only : timab
      43              :  use m_io_tools,       only : flush_unit
      44              : 
      45              :  use m_xg
      46              :  use m_xg_nonlop
      47              : 
      48              :  implicit none
      49              : 
      50              :  private
      51              : !!***
      52              : 
      53              :  public :: getcprj
      54              :  public :: cprj_rotate
      55              :  public :: ctocprj
      56              :  public :: xg_cprj_copy
      57              : 
      58              :  integer,parameter,public :: XG_TO_CPRJ=1
      59              :  integer,parameter,public :: CPRJ_TO_XG=2
      60              : !!***
      61              : 
      62              : contains
      63              : !!***
      64              : 
      65              : !!****f* ABINIT/getcprj
      66              : !! NAME
      67              : !! getcprj
      68              : !!
      69              : !! FUNCTION
      70              : !!  Compute <Proj_i|Cnk> for one wave function |Cnk> expressed in reciprocal space.
      71              : !!  Compute also derivatives of <Proj_i|Cnk>.
      72              : !!  |Proj_i> are non-local projectors (for each atom and each l,m,n)
      73              : !!
      74              : !! INPUTS
      75              : !!  choice=chooses possible output:
      76              : !!    In addition to projected wave function:
      77              : !!    choice=1 => nothing else
      78              : !!          =2 => 1st gradients with respect to atomic position(s)
      79              : !!          =3 => 1st gradients with respect to strain(s)
      80              : !!          =23=> 1st gradients with respect to strain(s) and atm pos
      81              : !!          =4 => 2nd derivatives with respect to atomic pos.
      82              : !!          =24=> 1st and 2nd derivatives with respect to atomic pos.
      83              : !!          =5 => 1st gradients with respect to k wavevector
      84              : !!          =6 => 2nd derivatives with respect to strain and atm. pos.
      85              : !!  cpopt=1 if <Proj_i|Cnk> are already in memory; see below (side effects).
      86              : !!  cwavef(2,nspinor*npw_k)=input cmplx wavefunction coefficients <G|Cnk>
      87              : !!  ffnl(npw_k,dimffnl,lmnmax,ntypat)=nonlocal form factors to be used for the application of the nl operator
      88              : !!  idir=direction of the derivative, i.e. dir. of - atom to be moved  in the case choice=2
      89              : !!                                                 - strain component  in the case choice=3
      90              : !!                                                 - k point direction in the case choice=5
      91              : !!       Compatible only with choice=2,3,5; if idir=0, all derivatives are computed
      92              : !!  indlmn(6,i,ntypat)= array giving l,m,n,lm,ln,s for i=lmn
      93              : !!  istwf_k=option parameter that describes the storage of wfs
      94              : !!  kg_k(3,npw_k)=reduced planewave coordinates
      95              : !!  kpg(npw_k,npkg)=(k+G) components and related data
      96              : !!  kpoint(3)=k point in terms of recip. translations
      97              : !!  lmnmax=max. number of (l,m,n) components over all types of atoms
      98              : !!  mgfft=maximum size of 1D FFTs
      99              : !!  mpi_enreg=information about MPI parallelization
     100              : !!  natom=number of atoms in cell
     101              : !!  nattyp(ntypat)=number of atoms of each type
     102              : !!  ngfft(18)=contain all needed information about 3D FFT, see ~ABINIT/Infos/vargs.htm#ngfft
     103              : !!  nloalg(3)=governs the choice of the algorithm for nonlocal operator
     104              : !!  npw_k=number of planewaves for given k point
     105              : !!  nspinor=number of spinorial components of the wavefunctions (on current proc)
     106              : !!  ntypat=number of types of atoms in unit cell
     107              : !!  phkxred(2,natom)=phase factors exp(2 pi kpoint.xred)
     108              : !!  ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information
     109              : !!  ph3d(2,npw_k,natom)=3D structure factors, for each atom and plane wave
     110              : !!                      only used if nloalg(2)>0
     111              : !!  ucvol= unit cell volume
     112              : !!  useylm=governs the way the nonlocal operator is to be applied
     113              : !!  is_kprime=wether provided arrays relate to K or Kprime for Hamiltonian operator (optional, for GEMM nonlop)
     114              : !!
     115              : !! SIDE EFFECTS
     116              : !!  cwaveprj(natom,nspinor) <type(pawcprj_type)>=projected input wave function <Proj_i|Cnk> with all NL projectors
     117              : !!                                (and derivatives)
     118              : !!                                if cpopt=1 the projected scalars have been already been computed and
     119              : !!                                           only derivatives are computed here
     120              : !!                                if cpopt=0 the projected scalars and derivatives are computed here
     121              : !!
     122              : !! TODO
     123              : !!  Spin-orbit
     124              : !!
     125              : !! SOURCE
     126              : 
     127      4264420 :  subroutine getcprj(choice,cpopt,cwavef,cwaveprj,ffnl,&
     128      1066105 : &                   idir,indlmn,istwf_k,kg_k,kpg,kpoint,lmnmax,mgfft,mpi_enreg,ndat,&
     129      1066105 : &                   natom,nattyp,ngfft,nloalg,npw_k,nspinor,ntypat,&
     130      1066105 : &                   phkxred,ph1d,ph3d,ucvol,useylm,is_kprime,gpu_option)
     131              : 
     132              : !Arguments -------------------------------
     133              : !scalars
     134              :  integer,intent(in) :: choice,cpopt,idir,istwf_k,lmnmax,ndat
     135              :  integer,intent(in) :: mgfft,natom,npw_k,nspinor,ntypat,useylm
     136              :  integer,intent(in),optional :: gpu_option
     137              :  real(dp),intent(in) :: ucvol
     138              :  logical,intent(in),optional :: is_kprime
     139              :  type(MPI_type),intent(in) :: mpi_enreg
     140              : !arrays
     141              :  integer,intent(in) :: indlmn(6,lmnmax,ntypat),kg_k(3,npw_k),nattyp(ntypat)
     142              :  integer,intent(in) :: ngfft(18),nloalg(3)
     143              :  real(dp),intent(in) :: cwavef(2,npw_k*nspinor*ndat)
     144              :  real(dp),intent(in),target :: ffnl(:,:,:,:),kpg(:,:),ph3d(:,:,:)
     145              :  real(dp),intent(in) :: kpoint(3),ph1d(2,3*(2*mgfft+1)*natom),phkxred(2,natom)
     146              :  type(pawcprj_type),intent(inout) :: cwaveprj(natom,nspinor*ndat)
     147              : 
     148              : !Local variables-------------------------------
     149              : !scalars
     150              :  logical :: no_opernla_mv,no_opernla_gemm,l_is_kprime
     151              :  integer :: choice_,cplex,dimffnl,ia,ia1,ia2,ia3,ia4,iatm,ic,ii,ilmn,ishift,ispinor,itypat,idat,nprojs,shift,iatom,igrad
     152              :  integer :: jc,matblk,mincat,nd2gxdt,ndgxdt,nincat,nkpg,nkpg_,nlmn,signs,l_gpu_option
     153              : !arrays
     154              :  real(dp) :: tsec(2)
     155      1066105 :  integer,allocatable :: cplex_dgxdt(:),cplex_d2gxdt(:),indlmn_typ(:,:)
     156      1066105 :  real(dp),allocatable :: d2gxdt(:,:,:,:,:),dgxdt(:,:,:,:,:),ffnl_typ(:,:,:)
     157      1066105 :  real(dp),allocatable :: gx(:,:,:,:)
     158      1066105 :  real(dp),allocatable :: vgx(:,:,:),vdgxdt(:,:,:)
     159      1066105 :  real(dp), pointer :: kpg_(:,:),ph3d_(:,:,:)
     160      1066105 :  real(dp), allocatable :: temp_realvec_r(:),temp_realvec_i(:)
     161              :  real(dp) :: d2gxdt_dum_in(1,1,1,1,1)
     162              : 
     163              : ! *********************************************************************
     164              : 
     165              :  DBG_ENTER('COLL')
     166              : 
     167      1066105 :  call timab(1290,1,tsec)
     168              : 
     169              : !Nothing to do in that case
     170      1066105 :  if (cpopt==1.and.choice==1) return
     171              : 
     172      1066105 :  l_gpu_option=ABI_GPU_DISABLED; if(present(gpu_option)) l_gpu_option = gpu_option
     173      1066105 :  l_is_kprime=.false.; if(present(is_kprime)) l_is_kprime = is_kprime
     174              : 
     175              : !Not available for useylm=0
     176      1066105 :  if (useylm==0) then
     177            0 :    ABI_ERROR('Not available for useylm=0 !')
     178              :  end if
     179              : 
     180              : !Error on bad choice
     181      1066105 :  if ((choice<1.or.choice>6).and.choice/=23.and.choice/=24) then
     182            0 :    ABI_BUG('Does not presently support this choice !')
     183              :  end if
     184              : 
     185              : !Error on bad idir
     186      1066105 :  if (idir>0.and.choice/=2.and.choice/=3.and.choice/=5) then
     187            0 :    ABI_BUG('Does not support idir>0 for this choice')
     188              :  end if
     189              : 
     190              : !Error on sizes
     191      1066105 :  nkpg=size(kpg,2)
     192      1066105 :  if (nkpg>0) then
     193              :    if( (choice==2.and.nkpg<3) .or. &
     194       177384 : &   ((choice==4.or.choice==24).and.nkpg<9) .or. &
     195              : &   ((choice==6.or.choice==3.or.choice==23).and.nkpg<3) ) then
     196            0 :      ABI_BUG('Incorrect size for kpg array !')
     197              :    end if
     198              :  end if
     199      1066105 :  if (size(ffnl,1)/=npw_k.or.size(ffnl,3)/=lmnmax) then
     200            0 :    ABI_BUG('Incorrect size for ffnl!')
     201              :  end if
     202      1066105 :  if (size(ph3d,dim=1)>0) then
     203      1066105 :    if (size(ph3d,2)/=npw_k) then
     204            0 :      ABI_BUG('Incorrect size for ph3d!')
     205              :    end if
     206              :  end if
     207              : 
     208      1066105 :  no_opernla_mv = nloalg(1)==4.or.nloalg(1)==8.or.nloalg(1)==10 ! have to be consistent with nonlop_ylm
     209              :  no_opernla_gemm = (.not. gemm_nonlop_use_gemm) &
     210              :  &    .or. choice==4 .or. choice==6 .or. ndat==1 &
     211      1066105 :  &    .or. l_gpu_option/=gemm_nonlop_gpu_option
     212              : 
     213              : !Define dimensions of projected scalars
     214      1066105 :  dimffnl=size(ffnl,2)
     215      1066105 :  ndgxdt=0;nd2gxdt=0
     216      1066105 :  if (idir==0) then
     217       919057 :    if (choice==2) ndgxdt=3
     218       919057 :    if (choice==3) ndgxdt=6
     219       919057 :    if (choice==23) ndgxdt=9
     220       919057 :    if (choice==4) nd2gxdt=6
     221       919057 :    if (choice==24) then
     222            0 :      ndgxdt=3;nd2gxdt=6
     223              :    end if
     224       919057 :    if (choice==5) ndgxdt=3
     225       919057 :    if (choice==6) then
     226            0 :      ndgxdt=9;nd2gxdt=54
     227              :    end if
     228              :  else
     229       147048 :    ndgxdt=1
     230              :  end if
     231      1066105 :  if(cwaveprj(1,1)%ncpgr<ndgxdt+nd2gxdt) then
     232            0 :    ABI_BUG('Incorrect size for ncpgr')
     233              :  end if
     234              : !Eventually re-compute (k+G) vectors (and related data)
     235      1066105 :  if (nkpg==0) then
     236       888721 :    nkpg_=0
     237       888721 :    if (choice==4.or.choice==24) nkpg_=9
     238       888721 :    if (choice==2.or.choice==3.or.choice==23) nkpg_=3
     239      3554884 :    ABI_MALLOC(kpg_,(npw_k,nkpg_))
     240       888721 :    if (nkpg_>0) then
     241        16128 :      call mkkpg(kg_k,kpg_,kpoint,nkpg_,npw_k)
     242              :    end if
     243              :  else
     244       177384 :    nkpg_=nkpg
     245       177384 :    kpg_ => kpg
     246              :  end if
     247              : 
     248              : !Some other dims
     249      2950572 :  mincat=min(NLO_MINCAT,maxval(nattyp))
     250      1066105 :  cplex=2;if (istwf_k>1) cplex=1
     251      1066105 :  choice_=choice;if (cpopt==1) choice_=-choice
     252      1066105 :  signs=1;if (idir>0) signs=2
     253              : !Eventually allocate temporary array for ph3d
     254      1066105 :  if (nloalg(2)<=0) then
     255            0 :    matblk=mincat
     256            0 :    ABI_MALLOC(ph3d_,(2,npw_k,matblk))
     257              :  else
     258      1066105 :    matblk=size(ph3d,3)
     259      1066105 :    ph3d_ => ph3d
     260              :  end if
     261              : 
     262      1066105 :  if(no_opernla_gemm) then
     263              :   !Loop over atom types
     264              :    ia1=1;iatm=0
     265      2950572 :    do itypat=1,ntypat
     266      1884467 :      ia2=ia1+nattyp(itypat)-1;if (ia2<ia1) cycle
     267     17490577 :      nlmn=count(indlmn(3,:,itypat)>0)
     268              : 
     269              :   !  Retrieve some data for this type of atom
     270      5653401 :      ABI_MALLOC(indlmn_typ,(6,nlmn))
     271      9422335 :      ABI_MALLOC(ffnl_typ,(npw_k,dimffnl,nlmn))
     272    110771749 :      indlmn_typ(:,1:nlmn)=indlmn(:,1:nlmn,itypat)
     273   2948221065 :      ffnl_typ(:,:,1:nlmn)=ffnl(:,:,1:nlmn,itypat)
     274              : 
     275              :   !  Loop on blocks of atoms inside type
     276      1884467 :      do ia3=ia1,ia2,mincat
     277      1884467 :        ia4=min(ia2,ia3+mincat-1);nincat=ia4-ia3+1
     278              :   !     Prepare the phase factors if they were not already computed
     279      1884467 :        if (nloalg(2)<=0) then
     280              :          call ph1d3d(ia3,ia4,kg_k,matblk,natom,npw_k,ngfft(1),ngfft(2),ngfft(3),&
     281            0 :   &       phkxred,ph1d,ph3d_)
     282              :        end if
     283              : 
     284              :   !    Allocate memory for projected scalars
     285     11306802 :        ABI_MALLOC(gx,(cplex,nlmn,nincat,nspinor*ndat))
     286     13191269 :        ABI_MALLOC(dgxdt,(cplex,ndgxdt,nlmn,nincat,nspinor*ndat))
     287     13191269 :        ABI_MALLOC(d2gxdt,(cplex,nd2gxdt,nlmn,nincat,nspinor*ndat))
     288      5653401 :        ABI_MALLOC(cplex_dgxdt,(ndgxdt))
     289      5653401 :        ABI_MALLOC(cplex_d2gxdt,(nd2gxdt))
     290              : 
     291              :   !    Retrieve eventually <p_i|c> coeffs
     292      1884467 :        if (cpopt==1) then
     293       429096 :          do ispinor=1,nspinor*ndat
     294       754824 :            do ia=1,nincat
     295      8544588 :              gx(1:cplex,1:nlmn,ia,ispinor)=cwaveprj(iatm+ia,ispinor)%cp(1:cplex,1:nlmn)
     296              :            end do
     297              :          end do
     298              :        end if
     299              : 
     300              :   !    Compute <p_i|c> scalars (and derivatives) for this block of atoms
     301      1884467 :        if (abs(choice_)>1.or.no_opernla_mv) then
     302      3768934 :          do idat=1,ndat
     303      1884467 :            call timab(1291,1,tsec)
     304              :            call opernla_ylm(choice_,cplex,cplex_dgxdt,cplex_d2gxdt,dimffnl,&
     305              :   &         d2gxdt(:,:,:,:,1+nspinor*(idat-1):nspinor*idat),&
     306              :   &         dgxdt(:,:,:,:,1+nspinor*(idat-1):nspinor*idat),ffnl_typ,&
     307              :   &         gx(:,:,:,1+nspinor*(idat-1):nspinor*idat),&
     308              :   &         ia3,idir,indlmn_typ,istwf_k,kpg_,matblk,mpi_enreg,nd2gxdt,ndgxdt,nincat,nkpg_,nlmn,&
     309      1884467 :   &         nloalg,npw_k,nspinor,ph3d_,signs,ucvol,cwavef(:,1+npw_k*nspinor*(idat-1):npw_k*nspinor*idat))
     310      3768934 :            call timab(1291,2,tsec)
     311              :          end do
     312              :        else
     313            0 :          call timab(1292,1,tsec)
     314            0 :          do idat=1,ndat
     315              :            call opernla_ylm_mv(choice_,cplex,dimffnl,ffnl_typ,gx(:,:,:,1+nspinor*(idat-1):nspinor*idat),&
     316              :   &         ia3,indlmn_typ,istwf_k,matblk,mpi_enreg,nincat,nlmn,&
     317            0 :   &         nloalg,npw_k,nspinor,ph3d_,ucvol,cwavef(:,1+npw_k*nspinor*(idat-1):npw_k*nspinor*idat))
     318              :          end do
     319            0 :          call timab(1292,2,tsec)
     320              :        end if
     321              : 
     322              :   !    Transfer result to output variable cwaveprj
     323      1884467 :        if (cpopt==0) then
     324      3356298 :          do ispinor=1,nspinor*ndat
     325      5288946 :            do ia=1,nincat
     326      1932648 :              cwaveprj(iatm+ia,ispinor)%nlmn=nlmn
     327     50680410 :              cwaveprj(iatm+ia,ispinor)%cp(1:cplex,1:nlmn)=gx(1:cplex,1:nlmn,ia,ispinor)
     328      3619027 :              if(cplex==1) cwaveprj(iatm+ia,ispinor)%cp(2,1:nlmn)=zero
     329              :            end do
     330              :          end do
     331              :        end if
     332      1884467 :        if (cpopt>=0.and.choice>1) then
     333       460344 :          ishift=0
     334       460344 :          if ((idir>0).and.(cwaveprj(1,1)%ncpgr>ndgxdt)) ishift=idir-1
     335       460344 :          if(cplex==2)then
     336       927228 :            do ispinor=1,nspinor*ndat
     337      1518908 :              do ia=1,nincat
     338              :   !             cwaveprj(iatm+ia,ispinor)%ncpgr=ndgxdt+nd2gxdt
     339       591680 :                if (ndgxdt>0) cwaveprj(iatm+ia,ispinor)%dcp(1:2,1+ishift:ndgxdt+ishift,1:nlmn)=&
     340     35976576 :   &             dgxdt(1:2,1:ndgxdt,1:nlmn,ia,ispinor)
     341       591680 :                if (nd2gxdt>0)cwaveprj(iatm+ia,ispinor)%dcp(1:2,ndgxdt+1+ishift:ndgxdt+nd2gxdt+ishift,1:nlmn)=&
     342       466884 :   &             d2gxdt(1:2,1:nd2gxdt,1:nlmn,ia,ispinor)
     343              :              end do
     344              :            end do
     345              :          else
     346              :   !        cplex_dgxdt(i)  = 1 if dgxdt(1,i,:,:)  is real, 2 if it is pure imaginary
     347              :   !        cplex_d2gxdt(i) = 1 if d2gxdt(1,i,:,:) is real, 2 if it is pure imaginary
     348            0 :            do ispinor=1,nspinor*ndat
     349            0 :              do ia=1,nincat
     350              :   !             cwaveprj(iatm+ia,ispinor)%ncpgr=ndgxdt+nd2gxdt
     351            0 :                if (ndgxdt>0) then
     352            0 :                  do ilmn =1,nlmn
     353            0 :                    do ii = 1,ndgxdt
     354            0 :                      ic = cplex_dgxdt(ii) ; jc = 3 - ic
     355            0 :                      cwaveprj(iatm+ia,ispinor)%dcp(ic,ii+ishift,ilmn)=dgxdt(1,ii,ilmn,ia,ispinor)
     356            0 :                      cwaveprj(iatm+ia,ispinor)%dcp(jc,ii+ishift,ilmn)=zero
     357              :                    end do
     358              :                  end do
     359              :                end if
     360            0 :                if (nd2gxdt>0) then
     361            0 :                  do ilmn =1,nlmn
     362            0 :                    do ii = 1,nd2gxdt
     363            0 :                      ic = cplex_d2gxdt(ii) ; jc = 3 - ic
     364            0 :                      cwaveprj(iatm+ia,ispinor)%dcp(ic,ndgxdt+ii+ishift,ilmn)=d2gxdt(1,ii,ilmn,ia,ispinor)
     365            0 :                      cwaveprj(iatm+ia,ispinor)%dcp(jc,ndgxdt+ii+ishift,ilmn)=zero
     366              :                    end do
     367              :                  end do
     368              :                end if
     369              :              end do
     370              :            end do
     371              :          end if
     372              :        end if
     373              : 
     374              :   !    End loop inside block of atoms
     375      1884467 :        iatm=iatm+nincat
     376      1884467 :        ABI_FREE(gx)
     377      1884467 :        ABI_FREE(dgxdt)
     378      1884467 :        ABI_FREE(d2gxdt)
     379      1884467 :        ABI_FREE(cplex_dgxdt)
     380      1884467 :        ABI_FREE(cplex_d2gxdt)
     381              :      end do
     382              : 
     383              :   !  End loop over atom types
     384      1884467 :      ia1=ia2+1
     385      1884467 :      ABI_FREE(indlmn_typ)
     386      2950572 :      ABI_FREE(ffnl_typ)
     387              :    end do
     388              : 
     389              :  else
     390              : 
     391              :    ! Batched GEMM call : proceed "ndat" bands at once with GEMM opernla
     392              : 
     393            0 :    if(cplex==1) ABI_BUG("toto")
     394            0 :    if (nloalg(2)<=0) ABI_BUG("toto")
     395              : 
     396            0 :    nprojs = 0
     397            0 :    do itypat=1,ntypat
     398            0 :      nprojs = nprojs + count(indlmn(3,:,itypat)>0)*nattyp(itypat)
     399              :    end do
     400              : 
     401            0 :    ABI_MALLOC(cplex_dgxdt,(ndgxdt))
     402            0 :    ABI_MALLOC(cplex_d2gxdt,(nd2gxdt))
     403            0 :    ABI_MALLOC(vgx,(cplex,nprojs,nspinor*ndat))
     404            0 :    ABI_MALLOC(vdgxdt,(cplex,ndgxdt*nprojs,nspinor*ndat))
     405            0 :    vgx(:,:,:) = zero
     406            0 :    vdgxdt(:,:,:) = zero
     407              : #ifdef HAVE_OPENMP_OFFLOAD
     408              :    !$OMP TARGET ENTER DATA MAP(to:vgx,vdgxdt,kpg_) IF (l_gpu_option==ABI_GPU_OPENMP)
     409              : #endif
     410              : 
     411              : !  Retrieve eventually <p_i|c> coeffs
     412            0 :    if (cpopt==1) then
     413            0 :     do idat=1, ndat*nspinor
     414              :       shift = 0
     415            0 :       do iatom = 1, natom
     416            0 :         nlmn = cwaveprj(iatom, idat)%nlmn
     417            0 :         vgx(1:cplex, shift+1:shift+nlmn, idat) = cwaveprj(iatom, idat)%cp(1:cplex, 1:nlmn)
     418            0 :         shift = shift + nlmn
     419              :       end do
     420              :     end do
     421              :    end if
     422              : 
     423            0 :    if (cplex /= 2) then
     424            0 :      ABI_MALLOC(temp_realvec_r,(npw_k*nspinor*ndat))
     425            0 :      ABI_MALLOC(temp_realvec_i,(npw_k*nspinor*ndat))
     426              : #ifdef HAVE_OPENMP_OFFLOAD
     427              :      !$OMP TARGET ENTER DATA MAP(alloc:temp_realvec_r,temp_realvec_i) IF (l_gpu_option==ABI_GPU_OPENMP)
     428              : #endif
     429              :    end if
     430              : 
     431              :    call opernla_gemm(choice,cplex,cplex_dgxdt,cplex_d2gxdt,dimffnl,&
     432              :    &       d2gxdt_dum_in,vdgxdt,ffnl,vgx,&
     433              :    &       idir,indlmn,istwf_k,kpg_,matblk,mpi_enreg,nd2gxdt,ndgxdt,nkpg_,&
     434              :    &       npw_k,nspinor,ph3d,signs,ucvol,ndat,ntypat,lmnmax,nattyp,l_is_kprime,&
     435              :    &       -1,0,cpopt,&
     436              :    &       nprojs,&
     437              :    &       cwavef,&
     438              :    &       temp_realvec_r,temp_realvec_i,&
     439            0 :    &       l_gpu_option,.false.)
     440              : 
     441            0 :    if (cplex /= 2) then
     442              : #ifdef HAVE_OPENMP_OFFLOAD
     443              :      !$OMP TARGET EXIT DATA MAP(delete:temp_realvec_r,temp_realvec_i) IF (l_gpu_option==ABI_GPU_OPENMP)
     444              : #endif
     445            0 :      ABI_FREE(temp_realvec_r)
     446            0 :      ABI_FREE(temp_realvec_i)
     447              :    end if
     448              : 
     449              : #ifdef HAVE_OPENMP_OFFLOAD
     450              :    !$OMP TARGET UPDATE FROM(vgx,vdgxdt) IF (l_gpu_option==ABI_GPU_OPENMP)
     451              : #endif
     452              : 
     453              : 
     454              : !  Transfer result to output variable cwaveprj
     455            0 :    if (cpopt==0) then
     456            0 :      do idat=1, ndat*nspinor
     457              :        shift = 0
     458            0 :        do iatom = 1, natom
     459            0 :          nlmn = cwaveprj(iatom, idat)%nlmn
     460            0 :          cwaveprj(iatom, idat)%cp(1:cplex, 1:nlmn) = vgx(1:cplex, shift+1:shift+nlmn, idat)
     461            0 :          shift = shift + nlmn
     462              :        end do
     463              :      end do
     464              :    end if
     465              : 
     466            0 :    if (cpopt>=0.and.choice>1) then
     467            0 :      ishift=0
     468              :      if ((idir>0).and.(cwaveprj(1,1)%ncpgr>ndgxdt)) ishift=idir-1
     469            0 :      if(cplex==2)then
     470            0 :        do idat=1, ndat*nspinor
     471              :          shift = 0
     472            0 :          do iatom = 1, natom
     473            0 :            nlmn = cwaveprj(iatom, idat)%nlmn
     474            0 :            do igrad=1,ndgxdt
     475              :              cwaveprj(iatom, idat)%dcp(1:cplex,igrad,1:nlmn) = &
     476            0 :              &                   vdgxdt(1:cplex, shift+1:shift+nlmn, idat)
     477            0 :              shift = shift + nlmn
     478              :            end do
     479              :          end do
     480              :        end do
     481              :      else
     482            0 :        ABI_BUG("toto")
     483              :      end if
     484              :    end if
     485              : 
     486              : 
     487              : #ifdef HAVE_OPENMP_OFFLOAD
     488              :    !$OMP TARGET EXIT DATA MAP(delete:vgx,vdgxdt,kpg_) IF (l_gpu_option==ABI_GPU_OPENMP)
     489              : #endif
     490            0 :    ABI_FREE(vgx)
     491            0 :    ABI_FREE(vdgxdt)
     492            0 :    ABI_FREE(cplex_dgxdt)
     493            0 :    ABI_FREE(cplex_d2gxdt)
     494              : 
     495              :  end if
     496              : 
     497      1066105 :  if (nkpg==0) then
     498       888721 :    ABI_FREE(kpg_)
     499              :  end if
     500      1066105 :  if (nloalg(2)<=0) then
     501            0 :    ABI_FREE(ph3d_)
     502              :  end if
     503              : 
     504      1066105 :  call timab(1290,2,tsec)
     505              : 
     506              :  DBG_EXIT('COLL')
     507              : 
     508      2132210 :  end subroutine getcprj
     509              : !!***
     510              : 
     511              : !!****f* ABINIT/ctocprj
     512              : !! NAME
     513              : !! ctocprj
     514              : !!
     515              : !! FUNCTION
     516              : !!  Compute all <Proj_i|Cnk> for every wave function |Cnk> expressed in reciprocal space.
     517              : !!  |Proj_i> are non-local projectors (for each atom and each l,m,n)
     518              : !!  Can also compute derivatives of <Proj_i|Cnk> wrt to several parameters
     519              : !!
     520              : !! INPUTS
     521              : !!  atindx(natom)=index table for atoms
     522              : !!  cg(2,mcg)=planewave coefficients of wavefunctions
     523              : !!  choice: chooses derivatives to compute:
     524              : !!          =1 => no derivatives
     525              : !!          =2 => 1st derivatives with respect to atomic position(s)
     526              : !!          =3 => 1st derivatives with respect to strain(s)
     527              : !!          =23=> 1st derivatives with respect to strain(s) and atm pos
     528              : !!          =4 => 2nd derivatives with respect to atomic pos.
     529              : !!          =24=> 1st and 2nd derivatives with respect to atomic pos.
     530              : !!          =5 => derivatives with respect to k wavevector
     531              : !!          =6 => 2nd derivatives with respect to strain and atm. pos.
     532              : !!  gmet(3,3)=reciprocal space metric tensor in bohr**-2
     533              : !!  gprimd(3,3)=dimensional reciprocal space primitive translations
     534              : !!  iatom= if <=0, cprj=<p_i|Cnk> are computed for all atoms 1...natom
     535              : !!         if  >0  cprj=<p_i|Cnk> are computed only for atom with index iatom
     536              : !!  idir=direction of the derivative, i.e. dir. of - atom to be moved  in the case choice=2
     537              : !!                                                 - strain component  in the case choice=3
     538              : !!                                                 - k point direction in the case choice=5
     539              : !!       Compatible only with choice=2,3,5; if idir=0, all derivatives are computed
     540              : !!  iorder_cprj=0 if output cprj=<p_i|Cnk> are sorted by atom type
     541              : !!                (first all elements of atom type 1, followed by those of atom type 2 and so on).
     542              : !!              1 if output cprj=<p_i|Cnk> are sorted according to
     543              : !!                the variable typat in the main input file
     544              : !!  istwfk(nkpt)=option parameter that describes the storage of wfs
     545              : !!  kg(3,mpw*mkmem)=reduced planewave coordinates
     546              : !!  kpt(3,nkpt)=reduced coordinates of k points.
     547              : !!  mcg=size of wave-functions array (cg) =mpw*nspinor*mband_mem*mkmem*nsppol
     548              : !!  mcprj=size of projected wave-functions array (cprj) =nspinor*mband*mkmem*nsppol
     549              : !!  mgfft=maximum size of 1D FFTs
     550              : !!  mkmem=number of k points treated by this node.
     551              : !!  mpi_enreg=information about MPI parallelization
     552              : !!  mpsang=1+maximum angular momentum for nonlocal pseudopotentials
     553              : !!  mpw=maximum dimensioned size of npw
     554              : !!  my_nsppol=number of spin components in memory for current MPI process
     555              : !!  natom=number of atoms in cell
     556              : !!  nattyp(ntypat)= # atoms of each type
     557              : !!  nband(nkpt*nsppol)=number of bands at this k point for that spin polarization
     558              : !!  mband_mem=max number of bands for this processor (in case of band parallelism)
     559              : !!  ncprj=1st dim. of cprj array (natom if iatom<=0, 1 if iatom>0)
     560              : !!  ngfft(18)=contain all needed information about 3D FFT, see ~ABINIT/Infos/vargs.htm#ngfft
     561              : !!  nkpt=number of k points
     562              : !!  nloalg(3)=governs the choice of the algorithm for nonlocal operator
     563              : !!  npwarr(nkpt)=number of planewaves in basis at this k point
     564              : !!  nspinor=number of spinorial components of the wavefunctions
     565              : !!  nsppol=1 for unpolarized, 2 for spin-polarized
     566              : !!  ntypat=number of types of atoms in unit cell
     567              : !!  paral_kgb= 1 if kpt-band-FFT is activated
     568              : !!  ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information
     569              : !!  psps <type(pseudopotential_type)>=variables related to pseudopotentials
     570              : !!  rmet(3,3)=real space metric (bohr**2)
     571              : !!  tim_ctocprj=timing code of the calling routine
     572              : !!  typat(natom)= types of atoms
     573              : !!  uncp=unit number for <P_lmn|Cnk> data (if used)
     574              : !!  xred(3,natom)=reduced dimensionless atomic coordinates
     575              : !!  ylm(mpw*mkmem,mpsang*mpsang)=real spherical harmonics for each G and k point
     576              : !!  ylmgr(npw*mkmem,nylmgr,mpsang*mpsang*useylmgr)=gradients of real spherical harmonics wrt (k+G)
     577              : !!!
     578              : !! OUTPUT
     579              : !!  cprj(ncprj,mcprj) <type(pawcprj_type)>= projected input wave functions <Proj_i|Cnk> with NL projectors
     580              : !!                                       Usually ncprj=natom
     581              : !!
     582              : !! SOURCE
     583              : 
     584         4458 :  subroutine ctocprj(atindx,cg,choice,cprj,gmet,gprimd,iatom,idir,&
     585         2229 : & iorder_cprj,istwfk,kg,kpt,mcg,mcprj,mgfft,mkmem,mpi_enreg,mpsang,&
     586         2229 : & mpw,natom,nattyp,nband,ncprj,ngfft,nkpt,nloalg,npwarr,nspinor,&
     587         2229 : & nsppol,my_nsppol,ntypat,paral_kgb,ph1d,psps,rmet,typat,ucvol,uncp,xred,ylm,ylmgr)
     588              : 
     589              : !Arguments -------------------------------
     590              : !scalars
     591              :  integer,intent(in) :: choice,iatom,idir,iorder_cprj,mcg,mcprj,mgfft,mkmem,mpsang,mpw
     592              :  integer,intent(in) :: my_nsppol,natom,ncprj,nkpt,nspinor,nsppol,ntypat,paral_kgb,uncp
     593              : !TODO : distribute cprj over bands as well
     594              :  real(dp),intent(in) :: ucvol
     595              :  type(MPI_type),intent(in) :: mpi_enreg
     596              :  type(pseudopotential_type),target,intent(in) :: psps
     597              : !arrays
     598              :  integer,intent(in) :: istwfk(nkpt),nband(nkpt*nsppol)
     599              :  integer,intent(in) :: ngfft(18),nloalg(3),npwarr(nkpt),kg(3,mpw*mkmem),typat(natom)
     600              :  integer,intent(in),target :: atindx(natom),nattyp(ntypat)
     601              :  real(dp),intent(in) :: cg(2,mcg)
     602              :  real(dp),intent(in) :: gmet(3,3),gprimd(3,3),kpt(3,nkpt),rmet(3,3)
     603              :  real(dp),intent(in) :: xred(3,natom),ylm(:,:),ylmgr(:,:,:)
     604              :  real(dp),intent(in),target :: ph1d(2,3*(2*mgfft+1)*natom)
     605              :  type(pawcprj_type),intent(inout) :: cprj(ncprj,mcprj)
     606              : 
     607              : !Local variables-------------------------------
     608              : !scalars
     609              :  integer :: blocksz,cg_bandpp,counter,cpopt,cprj_bandpp,dimffnl,ia,iatm,iatom1,iatom2
     610              :  integer :: iband_max,iband_min,iband_start,ibg,ibgb,iblockbd,ibp,icg,icgb,icp1,icp2
     611              :  integer :: ider,idir0,iend,ierr,ig,ii,ikg,ikpt,ilm,ipw,isize,isppol,istart,istwf_k,itypat,iwf1,iwf2,jdir
     612              :  integer :: matblk,me_distrb,my_nspinor,n1,n1_2p1,n2,n2_2p1,n3,n3_2p1,kk,nlmn
     613              :  integer :: mband,mband_cg,mband_cprj,npband_dfpt
     614              :  integer :: nband_k,nband_cprj_k,nblockbd,ncpgr,nkpg,npband_bandfft,npws,npw_k,npw_nk,ntypat0
     615              :  integer :: nband_cg_k
     616              :  integer :: shift1,shift1b,shift2,shift2b,shift3,shift3b
     617              :  integer :: spaceComm,spaceComm_band,spaceComm_fft,useylmgr
     618              :  logical :: cg_band_distributed,cprj_band_distributed,one_atom
     619              :  real(dp) :: arg
     620              :  character(len=500) :: msg
     621              : !arrays
     622         2229 :  integer,allocatable :: bufsize(:),bufsize_wf(:),bufdisp(:),bufdisp_wf(:)
     623         2229 :  integer,allocatable :: dimlmn(:),kg_k(:,:),kg_k_loc(:,:)
     624         2229 :  integer,allocatable :: npw_block(:),npw_disp(:)
     625         2229 :  integer,pointer :: atindx_atm(:),indlmn_atm(:,:,:),nattyp_atm(:),pspso_atm(:)
     626              :  real(dp) :: kpoint(3),work(6),tsec(2)
     627         2229 :  real(dp),allocatable :: cwavef(:,:),cwavef_tmp(:,:)
     628         2229 :  real(dp),allocatable :: ffnl(:,:,:,:),ffnl_npw(:,:,:,:),ffnl_tmp(:,:,:,:),ffnl_tmp_npw(:,:,:,:)
     629         2229 :  real(dp),allocatable :: kpg_k(:,:)
     630         2229 :  real(dp),allocatable :: ph3d(:,:,:),ph3d_npw(:,:,:),ph3d_tmp(:,:,:),ph3d_tmp_npw(:,:,:)
     631         2229 :  real(dp),allocatable :: phkxred(:,:),ylm_k(:,:),ylmgr_k(:,:,:)
     632         2229 :  real(dp),ABI_CONTIGUOUS pointer :: ekb_atm(:,:),ffspl_atm(:,:,:,:),ph1d_atm(:,:)
     633         2229 :  type(pawcprj_type),allocatable :: cwaveprj(:,:)
     634              : 
     635              : ! *********************************************************************
     636              : 
     637              :  DBG_ENTER('COLL')
     638              : 
     639              : !Nothing to do if current MPI process does treat kpoints or plane-waves
     640         2229 :  if (mcg==0.or.mcprj==0) return
     641              : 
     642              : !Preliminary tests
     643         2229 :  if (psps%useylm==0) then
     644            0 :    msg='Not available for useylm=0!'
     645            0 :    ABI_ERROR(msg)
     646              :  end if
     647         2229 :  if ((choice<1.or.choice>6).and.choice/=23.and.choice/=24) then
     648            0 :    msg='Bad choice!'
     649            0 :    ABI_BUG(msg)
     650              :  end if
     651         2229 :  if (idir>0.and.choice/=2.and.choice/=3.and.choice/=5) then
     652            0 :    msg='Does not support idir>0 for that choice!'
     653            0 :    ABI_BUG(msg)
     654              :  end if
     655         6687 :  if (size(ylm)/=mpw*mkmem*mpsang*mpsang) then
     656            0 :    msg='Wrong size for Ylm!'
     657            0 :    ABI_BUG(msg)
     658              :  end if
     659         8916 :  useylmgr=merge(0,1,(size(ylmgr)==0))
     660          158 :  if (useylmgr==0.and.(choice==3.or.choice==5.or.choice==23)) then
     661            0 :    msg=' Ylm gradients have to be in memory for choice=3, 5, or 23!'
     662            0 :    ABI_BUG(msg)
     663              :  end if
     664              : 
     665              : !Init parallelism
     666         2229 :  npband_dfpt = 1
     667         2229 :  if (paral_kgb==1) then
     668          832 :    me_distrb=mpi_enreg%me_kpt
     669          832 :    spaceComm=mpi_enreg%comm_kpt
     670          832 :    spaceComm_fft=mpi_enreg%comm_fft
     671          832 :    npband_bandfft=mpi_enreg%nproc_band
     672          832 :    cg_bandpp=mpi_enreg%bandpp
     673          832 :    cprj_bandpp=mpi_enreg%bandpp
     674          832 :    spaceComm_band=mpi_enreg%comm_band
     675          832 :    cg_band_distributed=.true.
     676          832 :    cprj_band_distributed=(mpi_enreg%nproc_band>1)
     677          832 :    npband_dfpt=1
     678              :  else
     679         1397 :    me_distrb=mpi_enreg%me_kpt
     680         1397 :    spaceComm=mpi_enreg%comm_cell
     681         1397 :    spaceComm_fft=xmpi_comm_self
     682         1397 :    npband_bandfft=1
     683         1397 :    cg_bandpp=1
     684         1397 :    cprj_bandpp=1
     685         1397 :    if (mpi_enreg%paralbd==1) then
     686          415 :      spaceComm_band=mpi_enreg%comm_band ! not actually used as npband_bandfft=1
     687          415 :      cg_band_distributed=.true.
     688          415 :      cprj_band_distributed=.true.
     689              :      !npband_dfpt=1
     690          415 :      npband_dfpt=mpi_enreg%nproc_band
     691              :    else
     692          982 :      spaceComm_band=xmpi_comm_self
     693          982 :      cg_band_distributed=.false.
     694          982 :      cprj_band_distributed=.false.
     695              :    end if
     696              :  end if
     697         2229 :  if (cg_bandpp/=cprj_bandpp) then
     698            0 :    ABI_BUG('cg_bandpp must be equal to cprj_bandpp!')
     699              :  end if
     700              : 
     701              : !Manage parallelization over bands
     702        87150 :  mband=maxval(nband(1:nkpt*my_nsppol))
     703         2229 :  mband_cg=mband/npband_bandfft/npband_dfpt
     704         2229 :  mband_cprj=mband_cg
     705              : 
     706              : !Manage parallelization over spinors
     707         2229 :  my_nspinor=max(1,nspinor/mpi_enreg%nproc_spinor)
     708              : 
     709              : !Check sizes
     710         2229 :  if (mpw*mband_cg*my_nspinor*mkmem*my_nsppol>mcg) then
     711            0 :    ABI_BUG(sjoin('Bad mcg value!', itoa(mcg)))
     712              :  end if
     713         2229 :  if (mband_cprj*my_nspinor*mkmem*my_nsppol>mcprj) then
     714            0 :    ABI_BUG(sjoin('Bad mcprj value!', itoa(mcprj)))
     715              :  end if
     716              : 
     717              :  !Check sizes for cprj (distribution is tricky)
     718         2229 :  one_atom=(iatom>0)
     719         2229 :  if (one_atom.and.ncprj/=1) then
     720            0 :    ABI_BUG('Bad value for ncprj dimension (should be 1) !')
     721              :  end if
     722         2229 :  if (.not.one_atom.and.ncprj/=natom) then
     723            0 :    ABI_BUG('Bad value for ncprj dimension (should be natom) !')
     724              :  end if
     725              : 
     726              : !Initialize some variables
     727         2229 :  n1=ngfft(1);n2=ngfft(2);n3=ngfft(3)
     728         2229 :  n1_2p1=2*n1+1;n2_2p1=2*n2+1;n3_2p1=2*n3+1
     729         2229 :  ibg=0;icg=0;cpopt=0
     730         2229 :  ider=0;idir0=0;istart=idir;iend=idir
     731         2229 :  if (choice==3.or.choice==5.or.choice==23) ider=1
     732         2229 :  if (idir>0) then
     733          156 :    if (choice==3) idir0=-idir
     734          156 :    if (choice==5) idir0=idir
     735              :  else
     736              : !   if (choice==23) idir0=-7
     737         2073 :    if (choice==3) idir0=-7
     738         2073 :    if (choice==5) idir0=4
     739              :  end if
     740         2229 :  if (idir0==0.or.idir0==4) then
     741         2057 :    dimffnl=1+3*ider
     742          172 :  else if (idir0/=-7) then
     743          156 :    dimffnl=1+ider
     744              :  else
     745           16 :    dimffnl=1+6*ider
     746           16 :    if(choice==3)then
     747         2229 :      istart=ider;iend=6*ider
     748              :    end if
     749              :  end if
     750         2229 :  nkpg=0
     751         2229 :  if (choice==3.or.choice==2.or.choice==23) nkpg=3*nloalg(3)
     752         2229 :  if (choice==4.or.choice==24) nkpg=9*nloalg(3)
     753              : 
     754              : !Set number of gradients for <p_i|Cnk>
     755         2229 :  ncpgr=0
     756         2229 :  if (idir==0) then
     757         2073 :    if (choice==2) ncpgr=3
     758         2073 :    if (choice==3) ncpgr=6
     759         2073 :    if (choice==23)ncpgr=9
     760         2073 :    if (choice==4) ncpgr=6
     761         2073 :    if (choice==24)ncpgr=9
     762         2073 :    if (choice==5) ncpgr=3
     763         2073 :    if (choice==6) ncpgr=63
     764              :  else
     765          156 :    ncpgr=1
     766              :  end if
     767              : !Test cprj gradients dimension (just to be sure)
     768         2229 :  if (cprj(1,1)%ncpgr/=ncpgr) then
     769            0 :    ABI_BUG('cprj are badly allocated !')
     770              :  end if
     771              : 
     772              : 
     773              : !Extract data for treated atom(s)
     774         2229 :  if (one_atom) then
     775            0 :    iatom1=iatom;iatom2=iatom
     776            0 :    ntypat0=1;itypat=typat(iatom)
     777            0 :    ABI_MALLOC(nattyp_atm,(ntypat0))
     778            0 :    nattyp_atm(1)=1
     779            0 :    ABI_MALLOC(atindx_atm,(ntypat0))
     780            0 :    atindx_atm(1)=atindx(iatom)
     781            0 :    ABI_MALLOC(ph1d_atm,(2,(n1_2p1+n2_2p1+n3_2p1)*ntypat0))
     782            0 :    shift1=(atindx(iatom)-1)*n1_2p1
     783            0 :    shift2=(atindx(iatom)-1)*n2_2p1+natom*n1_2p1
     784            0 :    shift3=(atindx(iatom)-1)*n3_2p1+natom*(n1_2p1+n2_2p1)
     785            0 :    shift1b=0;shift2b=n1_2p1;shift3b=n1_2p1+n2_2p1
     786            0 :    ph1d_atm(:,shift1b+1:shift1b+n1_2p1)=ph1d(:,shift1+1:shift1+n1_2p1)
     787            0 :    ph1d_atm(:,shift2b+1:shift2b+n2_2p1)=ph1d(:,shift2+1:shift2+n2_2p1)
     788            0 :    ph1d_atm(:,shift3b+1:shift3b+n3_2p1)=ph1d(:,shift3+1:shift3+n3_2p1)
     789            0 :    ABI_MALLOC(ekb_atm,(psps%dimekb,ntypat0))
     790            0 :    ABI_MALLOC(indlmn_atm,(6,psps%lmnmax,ntypat0))
     791            0 :    ABI_MALLOC(ffspl_atm,(psps%mqgrid_ff,2,psps%lnmax,ntypat0))
     792            0 :    ABI_MALLOC(pspso_atm,(ntypat0))
     793            0 :    ekb_atm(:,1)=psps%ekb(:,itypat)
     794            0 :    indlmn_atm(:,:,1)=psps%indlmn(:,:,itypat)
     795            0 :    ffspl_atm(:,:,:,1)=psps%ffspl(:,:,:,itypat)
     796            0 :    pspso_atm(1)=psps%pspso(itypat)
     797              :  else
     798         2229 :    iatom1=1;iatom2=natom
     799         2229 :    ntypat0=ntypat
     800         2229 :    atindx_atm => atindx
     801         2229 :    nattyp_atm => nattyp
     802         2229 :    ph1d_atm => ph1d
     803         2229 :    ekb_atm => psps%ekb
     804         2229 :    indlmn_atm => psps%indlmn
     805         2229 :    ffspl_atm => psps%ffspl
     806         2229 :    pspso_atm => psps%pspso
     807              :  end if
     808              : 
     809              : !Dimensioning and allocation of <p_i|Cnk>
     810         6687 :  ABI_MALLOC(dimlmn,(ncprj))
     811         7139 :  dimlmn=0  ! Type-sorted cprj
     812         2229 :  if (one_atom) then
     813            0 :    itypat=typat(iatom)
     814            0 :    dimlmn(1:nattyp(itypat))=count(indlmn_atm(3,:,itypat)>0)
     815              :  else
     816         2229 :    ia=0
     817         4957 :    do itypat=1,ntypat0
     818        30779 :      dimlmn(ia+1:ia+nattyp(itypat))=count(indlmn_atm(3,:,itypat)>0)
     819         4957 :      ia=ia+nattyp(itypat)
     820              :    end do
     821              :  end if
     822        23647 :  ABI_MALLOC(cwaveprj,(ncprj,my_nspinor*cprj_bandpp))
     823         2229 :  call pawcprj_alloc(cwaveprj,ncpgr,dimlmn)
     824              : 
     825              : !Additional statements if band-fft parallelism
     826         2229 :  if (npband_bandfft>1) then
     827         2496 :    ABI_MALLOC(npw_block,(npband_bandfft))
     828         1664 :    ABI_MALLOC(npw_disp,(npband_bandfft))
     829              :    !FB ABI_MALLOC(bufsize,(npband_bandfft*cg_bandpp))
     830         1664 :    ABI_MALLOC(bufsize,(npband_bandfft))
     831              :    !FB ABI_MALLOC(bufdisp,(npband_bandfft*cg_bandpp))
     832         1664 :    ABI_MALLOC(bufdisp,(npband_bandfft))
     833              :    !FB ABI_MALLOC(bufsize_wf,(npband_bandfft*cg_bandpp))
     834         1664 :    ABI_MALLOC(bufsize_wf,(npband_bandfft))
     835              :    !FB ABI_MALLOC(bufdisp_wf,(npband_bandfft*cg_bandpp))
     836         1664 :    ABI_MALLOC(bufdisp_wf,(npband_bandfft))
     837              :  end if
     838              : 
     839              : !Set output datastructure to zero
     840         2229 :  call pawcprj_set_zero(cprj)
     841              : 
     842              : !LOOP OVER SPINS
     843         4551 :  do isppol=1,my_nsppol
     844         2322 :    ikg=0
     845              : 
     846              : !  BIG FAT k POINT LOOP
     847        89472 :    do ikpt=1,nkpt
     848        84921 :      counter=100*ikpt+isppol
     849              : 
     850              : !    Select k point to be treated by this proc
     851        84921 :      nband_k=nband(ikpt+(isppol-1)*nkpt)
     852        84921 :      if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me_distrb)) cycle
     853              : 
     854              : !    Retrieve k-point
     855       212768 :      kpoint(:)=kpt(:,ikpt)
     856        53192 :      istwf_k=istwfk(ikpt)
     857              : 
     858              : !    Retrieve number of plane waves
     859        53192 :      npw_k=npwarr(ikpt)
     860        53192 :      if (npband_bandfft>1) then
     861              : !      Special treatment for band-fft //
     862         6656 :        call xmpi_allgather(npw_k,npw_block,spaceComm_band,ierr)
     863        19968 :        npw_nk=sum(npw_block);npw_disp(1)=0
     864        13312 :        do ii=2,npband_bandfft
     865        13312 :          npw_disp(ii)=npw_disp(ii-1)+npw_block(ii-1)
     866              :        end do
     867              :      else
     868        46536 :        npw_nk=npw_k
     869              :      end if
     870              : 
     871              : !    Retrieve (k+G) points and spherical harmonics
     872       212768 :      ABI_MALLOC(ylm_k,(npw_k,mpsang*mpsang))
     873       212768 :      ABI_MALLOC(ylmgr_k,(npw_k,3,mpsang*mpsang*useylmgr))
     874       159576 :      ABI_MALLOC(kg_k,(3,npw_nk))
     875        53192 :      if (npband_bandfft>1) then
     876              : !      Special treatment for band-fft //
     877        19968 :        ABI_MALLOC(kg_k_loc,(3,npw_k))
     878      1953536 :        kg_k_loc(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
     879        33280 :        bufsize(:)=3*npw_block(:);bufdisp(:)=3*npw_disp(:)
     880         6656 :        call xmpi_allgatherv(kg_k_loc,3*npw_k,kg_k,bufsize,bufdisp,spaceComm_band,ierr)
     881              :      else
     882     30547868 :        kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
     883              :      end if
     884       275330 :      do ilm=1,mpsang*mpsang
     885     34024285 :        ylm_k(1:npw_k,ilm)=ylm(1+ikg:npw_k+ikg,ilm)
     886     88615205 :        if (useylmgr>0) ylmgr_k(1:npw_k,1:3,ilm)=ylmgr(1+ikg:npw_k+ikg,1:3,ilm)
     887              :      end do
     888              : 
     889              : !    Compute (k+G) vectors
     890       212768 :      ABI_MALLOC(kpg_k,(npw_nk,nkpg))
     891        53192 :      if (nkpg>0) then
     892        12174 :        call mkkpg(kg_k,kpg_k,kpoint,nkpg,npw_nk)
     893              :      end if
     894              : !    Allocate and compute the arrays phkxred and ph3d
     895       159576 :      ABI_MALLOC(phkxred,(2,ncprj))
     896       158906 :      do ia=iatom1,iatom2
     897       105714 :        iatm=min(atindx_atm(ia),ncprj)
     898       105714 :        arg=two_pi*(kpoint(1)*xred(1,ia)+kpoint(2)*xred(2,ia)+kpoint(3)*xred(3,ia))
     899       158906 :        phkxred(1,iatm)=cos(arg);phkxred(2,iatm)=sin(arg)
     900              :      end do
     901        53192 :      matblk=ncprj;if (nloalg(2)<=0) matblk=0
     902       212768 :      ABI_MALLOC(ph3d,(2,npw_nk,matblk))
     903        53192 :      if (matblk>0)then
     904              : !      Here, precomputation of ph3d
     905        53192 :        if (npband_bandfft>1) then
     906              : !        Special treatment for band-fft //
     907        26624 :          ABI_MALLOC(ph3d_tmp,(2,npw_k,matblk))
     908         6656 :          call ph1d3d(1,ncprj,kg_k_loc,matblk,ncprj,npw_k,n1,n2,n3,phkxred,ph1d_atm,ph3d_tmp)
     909        26624 :          ABI_MALLOC(ph3d_tmp_npw,(2,matblk,npw_k))
     910        26624 :          ABI_MALLOC(ph3d_npw,(2,matblk,npw_nk))
     911        33280 :          isize=2*matblk;bufsize(:)=isize*npw_block(:);bufdisp(:)=isize*npw_disp(:)
     912       493376 :          do ipw=1,npw_k
     913      3413696 :            ph3d_tmp_npw(:,:,ipw)=ph3d_tmp(:,ipw,:)
     914              :          end do
     915         6656 :          call xmpi_allgatherv(ph3d_tmp_npw,isize*npw_k,ph3d_npw,bufsize,bufdisp,spaceComm_band,ierr)
     916       980096 :          do ipw=1,npw_nk
     917      6820736 :            ph3d(:,ipw,:)=ph3d_npw(:,:,ipw)
     918              :          end do
     919         6656 :          ABI_FREE(ph3d_npw)
     920         6656 :          ABI_FREE(ph3d_tmp_npw)
     921         6656 :          ABI_FREE(ph3d_tmp)
     922              :        else
     923        46536 :          call ph1d3d(1,ncprj,kg_k,matblk,ncprj,npw_k,n1,n2,n3,phkxred,ph1d_atm,ph3d)
     924              :        end if
     925            0 :      else if (npband_bandfft>1) then
     926            0 :        ABI_ERROR('Band-fft parallelism +nloag(1)<0 forbidden !')
     927              :      end if
     928              : 
     929              : !    Compute nonlocal form factors ffnl at all (k+G)
     930       319152 :      ABI_MALLOC(ffnl,(npw_nk,dimffnl,psps%lmnmax,ntypat0))
     931        53192 :      if (npband_bandfft>1) then
     932              : !      Special treatment for band-fft //
     933        39936 :        ABI_MALLOC(ffnl_tmp,(npw_k,dimffnl,psps%lmnmax,ntypat0))
     934              :        call mkffnl(psps%dimekb,dimffnl,ekb_atm,ffnl_tmp,ffspl_atm,&
     935              : &       gmet,gprimd,ider,idir0,indlmn_atm,kg_k_loc,kpg_k,kpoint,psps%lmnmax,&
     936              : &       psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,npw_k,ntypat0,&
     937         6656 : &       pspso_atm,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm_k,ylmgr_k)
     938        39936 :        ABI_MALLOC(ffnl_tmp_npw,(dimffnl,psps%lmnmax,ntypat0,npw_k))
     939        39936 :        ABI_MALLOC(ffnl_npw,(dimffnl,psps%lmnmax,ntypat0,npw_nk))
     940         6656 :        isize=dimffnl*psps%lmnmax*ntypat0
     941        33280 :        bufsize(:)=isize*npw_block(:);bufdisp(:)=isize*npw_disp(:)
     942       493376 :        do ipw=1,npw_k
     943      8767616 :          ffnl_tmp_npw(:,:,:,ipw)=ffnl_tmp(ipw,:,:,:)
     944              :        end do
     945         6656 :        call xmpi_allgatherv(ffnl_tmp_npw,isize*npw_k,ffnl_npw,bufsize,bufdisp,spaceComm_band,ierr)
     946       980096 :        do ipw=1,npw_nk
     947     17528576 :          ffnl(ipw,:,:,:)=ffnl_npw(:,:,:,ipw)
     948              :        end do
     949         6656 :        ABI_FREE(ffnl_npw)
     950         6656 :        ABI_FREE(ffnl_tmp_npw)
     951         6656 :        ABI_FREE(ffnl_tmp)
     952              :      else
     953              :        call mkffnl(psps%dimekb,dimffnl,ekb_atm,ffnl,ffspl_atm,&
     954              : &       gmet,gprimd,ider,idir0,indlmn_atm,kg_k,kpg_k,kpoint,psps%lmnmax,&
     955              : &       psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,npw_k,ntypat0,&
     956        46536 : &       pspso_atm,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm_k,ylmgr_k)
     957              :      end if
     958              : 
     959              : !    No more need of kg_g_tmp
     960        53192 :      if (npband_bandfft>1)  then
     961         6656 :        ABI_FREE(kg_k_loc)
     962              :      end if
     963              : 
     964              : !    Allocate arrays for a wave-function (or a block of WFs)
     965       159576 :      ABI_MALLOC(cwavef,(2,npw_nk*my_nspinor*cg_bandpp))
     966        53192 :      if (npband_bandfft>1) then
     967        33280 :        isize=2*my_nspinor*cg_bandpp;bufsize(:)=isize*npw_block(:);bufdisp(:)=isize*npw_disp(:)
     968        19968 :        isize=2*my_nspinor*npw_k*cg_bandpp;bufsize_wf(:)=isize
     969              :        !FB do ii=1,npband_bandfft*cg_bandpp
     970        19968 :        do ii=1,npband_bandfft
     971        19968 :          bufdisp_wf(ii)=(ii-1)*isize
     972              :        end do
     973              :      end if
     974              : 
     975              : !    Loop over bands or blocks of bands
     976        53192 :      icgb=icg ; ibgb=ibg ; iband_start=1
     977        53192 :      blocksz=npband_bandfft*cg_bandpp
     978        53192 :      nblockbd=nband_k/blocksz
     979        53192 :      nband_cprj_k=merge(nband_k/npband_bandfft/npband_dfpt,nband_k,cprj_band_distributed)
     980              :      nband_cg_k=merge(nband_k/npband_bandfft/npband_dfpt,nband_k,cg_band_distributed)
     981       377854 :      do iblockbd=1,nblockbd
     982       324662 :        iband_min=1+(iblockbd-1)*blocksz
     983       324662 :        iband_max=iblockbd*blocksz
     984              : 
     985       324662 :        if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,iband_min,iband_max,isppol,me_distrb)) then
     986          216 :          if (.not.cg_band_distributed) icgb=icgb+npw_k*my_nspinor*blocksz
     987          216 :          if (.not.cprj_band_distributed) ibgb=ibgb+my_nspinor*blocksz
     988              :          cycle
     989              :        end if
     990              : 
     991              : !      Extract wavefunction information
     992              : !      Special treatment for band-fft parallelism
     993       324446 :        if (npband_bandfft>1) then
     994              :          !Transpose WF to get them in "FFT" representation
     995        19968 :          ABI_MALLOC(cwavef_tmp,(2,npw_k*my_nspinor*blocksz))
     996      3900416 :          do ig=1,npw_k*my_nspinor*blocksz
     997      3893760 :            cwavef_tmp(1,ig)=cg(1,ig+icgb)
     998      3900416 :            cwavef_tmp(2,ig)=cg(2,ig+icgb)
     999              :          end do
    1000         6656 :          call xmpi_alltoallv(cwavef_tmp,bufsize_wf,bufdisp_wf,cwavef,bufsize,bufdisp,spaceComm_band,ierr)
    1001         6656 :          ABI_FREE(cwavef_tmp)
    1002              :          !Reorder WF according to cg_bandpp and/or spinor
    1003        13312 :          if (cg_bandpp>1.or.my_nspinor>1) then
    1004              :            !FB ABI_MALLOC(cwavef_tmp,(2,npw_nk*my_nspinor*blocksz))
    1005        13312 :            ABI_MALLOC(cwavef_tmp,(2,npw_nk*my_nspinor*cg_bandpp))
    1006              :            !FB do ig=1,npw_nk*my_nspinor*blocksz
    1007      3900416 :            do ig=1,npw_nk*my_nspinor*cg_bandpp
    1008     11687936 :              cwavef_tmp(:,ig)=cwavef(:,ig)
    1009              :            end do
    1010              :            shift1=0
    1011        33280 :            do iwf2=1,cg_bandpp
    1012        59904 :              do ig=1,my_nspinor
    1013              :                shift2=0
    1014       106496 :                do iwf1=1,npband_bandfft
    1015        53248 :                  npws=npw_block(iwf1)
    1016        53248 :                  ipw=shift2+(iwf2-1)*my_nspinor*npws+(ig-1)*npws
    1017     11734528 :                  cwavef(:,shift1+1:shift1+npws)=cwavef_tmp(:,ipw+1:ipw+npws)
    1018        79872 :                  shift1=shift1+npws ; shift2=shift2+cg_bandpp*my_nspinor*npws
    1019              :                end do
    1020              :              end do
    1021              :            end do
    1022         6656 :            ABI_FREE(cwavef_tmp)
    1023              :          end if
    1024              :        else
    1025     60986987 :          do ig=1,npw_k*my_nspinor*cg_bandpp
    1026     60669197 :            cwavef(1,ig)=cg(1,ig+icgb)
    1027     60986987 :            cwavef(2,ig)=cg(2,ig+icgb)
    1028              :          end do
    1029              :        end if
    1030              : 
    1031              : !      Compute scalar product of wavefunction with all NL projectors
    1032       668860 :        do ibp=1,cg_bandpp   ! Note: we suppose cp_bandpp=cprj_bandpp
    1033       344414 :          iwf1=1+(ibp-1)*npw_nk*my_nspinor;iwf2=ibp*npw_nk*my_nspinor
    1034       344414 :          icp1=1+(ibp-1)*my_nspinor;icp2=ibp*my_nspinor
    1035      1013704 :          do jdir=istart,iend
    1036       344844 :            call timab(1294,1,tsec)
    1037              :            call getcprj(choice,cpopt,cwavef(:,iwf1:iwf2),cwaveprj(:,icp1:icp2),&
    1038              : &           ffnl,jdir,indlmn_atm,istwf_k,kg_k,kpg_k,kpoint,psps%lmnmax,&
    1039              : &           mgfft,mpi_enreg,1,ncprj,nattyp_atm,ngfft,nloalg,&
    1040       344844 : &           npw_nk,my_nspinor,ntypat0,phkxred,ph1d_atm,ph3d,ucvol,psps%useylm,.false.)
    1041       689258 :            call timab(1294,2,tsec)
    1042              :          end do
    1043              :        end do
    1044              : !      Export cwaveprj to big array cprj
    1045              :        call pawcprj_put(atindx_atm,cwaveprj,cprj,ncprj,iband_start,ibgb,ikpt,iorder_cprj,isppol,&
    1046              : &       mband_cprj,mkmem,natom,cprj_bandpp,nband_cprj_k,dimlmn,my_nspinor,nsppol,uncp,&
    1047       324446 : &       mpi_comm_band=spaceComm_band,to_be_gathered=(cg_band_distributed.and.(.not.cprj_band_distributed)))
    1048              : 
    1049       324446 :        iband_start=iband_start+merge(cg_bandpp,blocksz,cprj_band_distributed)
    1050              : 
    1051              : !      End loop over bands
    1052       377638 :        icgb=icgb+npw_k*my_nspinor*blocksz
    1053              :      end do
    1054              : 
    1055              : !    Shift array memory (if mkmem/=0)
    1056        53192 :      if (mkmem/=0) then
    1057        53192 :        ibg=ibg+my_nspinor*nband_cprj_k
    1058              :        !FB icg=icg+my_nspinor*nband_cg_k*npw_k
    1059        53192 :        icg=icg+my_nspinor*nband_k*npw_k
    1060        53192 :        ikg=ikg+npw_k
    1061              :      end if
    1062              : 
    1063              : !    End big k point loop
    1064        53192 :      ABI_FREE(ffnl)
    1065        53192 :      ABI_FREE(ph3d)
    1066        53192 :      ABI_FREE(phkxred)
    1067        53192 :      ABI_FREE(kg_k)
    1068        53192 :      ABI_FREE(kpg_k)
    1069        53192 :      ABI_FREE(ylm_k)
    1070        53192 :      ABI_FREE(ylmgr_k)
    1071        87243 :      ABI_FREE(cwavef)
    1072              :    end do
    1073              : !  End loop over spins
    1074              :  end do
    1075              : 
    1076         2229 :  if ((iatom<=0).and.(choice==23)) then
    1077          261 :    do iatom1=1,ncprj
    1078        41285 :      do ii=1,mcprj
    1079        41024 :        nlmn=cprj(iatom1,ii)%nlmn
    1080       369390 :        do kk=1,nlmn
    1081      2297344 :          work(1:6)=cprj(iatom1,ii)%dcp(1,1:6,kk)
    1082       328192 :          call strconv(work,gprimd,work)
    1083      2297344 :          cprj(iatom1,ii)%dcp(1,1:6,kk)=work(1:6)
    1084      2297344 :          work(1:6)=cprj(iatom1,ii)%dcp(2,1:6,kk)
    1085       328192 :          call strconv(work,gprimd,work)
    1086      2338368 :          cprj(iatom1,ii)%dcp(2,1:6,kk)=work(1:6)
    1087              :        end do
    1088              :      end do
    1089              :    end do
    1090              :  end if
    1091              : 
    1092              : !If needed, gather computed scalars
    1093         2229 :  if (.not.(cg_band_distributed .and. cprj_band_distributed)) then
    1094          982 :    call pawcprj_mpi_sum(cprj,spaceComm_band,ierr)
    1095              :  end if
    1096              : 
    1097              : !Deallocate temporary storage
    1098         2229 :  if (one_atom)  then
    1099            0 :    ABI_FREE(atindx_atm)
    1100            0 :    ABI_FREE(nattyp_atm)
    1101            0 :    ABI_FREE(ph1d_atm)
    1102            0 :    ABI_FREE(ekb_atm)
    1103            0 :    ABI_FREE(indlmn_atm)
    1104            0 :    ABI_FREE(ffspl_atm)
    1105            0 :    ABI_FREE(pspso_atm)
    1106              :  end if
    1107         2229 :  nullify(atindx_atm,nattyp_atm,ph1d_atm,ekb_atm,indlmn_atm,ffspl_atm,pspso_atm)
    1108         2229 :  call pawcprj_free(cwaveprj)
    1109        12200 :  ABI_FREE(cwaveprj)
    1110         2229 :  ABI_FREE(dimlmn)
    1111         2229 :  if (npband_bandfft>1) then
    1112          832 :    ABI_FREE(npw_block)
    1113          832 :    ABI_FREE(npw_disp)
    1114          832 :    ABI_FREE(bufsize)
    1115          832 :    ABI_FREE(bufdisp)
    1116          832 :    ABI_FREE(bufsize_wf)
    1117          832 :    ABI_FREE(bufdisp_wf)
    1118              :  end if
    1119              : 
    1120              :  DBG_EXIT('COLL')
    1121              : 
    1122         4458 :  end subroutine ctocprj
    1123              : !!***
    1124              : 
    1125              : !!****f* ABINIT/cprj_rotate
    1126              : !! NAME
    1127              : !! cprj_rotate
    1128              : !!
    1129              : !! FUNCTION
    1130              : !!   Compute cprj_nk = \sum_m z_m cprj_mk
    1131              : !!   where z_m is an array of complex values.
    1132              : !!   The input is overwritten.
    1133              : !!
    1134              : !! INPUTS
    1135              : !!
    1136              : !! SIDE EFFECTS
    1137              : !!
    1138              : !! SOURCE
    1139              : 
    1140            0 :  subroutine cprj_rotate(cprj_in,evec,dimcprj,natom,nband,nspinor)
    1141              : 
    1142              : !Arguments -------------------------------
    1143              : !scalars
    1144              :  integer,intent(in) :: natom,nband,nspinor
    1145              : !arrays
    1146              :  integer,intent(in) :: dimcprj(:)
    1147              :  real(dp) :: evec(:,:)
    1148              :  type(pawcprj_type),intent(inout) :: cprj_in(natom,nspinor*nband)
    1149              : 
    1150              : !Local variables-------------------------------
    1151              : !scalars
    1152              :  integer :: iband,ncpgr
    1153              : !arrays
    1154              : ! real(dp) :: tsec(2)
    1155            0 :  real(dp) :: z_tmp(2,nband)
    1156            0 :  type(pawcprj_type),pointer :: cprj_iband(:,:)
    1157              :  type(pawcprj_type),allocatable,target :: cprj_tmp(:,:)
    1158              : 
    1159              : 
    1160              : ! *********************************************************************
    1161              : 
    1162              :  DBG_ENTER('COLL')
    1163              : 
    1164              : ! call timab(1211,1,tsec)
    1165              : 
    1166            0 :  ncpgr=cprj_in(1,1)%ncpgr
    1167            0 :  ABI_MALLOC(cprj_tmp,(natom,nspinor*nband))
    1168            0 :  call pawcprj_alloc(cprj_tmp,ncpgr,dimcprj)
    1169              : 
    1170            0 :  do iband=1,nband
    1171            0 :    z_tmp  = reshape(evec(:,iband),(/2,nband/))
    1172            0 :    cprj_iband => cprj_tmp(:,nspinor*(iband-1)+1:nspinor*iband)
    1173            0 :    call pawcprj_lincom(z_tmp,cprj_in,cprj_iband,nband)
    1174              :  end do
    1175              : 
    1176            0 :  call pawcprj_copy(cprj_tmp,cprj_in)
    1177            0 :  call pawcprj_free(cprj_tmp)
    1178            0 :  ABI_FREE(cprj_tmp)
    1179              : 
    1180              : ! call timab(1211,2,tsec)
    1181              : 
    1182              :  DBG_EXIT('COLL')
    1183              : 
    1184            0 :  end subroutine cprj_rotate
    1185              : !!***
    1186              : 
    1187        23072 :  subroutine xg_cprj_copy(cprj,xg_cprj,xg_nonlop,option)
    1188              : 
    1189              :    integer, intent(in) :: option
    1190              :    type(pawcprj_type),intent(inout)   :: cprj(:,:)
    1191              :    type(xgBlock_t), intent(inout) :: xg_cprj
    1192              :    type(xg_nonlop_t), intent(in)  :: xg_nonlop
    1193              : 
    1194        23072 :    real(dp),pointer :: cprj_contiguous(:,:)
    1195              :    integer :: cplex,iatom,iband,iband_spin,ilmn,ispinor
    1196              :    integer :: natom,nband_cprj,nlmn,nspinor
    1197              :    integer :: start,end,space_cprj
    1198        23072 :    integer,allocatable :: nlmn_shift(:)
    1199              : 
    1200        23072 :    if (option/=XG_TO_CPRJ.and.option/=CPRJ_TO_XG) then
    1201            0 :      ABI_ERROR('Bad option')
    1202              :    end if
    1203              : 
    1204        23072 :    natom   = xg_nonlop%natom
    1205        23072 :    nspinor = xg_nonlop%nspinor
    1206              : 
    1207        23072 :    nband_cprj   = cols(xg_cprj)/nspinor
    1208              : 
    1209        23072 :    if (size(cprj,1)/=natom) then
    1210            0 :      ABI_ERROR('Bad size for cprj (for dim=1)')
    1211              :    end if
    1212        23072 :    if (size(cprj,2)/=nband_cprj*nspinor) then
    1213            0 :      ABI_ERROR('Bad size for cprj (for dim=2)')
    1214              :    end if
    1215              : 
    1216        23072 :    space_cprj = space(xg_cprj)
    1217        23072 :    cplex=2;if (space_cprj==SPACE_R) cplex=1
    1218              : 
    1219        23072 :    call xgBlock_reverseMap(xg_cprj,cprj_contiguous)
    1220              : 
    1221        23072 :    if (size(cprj_contiguous,1)/=cplex*xg_nonlop%cprjdim) then
    1222            0 :      ABI_ERROR('Bad size for cprj_contiguous (for dim=1)')
    1223              :    end if
    1224              : 
    1225        69216 :    ABI_MALLOC(nlmn_shift,(natom))
    1226        23072 :    nlmn_shift(1) = 0
    1227              :    ! Check nlm for every atom and fill nlmn_shift
    1228       101224 :    do iband=1,nband_cprj
    1229       201656 :      do ispinor=1,nspinor
    1230       100432 :        iband_spin = (iband-1)*nspinor+ispinor
    1231       385208 :        do iatom=1,natom
    1232       206624 :          nlmn=xg_nonlop%nlmn_natom(iatom)
    1233       619872 :          if (size(cprj(iatom,iband_spin)%cp)/=2*nlmn) then ! NOTE: cprj%cp size is always (2,nlmn) even in the real case
    1234            0 :            ABI_ERROR('Bad size for cprj_cwavef_bands%cp')
    1235              :          end if
    1236       307056 :          if (iatom<natom) then
    1237       106192 :            nlmn_shift(iatom+1) = nlmn_shift(iatom) + nlmn
    1238              :          end if
    1239              :        end do
    1240              :      end do
    1241              :    end do
    1242              : 
    1243              :    ! Do the copy
    1244        23072 :    if (option==CPRJ_TO_XG) then
    1245              :      !$omp parallel default (none) &
    1246              :      !$omp& shared(xg_nonlop,nlmn_shift,cprj_contiguous,cprj), &
    1247              :      !$omp& firstprivate(cplex,nband_cprj,nspinor,natom), &
    1248              :      !$omp& private(iband,ispinor,iatom,iband_spin,nlmn,start,end)
    1249              :      !$omp do collapse(3)
    1250            0 :      do iband=1,nband_cprj
    1251            0 :        do ispinor=1,nspinor
    1252            0 :          do iatom=1,natom
    1253            0 :            iband_spin = (iband-1)*nspinor+ispinor
    1254            0 :            nlmn=xg_nonlop%nlmn_natom(iatom)
    1255            0 :            do ilmn=1,nlmn
    1256            0 :              start = 1+cplex*(ilmn-1)+cplex*nlmn_shift(iatom)
    1257            0 :              end   = cplex*ilmn      +cplex*nlmn_shift(iatom)
    1258              :              cprj_contiguous(start:end,iband_spin) = &
    1259            0 :                cprj(iatom,iband_spin)%cp(1:cplex,ilmn)
    1260              :            end do
    1261              :          end do
    1262              :        end do
    1263              :      end do
    1264              :      !$omp end do
    1265              :      !$omp end parallel
    1266        23072 :    else if (option==XG_TO_CPRJ) then
    1267              :      !$omp parallel default (none) &
    1268              :      !$omp& shared(xg_nonlop,nlmn_shift,cprj_contiguous,cprj), &
    1269              :      !$omp& firstprivate(cplex,nband_cprj,nspinor,natom), &
    1270              :      !$omp& private(iband,ispinor,iatom,iband_spin,nlmn,start,end)
    1271              :      !$omp do collapse(3)
    1272       101224 :      do iband=1,nband_cprj
    1273       201656 :        do ispinor=1,nspinor
    1274       385208 :          do iatom=1,natom
    1275       206624 :            iband_spin = (iband-1)*nspinor+ispinor
    1276       206624 :            nlmn=xg_nonlop%nlmn_natom(iatom)
    1277      2052848 :            do ilmn=1,nlmn
    1278      1745792 :              start = 1+cplex*(ilmn-1)+cplex*nlmn_shift(iatom)
    1279      1745792 :              end   = cplex*ilmn      +cplex*nlmn_shift(iatom)
    1280              :              cprj(iatom,iband_spin)%cp(1:cplex,ilmn) = &
    1281      5039120 :                cprj_contiguous(start:end,iband_spin)
    1282              :            end do
    1283              :          end do
    1284              :        end do
    1285              :      end do
    1286              :      !$omp end do
    1287              :      !$omp end parallel
    1288              :    end if
    1289              : 
    1290        23072 :    ABI_FREE(nlmn_shift)
    1291              : 
    1292        23072 :  end subroutine xg_cprj_copy
    1293              : 
    1294              : end module m_cgprj
    1295              : !!***
        

Generated by: LCOV version 2.3-1