LCOV - code coverage report
Current view: top level - src/65_paw - m_pawpwij.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.8 % 366 314
Test Date: 2026-09-20 18:56:22 Functions: 53.8 % 13 7

            Line data    Source code
       1              : !!****m* ABINIT/m_pawpwij
       2              : !! NAME
       3              : !!  m_pawpwij
       4              : !!
       5              : !! FUNCTION
       6              : !!  This module defines methods to calculate the onsite contribution of a plane wave in the PAW method:
       7              : !!
       8              : !!    - pawpwff_t: Form factors used to calculate the onsite contributions of a plane wave.
       9              : !!    - pawpwij_t: Onsite matrix elements of a plane wave for a given atom type.
      10              : !!
      11              : !! COPYRIGHT
      12              : !! Copyright (C) 2008-2026 ABINIT group (MG,GKA)
      13              : !! This file is distributed under the terms of the
      14              : !! GNU General Public License, see ~abinit/COPYING
      15              : !! or http://www.gnu.org/copyleft/gpl.txt .
      16              : !!
      17              : !! SOURCE
      18              : 
      19              : #if defined HAVE_CONFIG_H
      20              : #include "config.h"
      21              : #endif
      22              : 
      23              : #include "abi_common.h"
      24              : 
      25              : MODULE m_pawpwij
      26              : 
      27              :  use defs_basis
      28              :  use m_errors
      29              :  use m_abicore
      30              :  use m_fft
      31              : 
      32              :  use m_fstrings,       only : sjoin, itoa
      33              :  use defs_datatypes,   only : pseudopotential_type
      34              :  use defs_abitypes,    only : MPI_type
      35              :  use m_numeric_tools,  only : arth
      36              :  use m_geometry,       only : metric
      37              :  use m_crystal,        only : crystal_t
      38              :  use m_paw_numeric,    only : paw_jbessel_4spline, paw_spline
      39              :  use m_splines,        only : splfit
      40              :  use m_pawang,         only : pawang_type
      41              :  use m_paw_sphharm,    only : realgaunt
      42              :  use m_pawrad,         only : pawrad_type, pawrad_init, pawrad_free, pawrad_copy, simp_gen
      43              :  use m_pawtab,         only : pawtab_type
      44              :  use m_pawcprj,        only : pawcprj_type
      45              :  use m_mpinfo,         only : destroy_mpi_enreg, initmpi_seq
      46              :  use m_initylmg,       only : initylmg
      47              : 
      48              :  implicit none
      49              : 
      50              :  private
      51              : !!***
      52              : 
      53              : !!****t* m_pawpwij/pawpwff_t
      54              : !! NAME
      55              : !! pawpwff_t
      56              : !!
      57              : !! FUNCTION
      58              : !!  PAW form factors used to evaluate $<phi|e^{-i(q+G).r}|phj> - <tphi|e^{-i(q+G).r}|tphj>$
      59              : !!
      60              : !! SOURCE
      61              : 
      62              :  type,public :: pawpwff_t
      63              : 
      64              :   integer :: method = -1
      65              :   ! 1 For Arnaud-Alouani"s exact expression.
      66              :   ! 2 For Shishkin-Kresse"s approximated expression.
      67              : 
      68              :   integer :: dim1 = -1, dim2 = -1
      69              :   ! Dimensions of pwff_spl, depending on method.
      70              : 
      71              :   integer :: nq_spl = -1
      72              :    ! Number of points in the reciprocal space grid on which
      73              :    ! the radial integrals are evaluated.
      74              : 
      75              :   real(dp) :: gmet(3,3) = zero
      76              :   ! Reciprocal space metric tensor in Bohr**-2
      77              : 
      78              :   real(dp),allocatable :: qgrid_spl(:)
      79              :    ! qgrid_spl(nq_spl)
      80              :    ! The coordinates of the points of the radial grid for the integrals used in the spline.
      81              : 
      82              :   real(dp),allocatable :: pwff_spl(:,:,:,:)
      83              :   ! pwff_spl(nq_spl,2,0:dim1,dim2)
      84              :   ! The different integrals on the radial |q| grid, for a given atom type.
      85              : 
      86              :  end type pawpwff_t
      87              : 
      88              :  public :: pawpwff_init    ! Initialize form factors for spline.
      89              :  public :: pawpwff_free    ! Deallocate dynamic memory.
      90              : !!***
      91              : 
      92              : !----------------------------------------------------------------------
      93              : 
      94              : !!****t* m_pawpwij/pawpwij_t
      95              : !! NAME
      96              : !! pawpwij_t
      97              : !!
      98              : !! FUNCTION
      99              : !! For PAW, object storing $<phi|e^{-i(q+G).r}|phj> - <tphi|e^{-i(q+G).r}|tphj>$
     100              : !! for a given q-point, for a particular TYPE of atom. Therefore the phase factor
     101              : !! e^{i(q+G).R_at} has to be considered to have the onsite contribution of a particular atom.
     102              : !!
     103              : !! SOURCE
     104              : 
     105              :  type,public :: pawpwij_t
     106              : 
     107              :   integer :: istpw
     108              :   ! Storage mode (similar to istwfk), not used at present
     109              : 
     110              :   integer :: npw
     111              :    ! The number of plane waves
     112              : 
     113              :   integer :: lmn_size
     114              :    ! Number of (l,m,n) elements for the paw basis
     115              : 
     116              :   integer :: lmn2_size
     117              :    ! lmn2_size=lmn_size*(lmn_size+1)/2
     118              :    ! where lmn_size is the number of (l,m,n) elements for the paw basis
     119              : 
     120              :   real(dp) :: qpt(3)
     121              :   ! The q-point in e^{-i(q+G)}.r}
     122              : 
     123              :   real(dp),allocatable :: mqpgij(:,:,:)
     124              :   ! pwij(2,npw,lmn2_size)
     125              :   ! $<phi|e^{-i(q+G).r}|phj> - <tphi|e^{-i(q+G).r}|tphj>$
     126              : 
     127              :  end type pawpwij_t
     128              : 
     129              :  public :: pawpwij_init        ! Calculate onsite matrix elements of a set of plane waves.
     130              :  public :: pawpwij_free        ! Deallocate dynamic memory in the structure.
     131              :  public :: paw_rho_tw_g        ! Calculate the PAW contribution to the oscillator matrix element.
     132              :  public :: paw_cross_rho_tw_g  ! Calculate the PAW cross term contribution to the oscillator matrix element.
     133              : !!***
     134              : 
     135              :  interface pawpwij_free
     136              :    module procedure pawpwij_free_d1
     137              :    module procedure pawpwij_free_d2
     138              :  end interface pawpwij_free
     139              : 
     140              : !----------------------------------------------------------------------
     141              : 
     142              :  integer,parameter :: PWIJ_ARNAUD   = 1   ! Arnaud-Alouani exact expression. PRB 62. 4464 [[cite:Arnaud2000]]
     143              :  integer,parameter :: PWIJ_SHISHKIN = 2   ! Shishkin-Kresse approximated expression. PRB 74. 035101 [[cite:Shishkin2006]]
     144              : 
     145              : CONTAINS  !========================================================================================
     146              : !!***
     147              : 
     148              : !!****f* m_pawpwij/pawpwff_init
     149              : !! NAME
     150              : !!  pawpwff_init
     151              : !!
     152              : !! FUNCTION
     153              : !!  Initialize the structure containing integrals used to evaluate the onsite
     154              : !!  matrix elements of a plane wave by means of a spline fit technique.
     155              : !!
     156              : !! INPUTS
     157              : !!  method=1 for Arnaud-Alouani, 2 for Shishkin-Kresse.
     158              : !!  nq_spl(%ntypat)=Number of points in the mesh used for the spline.
     159              : !!  qmax(%ntypat)=Max |q| for the mesh
     160              : !!  gmet(3,3)=reciprocal space metric tensor in bohr**-2.
     161              : !!  Pawrad(%ntypat) <type(pawrad_type)>=paw radial mesh and related data....
     162              : !!  Pawtab(%ntypat) <type(pawtab_type)>=paw tabulated starting data.
     163              : !!    %lsize=1+maximum value of l leading to non zero Gaunt coeffs.
     164              : !!    %ij_size=Number of (i,j) elements for the symetric paw basis
     165              : !!    %lmn2_size=lmn_size*(lmn_size+1)/2
     166              : !!  Psps <type(pseudopotential_type)>=variables related to pseudopotentials
     167              : !!    %ntypat=Number of type of atoms.
     168              : !!
     169              : !! OUTPUT
     170              : !!  Paw_pwff(%ntypat) <pawpwff_t>=Object storing the form factors
     171              : !!                                    for the spline used in pawpwij_init.
     172              : !! SOURCE
     173              : 
     174          196 : subroutine pawpwff_init(Paw_pwff,method,nq_spl,qmax,gmet,Pawrad,Pawtab,Psps)
     175              : 
     176              : !Arguments ------------------------------------
     177              : !scalars
     178              :  integer,intent(in) :: method
     179              :  type(Pseudopotential_type),intent(in) :: Psps
     180              : !arrays
     181              :  integer,intent(in) :: nq_spl(Psps%ntypat)
     182              :  real(dp),intent(in) :: gmet(3,3)
     183              :  real(dp),intent(in) :: qmax(Psps%ntypat)
     184              :  type(Pawrad_type),intent(in) :: Pawrad(Psps%ntypat)
     185              :  type(Pawtab_type),intent(in) :: Pawtab(Psps%ntypat)
     186              :  type(pawpwff_t),intent(out) :: Paw_pwff(Psps%ntypat)
     187              : 
     188              : !Local variables-------------------------------
     189              : !scalars
     190              :  integer :: dim1,dim2,itypat,nq
     191              :  real(dp) :: dq
     192              : 
     193              : !************************************************************************
     194              : 
     195              :  !@pawpwff_t
     196              : 
     197              : ! === Evaluate form factors for the radial part of phi.phj-tphi.tphj ===
     198           32 :  do itypat=1,Psps%ntypat
     199           20 :    Paw_pwff(itypat)%method = method
     200              : 
     201           11 :    select case (method)
     202              :    case (PWIJ_ARNAUD)
     203           11 :      dim1 = Pawtab(itypat)%l_size-1
     204           11 :      dim2 = Pawtab(itypat)%ij_size
     205              :    case (PWIJ_SHISHKIN)
     206            9 :      dim1 = Pawtab(itypat)%l_size**2
     207            9 :      dim2 = Pawtab(itypat)%lmn2_size
     208              :    case default
     209           20 :      ABI_BUG(sjoin("Wrong method:", itoa(method)))
     210              :    end select
     211              : 
     212           20 :    Paw_pwff(itypat)%dim1 = dim1
     213           20 :    Paw_pwff(itypat)%dim2 = dim2
     214          260 :    Paw_pwff(itypat)%gmet = gmet
     215              : 
     216              :    ! Setup of the q-mesh for spline. It can be type-dependent.
     217           20 :    nq = nq_spl(itypat)
     218           20 :    dq = qmax(itypat)/(one*(nq-1))
     219              :    !write(std_out,*)"nq,dq",nq,dq
     220              : 
     221           20 :    Paw_pwff(itypat)%nq_spl = nq
     222           60 :    ABI_MALLOC(Paw_pwff(itypat)%qgrid_spl,(nq))
     223        60060 :    Paw_pwff(itypat)%qgrid_spl = arth(zero,dq,nq)
     224              :    !
     225              :    ! === Calculate form factors depending on method ===
     226          100 :    ABI_MALLOC(Paw_pwff(itypat)%pwff_spl,(nq,2,0:dim1,dim2))
     227              : 
     228              :    call paw_mkrhox_spl(itypat,Psps%ntypat,method,dim1,dim2,nq, &
     229           32 :      Paw_pwff(itypat)%qgrid_spl,Pawrad,Pawtab,Paw_pwff(itypat)%pwff_spl)
     230              :  end do ! itypat
     231              : 
     232           12 : end subroutine pawpwff_init
     233              : !!***
     234              : 
     235              : !----------------------------------------------------------------------
     236              : 
     237              : !!****f* m_pawpwij/pawpwff_free
     238              : !! NAME
     239              : !!  pawpwff_free
     240              : !!
     241              : !! FUNCTION
     242              : !!  Free memory
     243              : !!
     244              : !! SOURCE
     245              : 
     246           12 : subroutine pawpwff_free(Paw_pwff)
     247              : 
     248              : !Arguments ------------------------------------
     249              : !scalars
     250              :  type(pawpwff_t),intent(inout) :: Paw_pwff(:)
     251              : 
     252              : !Local variables-------------------------------
     253              :  integer :: ii
     254              : 
     255              : !************************************************************************
     256              : 
     257           32 :  do ii=1,SIZE(Paw_pwff)
     258           20 :    ABI_SFREE(Paw_pwff(ii)%qgrid_spl)
     259           32 :    ABI_SFREE(Paw_pwff(ii)%pwff_spl)
     260              :  end do
     261              : 
     262           12 : end subroutine pawpwff_free
     263              : !!***
     264              : 
     265              : !----------------------------------------------------------------------
     266              : 
     267              : !!****f* m_pawrhox/pawpwij_init
     268              : !! NAME
     269              : !!  pawpwij_init
     270              : !!
     271              : !! FUNCTION
     272              : !!  Calculate the onsite matrix elements
     273              : !!
     274              : !!   $ <phj|e^{-i(q+G)}|phi> - <tphj|e^{-i(q+G)}|tphi> $
     275              : !!
     276              : !!  for a given q and a set of g in gvec for a given TYPE of atom.
     277              : !!  Phase factors arising from atom positions are therefore not included.
     278              : !!
     279              : !! INPUTS
     280              : !!  npw=Number of plane waves
     281              : !!  Psps <type(pseudopotential_type)>=variables related to pseudopotentials
     282              : !   gvec(3,npw)=Plane wave reduced components.
     283              : !!  qpt_in(3)=The reduced components of the q-point.
     284              : !!  rprim(3,3)=dimensionless real space primitive translations
     285              : !!  Pawtab(%ntypat) <type(pawtab_type)>=paw tabulated starting data
     286              : !!  Paw_pwff(%ntypat) <pawpwff_t>=Object storing the form factors for the spline used in pawpwij_init.
     287              : !!  Psps<type(pseudopotential_type)>=variables related to pseudopotentials
     288              : !!
     289              : !! OUTPUT
     290              : !!  Pwij(%ntypat)<pawpwij_t>=Structure containing the onsite matrix elements of e^{-i(q+G).r}.
     291              : !!   Completely initialized in output.
     292              : !!
     293              : !! SOURCE
     294              : 
     295         4402 : subroutine pawpwij_init(Pwij, npw, qpt_in, gvec, rprimd, Psps, Pawtab, Paw_pwff)
     296              : 
     297              : !Arguments ------------------------------------
     298              : !scalars
     299              :  integer,intent(in) :: npw
     300              :  type(Pseudopotential_type),intent(in) :: Psps
     301              : !arrays
     302              :  integer,intent(in) :: gvec(3,npw)
     303              :  real(dp),intent(in) :: qpt_in(3),rprimd(3,3)
     304              :  type(Pawtab_type),intent(in) :: Pawtab(Psps%ntypat)
     305              :  type(pawpwff_t),intent(in) :: Paw_pwff(Psps%ntypat)
     306              :  type(pawpwij_t),intent(out) :: Pwij(Psps%ntypat)
     307              : 
     308              : !Local variables-------------------------------
     309              : !scalars
     310              :  integer,parameter :: unkg0=0,unylm0=0
     311              :  integer :: dim1,dim2,method, my_mqmem,my_nqpt,optder,two_lmaxp1,itypat
     312              :  integer :: dummy_nsppol,lmn_size,lmn2_size,nq_spl,ierr
     313              :  real(dp) :: ucvol
     314         1434 :  type(MPI_type) :: MPI_enreg_seq
     315              : !arrays
     316         1434 :  integer,allocatable :: npwarr(:),dummy_nband(:)
     317              :  real(dp) :: gmet(3,3),gprimd(3,3),rmet(3,3)
     318         1434 :  real(dp),allocatable :: my_qtmp(:,:), ylm_q(:,:),ylmgr_q(:,:,:)
     319              : 
     320              : ! *********************************************************************
     321              : 
     322              :  ! ===============================================
     323              :  ! === Get real spherical harmonics in G space ===
     324              :  ! ===============================================
     325         1434 :  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
     326              : 
     327              :  ! Set up of REAL Ylm(q+G) up to 2*l_max for this q-point.
     328         1434 :  my_mqmem=1; two_lmaxp1=2*Psps%mpsang-1; optder=0
     329              : 
     330         5736 :  ABI_MALLOC(ylm_q  ,(npw*my_mqmem,two_lmaxp1**2))
     331         7170 :  ABI_MALLOC(ylmgr_q,(npw*my_mqmem,3+6*(optder/2),two_lmaxp1**2))
     332              : 
     333         1434 :  my_nqpt=1
     334         1434 :  ABI_MALLOC(my_qtmp,(3,my_nqpt))
     335         5736 :  my_qtmp(:,1)=qpt_in(:)
     336              : 
     337              :  ! dummy_nband and dummy_nsppol are not used in sequential mode.
     338         1434 :  dummy_nsppol=1
     339         1434 :  ABI_MALLOC(dummy_nband,(my_nqpt*dummy_nsppol))
     340         2868 :  dummy_nband=0
     341         1434 :  ABI_MALLOC(npwarr,(my_nqpt))
     342         2868 :  npwarr(:)=npw
     343              : 
     344              :  ! Fake MPI_type for sequential part.
     345         1434 :  call initmpi_seq(MPI_enreg_seq)
     346              : 
     347              :  call initylmg(gprimd,gvec,my_qtmp,my_mqmem,MPI_enreg_seq,two_lmaxp1,npw,dummy_nband,my_nqpt,&
     348         1434 :    npwarr,dummy_nsppol,optder,rprimd,ylm_q,ylmgr_q)
     349              : 
     350         1434 :  call destroy_mpi_enreg(MPI_enreg_seq)
     351              : 
     352         1434 :  ABI_FREE(my_qtmp)
     353         1434 :  ABI_FREE(dummy_nband)
     354         1434 :  ABI_FREE(npwarr)
     355         1434 :  ABI_FREE(ylmgr_q)
     356              : 
     357              :  ! Construct the Pwij structure
     358         2918 :  do itypat=1,Psps%ntypat
     359              : 
     360         1484 :    Pwij(itypat)%istpw = 1
     361         1484 :    Pwij(itypat)%npw   = npw
     362              : 
     363         1484 :    lmn_size  = Pawtab(itypat)%lmn_size
     364         1484 :    lmn2_size = lmn_size*(lmn_size+1)/2
     365         1484 :    Pwij(itypat)%lmn_size  = lmn_size
     366         1484 :    Pwij(itypat)%lmn2_size = lmn2_size
     367              : 
     368         5936 :    Pwij(itypat)%qpt(:) = qpt_in(:)
     369              : 
     370              :    ! Prepare the call to paw_mkrhox
     371         1484 :    method = Paw_pwff(itypat)%method
     372         1484 :    dim1   = Paw_pwff(itypat)%dim1
     373         1484 :    dim2   = Paw_pwff(itypat)%dim2
     374         1484 :    nq_spl = Paw_pwff(itypat)%nq_spl
     375        19292 :    gmet   = Paw_pwff(itypat)%gmet
     376              : 
     377         5936 :    ABI_MALLOC_OR_DIE(Pwij(itypat)%mqpgij,(2,npw,lmn2_size), ierr)
     378              : 
     379              :    ! Evaluate oscillator matrix elements mqpgij
     380              :    call paw_mkrhox(itypat,lmn2_size,method,dim1,dim2,nq_spl,Paw_pwff(itypat)%qgrid_spl,Paw_pwff(itypat)%pwff_spl,&
     381         2918 :                    gmet,qpt_in,npw,gvec,ylm_q,Psps,Pawtab,Pwij(itypat)%mqpgij)
     382              :  end do ! itypat
     383              : 
     384         1434 :  ABI_FREE(ylm_q)
     385              : 
     386         1434 : end subroutine pawpwij_init
     387              : !!***
     388              : 
     389              : !----------------------------------------------------------------------
     390              : 
     391              : !!****f* m_pawpwij/pawpwij_free_d1
     392              : !! NAME
     393              : !!  pawpwij_free_d1
     394              : !!
     395              : !! FUNCTION
     396              : !!  Free all memory allocated in a structure of type pawpwij_t
     397              : !!
     398              : !! SOURCE
     399              : 
     400         1434 : subroutine pawpwij_free_d1(Pwij)
     401              : 
     402              : !Arguments ------------------------------------
     403              :  type(pawpwij_t),intent(inout) :: Pwij(:)
     404              : 
     405              : !Local variables-------------------------------
     406              :  integer :: ii
     407              : !************************************************************************
     408              : 
     409         2918 :  do ii=1,SIZE(Pwij)
     410         2918 :    ABI_SFREE(Pwij(ii)%mqpgij)
     411              :  end do
     412              : 
     413         1434 : end subroutine pawpwij_free_d1
     414              : !!***
     415              : 
     416              : !----------------------------------------------------------------------
     417              : 
     418              : !!****f* m_pawpwij/pawpwij_free_d2
     419              : !! NAME
     420              : !!  pawpwij_free_d2
     421              : !!
     422              : !! FUNCTION
     423              : !!  Free all memory allocated in a structure of type pawpwij_t
     424              : !!
     425              : !! SOURCE
     426              : 
     427            0 : subroutine pawpwij_free_d2(Pwij)
     428              : 
     429              : !Arguments ------------------------------------
     430              : !scalars
     431              :  type(pawpwij_t),intent(inout) :: Pwij(:,:)
     432              : 
     433              : !Local variables-------------------------------
     434              :  integer :: jj
     435              : 
     436              : !************************************************************************
     437              : 
     438            0 :  do jj=1,SIZE(Pwij,DIM=2)
     439            0 :    call pawpwij_free_d1(Pwij(:,jj))
     440              :  end do
     441              : 
     442            0 : end subroutine pawpwij_free_d2
     443              : !!***
     444              : 
     445              : !----------------------------------------------------------------------
     446              : 
     447              : !!****f* m_pawpwij/paw_mkrhox_spl
     448              : !! NAME
     449              : !! paw_mkrhox_spl
     450              : !!
     451              : !! FUNCTION
     452              : !!  Evaluate PAW form factor ff^{aL}_{ij}(q) for each angular momentum L,
     453              : !!  each type of atom, a, and each [(in,il),(jn,jl)] channel. These quantities
     454              : !!  are used in paw_mkrhox to evaluate $<phi|e^{-i(q+G)}|phj>-<tphi|e^{-i(q+G)}|tphj>$
     455              : !!  for an arbitrary q+G vector.
     456              : !!
     457              : !! INPUTS
     458              : !!  dim1
     459              : !!   = 2*(Pawtab(itypat)%l_size-1) if method=1
     460              : !!   = MAXVAL(Pawtab(:)%l_size)**2 if method=2
     461              : !!  dim2
     462              : !!   = Pawtab(itypat)%ij_size      if method=1
     463              : !!   = MAXVAL(Pawtab(:)%lmn2_size) if method=2
     464              : !!  method=integer flag defining the approach used:
     465              : !!   1 --> Expression based on the expansion on a plane wave in terms of Bessel functions
     466              : !!        and spherical harmonics (Arnaud-Alouani's methos, see PRB 62, 4464 [[cite:Arnaud2000]]
     467              : !!   2 --> Approximate expression with correct description of the multipoles. Eq. 9 in PRB 74, 035101 [[cite:Shishkin2006]]
     468              : !!  nq_spl=number of grid points in the q-mesh
     469              : !!  qgrid_spl(nq_spl)=values where form factors are returned
     470              : !!  ntypat=number of type of atoms
     471              : !!  Pawrad<type(Pawrad_type)>=datatype containing radial grid information
     472              : !!  Pawtab(ntypat)<type(pawtab_type)>=PAW tabulated starting data
     473              : !!
     474              : !! OUTPUT
     475              : !!  pwff_spl(nq_spl,2,0:dim1,dim1_rhox2,ntypat)
     476              : !!   form factors ff^{aL}_{ij}(q) and second derivative in packed storage mode
     477              : !!  === if method=1 ===
     478              : !!    $ff_^{aL}_{ij}(q) =
     479              : !!      \int_0^{r_a} j_L(2\pi qr) [phi_{n_i,l_i}.phi_{n_j l_j}(r) - tphi_{n_i l_i}.tph_{n_j l_j}(r)] dr$
     480              : !!  === if method=2 ===
     481              : !!    $ff_^{aL}_{ij}(q) = q_ij^{LM} \int_0^{r_a} j_L(2\pi qr) g_L(r) r^2 dr$
     482              : !!
     483              : !! NOTES
     484              : !!  * $j_L(2\pi q)$ is a spherical Bessel function
     485              : !!  * Output matrix elements are stored in packed storage mode
     486              : !!  * Inspired by pawpsp_nl
     487              : !!
     488              : !! TODO
     489              : !!  One might save CPU time taking into account Gaunt selection rules!
     490              : !!
     491              : !! SOURCE
     492              : 
     493           20 : subroutine paw_mkrhox_spl(itypat,ntypat,method,dim1,dim2,nq_spl,qgrid_spl,Pawrad,Pawtab,pwff_spl)
     494              : 
     495              : !Arguments ------------------------------------
     496              : !scalars
     497              :  integer,intent(in) :: itypat,ntypat,method,dim2,dim1,nq_spl
     498              : !arrays
     499              :  real(dp),intent(in) :: qgrid_spl(nq_spl)
     500              :  real(dp),intent(out) :: pwff_spl(nq_spl,2,0:dim1,dim2)
     501              :  type(Pawrad_type),intent(in) :: Pawrad(ntypat)
     502              :  type(Pawtab_type),intent(in) :: Pawtab(ntypat)
     503              : 
     504              : !Local variables-------------------------------
     505              : !scalars
     506              :  integer :: mm,nlmn,jlmn,ilmn,klmn,ij_size,l_size !,ider
     507              :  integer :: iq,ir,ll,meshsz,mmax,iln,jln,nln,k0ln,kln,qlm
     508              :  real(dp),parameter :: EPS=tol14**4,TOLJ=0.001_dp
     509              :  real(dp) :: arg,argn,bes,besp,qr,yp1,ypn
     510              :  character(len=500) :: msg
     511           20 :  type(Pawrad_type) :: Tmpmesh
     512              : !arrays
     513           20 :  real(dp),allocatable :: rrshape_l(:),shape_l(:),ff(:),gg(:),rr(:),rrdphi_ij(:)
     514           20 :  real(dp),allocatable :: dphi_ij(:),tmp_spl(:,:,:,:),tmp_jgl(:,:,:)
     515              : 
     516              : !*************************************************************************
     517              : 
     518              :  DBG_ENTER("COLL")
     519              : 
     520     57054114 :  pwff_spl=zero
     521              : 
     522           31 :  SELECT CASE (method)
     523              : 
     524              :  CASE (PWIJ_ARNAUD)
     525              :    ! === Arnaud-Alouani exact expression PRB 62. 4464 [[cite:Arnaud2000]] ===
     526              :    ! * $ff_^{aL}_{ij}(q) =
     527              :    !    \int_0^{r_a} j_L(2\pi qr) [phi_{n_i,l_i}.phi_{n_j l_j}(r)-tphi_{n_i l_i}.tph_{n_j l_j}(r)]dr$
     528              :    ! * It does not descrive correctly the multipoles of the AE charge density if low cutoff on G
     529           11 :    write(msg,'(a,i3)')' paw_mkrhox_spl: Using Arnaud-Alouani expression for atom type: ',itypat
     530           11 :    call wrtout(std_out,msg)
     531              : 
     532           11 :    nln     = Pawtab(itypat)%basis_size
     533           11 :    ij_size = Pawtab(itypat)%ij_size
     534           11 :    l_size  = Pawtab(itypat)%l_size
     535              : 
     536           55 :    ABI_MALLOC(tmp_spl,(nq_spl,2,0:l_size-1,ij_size))
     537              : 
     538              :    ! Is mesh beginning with r=0 ?
     539           11 :    if (abs(Pawrad(itypat)%rad(1)) > tol10) then
     540            0 :      ABI_ERROR("Radial mesh starts with r/=0")
     541              :    end if
     542              :    !
     543              :    ! === Initialize temporary arrays and variables ===
     544           11 :    meshsz = Pawtab(itypat)%mesh_size ; mmax=meshsz
     545              : 
     546           33 :    ABI_MALLOC(dphi_ij,(meshsz))
     547           22 :    ABI_MALLOC(rrdphi_ij,(meshsz))
     548           22 :    ABI_MALLOC(ff,(meshsz))
     549         8003 :    ABI_CALLOC(gg,(meshsz))
     550           22 :    ABI_MALLOC(rr,(meshsz))
     551         7992 :    rr(1:meshsz) = Pawrad(itypat)%rad(1:meshsz)
     552              :    !
     553              :    ! === Loop on (jln,iln) channels for this type. Packed form ===
     554      2720397 :    tmp_spl=zero
     555              : 
     556           57 :    do jln=1,nln
     557           46 :      k0ln=jln*(jln-1)/2
     558          178 :      do iln=1,jln
     559          121 :        kln=k0ln+iln
     560              : 
     561        99165 :        dphi_ij(1:meshsz) = Pawtab(itypat)%phiphj(1:meshsz,kln)-Pawtab(itypat)%tphitphj(1:meshsz,kln)
     562        99165 :        rrdphi_ij(1:meshsz) = rr(1:meshsz)*dphi_ij(1:meshsz) ! will be used for first derivative
     563              : 
     564              :        ir=meshsz
     565          703 :        do while (ABS(dphi_ij(ir))<EPS)
     566          582 :          ir=ir-1
     567              :        end do
     568          121 :        mmax=MIN(ir+1,meshsz)
     569              :        ! ir is equal to meshsz if no point are below EPS
     570          121 :        if (mmax/=Pawrad(itypat)%int_meshsz) then  ! mmax=meshsz
     571              :          call pawrad_init(Tmpmesh,mesh_size=Pawtab(itypat)%mesh_size,mesh_type=Pawrad(itypat)%mesh_type, &
     572            3 : &                         rstep=Pawrad(itypat)%rstep,lstep=Pawrad(itypat)%lstep,r_for_intg=rr(mmax))
     573              :        else
     574          118 :          call pawrad_copy(Pawrad(itypat),Tmpmesh)
     575              :        end if
     576              :        !
     577              :        ! === Loop on l for Bessel function. Note the starting point ===
     578              :        ! TODO Here I should loop only the moments allowed by Gaunt, I should use indklm!
     579              :        ! and only on lmax for this atom
     580          574 :        do ll=0,l_size-1
     581              :          !
     582              :          ! === Compute f_l(q=0) only if l=0, and first derivative fp_l(q=0) (nonzero only if ll==1) ===
     583          453 :          tmp_spl(1,1,ll,kln)=zero; yp1=zero
     584          453 :          if (ll==0) then
     585          121 :            call simp_gen(tmp_spl(1,1,ll,kln),dphi_ij,Tmpmesh)
     586              :          end if
     587          453 :          if (ll==1) then
     588          121 :            call simp_gen(yp1,rrdphi_ij,Tmpmesh)
     589          121 :            yp1=yp1*two_pi*third
     590              :          end if
     591              :          !
     592              :          ! === Compute f_l(0<q<qmax) ===
     593          453 :          if (nq_spl>2) then
     594      1359000 :            do iq=2,nq_spl-1
     595      1358547 :              arg=two_pi*qgrid_spl(iq)
     596   1264258440 :              do ir=1,mmax
     597   1262899893 :                qr=arg*rr(ir)
     598   1262899893 :                call paw_jbessel_4spline(bes,besp,ll,0,qr,TOLJ)
     599   1264258440 :                ff(ir)=bes*dphi_ij(ir)
     600              :              end do
     601      1359000 :              call simp_gen(tmp_spl(iq,1,ll,kln),ff,Tmpmesh)
     602              :            end do
     603              :          end if
     604              :          !
     605              :          ! === Compute f_l(q=qmax) and first derivative ===
     606          453 :          if (nq_spl>1) then
     607          453 :            argn=two_pi*qgrid_spl(nq_spl)
     608       421560 :            do ir=1,mmax
     609       421107 :              qr=argn*rr(ir)
     610       421107 :              call paw_jbessel_4spline(bes,besp,ll,1,qr,TOLJ)
     611       421107 :              ff(ir)=bes *  dphi_ij(ir)
     612       421560 :              gg(ir)=besp*rrdphi_ij(ir)
     613              :            end do
     614          453 :            call simp_gen(tmp_spl(nq_spl,1,ll,kln),ff,Tmpmesh)
     615       423405 :            gg(:)=two_pi*gg(:) ! two_pi comes from 2\pi|q| in the Bessel function
     616          453 :            call simp_gen(ypn,gg,Tmpmesh)
     617              :          else
     618            0 :            ypn=yp1
     619              :          end if
     620              :          !
     621              :          ! === Compute second derivative of ff^{al}_{ij)(q) ===
     622              :          !yp1=zero; ypn=zero
     623          574 :          call paw_spline(qgrid_spl,tmp_spl(:,1,ll,kln),nq_spl,yp1,ypn,tmp_spl(:,2,ll,kln))
     624              :        end do !ll
     625              : 
     626          167 :        call pawrad_free(Tmpmesh)
     627              : 
     628              :      end do !iln
     629              :    end do !jln
     630              :    !
     631              :    ! === Save values for this atom type, each ll and kln channel ===
     632      2720397 :    pwff_spl = tmp_spl
     633              : 
     634           11 :    ABI_FREE(dphi_ij)
     635           11 :    ABI_FREE(rrdphi_ij)
     636           11 :    ABI_FREE(ff)
     637           11 :    ABI_FREE(gg)
     638           11 :    ABI_FREE(rr)
     639           11 :    ABI_FREE(tmp_spl)
     640              : 
     641              :    !if (.FALSE.) then ! write form factors on file for plotting purpose.
     642              :    !  ll=0
     643              :    !  do iq=1,nq_spl
     644              :    !    write(777+itypat,'(50(es16.8))')qgrid_spl(iq),((pwff_spl(iq,ider,ll,iln),ider=1,2),iln=1,dim2)
     645              :    !  end do
     646              :    !end if
     647              : 
     648              :  CASE (PWIJ_SHISHKIN)
     649              :    ! ==== Shishkin-Kresse approximated expression ====
     650              :    ! $ff_^{aL}_{ij}(q) = q_ij^{LM} \int_0^{r_a} j_L(2\pi qr) g_L(r) r^2 dr$
     651              :    ! * Better description of multipoles of AE charge,
     652              :    ! * Better results for energy degeneracies in GW band structure
     653            9 :    write(msg,'(a,i3)')' paw_mkrhox_spl: Using Shishkin-Kresse expression for atom type ',itypat
     654            9 :    call wrtout(std_out, msg)
     655            9 :    l_size = Pawtab(itypat)%l_size
     656            9 :    nlmn   = Pawtab(itypat)%lmn_size
     657              : 
     658              :    !allocate(tmp_jgl(nq_spl,2,0:2*(Psps%mpsang-1)))
     659           36 :    ABI_MALLOC(tmp_jgl,(nq_spl,2,0:l_size-1))
     660              : 
     661              :    ! Is mesh beginning with r=0 ?
     662            9 :    if (ABS(Pawrad(itypat)%rad(1))>tol10) then
     663            0 :      ABI_ERROR("Radial mesh starts with r/=0")
     664              :    end if
     665              : 
     666              :    ! === Initialize temporary arrays and variables ===
     667            9 :    call pawrad_copy(Pawrad(itypat),Tmpmesh)
     668            9 :    meshsz=Pawtab(itypat)%mesh_size ; mmax=meshsz
     669           27 :    ABI_MALLOC(ff,(meshsz))
     670         6759 :    ABI_CALLOC(gg,(meshsz))
     671           18 :    ABI_MALLOC(rr,(meshsz))
     672           18 :    ABI_MALLOC(shape_l,(meshsz))
     673           18 :    ABI_MALLOC(rrshape_l,(meshsz))
     674         6750 :    rr(1:meshsz)=Tmpmesh%rad(1:meshsz)
     675              : 
     676       198174 :    tmp_jgl(:,:,:)=zero
     677            9 :    rrshape_l(1)=zero
     678            9 :      shape_l(1)=zero
     679              :    !
     680              :    ! TODO Here I should loop only the moments allowed by Gaunt, I should use indklm!
     681              :    ! and only lmax for this atom
     682              :    !do ll=0,2*(Psps%mpsang-1)
     683           42 :    do ll=0,l_size-1
     684        28611 :        shape_l(2:meshsz)=Pawtab(itypat)%shapefunc(2:meshsz,ll+1)*rr(2:meshsz)**2
     685        28611 :      rrshape_l(2:meshsz)=Pawtab(itypat)%shapefunc(2:meshsz,ll+1)*rr(2:meshsz)**3
     686              :      !
     687              :      ! === Compute f_l(q=0) and first derivative fp_l(q=0) (only if ll==1) ===
     688           33 :      tmp_jgl(1,1,ll)=zero ; yp1=zero
     689           33 :      if (ll==0) then
     690            9 :        call simp_gen(tmp_jgl(1,1,ll),shape_l,Tmpmesh)
     691              :      end if
     692           33 :      if (ll==1) then
     693            9 :        call simp_gen(yp1,rrshape_l,Tmpmesh) !rr comes from d/dq
     694            9 :        yp1=yp1*two_pi*third
     695              :      end if
     696              :      !
     697              :      ! === Compute f_l(0<q<qmax) ===
     698           33 :      if (nq_spl>2) then
     699        99000 :        do iq=2,nq_spl-1
     700        98967 :          arg=two_pi*qgrid_spl(iq)
     701     85903356 :          do ir=1,mmax
     702     85804389 :            qr=arg*rr(ir)
     703     85804389 :            call paw_jbessel_4spline(bes,besp,ll,0,qr,TOLJ)
     704     85903356 :            ff(ir)=bes*shape_l(ir)
     705              :          end do
     706        99000 :          call simp_gen(tmp_jgl(iq,1,ll),ff,Tmpmesh)
     707              :        end do
     708              :      end if
     709              :      !
     710              :      ! === Compute f_l(q=qmax) and first derivative ===
     711           33 :      if (nq_spl>1) then
     712           33 :        argn=two_pi*qgrid_spl(nq_spl)
     713        28644 :        do ir=1,mmax
     714        28611 :          qr=argn*rr(ir)
     715        28611 :          call paw_jbessel_4spline(bes,besp,ll,1,qr,TOLJ)
     716        28611 :          ff(ir)=bes *  shape_l(ir)
     717        28644 :          gg(ir)=besp*rrshape_l(ir)
     718              :        end do
     719           33 :        call simp_gen(tmp_jgl(nq_spl,1,ll),ff,Tmpmesh)
     720        28644 :        gg(:)=two_pi*gg(:) !two_pi comes from 2\pi|q|
     721           33 :        call simp_gen(ypn,gg,Tmpmesh)
     722              :      else
     723            0 :        ypn=yp1
     724              :      end if
     725              :      !
     726              :      ! === Compute second derivative of ff_^{al}_{ij)(q) ===
     727           42 :      call paw_spline(qgrid_spl,tmp_jgl(:,1,ll),nq_spl,yp1,ypn,tmp_jgl(:,2,ll))
     728              :    end do !ll
     729              :    !
     730              :    ! === Save values for this type, each ll and ilmn,jlm channels ===
     731              :    ! * Here we assembly q_{ij}^{lm} \int_0^{r_a} j_l(2\pi(q+G)r) g_l(r)r^2 dr
     732              :    ! * Some of the contributions from qijl are zero due to Gaunt selection rules
     733           93 :    do jlmn=1,nlmn
     734          561 :      do ilmn=1,jlmn
     735          468 :        klmn=ilmn+(jlmn-1)*jlmn/2
     736              :        !do ll=0,2*(Psps%mpsang-1)
     737         2502 :        do ll=0,l_size-1
     738        10998 :          do mm=-ll,ll
     739         8580 :            qlm=1+ll**2+ll+mm
     740     51524850 :            pwff_spl(:,:,qlm-1,klmn)=tmp_jgl(:,:,ll)*Pawtab(itypat)%qijl(qlm,klmn)
     741              :          end do
     742              :        end do
     743              :      end do
     744              :    end do
     745              : 
     746            9 :    call pawrad_free(Tmpmesh)
     747            9 :    ABI_FREE(shape_l)
     748            9 :    ABI_FREE(rrshape_l)
     749            9 :    ABI_FREE(ff)
     750            9 :    ABI_FREE(gg)
     751            9 :    ABI_FREE(rr)
     752            9 :    ABI_FREE(tmp_jgl)
     753              : 
     754              :  CASE DEFAULT
     755           20 :    ABI_BUG(sjoin('Called with wrong value for method:', itoa(method)))
     756              :  END SELECT
     757              : 
     758              :  DBG_EXIT("COLL")
     759              : 
     760           20 : end subroutine paw_mkrhox_spl
     761              : !!***
     762              : 
     763              : !----------------------------------------------------------------------
     764              : 
     765              : !!****f* m_pawpwij/paw_mkrhox
     766              : !! NAME
     767              : !! paw_mkrhox
     768              : !!
     769              : !! FUNCTION
     770              : !!  Evaluate $<phj|e^{-i(q+G)}|phi>-<tphj|e^{-i(q+G)}|tphi>$
     771              : !!  for a fixed q-point and npw G vectors. Matrix elements are stored in packed storage mode.
     772              : !!
     773              : !! INPUTS
     774              : !!  gmet(3,3)=reciprocal lattice metric tensor ($\textrm{Bohr}^{-2}$)
     775              : !!  gvec(3,npw)=G vectors in reduced coordinates
     776              : !!  npw=numper of G vectors
     777              : !!  Psps<pseudopotential_type>:
     778              : !!     %lnmax=Max. number of (l,n) components over all type of PAW datasets
     779              : !!  nq_spl=Number of points in the reciprocal space grid on which the radial functions pwff_spl are specified
     780              : !!  qgrid_spl(nq_spl)=values at which form factors have been evaluated
     781              : !!     %mpsang=1+maximum angular momentum
     782              : !!  qpt(3)= q-point in reduced coordinates
     783              : !!  ylm_q(npw,(2*Psps%mpsang-1)**2)=real spherical harmonics Ylm(q+G) for q-point qpt up to l=2*l_max
     784              : !!  pwff_spl(nq_spl,2,0:2*(Psps%mpsang-1),Psps%lnmax*(Psps%lnmax+1)/2))
     785              : !!  Pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
     786              : !!     %indklmn(8,lmn2_size)=array giving klm, kln, abs(il-jl) and (il+jl), ilm and jlm, ilmn and jlmn for each klmn=(ilmn,jlmn)
     787              : !!
     788              : !! OUTPUT
     789              : !!  paw_rhox(2,npw,lmn2_size): $<phj|e^{-i(q+G).r}|phi>-<tphj|e^{-i(q+G).r}|tphi>$ in packed form for
     790              : !!    a type itypat (phase factor arising from atom position is not included)
     791              : !!
     792              : !! SOURCE
     793              : 
     794         1484 : subroutine paw_mkrhox(itypat,lmn2_size,method,dim1,dim2,nq_spl,qgrid_spl,pwff_spl,&
     795         1484 :                        gmet,qpt,npw,gvec,ylm_q,Psps,Pawtab,paw_rhox)
     796              : 
     797              : !Arguments ------------------------------------
     798              : !scalars
     799              :  integer,intent(in) :: itypat,dim1,dim2,method,npw,nq_spl,lmn2_size
     800              :  type(Pseudopotential_type),intent(in) :: Psps
     801              : !arrays
     802              :  integer,intent(in) :: gvec(3,npw)
     803              :  real(dp),intent(in) :: gmet(3,3)
     804              :  real(dp),intent(in) :: pwff_spl(nq_spl,2,0:dim1,dim2)
     805              :  real(dp),intent(in) :: qpt(3),ylm_q(npw,(2*Psps%mpsang-1)**2)
     806              :  real(dp),intent(out) :: paw_rhox(2,npw,lmn2_size)
     807              :  real(dp),intent(in) :: qgrid_spl(nq_spl)
     808              :  type(Pawtab_type),target,intent(in) :: Pawtab(Psps%ntypat)
     809              : 
     810              : !Local variables-------------------------------
     811              : !scalars
     812              :  integer :: ider,ig,ignt,il,ilm,ilm_G,ilmn,iln,im,ipow,jl,jlm
     813              :  integer :: jlmn,jln,jm,k0lm,k0lmn,k0ln,klm,klmn,kln,ll_G,mm_G,mpsang,ngnt
     814              :  real(dp) :: rgnt,dummy
     815              :  character(len=500) :: msg
     816              : !arrays
     817         1484 :  integer,allocatable :: gntselect(:,:)
     818         1484 :  integer,ABI_CONTIGUOUS pointer :: indlmn(:,:)
     819              :  real(dp) :: mi_l(2,0:3),qpg(3)
     820         1484 :  real(dp),allocatable :: derfun(:),newfun(:),qpg_norm(:),realgnt(:),wk_ffnl(:,:)
     821              : 
     822              : ! *************************************************************************
     823              : 
     824              :  !write(std_out,*)itypat,dim1,dim2,method,npw,nq_spl,lmn2_size,Psps%mpsang
     825         1484 :  mpsang = Psps%mpsang
     826         1484 :  indlmn => Pawtab(itypat)%indlmn
     827              : 
     828              :  ! === Pre-calculate (-i)^l ===
     829         1484 :  mi_l(1,0)=one  ; mi_l(2,0)=zero
     830         1484 :  mi_l(1,1)=zero ; mi_l(2,1)=-one
     831         1484 :  mi_l(1,2)=-one ; mi_l(2,2)=zero
     832         1484 :  mi_l(1,3)=zero ; mi_l(2,3)=one
     833              : 
     834              :  ! === Calculate |q+G| ===
     835              :  ! * 2\pi is not included to be consistent with the spline.
     836         4452 :  ABI_MALLOC(qpg_norm,(npw))
     837        98564 :  do ig=1,npw
     838       388320 :    qpg = qpt + gvec(:,ig)
     839      1554764 :    qpg_norm(ig)=SQRT(DOT_PRODUCT(qpg,MATMUL(gmet,qpg)))
     840              :  end do
     841              : 
     842              :  ! Check q-grid as %qgrid_spl must be large enoung.
     843      4555016 :  if (MAXVAL(qpg_norm)>MAXVAL(qgrid_spl)) then
     844              :    write(msg,'(3a,f8.4,a,f8.4,2a)')&
     845            0 :     ' Function values are being requested outside range of data. ',ch10,&
     846            0 :     ' Max qpg_norm = ',MAXVAL(qpg_norm),' Max qgrid_spl = ',MAXVAL(qgrid_spl),ch10,&
     847            0 :     ' Increase ecut(wfn), check qrid_ff and gsqcut '
     848            0 :    ABI_ERROR(msg)
     849              :  end if
     850              : 
     851         4452 :  ABI_MALLOC(wk_ffnl,(nq_spl,2))
     852         2968 :  ABI_MALLOC(newfun,(npw))
     853         2968 :  ABI_MALLOC(derfun,(npw))
     854              : 
     855         2931 :  SELECT CASE (method)
     856              :  CASE (PWIJ_ARNAUD)
     857              :    ! === Arnaud-Alouani exact expression ===
     858              :    ! * It does not describe the multipoles of the AE charge density
     859              :    ! * $ 4\pi \sum_{LM} (-i)^l Y_M^L(q+G) G_{\li\mi\lj\mj}^{\LM} ff^{aL}_{ij}(|q+G|) $
     860              :    !   where f has been calculated in paw_mkrhox_spl
     861              :    !
     862              :    ! === Re-evaluate Gaunt coefficients, just to be on the safe side ===
     863              :    ! * Note that gntselect is in packed form, thanks to invariance under permutation.
     864              :    ! * Could use Pawang% but size of gntselect depends on pawxcdev!
     865              : 
     866         4341 :    ABI_MALLOC(  realgnt,((2*mpsang-1)**2*(mpsang)**4))
     867         5788 :    ABI_MALLOC(gntselect,((2*mpsang-1)**2, mpsang**2*(mpsang**2+1)/2))
     868         1447 :    call realgaunt(mpsang,ngnt,gntselect,realgnt)
     869     10960825 :    paw_rhox=zero
     870              : 
     871              :    ! Loop on (jl,jm,jn) channels for this atom
     872        12996 :    do jlmn=1,Pawtab(itypat)%lmn_size
     873        11549 :      jl =indlmn(1,jlmn)
     874        11549 :      jm =indlmn(2,jlmn)
     875        11549 :      jlm=indlmn(4,jlmn)
     876        11549 :      jln=indlmn(5,jlmn)
     877              : 
     878        11549 :      k0lmn=jlmn*(jlmn-1)/2
     879        11549 :      k0lm =jlm *(jlm -1)/2
     880        11549 :      k0ln =jln *(jln -1)/2
     881              : 
     882              :      ! === Loop on (il,im,in) channels; klmn is index for packed form ===
     883        65139 :      do ilmn=1,jlmn
     884        52143 :        il =indlmn(1,ilmn)
     885        52143 :        im =indlmn(2,ilmn)
     886        52143 :        ilm=indlmn(4,ilmn)
     887        52143 :        iln=indlmn(5,ilmn)
     888              : 
     889        52143 :        klmn=k0lmn+ilmn
     890        52143 :        klm = Pawtab(itypat)%indklmn(1,klmn) !SF klm =k0lm +ilm is incorrect,
     891              :        ! because ilm can be larger than jlm if more than 1 proj per angular momentum
     892        52143 :        kln =k0ln +iln ! This problem does not occur for kln, because always jln>=iln
     893              : 
     894              :        ! === Summing over allowed (L,M), taking into account Gaunt selection rules ===
     895       146507 :        do ll_G=ABS(jl-il),jl+il,2
     896        82815 :          ipow=MOD(ll_G,4)
     897        82815 :          ider=0
     898    497304075 :          wk_ffnl(:,:)=pwff_spl(:,:,ll_G,kln)
     899        82815 :          call splfit(qgrid_spl,derfun,wk_ffnl,ider,qpg_norm,newfun,nq_spl,npw)
     900       377481 :          do mm_G=-ll_G,ll_G
     901       242523 :            ilm_G=1+ll_G**2+ll_G+mm_G
     902       242523 :            ignt=gntselect(ilm_G,klm)
     903       242523 :            if (ignt==0) CYCLE
     904        74314 :            rgnt=realgnt(ignt)
     905              : 
     906              :            ! === Evaluate matrix elements for each plane wave ===
     907      5452051 :            do ig=1,npw
     908      5294922 :              dummy = newfun(ig) * ylm_q(ig,ilm_G) * rgnt
     909      5294922 :              paw_rhox(1,ig,klmn) = paw_rhox(1,ig,klmn) + ( dummy * mi_l(1,ipow) )
     910      5537445 :              paw_rhox(2,ig,klmn) = paw_rhox(2,ig,klmn) + ( dummy * mi_l(2,ipow) )
     911              :            end do
     912              :          end do !mm_G
     913              :        end do !ll_G
     914              : 
     915              :      end do !ilmn
     916              :    end do !jlmn
     917              : 
     918              :    ! Multiply by 4\pi arising from the expansion of the plane wave
     919     10960825 :    paw_rhox = four_pi*paw_rhox
     920         1447 :    ABI_FREE(realgnt)
     921         2894 :    ABI_FREE(gntselect)
     922              : 
     923              :  CASE (PWIJ_SHISHKIN)
     924              :    ! === Shishkin-Kresse approximated expression ====
     925              :    ! * Better description of multipoles of AE charge,
     926              :    ! * Better results for energy degeneracies in GW band structure
     927              :    ! * $4\pi \sum_{LM} q_ij^{LM} Y_M^L(q+G) f^{aL}_{ij}(q+G)$ where f has been calculated in paw_mkrhox_spl
     928              :    !
     929       163159 :    paw_rhox=zero
     930              :    !
     931              :    ! === Loop on (jl,jm,jn) channels for this atom ===
     932              :    !itypat=Cryst%typat(iatm)
     933          354 :    do jlmn=1,Pawtab(itypat)%lmn_size
     934          317 :      jl =indlmn(1,jlmn)
     935          317 :      jm =indlmn(2,jlmn)
     936          317 :      jlm=indlmn(4,jlmn)
     937          317 :      jln=indlmn(5,jlmn)
     938              : 
     939          317 :      k0lmn=jlmn*(jlmn-1)/2
     940          317 :      k0lm =jlm *(jlm -1)/2
     941          317 :      k0ln =jln *(jln -1)/2
     942              :      !
     943              :      ! === Loop on (il,im,in) channels; klmn is index for packed form ===
     944         1953 :      do ilmn=1,jlmn
     945         1599 :        il =indlmn(1,ilmn)
     946         1599 :        im =indlmn(2,ilmn)
     947         1599 :        ilm=indlmn(4,ilmn)
     948         1599 :        iln=indlmn(5,ilmn)
     949              : 
     950         1599 :        klmn=k0lmn+ilmn
     951              : !       klm =k0lm +ilm !SF klm incorrect, see AA, but not used in SK
     952         1599 :        kln =k0ln +iln
     953              :        !
     954              :        ! === Summing over allowed (l,m), taking into account Gaunt selection rules ===
     955         4607 :        do ll_G=ABS(jl-il),jl+il,2
     956         2691 :          ipow=MOD(ll_G,4)
     957        13521 :          do mm_G=-ll_G,ll_G
     958              :            ! here I can move splfit before the loop over mm_G but I have to change paw_rhox_spl
     959         9231 :            ilm_G=1+ll_G**2+ll_G+mm_G
     960         9231 :            ider=0
     961     55432155 :            wk_ffnl(:,:)=pwff_spl(:,:,ilm_G-1,klmn)  ! Note klmn and ilm_G-1
     962         9231 :            call splfit(qgrid_spl,derfun,wk_ffnl,ider,qpg_norm,newfun,nq_spl,npw)
     963              :            !
     964              :            ! === Evaluate matrix elements for each plane wave ===
     965       337179 :            do ig=1,npw
     966       325257 :              dummy = newfun(ig) * ylm_q(ig,ilm_G)
     967              :              paw_rhox(1,ig,klmn) = paw_rhox(1,ig,klmn) &
     968       325257 :                + dummy * mi_l(1,ipow) !(ph3d(1,ig)*mi_l(1,ipow)-ph3d(2,ig)*mi_l(2,ipow))
     969              :              paw_rhox(2,ig,klmn) = paw_rhox(2,ig,klmn) &
     970       334488 :                + dummy * mi_l(2,ipow) !(ph3d(1,ig)*mi_l(2,ipow)+ph3d(2,ig)*mi_l(1,ipow))
     971              :            end do
     972              :          end do !mm_G
     973              :        end do !ll_G
     974              : 
     975              :      end do !ilmn
     976              :    end do !jlmn
     977              : 
     978              :    ! Multiply by 4\pi arising from the expansion of the plane wave
     979       163159 :    paw_rhox=four_pi*paw_rhox
     980              : 
     981              :  CASE DEFAULT
     982         1484 :    ABI_BUG(sjoin('Wrong value for method:', itoa(method)))
     983              :  END SELECT
     984              : 
     985         1484 :  ABI_FREE(wk_ffnl)
     986         1484 :  ABI_FREE(newfun)
     987         1484 :  ABI_FREE(derfun)
     988         1484 :  ABI_FREE(qpg_norm)
     989              : 
     990         2968 : end subroutine paw_mkrhox
     991              : !!***
     992              : 
     993              : !----------------------------------------------------------------------
     994              : 
     995              : !!****f* m_pawpwij/paw_rho_tw_g
     996              : !! NAME
     997              : !! paw_rho_tw_g
     998              : !!
     999              : !! FUNCTION
    1000              : !!  Evaluates the PAW onsite contribution to the oscillator strengths:
    1001              : !!
    1002              : !!  sum_{i,j} <\tpsi_{k-q,b1}|\cprj_i> <\cprj_j|\tpsi_{k,b2}>*
    1003              : !!   \[ <\phi_i|e^{-i(q+G).r}|\phi_j> - <\tilde\phi_i|e^{-i(q+G).r}|\tilde\phi_j> \].
    1004              : !!
    1005              : !! INPUTS
    1006              : !! dim_rtwg=Define the size of the array rhotwg
    1007              : !!   === for nspinor==1 ===
    1008              : !!    dim_rtwg=1
    1009              : !!   === for nspinor==2 ===
    1010              : !!    dim_rtwg=2 if only <up|up>, <dwn|dwn> matrix elements are required
    1011              : !!    dim_rtwg=4 for <up|up>, <dwn|dwn>, <up|dwn> and <dwn|up>.
    1012              : !!  nspinor=number of spinorial components.
    1013              : !!  npw=number of plane waves for oscillator matrix elements
    1014              : !!  Cprj_kmqb1(natom,nspinor),Cprj_kb2(natom,nspinor) <type(pawcprj_type)>=
    1015              : !!   projected input wave functions <Proj_i|Cnk> with all NL projectors corresponding to
    1016              : !!   wavefunctions (k-q,b1,s) and (k,b2,s), respectively.
    1017              : !!
    1018              : !! SIDE EFFECTS
    1019              : !!  rhotwg(npw*dim_rtwg)=Updated oscillator strengths with the on-site PAW contributions added.
    1020              : !!
    1021              : !! SOURCE
    1022              : 
    1023       294679 : pure subroutine paw_rho_tw_g(cryst, pwij, npw, dim_rtwg, nspinor, gvec, Cprj_kmqb1, Cprj_kb2, rhotwg)
    1024              : 
    1025              : !Arguments ------------------------------------
    1026              : !scalars
    1027              :  type(crystal_t),intent(in) :: cryst
    1028              :  integer,intent(in) :: npw,nspinor,dim_rtwg
    1029              : !arrays
    1030              :  integer,intent(in) :: gvec(3,npw)
    1031              :  type(pawcprj_type),intent(in) :: Cprj_kmqb1(cryst%natom,nspinor), Cprj_kb2(cryst%natom,nspinor)
    1032              :  type(pawpwij_t),intent(in) :: Pwij(cryst%ntypat)
    1033              :  complex(gwp),intent(inout) :: rhotwg(npw*dim_rtwg)
    1034              : 
    1035              : !Local variables-------------------------------
    1036              : !scalars
    1037              :  integer :: ig,iat,nlmn,ilmn,jlmn,k0lmn,klmn,iab,isp1,isp2,spad,itypat
    1038              :  real(dp) :: fij,re_psp,im_psp,re_pw,im_pw,arg
    1039              : !arrays
    1040              :  integer,parameter :: spinor_idxs(2,4) = RESHAPE([1,1,2,2,1,2,2,1], [2, 4])
    1041              :  real(dp) :: tmp(2),qpg(3),x0(3),ph3d(2)
    1042              : ! *************************************************************************
    1043              : 
    1044              :  ! Loop over the four spinorial combinations
    1045       589358 :  do iab=1,dim_rtwg
    1046       294679 :    isp1 = spinor_idxs(1,iab)
    1047       294679 :    isp2 = spinor_idxs(2,iab)
    1048       294679 :    spad = npw*(iab-1)
    1049              : 
    1050     13226075 :    do ig=1,npw
    1051              :      tmp(:)=zero
    1052     39389559 :      do iat=1,cryst%natom
    1053     26752842 :        itypat = cryst%typat(iat)
    1054     26752842 :        nlmn   = Pwij(itypat)%lmn_size
    1055    107011368 :        x0(:) = cryst%xred(:,iat)
    1056              : 
    1057              :        ! Structure factor e^{-i(q+G)*xred}
    1058    107011368 :        qpg(:)= Pwij(itypat)%qpt(:) + gvec(:,ig)
    1059    107011368 :        arg=-two_pi*DOT_PRODUCT(qpg(:),x0)
    1060     26752842 :        ph3d(1)=COS(arg)
    1061     26752842 :        ph3d(2)=SIN(arg)
    1062              : 
    1063              :        ! Loop over [(jl,jm,jn), (il,im,in)] channels in packed storage mode.
    1064    256219008 :        do jlmn=1,nlmn
    1065    216829449 :          k0lmn=jlmn*(jlmn-1)/2
    1066   1239012234 :          do ilmn=1,jlmn
    1067              :            re_psp =  Cprj_kmqb1(iat,isp1)%cp(1,ilmn) * Cprj_kb2(iat,isp2)%cp(1,jlmn) &
    1068              :                     +Cprj_kmqb1(iat,isp1)%cp(2,ilmn) * Cprj_kb2(iat,isp2)%cp(2,jlmn) &
    1069              :                     +Cprj_kmqb1(iat,isp1)%cp(1,jlmn) * Cprj_kb2(iat,isp2)%cp(1,ilmn) &
    1070    995429943 :                     +Cprj_kmqb1(iat,isp1)%cp(2,jlmn) * Cprj_kb2(iat,isp2)%cp(2,ilmn)
    1071              : 
    1072              :            im_psp =  Cprj_kmqb1(iat,isp1)%cp(1,ilmn) * Cprj_kb2(iat,isp2)%cp(2,jlmn) &
    1073              :                     -Cprj_kmqb1(iat,isp1)%cp(2,ilmn) * Cprj_kb2(iat,isp2)%cp(1,jlmn) &
    1074              :                     +Cprj_kmqb1(iat,isp1)%cp(1,jlmn) * Cprj_kb2(iat,isp2)%cp(2,ilmn) &
    1075    995429943 :                     -Cprj_kmqb1(iat,isp1)%cp(2,jlmn) * Cprj_kb2(iat,isp2)%cp(1,ilmn)
    1076              : 
    1077    995429943 :            klmn=k0lmn+ilmn; fij=one; if (jlmn==ilmn) fij=half
    1078              : 
    1079              :            ! Multiply by the phase due to the atom position.
    1080              :            re_pw =  Pwij(itypat)%mqpgij(1,ig,klmn) * ph3d(1) &
    1081    995429943 :                    -Pwij(itypat)%mqpgij(2,ig,klmn) * ph3d(2)
    1082              : 
    1083              :            im_pw =  Pwij(itypat)%mqpgij(1,ig,klmn) * ph3d(2) &
    1084    995429943 :                    +Pwij(itypat)%mqpgij(2,ig,klmn) * ph3d(1)
    1085              : 
    1086    995429943 :            tmp(1)=tmp(1)+ fij * (re_pw*re_psp - im_pw*im_psp)
    1087   1212259392 :            tmp(2)=tmp(2)+ fij * (re_pw*im_psp + im_pw*re_psp)
    1088              :          end do !ilmn
    1089              :        end do !jlmn
    1090              :      end do !iat
    1091              : 
    1092              :      !if(ig==1) write(std_out,*) " TOTAL PW     osc str = ",rhotwg(ig+spad)
    1093              :      !if(ig==1) write(std_out,*) " TOTAL PAW    osc str = ",tmp(1),tmp(2)
    1094              :      ! Update input data using the appropriate index.
    1095     12931396 :      rhotwg(ig+spad) = rhotwg(ig+spad) + CMPLX(tmp(1),tmp(2),kind=gwp)
    1096              :      !if(ig==1) write(std_out,*) " TOTAL PW+PAW osc str = ",rhotwg(ig+spad)
    1097              :    end do !ig
    1098              : 
    1099              :  end do ! dim_rtwg
    1100              : 
    1101       294679 : end subroutine paw_rho_tw_g
    1102              : !!***
    1103              : 
    1104              : !----------------------------------------------------------------------
    1105              : 
    1106              : !!****f* ABINIT/paw_cross_rho_tw_g
    1107              : !! NAME
    1108              : !!  paw_cross_rho_tw_g
    1109              : !!
    1110              : !! FUNCTION
    1111              : !!  Compute the cross term between the PAW onsite part and plane-wave part in rho_tw
    1112              : !!
    1113              : !! INPUTS
    1114              : !!
    1115              : !! OUTPUT
    1116              : !!
    1117              : !! SOURCE
    1118              : 
    1119            0 : subroutine paw_cross_rho_tw_g(nspinor,npwvec,nr,ngfft,map2sphere,use_padfft,igfftg0,gbound,&
    1120            0 :   ur_ae1,ur_ae_onsite1,ur_ps_onsite1,i1,ktabr1,ktabp1,spinrot1,&
    1121            0 :   ur_ae2,ur_ae_onsite2,ur_ps_onsite2,i2,ktabr2,ktabp2,spinrot2,&
    1122            0 :   dim_rtwg,rhotwg)
    1123              : 
    1124              : !Arguments ------------------------------------
    1125              : !scalars
    1126              :  integer,intent(in) :: i1,i2,npwvec,nr,nspinor,dim_rtwg,map2sphere,use_padfft
    1127              :  complex(dp),intent(in) :: ktabp1,ktabp2
    1128              : !arrays
    1129              :  integer,intent(in) :: gbound(:,:)
    1130              :  integer,intent(in) :: igfftg0(npwvec*map2sphere),ngfft(18)
    1131              :  integer,intent(in) :: ktabr1(nr),ktabr2(nr)
    1132              :  real(dp),intent(in) :: spinrot1(4),spinrot2(4)
    1133              :  complex(gwp),intent(in) :: ur_ae1(nr),ur_ae2(nr)
    1134              :  complex(gwp),intent(in) :: ur_ae_onsite1(nr),ur_ae_onsite2(nr)
    1135              :  complex(gwp),intent(in) :: ur_ps_onsite1(nr),ur_ps_onsite2(nr)
    1136              :  complex(gwp),intent(inout) :: rhotwg(npwvec*dim_rtwg)
    1137              : 
    1138              : !Local variables-------------------------------
    1139              : !scalars
    1140              :  integer,parameter :: ndat1 = 1, fftcache0 = 0, gpu_option_0 = 0
    1141              :  integer :: ig,igfft,nx,ny,nz,ldx,ldy,ldz,mgfft,isprot1,isprot2
    1142              :  type(fftbox_plan3_t) :: plan
    1143              : !arrays
    1144            0 :  complex(dp),allocatable :: usk(:),uu(:),rho(:)
    1145              : ! *************************************************************************
    1146              : 
    1147            0 :  SELECT CASE (nspinor)
    1148              : 
    1149              :  CASE (1) ! Collinear case.
    1150              : 
    1151            0 :    ABI_MALLOC(uu,(nr))
    1152            0 :    ABI_MALLOC(usk,(nr))
    1153            0 :    ABI_MALLOC(rho,(nr))
    1154              : 
    1155            0 :    uu  = ur_ae1(ktabr1)*ktabp1        - ur_ae_onsite1(ktabr1)*ktabp1; if (i1==1) uu  = CONJG(uu)
    1156            0 :    usk = ur_ae_onsite2(ktabr2)*ktabp2 - ur_ps_onsite2(ktabr2)*ktabp2; if (i2==2) usk = CONJG(usk)
    1157            0 :    rho = uu * usk
    1158              : 
    1159            0 :    uu  = ur_ae_onsite1(ktabr1)*ktabp1 - ur_ps_onsite1(ktabr1)*ktabp1; if (i1==1) uu  = CONJG(uu)
    1160            0 :    usk = ur_ae2(ktabr2)*ktabp2        - ur_ae_onsite2(ktabr2)*ktabp2; if (i2==2) usk = CONJG(usk)
    1161            0 :    rho = rho + uu * usk
    1162              : 
    1163            0 :    SELECT CASE (map2sphere)
    1164              : 
    1165              :    CASE (0)
    1166              :      ! Need results on the full FFT box thus cannot use zero-padded FFT.
    1167            0 :      call plan%init(ndat1, ngfft(1:3), ngfft(1:3), ngfft(7), fftcache0, gpu_option_0)
    1168            0 :      call plan%execute(rho, -1, ndat1)
    1169            0 :      call plan%free()
    1170              : 
    1171            0 :      rhotwg=rhotwg + rho
    1172              : 
    1173              :    CASE (1)
    1174              :      ! Need results on the G-sphere. Call zero-padded FFT routines if required.
    1175            0 :      if (use_padfft==1) then
    1176            0 :        nx =ngfft(1); ny =ngfft(2); nz =ngfft(3); mgfft = MAXVAL(ngfft(1:3))
    1177            0 :        ldx=nx      ; ldy=ny      ; ldz=nz
    1178            0 :        call fftpad(rho,ngfft,nx,ny,nz,ldx,ldy,ldz,ndat1,mgfft,-1,gbound)
    1179              :      else
    1180            0 :        call plan%init(ndat1, ngfft(1:3), ngfft(1:3), ngfft(7), fftcache0, gpu_option_0)
    1181            0 :        call plan%execute(rho, -1, ndat1)
    1182            0 :        call plan%free()
    1183              :      end if
    1184              : 
    1185              :      ! Have to map FFT to G-sphere.
    1186            0 :      do ig=1,npwvec
    1187            0 :        igfft=igfftg0(ig)
    1188              :        ! If G-G0 belong to the FFT mesh.
    1189            0 :        if (igfft/=0) rhotwg(ig)=rhotwg(ig)+rho(igfft)
    1190              :      end do
    1191              : 
    1192              :    CASE DEFAULT
    1193            0 :      ABI_BUG(sjoin("Wrong map2sphere:", itoa(map2sphere)))
    1194              :    END SELECT
    1195              : 
    1196            0 :    RETURN
    1197              : 
    1198              :  CASE (2)
    1199              :    ! Spinorial case.
    1200            0 :    isprot1=spinrot1(1); isprot2=spinrot2(1) ! This is to bypass abirule
    1201            0 :    ABI_ERROR("Spinorial case not implemented yet")
    1202              : 
    1203            0 :    SELECT CASE (map2sphere)
    1204              : 
    1205              :    CASE (0) ! Need results on the full FFT box thus cannot use zero-padded FFT.
    1206              :    CASE (1) ! Need results on the G-sphere. Call zero-padded FFT routines if required.
    1207              :    CASE DEFAULT
    1208            0 :      ABI_BUG("Wrong map2sphere")
    1209              :    END SELECT
    1210            0 :    RETURN
    1211              : 
    1212              :  CASE DEFAULT
    1213            0 :    ABI_BUG(sjoin('Wrong nspinor:', itoa(nspinor)))
    1214              :  END SELECT
    1215              : 
    1216            0 : end subroutine paw_cross_rho_tw_g
    1217              : !!***
    1218              : 
    1219              : !----------------------------------------------------------------------
    1220              : 
    1221            0 : END MODULE m_pawpwij
    1222              : !!***
        

Generated by: LCOV version 2.3-1