LCOV - code coverage report
Current view: top level - shared/libpaw/src - m_pawrad.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 69.2 % 623 431
Test Date: 2026-09-19 17:42:43 Functions: 83.3 % 18 15

            Line data    Source code
       1              : !!****m* ABINIT/m_pawrad
       2              : !! NAME
       3              : !! m_pawrad
       4              : !!
       5              : !! FUNCTION
       6              : !! Module containing all the functions related to the PAW radial meshes
       7              : !!
       8              : !! COPYRIGHT
       9              : !! Copyright (C) 2013-2026 ABINIT group (MT,FJ,MG)
      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              : !! NOTES
      15              : !!  * Routines tagged with "@type_name" are strongly connected to the definition of the data type.
      16              : !!    Strongly connected means that the proper functioning of the implementation relies on the
      17              : !!    assumption that the tagged procedure is consistent with the type declaration.
      18              : !!    Every time a developer changes the structure "type_name" adding new entries, he/she has to make sure
      19              : !!    that all the strongly connected routines are changed accordingly to accommodate the modification of the data type
      20              : !!    Typical examples of strongly connected routines are creation, destruction or reset methods.
      21              : !!
      22              : !!  * FOR DEVELOPERS: in order to preserve the portability of libPAW library,
      23              : !!    please consult ~abinit/src/??_libpaw/libpaw-coding-rules.txt
      24              : !!
      25              : !! SOURCE
      26              : 
      27              : #include "libpaw.h"
      28              : 
      29              : MODULE m_pawrad
      30              : 
      31              :  USE_DEFS
      32              :  USE_MSG_HANDLING
      33              :  USE_MPI_WRAPPERS
      34              :  USE_MEMORY_PROFILING
      35              : 
      36              :  use m_paw_numeric, only : paw_derfc
      37              : 
      38              :  implicit none
      39              : 
      40              :  private
      41              : 
      42              : !public procedures.
      43              :  public :: pawrad_init          ! Main creation method
      44              :  public :: pawrad_free          ! Free the allocated memory
      45              :  public :: pawrad_print         ! Printout of the basic info
      46              :  public :: pawrad_isame         ! Checks whether two meshes are equivalent or have the same equation.
      47              :  public :: pawrad_copy          ! Returns a copy of the mesh.
      48              :  public :: pawrad_ifromr        ! Retrieve the Index FROM a given R value in a radial grid.
      49              :  public :: pawrad_deducer0      ! Extrapolate r=0 value of a function from values near r=0.
      50              :  public :: pawrad_bcast         ! Broadcast pawrad datastructure over a given MPI communicator
      51              :  public :: simp_gen             ! Performs integral on a given (generalized) grid using Simpson rule.
      52              :  public :: nderiv_gen           ! Do corrected first (and 2nd) derivation on a given (generalized) grid.
      53              :  public :: nderiv_lin           ! Do corrected first (and 2nd) derivation on a given linear grid.
      54              :  public :: bound_deriv          ! Computes derivatives at boundaries of the mesh
      55              :  public :: poisson              ! Solves Poisson eq. for angularly dependent charge distribution of angular momentum l
      56              :  public :: screened_coul_kernel ! Kernel used to compute short-range screened Coulomb integrals
      57              :  public :: calc_slatradl        ! Calculates the radial part of Slater integrals.
      58              : 
      59              :  interface pawrad_free
      60              :    module procedure pawrad_free_0D
      61              :    module procedure pawrad_free_1D
      62              :  end interface pawrad_free
      63              : 
      64              :  ! TODO: Might use bit flags, but all radmesh stuff should be encapsulated here!
      65              :  integer,private,parameter :: RMESH_LINEAR = 1
      66              :  integer,private,parameter :: RMESH_LOG1   = 2
      67              :  integer,private,parameter :: RMESH_LOG2   = 3
      68              :  integer,private,parameter :: RMESH_LOG3   = 4
      69              :  integer,private,parameter :: RMESH_NL     = 5
      70              : !!***
      71              : 
      72              : !-------------------------------------------------------------------------
      73              : 
      74              : !!****t* m_pawrad/pawrad_type
      75              : !! NAME
      76              : !! pawrad_type
      77              : !!
      78              : !! FUNCTION
      79              : !! For PAW, RADial mesh discretization and related data
      80              : !!
      81              : !! SOURCE
      82              : 
      83              :  type, public :: pawrad_type
      84              : 
      85              : !Integer scalars
      86              : 
      87              :   integer :: int_meshsz=0
      88              :    ! Mesh size used in integrals computation
      89              :    ! Integrals will be computed up to r(int_meshsz)
      90              : 
      91              :   integer :: mesh_size=0
      92              :    ! Dimension of radial mesh
      93              : 
      94              :   integer :: mesh_type=-1
      95              :    ! Type of mesh
      96              :    !     1=regular grid: r(i)=(i-1)*AA
      97              :    !     2=logarithmic grid: r(i)=AA*(exp[BB*(i-1)]-1)
      98              :    !     3=logarithmic grid: r(i>1)=AA*exp[BB*(i-1)] and r(1)=0
      99              :    !     4=logarithmic grid: r(i)=-AA*ln[1-BB*(i-1)] with BB=1/n
     100              : 
     101              : !Real (real(dp)) scalars
     102              : 
     103              :   real(dp) :: lstep=zero
     104              :    ! Exponential step of the mesh (BB parameter above)
     105              :    ! Defined only if mesh type is logarithmic
     106              : 
     107              :   real(dp) :: rmax=zero
     108              :    ! Max. value of r = rad(mesh_size)
     109              : 
     110              :   real(dp) :: rstep=zero
     111              :    ! Radial step of the mesh (AA parameter above)
     112              : 
     113              :   real(dp) :: stepint=zero
     114              :    ! Radial step used to convert any function from the
     115              :    ! present grid onto a regular grid in order to
     116              :    ! integrate it using trapeze method
     117              : 
     118              : !Real (real(dp)) arrays
     119              : 
     120              :   real(dp), allocatable :: rad(:)
     121              :    ! rad(mesh_size)
     122              :    ! Coordinates of all the points of the mesh
     123              : 
     124              :   real(dp), allocatable :: radfact(:)
     125              :    ! radfact(mesh_size)
     126              :    ! Factor used to compute radial integrals
     127              :    ! Before being integrated on the present mesh,
     128              :    ! any function is multiplied by this factor
     129              : 
     130              :   real(dp), allocatable :: simfact(:)
     131              :    ! simfact(mesh_size)
     132              :    ! Factor used to compute radial integrals by the a Simpson scheme
     133              :    ! Integral[f] = Sum_i [simfact(i)*f(i)]
     134              : 
     135              :  end type pawrad_type
     136              : !!***
     137              : 
     138              : CONTAINS
     139              : !===========================================================
     140              : !!***
     141              : 
     142              : !!****f* m_pawrad/pawrad_init
     143              : !! NAME
     144              : !!  pawrad_init
     145              : !!
     146              : !! FUNCTION
     147              : !!  Creation method for radial meshes.
     148              : !!  Compute all points (and related weights) of a radial mesh.
     149              : !!  Grid can be regular or logarithimc.
     150              : !!
     151              : !! INPUTS
     152              : !!  [mesh_size]=Dimension of the radial mesh
     153              : !!              If not present, take mesh%mesh_size
     154              : !!  [mesh_type]=Type of mesh
     155              : !!              If not present, take mesh%mesh_type
     156              : !!  [rstep]=Radial step of the mesh (AA parameter above)
     157              : !!          If not present, take mesh%rstep
     158              : !!  [lstep]=Exponential step of the mesh (BB parameter above)
     159              : !!          If not present, take mesh%lstep
     160              : !!          Needed only if mesh type is logarithmic.
     161              : !!  [r_for_intg]=Mesh size used in integrals computation
     162              : !!               If not present, take mesh%r_for_intg
     163              : !!    Integrals will be computed up to rr(r_for_intg)
     164              : !!    (can be negative for an integration over the whole grid)
     165              : !!
     166              : !! OUTPUT
     167              : !!
     168              : !! SIDE EFFECTS
     169              : !!  mesh<pawrad_type>=The object completely initialized (containing radial grid information).
     170              : !!  The following quantities are calculated inside the routine:
     171              : !!    %stepint = Radial step used to convert any function from the
     172              : !!               present grid onto a regular grid in order to integrate it using trapeze method
     173              : !!    %rad(mesh_size) = Coordinates of all the points of the mesh.
     174              : !!    %radfact(mesh_size) = Factors used to compute radial integrals.
     175              : !!    %int_meshsz = Integrals will be computed up to r(int_meshsz)
     176              : !!    %simfact(mesh_size) = Factor used to compute radial integrals by the a Simpson scheme
     177              : !!                          Integral[f] = Sum_i [simfact(i)*f(i)]
     178              : !!    %rmax = Max. value of r = rad(mesh_size)
     179              : !!
     180              : !! NOTES
     181              : !!  Possible mesh types (mesh%mesh_type)
     182              : !!   mesh_type=1 (regular grid): rad(i)=(i-1)*AA
     183              : !!   mesh_type=2 (logari. grid): rad(i)=AA*(exp[BB*(i-1)]-1)
     184              : !!   mesh_type=3 (logari. grid): rad(i>1)=AA*exp[BB*(i-2)] and rad(1)=0
     185              : !!   mesh_type=4 (logari. grid): rad(i)=-AA*ln[1-BB*(i-1)] with BB=1/n
     186              : !!   mesh_type=5 ( grid): rad(i)=AA*i/(n-i)
     187              : !!
     188              : !! SOURCE
     189              : 
     190         5156 : subroutine pawrad_init(mesh,mesh_size,mesh_type,rstep,lstep,r_for_intg)
     191              : 
     192              : !Arguments ------------------------------------
     193              : !scalars
     194              :  integer,intent(in),optional :: mesh_size,mesh_type
     195              :  real(dp),intent(in),optional :: rstep,lstep
     196              :  real(dp),intent(in),optional :: r_for_intg
     197              :  type(pawrad_type),intent(inout) :: mesh
     198              : 
     199              : !Local variables-------------------------------
     200              : !scalars
     201              :  integer :: ir,ir_last,isim,mesh_size_,mesh_type_
     202              :  real(dp) :: hh,lstep_,rstep_,r_for_intg_
     203              :  character(len=500) :: msg
     204              : 
     205              : ! *************************************************************************
     206              : 
     207              :  !@pawrad_type
     208              : 
     209              : !Retrieve mesh data
     210         5156 :  mesh_size_ = mesh%mesh_size ; if (present(mesh_size)) mesh_size_ = mesh_size
     211         5156 :  mesh_type_ = mesh%mesh_type ; if (present(mesh_type)) mesh_type_ = mesh_type
     212         5156 :  rstep_ = mesh%rstep ; if (present(rstep)) rstep_ = rstep
     213         5156 :  lstep_ = mesh%lstep ; if (present(lstep)) lstep_ = lstep
     214              : 
     215         5156 :  r_for_intg_=-1._dp;if (present(r_for_intg)) r_for_intg_=r_for_intg
     216              : 
     217         5156 :  mesh%mesh_size = mesh_size_
     218         5156 :  mesh%mesh_type = mesh_type_
     219         5156 :  mesh%rstep     = rstep_
     220         5156 :  mesh%lstep     = lstep_
     221        15468 :  LIBPAW_ALLOCATE(mesh%rad    ,(mesh%mesh_size))
     222        10312 :  LIBPAW_ALLOCATE(mesh%radfact,(mesh%mesh_size))
     223        10312 :  LIBPAW_ALLOCATE(mesh%simfact,(mesh%mesh_size))
     224      7829511 :  mesh%simfact=zero
     225              :  if (mesh%mesh_type==1) then
     226         1636 :    isim=3
     227         1636 :    mesh%stepint=mesh%rstep
     228         1636 :    mesh%rad(1)=zero;mesh%radfact(1)=one
     229      3038160 :    do ir=2,mesh%mesh_size
     230      3036524 :      mesh%rad(ir) =mesh%rstep*dble(ir-1)
     231      3038160 :      mesh%radfact(ir)=one
     232              :    end do
     233              :  else if (mesh%mesh_type==2) then
     234         3371 :    isim=3
     235         3371 :    mesh%stepint=mesh%lstep
     236         3371 :    mesh%rad(1)=zero;mesh%radfact(1)=mesh%rstep
     237      4693128 :    do ir=2,mesh%mesh_size
     238      4689757 :      mesh%rad(ir) =mesh%rstep*(exp(mesh%lstep*dble(ir-1))-one)
     239      4693128 :      mesh%radfact(ir)=mesh%rad(ir)+mesh%rstep
     240              :    end do
     241              :  else if (mesh%mesh_type==3) then
     242          133 :    isim=4
     243          133 :    mesh%stepint=mesh%lstep
     244          133 :    mesh%rad(1)=zero;mesh%radfact(1)=zero
     245        85883 :    do ir=2,mesh%mesh_size
     246        85750 :      mesh%rad(ir) =mesh%rstep*exp(mesh%lstep*dble(ir-2))
     247        85883 :      mesh%radfact(ir)=mesh%rad(ir)
     248              :    end do
     249              :  else if (mesh%mesh_type==4) then
     250            0 :    isim=3
     251            0 :    mesh%lstep=one/dble(mesh%mesh_size)
     252            0 :    mesh%stepint=mesh%lstep
     253            0 :    mesh%rad(1)=zero;mesh%radfact(1)=mesh%rstep
     254            0 :    do ir=2,mesh%mesh_size
     255            0 :      mesh%rad(ir) =-mesh%rstep*log(one-mesh%lstep*dble(ir-1))
     256            0 :      mesh%radfact(ir)=mesh%rstep/(one-mesh%lstep*dble(ir-1))
     257              :    end do
     258              :  else if (mesh%mesh_type==5) then
     259           16 :    isim=3
     260           16 :    mesh%stepint=mesh%rstep
     261           16 :    mesh%rad(1)=zero;mesh%radfact(1)=1/mesh%lstep
     262         7184 :    do ir=2,mesh%mesh_size
     263         7168 :      mesh%rad(ir) =mesh%rstep*dble(ir-1)/(mesh%lstep-dble(ir-1))
     264         7184 :      mesh%radfact(ir)=(mesh%rstep+mesh%rad(ir))/(mesh%lstep-dble(ir-1))/mesh%rstep
     265              :    end do
     266              : 
     267              :  else !  Other values of mesh_type are not allowed (see psp7in.F90)
     268            0 :   write(msg,'(a,i0)')" Unknown value of mesh_type: ",mesh%mesh_type
     269            0 :   LIBPAW_ERROR(msg)
     270              :  end if
     271              : 
     272         5156 :  mesh%int_meshsz=mesh%mesh_size
     273         5156 :  if (r_for_intg_>0.d0) then
     274         2108 :    ir=min(pawrad_ifromr(mesh,r_for_intg_),mesh%mesh_size)
     275         2108 :    if (ir<mesh%mesh_size) then
     276         1786 :      if (abs(mesh%rad(ir+1)-r_for_intg_)<abs(mesh%rad(ir)-r_for_intg_)) ir=ir+1
     277              :    end if
     278         2108 :    if (ir>1) then
     279         2108 :      if (abs(mesh%rad(ir-1)-r_for_intg_)<abs(mesh%rad(ir)-r_for_intg_)) ir=ir-1
     280              :    end if
     281         2108 :    mesh%int_meshsz=ir
     282              :  end if
     283              : 
     284         5156 :  hh=mesh%stepint/3.d0
     285         5156 :  mesh%simfact(mesh%int_meshsz)=hh*mesh%radfact(mesh%int_meshsz)
     286        10445 :  mesh%simfact(1:isim-2)=zero
     287         5156 :  ir_last=1
     288         5156 :  do ir=mesh%int_meshsz,isim,-2
     289      3487353 :    mesh%simfact(ir-1)=4.d0*hh*mesh%radfact(ir-1)
     290      3487353 :    mesh%simfact(ir-2)=2.d0*hh*mesh%radfact(ir-2)
     291      3487353 :    ir_last=ir-2
     292              :  end do
     293         5156 :  mesh%simfact(ir_last)=half*mesh%simfact(ir_last)
     294       847601 :  if (mesh%int_meshsz<mesh%mesh_size) mesh%simfact(mesh%int_meshsz+1:mesh%mesh_size)=zero
     295              : 
     296         5156 :  mesh%rmax=mesh%rad(mesh%mesh_size)
     297              : 
     298         5156 : end subroutine pawrad_init
     299              : !!***
     300              : 
     301              : !----------------------------------------------------------------------
     302              : 
     303              : !!****f* m_pawrad/pawrad_free_0D
     304              : !! NAME
     305              : !!  pawrad_free_0D
     306              : !!
     307              : !! FUNCTION
     308              : !!  Frees all memory allocated in the object
     309              : !!
     310              : !! SOURCE
     311              : 
     312         9633 : subroutine pawrad_free_0D(Rmesh)
     313              : 
     314              : !Arguments ------------------------------------
     315              : !arrays
     316              :  type(pawrad_type),intent(inout) :: Rmesh
     317              : 
     318              : !Local variables-------------------------------
     319              : 
     320              : ! *************************************************************************
     321              : 
     322              :  !@Pawrad_type
     323              : 
     324         9633 :  if (allocated(Rmesh%rad    ))  then
     325         8690 :    LIBPAW_DEALLOCATE(Rmesh%rad)
     326              :  end if
     327         9633 :  if (allocated(Rmesh%radfact))  then
     328         8690 :    LIBPAW_DEALLOCATE(Rmesh%radfact)
     329              :  end if
     330         9633 :  if (allocated(Rmesh%simfact))  then
     331         8690 :    LIBPAW_DEALLOCATE(Rmesh%simfact)
     332              :  end if
     333         9633 :  Rmesh%int_meshsz=0
     334         9633 :  Rmesh%mesh_size=0
     335         9633 :  Rmesh%mesh_type=-1
     336              : 
     337         9633 : end subroutine pawrad_free_0D
     338              : !!***
     339              : 
     340              : !----------------------------------------------------------------------
     341              : 
     342              : !!****f* m_pawrad/pawrad_free_1D
     343              : !! NAME
     344              : !!  pawrad_free_1D
     345              : !!
     346              : !! FUNCTION
     347              : !!  Destroy all objects in an array of pawrad data structures
     348              : !!
     349              : !! SOURCE
     350              : 
     351         1979 : subroutine pawrad_free_1D(Rmesh)
     352              : 
     353              : !Arguments ------------------------------------
     354              :  type(pawrad_type),intent(inout) :: Rmesh(:)
     355              : 
     356              : !Local variables-------------------------------
     357              :  integer :: ii,nn
     358              : 
     359              : ! *************************************************************************
     360              : 
     361              :  !@pawrad_type
     362              : 
     363         1979 :  nn=size(Rmesh)
     364         1979 :  if (nn==0) return
     365              : 
     366         2918 :  do ii=1,nn
     367         2918 :    call pawrad_free_0D(Rmesh(ii))
     368              :  end do
     369              : 
     370              : end subroutine pawrad_free_1D
     371              : !!***
     372              : 
     373              : !----------------------------------------------------------------------
     374              : 
     375              : !!****f* m_pawrad/pawrad_print
     376              : !! NAME
     377              : !!  pawrad_print
     378              : !!
     379              : !! FUNCTION
     380              : !!  Reports basic info on the object.
     381              : !!
     382              : !! INPUTS
     383              : !!  Rmesh<pawrad_type>=Object defining the radial mesh
     384              : !!  header=String for the header provided by the user.
     385              : !!  [unit]=Unit number for output, defaults to std_out
     386              : !!  [prtvol]=Verbosity level, minimal if not specified.
     387              : !!  [mode_paral]=Either "COLL" or "PERS". Passed to wrtout. Defaults to "COLL"
     388              : !!
     389              : !! OUTPUT
     390              : !!  Only writing.
     391              : !!
     392              : !! SOURCE
     393              : 
     394            0 : subroutine pawrad_print(Rmesh,header,unit,prtvol,mode_paral)
     395              : 
     396              : !Arguments ------------------------------------
     397              :  integer,intent(in),optional :: prtvol,unit
     398              :  character(len=4),intent(in),optional :: mode_paral
     399              :  character(len=*),intent(in),optional :: header
     400              :  type(pawrad_type),intent(in) :: Rmesh
     401              : 
     402              : !Local variables-------------------------------
     403              : !scalars
     404              :  integer :: my_unt,my_prtvol
     405              :  character(len=4) :: my_mode
     406              :  character(len=500) :: msg
     407              : 
     408              : ! *************************************************************************
     409              : 
     410              :  !@pawrad_type
     411            0 :  my_unt   =std_out; if (PRESENT(unit      )) my_unt   =unit
     412            0 :  my_prtvol=0      ; if (PRESENT(prtvol    )) my_prtvol=prtvol
     413            0 :  my_mode  ='COLL' ; if (PRESENT(mode_paral)) my_mode  =mode_paral
     414              : 
     415            0 :  msg=ch10//' ==== Info on the Radial Mesh ==== '
     416            0 :  if (PRESENT(header)) msg=ch10//' ==== '//TRIM(ADJUSTL(header))//' ==== '
     417            0 :  call wrtout(my_unt,msg,my_mode)
     418              : 
     419            0 :  SELECT CASE (Rmesh%mesh_type)
     420              : 
     421              :  CASE (RMESH_LINEAR)
     422              :    write(msg,'(a,i4,a,g12.5)')&
     423            0 : &    ' - Linear mesh: r(i)=step*(i-1), size=',Rmesh%mesh_size,', step=',Rmesh%rstep
     424              : 
     425              :  CASE (RMESH_LOG1)
     426              :    write(msg,'(a,i4,2(a,g12.5))')&
     427            0 : &    ' - Logarithimc mesh: r(i)=AA*[exp(BB*(i-1))-1], size=',Rmesh%mesh_size,', AA=',Rmesh%rstep,' BB=',Rmesh%lstep
     428              : 
     429              :  CASE (RMESH_LOG2)
     430              :    write(msg,'(a,i4,2(a,g12.5))')&
     431            0 : &    ' - Logarithimc mesh: r(i)=AA*exp(BB*(i-2)), size=',Rmesh%mesh_size,', AA=',Rmesh%rstep,' BB=',Rmesh%lstep
     432              : 
     433              :  CASE (RMESH_LOG3)
     434              :    write(msg,'(a,i1,a,i4,a,g12.5)')&
     435            0 : &    ' - Logarithimc mesh: r(i)=-AA*ln(1-(i-1)/n), n=size=',Rmesh%mesh_size,', AA=',Rmesh%rstep
     436              : 
     437              :  CASE (RMESH_NL)
     438              :    write(msg,'(a,i1,a,i4,a,g12.5)')&
     439            0 : &    ' - Non-linear mesh: r(i)=-AA*i/(n-i), n=size=',Rmesh%mesh_size,', AA=',Rmesh%rstep
     440              : 
     441              :  CASE DEFAULT
     442            0 :    msg = ' Unknown mesh type! Action : check your pseudopotential or input file.'
     443            0 :    LIBPAW_ERROR(msg)
     444              :  END SELECT
     445              : 
     446            0 :  call wrtout(my_unt,msg,my_mode)
     447              : 
     448            0 :  if (my_prtvol>1) then
     449            0 :    write(msg,'(a,i4)')' Mesh size for integrals = ',Rmesh%int_meshsz
     450            0 :    call wrtout(my_unt,msg,my_mode)
     451            0 :    write(msg,'(a,g12.5)')' rmax=rad(mesh_size)     = ',Rmesh%rmax
     452            0 :    call wrtout(my_unt,msg,my_mode)
     453            0 :    write(msg,'(a,g12.5)')' Value of stepint        = ',Rmesh%stepint
     454            0 :    call wrtout(my_unt,msg,my_mode)
     455              :  end if
     456              : 
     457            0 : end subroutine pawrad_print
     458              : !!***
     459              : 
     460              : !----------------------------------------------------------------------
     461              : 
     462              : !!****f* m_pawrad/pawrad_isame
     463              : !! NAME
     464              : !!  pawrad_isame
     465              : !!
     466              : !! FUNCTION
     467              : !!  Check two radial meshes, returns a logical flag defining
     468              : !!  whether the meshes have the same equation and an integer
     469              : !!  flag
     470              : !!
     471              : !! INPUTS
     472              : !!  Rmesh1,Rmesh2<pawrad_type>=The two radial meshes.
     473              : !!
     474              : !! OUTPUT
     475              : !!  hasameq=.true. if the two meshes are defined by the same equation.
     476              : !!  whichdenser=
     477              : !!    * 0 if meshes are not compatible
     478              : !!    * 1 if Rmesh1 is denser than Rmesh2
     479              : !!    * 2 if Rmesh2 is denser than Rmesh1
     480              : !!
     481              : !! SOURCE
     482              : 
     483            2 : subroutine pawrad_isame(Rmesh1,Rmesh2,hasameq,whichdenser)
     484              : 
     485              : !Arguments ------------------------------------
     486              :  integer,intent(out) :: whichdenser
     487              :  logical,intent(out) :: hasameq
     488              :  type(pawrad_type),intent(in) :: Rmesh1
     489              :  type(pawrad_type),intent(in) :: Rmesh2
     490              : 
     491              : !Local variables-------------------------------
     492              :  character(len=50) :: msg
     493              : 
     494              : ! *************************************************************************
     495              : 
     496              :  !@pawrad_type
     497              : 
     498            2 :  whichdenser =0 ; hasameq=.FALSE.
     499              : 
     500            2 :  if (Rmesh1%mesh_type /= Rmesh2%mesh_type) RETURN
     501              : 
     502            0 :  SELECT CASE (Rmesh1%mesh_type)
     503              : 
     504              :  CASE (RMESH_LINEAR) !check for linear meshes
     505            0 :    hasameq = (Rmesh1%rstep == Rmesh2%rstep)
     506              : 
     507              :  CASE (RMESH_LOG1,&  !check for logarithmic meshes
     508              : &      RMESH_LOG2,&
     509              : &      RMESH_LOG3)
     510              : 
     511              :    hasameq = (    Rmesh1%rstep == Rmesh2%rstep &
     512            4 : &            .and.Rmesh1%lstep == Rmesh2%lstep )
     513              : 
     514              :  CASE (RMESH_NL) !check for linear meshes
     515            0 :    hasameq = (Rmesh1%rstep == Rmesh2%rstep)
     516              : 
     517              :  CASE DEFAULT
     518            0 :    msg='Unknown mesh type'
     519            2 :    LIBPAW_ERROR(msg)
     520              : 
     521              :  END SELECT
     522              : 
     523              :  ! === If meshes have same equation, check whether they are equal ===
     524              :  ! * Note that also int_meshsz must be equal
     525            2 :  if (hasameq) then
     526            0 :    whichdenser= 1
     527            0 :    if (Rmesh2%mesh_size  > Rmesh1%mesh_size ) whichdenser = 2
     528              :    !if (Rmesh1%int_meshsz == Rmesh2%int_meshsz) whichdenser = 2
     529              :  end if
     530              : 
     531              : end subroutine pawrad_isame
     532              : !!***
     533              : 
     534              : !----------------------------------------------------------------------
     535              : 
     536              : !!****f* m_pawrad/pawrad_copy
     537              : !! NAME
     538              : !! pawrad_copy
     539              : !!
     540              : !! FUNCTION
     541              : !! Copy one radial mesh (in a generalized format) to another
     542              : !!
     543              : !! INPUTS
     544              : !!  mesh1 <type(pawrad_type)>=data containing radial grid information of input mesh
     545              : !!
     546              : !! OUTPUT
     547              : !!  mesh2 <type(pawrad_type)>=data containing radial grid information of output mesh
     548              : !!
     549              : !! NOTES
     550              : !!  Possible mesh types (mesh%mesh_type)
     551              : !!   mesh_type=1 (regular grid): rad(i)=(i-1)*AA
     552              : !!   mesh_type=2 (logari. grid): rad(i)=AA*(exp[BB*(i-1)]-1)
     553              : !!   mesh_type=3 (logari. grid): rad(i>1)=AA*exp[BB*(i-2)] and rad(1)=0
     554              : !!   mesh_type=4 (logari. grid): rad(i)=-AA*ln[1-BB*(i-1)] with BB=1/n
     555              : !!   mesh_type=5 ( grid): rad(i)=AA*i/(n-i)
     556              : !!
     557              : !! SOURCE
     558              : 
     559         3350 : subroutine pawrad_copy(mesh1,mesh2)
     560              : 
     561              : !Arguments ------------------------------------
     562              : !scalars
     563              :  type(pawrad_type),intent(in) :: mesh1
     564              :  type(pawrad_type),intent(out) :: mesh2
     565              : 
     566              : !Local variables-------------------------------
     567              : !scalars
     568              :  integer :: ir
     569              : 
     570              : ! *************************************************************************
     571              : 
     572         3350 :  mesh2%mesh_type =mesh1%mesh_type
     573         3350 :  mesh2%mesh_size =mesh1%mesh_size
     574         3350 :  mesh2%int_meshsz=mesh1%int_meshsz
     575         3350 :  mesh2%lstep     =mesh1%lstep
     576         3350 :  mesh2%rstep     =mesh1%rstep
     577         3350 :  mesh2%stepint   =mesh1%stepint
     578         3350 :  mesh2%rmax      =mesh1%rmax
     579              : 
     580        10050 :  LIBPAW_ALLOCATE(mesh2%rad,(mesh1%mesh_size))
     581         6700 :  LIBPAW_ALLOCATE(mesh2%radfact,(mesh1%mesh_size))
     582         6700 :  LIBPAW_ALLOCATE(mesh2%simfact,(mesh1%mesh_size))
     583      3741489 :  do ir=1,mesh1%mesh_size
     584      3738139 :    mesh2%rad(ir)    =mesh1%rad(ir)
     585      3738139 :    mesh2%radfact(ir)=mesh1%radfact(ir)
     586      3741489 :    mesh2%simfact(ir)=mesh1%simfact(ir)
     587              :  end do
     588              : 
     589         3350 : end subroutine pawrad_copy
     590              : !!***
     591              : 
     592              : !----------------------------------------------------------------------
     593              : 
     594              : !!****f* m_pawrad/pawrad_deducer0
     595              : !! NAME
     596              : !! pawrad_deducer0
     597              : !!
     598              : !! FUNCTION
     599              : !! Extrapolate r=0 value of a function from values near r=0
     600              : !! using a 3 points formula
     601              : !!
     602              : !! INPUTS
     603              : !!  funcsz=size of array func
     604              : !!  radmesh <type(pawrad_type)>=data containing radial grid information
     605              : !!
     606              : !! SIDE EFFECTS
     607              : !!  func(funcsz)=array containing values of function to extrapolate
     608              : !!
     609              : !! SOURCE
     610              : 
     611     11374689 : subroutine pawrad_deducer0(func,funcsz,radmesh)
     612              : 
     613              : !Arguments ------------------------------------
     614              : !scalars
     615              :  integer,intent(in) :: funcsz
     616              :  type(pawrad_type),intent(in) :: radmesh
     617              : !arrays
     618              :  real(dp),intent(inout) :: func(funcsz)
     619              : 
     620              : ! *************************************************************************
     621              : 
     622     11374689 :  if (radmesh%mesh_type==1.or.radmesh%mesh_type==2.or.radmesh%mesh_type==4.or.radmesh%mesh_type==5) then
     623     11265318 :    func(1)=func(4)+3*(func(2)-func(3))
     624       109371 :  else if (radmesh%mesh_type==3) then
     625       109371 :    func(1)=func(4)+exp(two*radmesh%lstep)/(exp(radmesh%lstep)-one)*(func(2)-func(3))
     626              :  end if
     627              : 
     628     11374689 : end subroutine pawrad_deducer0
     629              : !!***
     630              : 
     631              : !----------------------------------------------------------------------
     632              : 
     633              : !!****f* m_pawrad/pawrad_bcast
     634              : !! NAME
     635              : !! pawrad_bcast
     636              : !!
     637              : !! FUNCTION
     638              : !! Communicate pawrad data over a given MPI communicator
     639              : !!
     640              : !! INPUTS
     641              : !! comm_mpi= communicator used to broadcast data
     642              : !!
     643              : !! SIDE EFFECTS
     644              : !!  pawrad=<type pawrad_type>= a radial mesh datastructure for PAW
     645              : !!
     646              : !! SOURCE
     647              : 
     648          276 : subroutine pawrad_bcast(pawrad,comm_mpi)
     649              : 
     650              : !Arguments ------------------------------------
     651              : !scalars
     652              :  integer,intent(in) :: comm_mpi
     653              :  type(pawrad_type),intent(inout) :: pawrad
     654              : 
     655              : !Local variables-------------------------------
     656              : !scalars
     657              :  integer :: ierr,indx,me,nn,isz1
     658              :  integer :: if_rad,if_radfact,if_simfact !flags used to communicate
     659              :  character(len=500) :: msg
     660              : !arrays
     661          276 :  integer,allocatable :: list_int(:)
     662          276 :  real(dp),allocatable :: list_dpr(:)
     663              : 
     664              : !*************************************************************************
     665              : 
     666          276 :  me=xmpi_comm_rank(comm_mpi)
     667              : 
     668              : !Initializations
     669          276 :  if_rad=0; if_radfact=0; if_simfact=0
     670              : 
     671              : !calculate the size of the reals
     672          276 :  if(me==0) then
     673           70 :    if (allocated(pawrad%rad)) then
     674           70 :      if_rad=1 !communicate rad
     675           70 :      isz1=size(pawrad%rad)
     676           70 :      if(isz1/=pawrad%mesh_size) then
     677            0 :        msg='rad: sz1 /= pawrad%mesh_size (1)'
     678            0 :        LIBPAW_BUG(msg)
     679              :      end if
     680              :    end if
     681           70 :    if (allocated(pawrad%radfact)) then
     682           70 :      if_radfact=1 !communicate radfact
     683           70 :      isz1=size(pawrad%radfact)
     684           70 :      if(isz1/=pawrad%mesh_size) then
     685            0 :        msg='radfact: sz1 /= pawrad%mesh_size (2)'
     686            0 :        LIBPAW_BUG(msg)
     687              :      end if
     688              :    end if
     689           70 :    if (allocated(pawrad%simfact)) then
     690           70 :      if_simfact=1 !communicate simfact
     691           70 :      isz1=size(pawrad%simfact)
     692           70 :      if(isz1/=pawrad%mesh_size) then
     693            0 :        msg='simfact: sz1 /= pawrad%mesh_size (3)'
     694            0 :        LIBPAW_BUG(msg)
     695              :      end if
     696              :    end if
     697              :  end if
     698              : 
     699              : !Brodcast the integers
     700          276 :  LIBPAW_ALLOCATE(list_int,(6))
     701          276 :  if(me==0) then
     702           70 :    list_int(1)=pawrad%int_meshsz
     703           70 :    list_int(2)=pawrad%mesh_size
     704           70 :    list_int(3)=pawrad%mesh_type
     705           70 :    list_int(4)=if_rad
     706           70 :    list_int(5)=if_radfact
     707           70 :    list_int(6)=if_simfact
     708              :  end if
     709          276 :  call xmpi_bcast(list_int,0,comm_mpi,ierr)
     710          276 :  if(me/=0) then
     711          206 :    pawrad%int_meshsz =list_int(1)
     712          206 :    pawrad%mesh_size =list_int(2)
     713          206 :    pawrad%mesh_type =list_int(3)
     714          206 :    if_rad=list_int(4)
     715          206 :    if_radfact=list_int(5)
     716          206 :    if_simfact=list_int(6)
     717              :  end if
     718          276 :  LIBPAW_DEALLOCATE(list_int)
     719              : 
     720              : !Broadcast the reals
     721          276 :  nn=4+pawrad%mesh_size*(if_rad+if_radfact+if_simfact)
     722          828 :  LIBPAW_ALLOCATE(list_dpr,(nn))
     723          276 :  if(me==0) then
     724           70 :    list_dpr(1)=pawrad%lstep
     725           70 :    list_dpr(2)=pawrad%rmax
     726           70 :    list_dpr(3)=pawrad%rstep
     727           70 :    list_dpr(4)=pawrad%stepint
     728           70 :    indx=5
     729           70 :    if (if_rad==1) then
     730           70 :      isz1=pawrad%mesh_size
     731        79770 :      list_dpr(indx:indx+isz1-1)=pawrad%rad(1:isz1)
     732           70 :      indx=indx+isz1
     733              :    end if
     734           70 :    if (if_radfact==1) then
     735           70 :      isz1=pawrad%mesh_size
     736        79770 :      list_dpr(indx:indx+isz1-1)=pawrad%radfact(1:isz1)
     737              :      indx=indx+isz1
     738              :    end if
     739           70 :    if (if_simfact==1) then
     740           70 :      isz1=pawrad%mesh_size
     741        79770 :      list_dpr(indx:indx+isz1-1)=pawrad%simfact(1:isz1)
     742          276 :      indx=indx+isz1
     743              :    end if
     744              :  end if
     745          276 :  call xmpi_bcast(list_dpr,0,comm_mpi,ierr)
     746          276 :  if(me/=0) then
     747          206 :    pawrad%lstep=list_dpr(1)
     748          206 :    pawrad%rmax=list_dpr(2)
     749          206 :    pawrad%rstep=list_dpr(3)
     750          206 :    pawrad%stepint=list_dpr(4)
     751          206 :    indx=5
     752              : !  Deallocate all arrays:
     753          206 :    if (allocated(pawrad%rad)) then
     754           21 :      LIBPAW_DEALLOCATE(pawrad%rad)
     755              :    end if
     756          206 :    if (allocated(pawrad%radfact)) then
     757           21 :      LIBPAW_DEALLOCATE(pawrad%radfact)
     758              :    end if
     759          206 :    if (allocated(pawrad%simfact)) then
     760           21 :      LIBPAW_DEALLOCATE(pawrad%simfact)
     761              :    end if
     762              : !  Communicate if flag is set to 1:
     763          206 :    if(if_rad==1) then
     764          206 :      isz1=pawrad%mesh_size
     765          618 :      LIBPAW_ALLOCATE(pawrad%rad,(isz1))
     766       243438 :      pawrad%rad(1:isz1)=list_dpr(indx:indx+isz1-1)
     767          206 :      indx=indx+isz1
     768              :    end if
     769          206 :    if(if_radfact==1) then
     770          206 :      isz1=pawrad%mesh_size
     771          618 :      LIBPAW_ALLOCATE(pawrad%radfact,(isz1))
     772       243438 :      pawrad%radfact(1:isz1)=list_dpr(indx:indx+isz1-1)
     773              :      indx=indx+isz1
     774              :    end if
     775          206 :    if(if_simfact==1) then
     776          206 :      isz1=pawrad%mesh_size
     777          618 :      LIBPAW_ALLOCATE(pawrad%simfact,(isz1))
     778       243438 :      pawrad%simfact(1:isz1)=list_dpr(indx:indx+isz1-1)
     779          276 :      indx=indx+isz1
     780              :    end if
     781              :  end if
     782          276 :  LIBPAW_DEALLOCATE(list_dpr)
     783              : 
     784          276 : end subroutine pawrad_bcast
     785              : !!***
     786              : 
     787              : !----------------------------------------------------------------------
     788              : 
     789              : !!****f* m_pawrad/simp_gen
     790              : !! NAME
     791              : !! simp_gen
     792              : !!
     793              : !! FUNCTION
     794              : !! Do integral on a given (generalized) grid using Simpson rule
     795              : !!
     796              : !! INPUTS
     797              : !!  radmesh <type(pawrad_type)>=data containing radial grid information
     798              : !!  func(:)=integrand values
     799              : !!  r_for_intg=upper boundary for (future) integration over the radial grid
     800              : !!            (can be negative for an integration over the whole grid)
     801              : !!
     802              : !! OUTPUT
     803              : !!  intg=resulting integral by Simpson rule
     804              : !!
     805              : !! NOTES
     806              : !!  Possible mesh types (radmesh%mesh_type)
     807              : !!   mesh_type=1 (regular grid): rad(i)=(i-1)*AA
     808              : !!   mesh_type=2 (logari. grid): rad(i)=AA*(exp[BB*(i-1)]-1)
     809              : !!   mesh_type=3 (logari. grid): rad(i>1)=AA*exp[BB*(i-2)] and rad(1)=0
     810              : !!   mesh_type=4 (logari. grid): rad(i)=-AA*ln[1-BB*(i-1)] with BB=1/n
     811              : !!   mesh_type=5 ( grid): rad(i)=AA*i/(n-i)
     812              : !!
     813              : !! SOURCE
     814              : 
     815     89191545 : subroutine simp_gen(intg,func,radmesh,r_for_intg)
     816              : 
     817              : #if defined HAVE_AVX_SAFE_MODE
     818              : !DEC$ NOOPTIMIZE
     819              : #endif
     820              : 
     821              : !Arguments ------------------------------------
     822              : !scalars
     823              :  real(dp),intent(out) :: intg
     824              :  real(dp),intent(in),optional :: r_for_intg
     825              :  type(pawrad_type),intent(in) :: radmesh
     826              : !arrays
     827              :  real(dp),intent(in) :: func(:)
     828              : 
     829              : !Local variables-------------------------------
     830              : !scalars
     831              :  integer :: ii,int_meshsz,ir,ir_last,isim,nn
     832              :  real(dp) :: hh,resid,simp
     833     89191545 :  real(dp),allocatable :: simfact(:)
     834              :  character(len=500) :: msg
     835              : 
     836              : ! *************************************************************************
     837              : 
     838     89191545 :  if (present(r_for_intg)) then
     839         3275 :    if (r_for_intg>0.d0) then
     840         3275 :      ir=min(pawrad_ifromr(radmesh,r_for_intg),radmesh%mesh_size)
     841         3275 :      if (ir<radmesh%mesh_size) then
     842         2650 :        if (abs(radmesh%rad(ir+1)-r_for_intg)<abs(radmesh%rad(ir)-r_for_intg)) ir=ir+1
     843              :      end if
     844         3275 :      if (ir>1) then
     845         3275 :        if (abs(radmesh%rad(ir-1)-r_for_intg)<abs(radmesh%rad(ir)-r_for_intg)) ir=ir-1
     846              :      end if
     847         3275 :      int_meshsz=ir
     848              :    else
     849            0 :      int_meshsz=radmesh%mesh_size
     850              :    end if
     851         3275 :    if (int_meshsz>radmesh%mesh_size.or.int_meshsz>size(func)) then
     852            0 :      write(msg,'(3(a,i4))')"int_meshsz= ",int_meshsz," > mesh_size=",radmesh%mesh_size,&
     853            0 : &                          ", size(func)=",size(func)
     854            0 :      LIBPAW_BUG(msg)
     855              :    end if
     856         3275 :    isim=3; if (radmesh%mesh_type==3)isim=4
     857         9825 :    LIBPAW_ALLOCATE(simfact,(radmesh%mesh_size))
     858         3275 :    hh=radmesh%stepint/3.d0
     859         3275 :    simfact(int_meshsz)=hh*radmesh%radfact(int_meshsz)
     860         6743 :    simfact(1:isim-2)=zero
     861         3275 :    ir_last=1
     862         3275 :    do ir=int_meshsz,isim,-2
     863      1537138 :      simfact(ir-1)=4.d0*hh*radmesh%radfact(ir-1)
     864      1537138 :      simfact(ir-2)=2.d0*hh*radmesh%radfact(ir-2)
     865      1537138 :      ir_last=ir-2
     866              :    end do
     867         3275 :    simfact(ir_last)=half*simfact(ir_last)
     868       998441 :    if (int_meshsz<radmesh%mesh_size) simfact(int_meshsz+1:radmesh%mesh_size)=zero
     869              : 
     870         3275 :    nn=int_meshsz
     871         3275 :    simp=zero
     872      3082713 :    do ii=1,nn
     873      3082713 :      simp=simp+func(ii)*simfact(ii)
     874              :    end do
     875         3275 :    LIBPAW_DEALLOCATE(simfact)
     876              : 
     877              :  else
     878     89188270 :    if (radmesh%int_meshsz>size(func)) then
     879            0 :      write(msg,'(2(a,i4))')"int_meshsz= ",int_meshsz," > size(func)=",size(func)
     880            0 :      LIBPAW_BUG(msg)
     881              :    end if
     882     89188270 :    nn=radmesh%int_meshsz
     883     89188270 :    simp=zero
     884  >10995*10^7 :    do ii=1,nn
     885  >10995*10^7 :      simp=simp+func(ii)*radmesh%simfact(ii)
     886              :    end do
     887              :  end if
     888              : 
     889     89191545 :  resid=zero
     890     89191545 :  if (radmesh%mesh_type==3) then
     891      1302684 :    resid=half*(func(2)+func(1))*(radmesh%rad(2)-radmesh%rad(1))
     892      1302684 :    if (mod(nn,2)==1) resid=resid+radmesh%stepint/3.d0*(1.25d0*func(2)*radmesh%radfact(2) &
     893        99204 : &   +2.d0*func(3)*radmesh%radfact(3)-0.25d0*func(4)*radmesh%radfact(4))
     894     87888861 :  else if (mod(nn,2)==0) then
     895              :    resid=radmesh%stepint/3.d0*(1.25d0*func(1)*radmesh%radfact(1)+2.d0*func(2)*radmesh%radfact(2) &
     896     51853799 : &   -0.25d0*func(3)*radmesh%radfact(3))
     897              :  end if
     898              : 
     899     89191545 :  intg=simp+resid
     900              : 
     901     89191545 : end subroutine simp_gen
     902              : !!***
     903              : 
     904              : !----------------------------------------------------------------------
     905              : 
     906              : !!****f* m_pawrad/nderiv_gen
     907              : !! NAME
     908              : !! nderiv_gen
     909              : !!
     910              : !! FUNCTION
     911              : !! Do corrected first (and -if requested- second) derivation on a given (generalized) grid.
     912              : !! This routine interfaces nderiv_lin (derivation on a linear grid).
     913              : !!
     914              : !! INPUTS
     915              : !!  func(:)=input function
     916              : !!  radmesh <type(pawrad_type)>=data containing radial grid information
     917              : !!
     918              : !! OUTPUT
     919              : !!  der(:)= 1st derivative of input function
     920              : !!  [der2(:)]= -- optional -- 2nd derivative of input function
     921              : !!
     922              : !! NOTES
     923              : !!  Possible mesh types (radmesh%mesh_type)
     924              : !!   mesh_type=1 (regular grid): rad(i)=(i-1)*AA
     925              : !!   mesh_type=2 (logari. grid): rad(i)=AA*(exp[BB*(i-1)]-1)
     926              : !!   mesh_type=3 (logari. grid): rad(i>1)=AA*exp[BB*(i-2)] and rad(1)=0
     927              : !!   mesh_type=4 (logari. grid): rad(i)=-AA*ln[1-BB*(i-1)] with BB=1/n
     928              : !!
     929              : !! SOURCE
     930              : 
     931      7645232 : subroutine nderiv_gen(der,func,radmesh,der2)
     932              : 
     933              : !Arguments ------------------------------------
     934              : !scalars
     935              :  type(pawrad_type),intent(in) :: radmesh
     936              : !arrays
     937              :  real(dp),intent(in) :: func(:)
     938              :  real(dp),intent(out) :: der(:)
     939              :  real(dp),optional,intent(out) :: der2(:)
     940              : 
     941              : !Local variables-------------------------------
     942              : !scalars
     943              :  integer :: msz
     944              :  logical :: compute_2der
     945              :  character(len=500) :: msg
     946              : 
     947              : ! *************************************************************************
     948              : 
     949      7645232 :  msz=size(func)
     950      7645232 :  if (size(der)/=msz.or.msz>radmesh%mesh_size) then
     951            0 :    msg='wrong sizes for in/out arrays!'
     952            0 :    LIBPAW_BUG(msg)
     953              :  end if
     954              : 
     955      7645232 :  compute_2der=(present(der2))
     956              : 
     957      7645232 :  if (radmesh%mesh_type==1) then
     958              : 
     959          138 :    call nderiv_lin(radmesh%rstep,func,der,msz,1)
     960          138 :    if (compute_2der) then
     961            0 :      call nderiv_lin(radmesh%rstep,func,der2,msz,2)
     962              :    end if
     963              : 
     964              :  else if (radmesh%mesh_type==2) then
     965              : 
     966      7644958 :    call nderiv_lin(radmesh%lstep,func,der,msz,1)
     967   9622438658 :    der(1:msz)=der(1:msz)/radmesh%radfact(1:msz)
     968      7644958 :    if (compute_2der)then
     969            0 :      call nderiv_lin(radmesh%lstep,func,der2,msz,2)
     970            0 :      der2(1:msz)=(der2(1:msz)/radmesh%radfact(1:msz)-der(1:msz))/radmesh%radfact(1:msz)
     971              :    end if
     972              : 
     973              :  else if (radmesh%mesh_type==3) then
     974              : 
     975          136 :    call nderiv_lin(radmesh%lstep,func(2:msz),der(2:msz),msz-1,1)
     976        47600 :    der(2:msz)=der(2:msz)/radmesh%radfact(2:msz)
     977          136 :    call pawrad_deducer0(der,msz,radmesh)
     978          136 :    if (compute_2der)then
     979            0 :      call nderiv_lin(radmesh%lstep,func(2:msz),der2(2:msz),msz-1,2)
     980            0 :      der2(2:msz)=(der2(2:msz)/radmesh%radfact(2:msz)-der(2:msz))/radmesh%radfact(2:msz)
     981            0 :      call pawrad_deducer0(der2,msz,radmesh)
     982              :    end if
     983              : 
     984              :  else if (radmesh%mesh_type==4) then
     985              : 
     986            0 :    call nderiv_lin(radmesh%lstep,func,der,msz,1)
     987            0 :    der(1:msz)=der(1:msz)/radmesh%radfact(1:msz)
     988            0 :    if (compute_2der)then
     989            0 :      call nderiv_lin(radmesh%lstep,func,der2,msz,2)
     990            0 :      der2(1:msz)=der2(1:msz)/radmesh%radfact(1:msz)**2-der(1:msz)/radmesh%rstep
     991              :    end if
     992              : 
     993              :  else if (radmesh%mesh_type==5) then
     994              : 
     995            0 :    call nderiv_lin(one,func,der,msz,1)
     996            0 :    der(1:msz)=der(1:msz)/(radmesh%radfact(1:msz)*radmesh%rstep)
     997            0 :    if (compute_2der)then
     998            0 :      call nderiv_lin(one,func,der2,msz,2)
     999              :      der2(1:msz)=der2(1:msz)/(radmesh%radfact(1:msz)*radmesh%rstep)**2-two*der(1:msz)/&
    1000            0 : &                            (radmesh%rstep+radmesh%rad(1:msz))
    1001              :    end if
    1002              :  end if
    1003              : 
    1004      7645232 : end subroutine nderiv_gen
    1005              : !!***
    1006              : 
    1007              : !----------------------------------------------------------------------
    1008              : 
    1009              : !!****f* m_pawrad/nderiv_lin
    1010              : !! NAME
    1011              : !! nderiv_lin
    1012              : !!
    1013              : !! FUNCTION
    1014              : !! Do corrected first (and -if requested- second) derivation on a given LINEAR grid.
    1015              : !!
    1016              : !! INPUTS
    1017              : !!  hh= radial step
    1018              : !!  ndim= radial mesh size
    1019              : !!  yy(ndim)= input function
    1020              : !!  norder= order of derivation (1 or 2)
    1021              : !!
    1022              : !! OUTPUT
    1023              : !!  zz(ndim)= first or second derivative of y
    1024              : !!
    1025              : !! SOURCE
    1026              : 
    1027      7645232 : subroutine nderiv_lin(hh,yy,zz,ndim,norder)
    1028              : 
    1029              : !Arguments ---------------------------------------------
    1030              : !scalars
    1031              :  integer,intent(in) :: ndim,norder
    1032              :  real(dp),intent(in) :: hh
    1033              : !arrays
    1034              :  real(dp),intent(in) :: yy(ndim)
    1035              :  real(dp),intent(out) :: zz(ndim)
    1036              : 
    1037              : !Local variables ---------------------------------------
    1038              : !scalars
    1039              :  integer :: ier,ii
    1040              :  real(dp) :: aa,bb,cc,h1,y1
    1041              : 
    1042              : ! *************************************************************************
    1043              : 
    1044              : !Initialization (common to 1st and 2nd derivative)
    1045      7645232 :  h1=one/(12.d0*hh)
    1046      7645232 :  y1=yy(ndim-4)
    1047              : 
    1048              : !FIRST DERIVATIVE
    1049              : !================
    1050      7645232 :  if (norder==1) then
    1051              : 
    1052              : !  Prepare differentiation loop
    1053      7645232 :    bb=h1*(-25.d0*yy(1)+48.d0*yy(2)-36.d0*yy(3)+16.d0*yy(4)-3.d0*yy(5))
    1054      7645232 :    cc=h1*(-3.d0*yy(1)-10.d0*yy(2)+18.d0*yy(3)-6.d0*yy(4)+yy(5))
    1055              : !  Start differentiation loop
    1056   9591973696 :    do ii=5,ndim
    1057   9584328464 :      aa=bb;bb=cc
    1058   9584328464 :      cc=h1*(yy(ii-4)-yy(ii)+8.d0*(yy(ii-1)-yy(ii-3)))
    1059   9591973696 :      zz(ii-4)=aa
    1060              :    end do
    1061              : !  Normal exit
    1062      7645232 :    ier=0
    1063      7645232 :    aa=h1*(-y1+6.d0*yy(ndim-3)-18.d0*yy(ndim-2)+10.d0*yy(ndim-1)+3.d0*yy(ndim))
    1064      7645232 :    zz(ndim)=h1*(3.d0*y1-16.d0*yy(ndim-3)+36.d0*yy(ndim-2) -48.d0*yy(ndim-1)+25.d0*yy(ndim))
    1065      7645232 :    zz(ndim-1)=aa
    1066      7645232 :    zz(ndim-2)=cc
    1067      7645232 :    zz(ndim-3)=bb
    1068              : 
    1069              : !  SECOND DERIVATIVE
    1070              : !  =================
    1071              :  else
    1072            0 :    h1=h1/hh
    1073              : !  Prepare differentiation loop
    1074            0 :    bb=h1*(35.d0*yy(1)-104.d0*yy(2)+114.d0*yy(3)-56.d0*yy(4)+11.d0*yy(5))
    1075            0 :    cc=h1*(11.d0*yy(1)-20.d0*yy(2)+6.d0*yy(3)+4.d0*yy(4)-yy(5))
    1076              : !  Start differentiation loop
    1077            0 :    do ii=5,ndim
    1078            0 :      aa=bb;bb=cc
    1079            0 :      cc=h1*(-yy(ii-4)-yy(ii)+16.d0*(yy(ii-1)+yy(ii-3))-30.d0*yy(ii-2))
    1080            0 :      zz(ii-4)=aa
    1081              :    end do
    1082              : !  Normal exit
    1083            0 :    ier=0
    1084            0 :    aa=h1*(-y1+4.d0*yy(ndim-3)+6.d0*yy(ndim-2)-20.d0*yy(ndim-1)+11.d0*yy(ndim))
    1085            0 :    zz(ndim)=h1*(11.d0*y1-56.d0*yy(ndim-3)+114.d0*yy(ndim-2) -104.d0*yy(ndim-1)+35.d0*yy(ndim))
    1086            0 :    zz(ndim-1)=aa
    1087            0 :    zz(ndim-2)=cc
    1088            0 :    zz(ndim-3)=bb
    1089              : 
    1090              :  end if !norder
    1091              : 
    1092      7645232 : end subroutine nderiv_lin
    1093              : !!***
    1094              : 
    1095              : !----------------------------------------------------------------------
    1096              : 
    1097              : !!****f* m_pawrad/bound_deriv
    1098              : !! NAME
    1099              : !! bound_deriv
    1100              : !!
    1101              : !! FUNCTION
    1102              : !! Computes derivatives of a function a boundaries of interval (first and last derivative)
    1103              : !!
    1104              : !! INPUTS
    1105              : !!  func(n)= array containing function
    1106              : !!  mesh <type(pawrad_type)>= radial mesh and related data
    1107              : !!  nn= size of intervall
    1108              : !!
    1109              : !! OUTPUT
    1110              : !!  yp1,ypn= derivatives of func at r(1) and r(n)
    1111              : !!
    1112              : !! SOURCE
    1113              : 
    1114          104 :  subroutine bound_deriv(func,mesh,nn,yp1,ypn)
    1115              : 
    1116              : !Arguments----------------------
    1117              :  integer, intent(in) :: nn
    1118              :  real(dp), intent(in) :: func(nn)
    1119              :  real(dp), intent(out) :: yp1,ypn
    1120              :  type(pawrad_type),intent(in) :: mesh
    1121              : 
    1122              : !*************************************************************************
    1123              : 
    1124          104 :  if (mesh%radfact(1)>zero) then
    1125              :    yp1=1._dp/12._dp/mesh%stepint/mesh%radfact(1) &
    1126          104 : &   *(-25._dp*func(1)+48._dp*func(2)-36._dp*func(3)+16._dp*func(4)-3._dp*func(5))
    1127              :  else
    1128            0 :    yp1=(func(2)-func(1))/(mesh%rad(2)-mesh%rad(1))
    1129              :  end if
    1130              :  ypn=1._dp/12._dp/mesh%stepint &
    1131              : & *( 3._dp*func(nn-4)-16._dp*func(nn-3)+36._dp*func(nn-2)-48._dp*func(nn-1) &
    1132          104 : & +25._dp*func(nn))/mesh%radfact(nn)
    1133              : 
    1134          104 : end subroutine bound_deriv
    1135              : 
    1136              : !!***
    1137              : 
    1138              : !----------------------------------------------------------------------
    1139              : 
    1140              : !!****f* m_pawrad/poisson
    1141              : !! NAME
    1142              : !! poisson
    1143              : !!
    1144              : !! FUNCTION
    1145              : !!  Solve poisson equation for angularly dependent charge
    1146              : !!  distribution of angular momentum l
    1147              : !!  Densities and potentials are given on a (generalized) radial grid
    1148              : !!
    1149              : !! INPUTS
    1150              : !!  den(:)= electron density * (4*pi*r**2) appropriate for l
    1151              : !!  ll= l quantum number
    1152              : !!  radmesh <type(pawrad_type)>=data containing radial grid information
    1153              : !!  [screened_sr_separation]= --optional-- separation for screened short-range kernel
    1154              : !!                            no screening by default
    1155              : !!
    1156              : !! OUTPUT
    1157              : !!  [qq]= --optional-- lth moment of the charge; not compatible with screened Coulomb interaction
    1158              : !!  rv(:)= electrostatic potential * r in (Hartree*Bohr) units
    1159              : !!          where v(r)=\frac{1}{2l+1}(\frac{int[(r''^(l+2))g(r'')dr'']} {r^(l+1)}
    1160              : !!                                   +(r^l) int[r''^(1-l)g(r'')dr''])
    1161              : !!
    1162              : !! SOURCE
    1163              : 
    1164       296755 : subroutine poisson(den,ll,radmesh,rv,screened_sr_separation,qq)
    1165              : 
    1166              : !Arguments ---------------------------------------------
    1167              : !scalars
    1168              :  integer,intent(in) :: ll
    1169              :  real(dp),intent(out),optional :: qq
    1170              :  real(dp),intent(in),optional :: screened_sr_separation
    1171              :  type(pawrad_type),intent(in) :: radmesh
    1172              : !arrays
    1173              :  real(dp),intent(in) :: den(:)
    1174              :  real(dp),intent(out) :: rv(:)
    1175              : 
    1176              : !Local variables ---------------------------------------
    1177              : !scalars
    1178              :  integer :: ir,jr,mesh_size,mm,nn
    1179              :  logical :: use_numerov,use_screened
    1180              :  real(dp) :: angm,hh,intg,qq_,ri,rj,rr,sr_omega
    1181              : !arrays
    1182              :  real(dp) :: ee(4)
    1183       296755 :  real(dp),allocatable :: aa(:),bb(:),cc(:),dd(:),radl(:),radl1(:)
    1184              : 
    1185              : ! ***************************************************************************
    1186              : 
    1187       296755 :  mesh_size=size(den)
    1188       296755 :  if (size(rv)/=mesh_size.or.mesh_size>radmesh%mesh_size) then
    1189            0 :    LIBPAW_BUG('wrong sizes!')
    1190              :  end if
    1191              : 
    1192       296755 :  use_numerov=(radmesh%mesh_type==1)
    1193              : 
    1194       296755 :  use_screened=.false.;sr_omega=zero
    1195       296755 :  if (present(screened_sr_separation)) then
    1196          358 :    sr_omega=screened_sr_separation
    1197          358 :    use_screened=(sr_omega>tol8)
    1198              : !  Numerov method not coded for screened Coulomb interaction
    1199          358 :    if (use_numerov.and.use_screened) use_numerov=.false.
    1200              :  end if
    1201              : 
    1202              : !==============================================
    1203              : !UNIFORM GRID - NUMEROV ALGORITHM
    1204              : !==============================================
    1205       296755 :  if (use_numerov) then
    1206         7449 :    hh=radmesh%rstep
    1207         7449 :    nn=radmesh%int_meshsz-1
    1208        22347 :    LIBPAW_ALLOCATE(aa,(nn))
    1209        14898 :    LIBPAW_ALLOCATE(bb,(nn))
    1210        29796 :    LIBPAW_ALLOCATE(cc,(nn+1))
    1211      5207879 :    do ir=1,nn
    1212      5200430 :      aa(ir)=two*hh*den(ir+1)/(ir)
    1213      5207879 :      bb(ir)=den(ir+1)*((ir*hh)**ll)
    1214              :    end do
    1215         7449 :    cc(1)=zero
    1216      5207879 :    cc(2:nn+1)=bb(1:nn)
    1217         7449 :    call simp_gen(qq_,cc,radmesh)
    1218         7449 :    qq_=qq_/dble(2*ll+1)
    1219         7449 :    rv(1)=aa(1)+0.1_dp*aa(2)
    1220      5192981 :    do ir=2,nn-1
    1221      5192981 :      rv(ir)=aa(ir)+0.1_dp*(aa(ir+1)+aa(ir-1))
    1222              :    end do
    1223         7449 :    rv(nn)=aa(nn)+0.1_dp*aa(nn-1)
    1224         7449 :    angm=dble(ll*(ll+1))
    1225         7449 :    rr=(nn+1)*hh
    1226         7449 :    rv(nn)=rv(nn)+(2.4_dp-0.2_dp*angm/((nn+1)**2))*qq_/(rr**ll)
    1227      5207879 :    do ir=1,nn
    1228      5200430 :      aa(ir)=angm/(ir*ir)
    1229      5207879 :      bb(ir)=2.4_dp+aa(ir)
    1230              :    end do
    1231      5200430 :    do ir=1,nn-1
    1232      5200430 :      cc(ir)=-1.2_dp+0.1_dp*aa(ir+1)
    1233              :    end do
    1234      5200430 :    do ir=nn,2,-1
    1235      5200430 :      aa(ir)=-1.2_dp+0.1_dp*aa(ir-1)
    1236              :    end do
    1237         7449 :    if (nn.eq.1) then
    1238            0 :      rv(2)=rv(1)/bb(1)
    1239            0 :      rv(1)=zero
    1240              :    else
    1241      5200430 :      do ir=2,nn
    1242      5200430 :        bb(ir)=bb(ir)-aa(ir)*cc(ir-1)/bb(ir-1)
    1243              :      end do
    1244         7449 :      rv(1)=rv(1)/bb(1)
    1245      5200430 :      do ir=2,nn
    1246      5200430 :        rv(ir)=(rv(ir)-aa(ir)*rv(ir-1))/bb(ir)
    1247              :      end do
    1248      5200430 :      do ir=nn-1,1,-1
    1249      5200430 :        rv(ir)=rv(ir)-cc(ir)*rv(ir+1)/bb(ir)
    1250              :      end do
    1251      5207879 :      do ir=nn+1,2,-1
    1252      5207879 :        rv(ir)=rv(ir-1)
    1253              :      end do
    1254         7449 :      rv(1)=zero
    1255        44544 :      if (nn+1<mesh_size) rv(nn+2:mesh_size)=zero
    1256              :    end if
    1257      5252423 :    rv(:)=half*rv(:)
    1258         7449 :    if (present(qq)) qq=qq_
    1259         7449 :    LIBPAW_DEALLOCATE(aa)
    1260         7449 :    LIBPAW_DEALLOCATE(bb)
    1261        14898 :    LIBPAW_DEALLOCATE(cc)
    1262              : 
    1263              : !  ==============================================
    1264              : !  ANY OTHER GRID - SIMPSON ALGORITHM
    1265              : !  ==============================================
    1266              :  else
    1267       289306 :    nn=mesh_size;hh=third*radmesh%stepint
    1268      1477793 :    do while (abs(den(nn))<tol16.and.nn>radmesh%int_meshsz)
    1269      1192746 :      nn=nn-1
    1270              :    end do
    1271       289306 :    mm=nn;if (radmesh%mesh_type==3) mm=mm-1
    1272       867918 :    LIBPAW_ALLOCATE(aa,(nn))
    1273       578612 :    LIBPAW_ALLOCATE(bb,(nn))
    1274       578612 :    LIBPAW_ALLOCATE(cc,(nn))
    1275       578612 :    LIBPAW_ALLOCATE(dd,(nn))
    1276              : 
    1277       289306 :    if (.not.use_screened) then
    1278              : 
    1279              : !    Standard Coulomb integral
    1280       577896 :      LIBPAW_ALLOCATE(radl,(nn))
    1281       577896 :      LIBPAW_ALLOCATE(radl1,(nn))
    1282    278857225 :      do jr=nn,2,-1
    1283    278568277 :        ir=nn-jr+1
    1284    278568277 :        radl(jr) =radmesh%rad(jr)**ll
    1285    278568277 :        radl1(jr)=radmesh%rad(jr)*radl(jr)
    1286    278568277 :        aa(ir)=den(jr)*radmesh%radfact(jr)*radl(jr)
    1287    278857225 :        bb(ir)=den(jr)*radmesh%radfact(jr)/radl1(jr)
    1288              :      end do
    1289       288948 :      radl(1)=zero;radl1(1)=zero
    1290       288948 :      ee(2)=aa(nn-1);ee(3)=aa(nn-2);ee(4)=aa(nn-3)
    1291       288948 :      call pawrad_deducer0(ee,4,radmesh)
    1292       288948 :      aa(nn)=ee(1)
    1293       288948 :      ee(2)=bb(nn-1);ee(3)=bb(nn-2);ee(4)=bb(nn-3)
    1294       288948 :      call pawrad_deducer0(ee,4,radmesh)
    1295       288948 :      bb(nn)=ee(1)
    1296       288948 :      cc(1)=zero;dd(1)=zero
    1297       288948 :      do ir=3,mm,2
    1298    139194772 :        cc(ir)  =cc(ir-2)+hh*(aa(ir-2)+four*aa(ir-1)+aa(ir))
    1299    139194772 :        cc(ir-1)=cc(ir-2)+hh*(1.25_dp*aa(ir-2)+two*aa(ir-1)-quarter*aa(ir))
    1300    139194772 :        dd(ir)  =dd(ir-2)+hh*(bb(ir-2)+four*bb(ir-1)+bb(ir))
    1301    139194772 :        dd(ir-1)=dd(ir-2)+hh*(1.25_dp*bb(ir-2)+two*bb(ir-1)-quarter*bb(ir))
    1302              :      end do
    1303       288948 :      if (mod(mm,2)==0) then
    1304              : !      cc(mm)=cc(mm-2)+hh*(aa(mm-2)+four*aa(mm-1)+aa(mm))
    1305              : !      dd(mm)=dd(mm-2)+hh*(bb(mm-2)+four*bb(mm-1)+bb(mm))
    1306       167704 :        cc(mm)=cc(mm-1)+hh*(1.25_dp*aa(mm-2)+two*aa(mm-1)-quarter*aa(mm))
    1307       167704 :        dd(mm)=dd(mm-1)+hh*(1.25_dp*bb(mm-2)+two*bb(mm-1)-quarter*bb(mm))
    1308              :      end if
    1309       288948 :      if (mm<nn) then
    1310        11029 :        cc(nn)=cc(mm)+half*(aa(mm)+aa(nn))*(radmesh%rad(1+nn-mm)-radmesh%rad(1))
    1311        11029 :        dd(nn)=dd(mm)+half*(bb(mm)+bb(nn))*(radmesh%rad(1+nn-mm)-radmesh%rad(1))
    1312              :      end if
    1313       288948 :      rv(1)=zero
    1314    278857225 :      do ir=2,nn
    1315    278568277 :        jr=nn-ir+1
    1316    278857225 :        rv(ir)=(dd(jr)*radl1(ir)+(cc(nn)-cc(jr))/radl(ir))/(two*ll+one)
    1317              :      end do
    1318      1475645 :      if (nn<mesh_size) rv(nn+1:mesh_size)=rv(nn)
    1319       288948 :      if (present(qq)) qq=cc(nn)/(two*ll+one)
    1320       288948 :      LIBPAW_DEALLOCATE(radl)
    1321       288948 :      LIBPAW_DEALLOCATE(radl1)
    1322              :    else
    1323              : 
    1324              : !    Short-range screened Coulomb integral
    1325          358 :      rv(1)=zero
    1326       278133 :      do ir=2,nn
    1327       277775 :        ri=sr_omega*radmesh%rad(ir)
    1328    264402876 :        do jr=2,nn
    1329    264125101 :          rj=sr_omega*radmesh%rad(jr)
    1330    264402876 :          aa(jr)=den(jr)*radmesh%radfact(jr)*sr_omega*screened_coul_kernel(ll,ri,rj)
    1331              :        end do
    1332       277775 :        call pawrad_deducer0(aa(1:4),4,radmesh)
    1333       277775 :        intg=zero
    1334              : !      Compute the integral in 2 parts because the function is not differentiable at r(ir)
    1335              : !      Integral from zero to r(ir)
    1336       277775 :        if (ir>2) then
    1337       277417 :          do jr=ir-2,1,-2
    1338     66031246 :            intg=intg+hh*(aa(jr)+four*aa(jr+1)+aa(jr+2))
    1339              :          end do
    1340       277417 :          if (mod(ir,2)==0) intg=intg+hh*(-quarter*aa(1)+two*aa(2)+1.25_dp*aa(3))
    1341              :        else if (ir==2) then
    1342          358 :         if (nn >2) intg=intg+hh*(+1.25_dp*aa(1)+two*aa(2)-quarter*aa(3))
    1343          358 :         if (nn==2) intg=intg+(aa(1)+aa(2))*hh*half
    1344              :        end if
    1345       277775 :        if (mm<nn) intg=intg+half*(aa(1+nn-mm)+aa(nn))*(radmesh%rad(1+nn-mm)-radmesh%rad(1))
    1346              : !      Integral from r(ir) to rmax
    1347       277775 :        if (ir<nn-2) then
    1348       276701 :          do jr=ir+2,nn,2
    1349     65892059 :            intg=intg+hh*(aa(jr-2)+four*aa(jr-1)+aa(jr))
    1350              :          end do
    1351       276701 :          if (mod(nn-ir,2)==1) then
    1352       138471 :            if (ir<=nn-4) then
    1353              :              !Use a high-order formula because points are spaced
    1354              :              intg=intg+hh*(251._dp*aa(nn)+646._dp*aa(nn-1)-264._dp*aa(nn-2) &
    1355       138113 : &                         +106._dp*aa(nn-3)-19._dp*aa(nn-4))/240._dp
    1356              :            else
    1357          358 :              intg=intg+hh*(1.25_dp*aa(nn)+two*aa(nn-1)-quarter*aa(nn-2))
    1358              :            endif
    1359              :          end if
    1360         1074 :        else if (ir==nn-1) then
    1361          358 :          intg=intg+(aa(nn-1)+aa(nn))*hh*half
    1362              :        end if
    1363       278133 :        rv(ir)=intg/(two*ll+one)*radmesh%rad(ir)
    1364              :      end do
    1365         2148 :      if (nn<mesh_size) rv(nn+1:mesh_size)=rv(nn)
    1366          358 :      if (present(qq)) qq=zero ! Not relevant
    1367              : 
    1368              :    end if
    1369       289306 :    LIBPAW_DEALLOCATE(aa)
    1370       289306 :    LIBPAW_DEALLOCATE(bb)
    1371       289306 :    LIBPAW_DEALLOCATE(cc)
    1372       289306 :    LIBPAW_DEALLOCATE(dd)
    1373              : 
    1374              :  end if
    1375              : 
    1376       296755 : end subroutine poisson
    1377              : !!***
    1378              : 
    1379              : !----------------------------------------------------------------------
    1380              : 
    1381              : !!****f* m_pawrad/pawrad_ifromr
    1382              : !! NAME
    1383              : !! pawrad_ifromr
    1384              : !!
    1385              : !! FUNCTION
    1386              : !! Retreive Index FROM a given R value in a radial grid
    1387              : !! Grid can be regular or logarithimc
    1388              : !!
    1389              : !! INPUTS
    1390              : !!  rr=given input r value
    1391              : !!  radmesh <type(pawrad_type)>=data containing radial grid information
    1392              : !!
    1393              : !! OUTPUT
    1394              : !!  pawrad_ifromr=index of rr in radial grid
    1395              : !!
    1396              : !! NOTES
    1397              : !!  Possible mesh types (radmesh%mesh_type)
    1398              : !!   mesh_type=1 (regular grid): rad(i)=(i-1)*AA
    1399              : !!   mesh_type=2 (logari. grid): rad(i)=AA*(exp[BB*(i-1)]-1)
    1400              : !!   mesh_type=3 (logari. grid): rad(i>1)=AA*exp[BB*(i-2)] and rad(1)=0
    1401              : !!   mesh_type=4 (logari. grid): rad(i)=-AA*ln[1-BB*(i-1)] with BB=1/n
    1402              : !!   mesh_type=5 ( grid): rad(i)=AA*i/(n-i)
    1403              : !!
    1404              : !! SOURCE
    1405              : 
    1406        11145 : function pawrad_ifromr(radmesh,rr)
    1407              : 
    1408              : !Arguments ------------------------------------
    1409              : !scalars
    1410              :  integer :: pawrad_ifromr
    1411              :  real(dp),intent(in) :: rr
    1412              :  type(pawrad_type),intent(in) :: radmesh
    1413              : 
    1414              : !Local variables-------------------------------
    1415              :  character(len=500) :: msg
    1416              : 
    1417              : ! *************************************************************************
    1418              : 
    1419        11145 :  if (radmesh%mesh_type==1) then
    1420          158 :    pawrad_ifromr=int(tol8+rr/radmesh%rstep)+1
    1421              :  else if (radmesh%mesh_type==2) then
    1422        10463 :    pawrad_ifromr=int(tol8+log(1.d0+rr/radmesh%rstep)/radmesh%lstep)+1
    1423              :  else if (radmesh%mesh_type==3) then
    1424          484 :    if (rr<radmesh%rstep) then
    1425              :      pawrad_ifromr=1
    1426              :    else
    1427          484 :      pawrad_ifromr=int(tol8+log(rr/radmesh%rstep)/radmesh%lstep)+2
    1428              :    end if
    1429              :  else if (radmesh%mesh_type==4) then
    1430            0 :    pawrad_ifromr=int(tol8+(1.d0-exp(-rr/radmesh%rstep))/radmesh%lstep)+1
    1431              :  else if (radmesh%mesh_type==5) then
    1432           40 :    pawrad_ifromr=int(tol8+(radmesh%lstep*rr)/(radmesh%rstep+rr))+1
    1433              :  else
    1434              : !  Other values of mesh_type are not allowed (see psp7in.F90)
    1435            0 :    write(msg,'(a,i0)')" Unknown value of %mesh_type ",radmesh%mesh_type
    1436            0 :    LIBPAW_ERROR(msg)
    1437              :  end if
    1438              : 
    1439        11145 : end function pawrad_ifromr
    1440              : !!***
    1441              : 
    1442              : !----------------------------------------------------------------------
    1443              : 
    1444              : !!****f* m_pawrad/screened_coul_kernel
    1445              : !! NAME
    1446              : !! screened_coul_kernel
    1447              : !!
    1448              : !! FUNCTION
    1449              : !!  Evaluates the kernel function used to compute the integral
    1450              : !!  of a screened Coulomb potential (with erfc function)
    1451              : !!  See Angyan, Gerber, Marsman, J. Phys. A: Math. Gen. 39, 8613 (2006) [[cite:Angyan2006]]
    1452              : !!
    1453              : !! INPUTS
    1454              : !!  [formula]=optional; used to force formula (1=full; 2=dev. near r2=0; 3=dev near r1*r2=0)
    1455              : !!  order= order of the function (typically l quantum number)
    1456              : !!  r1,r2=input arguments
    1457              : !!
    1458              : !! OUTPUT
    1459              : !!  screened_coul_kernel=output radial function
    1460              : !!
    1461              : !! SOURCE
    1462              : 
    1463    264125101 : function screened_coul_kernel(order,r1,r2,formula)
    1464              : 
    1465              : !Arguments ------------------------------------
    1466              : !scalars
    1467              :  integer,intent(in) :: order
    1468              :  integer,optional :: formula
    1469              :  real(dp),intent(in) :: r1,r2
    1470              :  real(dp) :: screened_coul_kernel
    1471              : !Local variables-------------------------------
    1472              :  integer :: formula_
    1473              :  real(dp) :: difexp,erfcp,erfcm,f0,f1,f2,f3,f4,f5,f6,hh,sqrtpi,sumexp,xx,xy,yy
    1474              :  character(len=100) :: msg
    1475              : 
    1476              : !******************************************************************
    1477              : 
    1478    264125101 :  if (order>6) then
    1479            0 :    msg='PAW screened exchange not coded for l>2!'
    1480            0 :    LIBPAW_ERROR(msg)
    1481              :  end if
    1482              : 
    1483              : !Use max and min of arguments
    1484    264125101 :  xx=max(r1,r2) ; yy=min(r1,r2)
    1485              : 
    1486              : !Unscreened Coulomb interaction for very small (or negative) arguments
    1487    264125101 :  if (xx<tol8) then
    1488            0 :   screened_coul_kernel=yy**order/xx**(order+1) ; return
    1489              :  end if
    1490              : 
    1491              : !Choice of formula
    1492              : !Empirical criterion, inspired by J. Phys. A 39, pp8624 [[cite:Angyan2006]] and adjusted
    1493    264125101 :  formula_=1;if (xx<0.25_dp.and.yy<0.25_dp) formula_=2
    1494    264125101 :  if (present(formula)) formula_=formula
    1495            0 :  select case (formula_)
    1496              : 
    1497              : !Full formula
    1498              : !J. Phys. A 39, 8613 (2006) - Eq. (21), (22), (24) [[cite:Angyan2006]]
    1499              : !   Note: typo in the paper: in eq (22), the sum begins at p=0
    1500              : !------------------------------------------------------------------
    1501              :  case(1)
    1502            0 :    xy=xx*yy ; sqrtpi=sqrt(pi)
    1503            0 :    sumexp=exp(-(xx+yy)**2)+exp(-(xx-yy)**2)
    1504            0 :    difexp=exp(-(xx+yy)**2)-exp(-(xx-yy)**2)
    1505            0 :    erfcp=paw_derfc(xx+yy) ; erfcm=paw_derfc(xx-yy)
    1506    264125101 :    if (order==0) then
    1507            0 :      f0=-difexp/(two*sqrtpi*xy)
    1508            0 :      hh=((xx+yy)*erfcp-(xx-yy)*erfcm)/(two*xy)
    1509            0 :      screened_coul_kernel = hh + f0
    1510              :    else if(order==1) then
    1511            0 :      f0=-difexp/(two*sqrtpi*xy)
    1512            0 :      f1=(difexp+two*xy*sumexp)/(sqrtpi*(two*xy)**2)
    1513            0 :      hh=((xx**3+yy**3)*erfcp-(xx**3-yy**3)*erfcm)/(two*xy**2)
    1514            0 :      screened_coul_kernel = hh + f1 + f0*(xx**2+yy**2)/xy
    1515              :    else if (order==2) then
    1516            0 :      f0=-difexp/(two*sqrtpi*xy)
    1517            0 :      f1=(difexp+two*xy*sumexp)/(sqrtpi*(two*xy)**2)
    1518            0 :      f2= -((four*xy**2+three)*difexp+6._dp*xy*sumexp)/(sqrtpi*(two*xy)**3)
    1519            0 :      hh=((xx**5+yy**5)*erfcp-(xx**5-yy**5)*erfcm)/(two*xy**3)
    1520            0 :      screened_coul_kernel = hh + f2 + f1*(xx**2+yy**2)/xy + f0*(xx**4+yy**4)/xy**2
    1521              :    else if (order==3) then
    1522            0 :      f0=-difexp/(two*sqrtpi*xy)
    1523            0 :      f1=(difexp+two*xy*sumexp)/(sqrtpi*(two*xy)**2)
    1524            0 :      f2= -((four*xy**2+three)*difexp+6._dp*xy*sumexp)/(sqrtpi*(two*xy)**3)
    1525            0 :      f3=((24._dp*xy**2+15._dp)*difexp+(8._dp*xy**3+30._dp*xy)*sumexp)/(sqrtpi*(two*xy)**4)
    1526            0 :      hh=((xx**7+yy**7)*erfcp-(xx**7-yy**7)*erfcm)/(two*xy**4)
    1527              :      screened_coul_kernel = hh + f3 + f2*(xx**2+yy**2)/xy    + f1*(xx**4+yy**4)/xy**2 &
    1528            0 : &                                   + f0*(xx**6+yy**6)/xy**3
    1529              :    else if (order==4) then
    1530            0 :      f0=-difexp/(two*sqrtpi*xy)
    1531            0 :      f1=(difexp+two*xy*sumexp)/(sqrtpi*(two*xy)**2)
    1532            0 :      f2= -((four*xy**2+three)*difexp+6._dp*xy*sumexp)/(sqrtpi*(two*xy)**3)
    1533            0 :      f3=((24._dp*xy**2+15._dp)*difexp+(8._dp*xy**3+30._dp*xy)*sumexp)/(sqrtpi*(two*xy)**4)
    1534              :      f4=-((16._dp*xy**4+180._dp*xy**2+105._dp)*difexp &
    1535            0 : &        +(80._dp*xy**3+210._dp*xy)*sumexp)/(sqrtpi*(two*xy)**5)
    1536            0 :      hh=((xx**9+yy**9)*erfcp-(xx**9-yy**9)*erfcm)/(two*xy**5)
    1537              :      screened_coul_kernel = hh + f4 + f3*(xx**2+yy**2)/xy    + f2*(xx**4+yy**4)/xy**2 &
    1538            0 : &                                   + f1*(xx**6+yy**6)/xy**3 + f0*(xx**8+yy**8)/xy**4
    1539              :    else if (order==5) then
    1540            0 :      f0=-difexp/(two*sqrtpi*xy)
    1541            0 :      f1=(difexp+two*xy*sumexp)/(sqrtpi*(two*xy)**2)
    1542            0 :      f2= -((four*xy**2+three)*difexp+6._dp*xy*sumexp)/(sqrtpi*(two*xy)**3)
    1543            0 :      f3=((24._dp*xy**2+15._dp)*difexp+(8._dp*xy**3+30._dp*xy)*sumexp)/(sqrtpi*(two*xy)**4)
    1544              :      f4=-((16._dp*xy**4+180._dp*xy**2+105._dp)*difexp &
    1545            0 : &        +(80._dp*xy**3+210._dp*xy)*sumexp)/(sqrtpi*(two*xy)**5)
    1546              :      f5=((240._dp*xy**4+1680._dp*xy**2+945._dp)*difexp &
    1547            0 : &       +(32._dp*xy**5+840._dp*xy**3+1890._dp*xy)*sumexp)/(sqrtpi*(two*xy)**6)
    1548            0 :      hh=((xx**11+yy**11)*erfcp-(xx**11-yy**11)*erfcm)/(two*xy**6)
    1549              :      screened_coul_kernel = hh + f5 + f4*(xx**2+yy**2)  /xy    + f3*(xx**4+yy**4)/xy**2 &
    1550              : &                                   + f2*(xx**6+yy**6)  /xy**3 + f1*(xx**8+yy**8)/xy**4 &
    1551            0 : &                                   + f0*(xx**10+yy**10)/xy**5
    1552              :    else if (order==6) then
    1553            0 :      f0=-difexp/(two*sqrtpi*xy)
    1554            0 :      f1=(difexp+two*xy*sumexp)/(sqrtpi*(two*xy)**2)
    1555            0 :      f2= -((four*xy**2+three)*difexp+6._dp*xy*sumexp)/(sqrtpi*(two*xy)**3)
    1556            0 :      f3=((24._dp*xy**2+15._dp)*difexp+(8._dp*xy**3+30._dp*xy)*sumexp)/(sqrtpi*(two*xy)**4)
    1557              :      f4=-((16._dp*xy**4+180._dp*xy**2+105._dp)*difexp &
    1558            0 : &        +(80._dp*xy**3+210._dp*xy)*sumexp)/(sqrtpi*(two*xy)**5)
    1559              :      f5=((240._dp*xy**4+1680._dp*xy**2+945._dp)*difexp &
    1560            0 : &       +(32._dp*xy**5+840._dp*xy**3+1890._dp*xy)*sumexp)/(sqrtpi*(two*xy)**6)
    1561              :      f6=-((64._dp*xy**6+3360._dp*xy**4+18900._dp*xy**2+10395._dp)*difexp+ &
    1562            0 : &         (672._dp*xy**5+10080._dp*xy**3+20790._dp*xy)*sumexp)/(sqrtpi*(two*xy)**7)
    1563            0 :      hh=((xx**13+yy**13)*erfcp-(xx**13-yy**13)*erfcm)/(two*xy**7)
    1564              :      screened_coul_kernel = hh + f6 + f5*(xx**2+yy**2)  /xy    + f4*(xx**4+yy**4)  /xy**2 &
    1565              : &                                   + f3*(xx**6+yy**6)  /xy**3 + f1*(xx**8+yy**8)  /xy**4 &
    1566            0 : &                                   + f1*(xx**10+yy**10)/xy**5 + f0*(xx**12+yy**12)/xy**6
    1567              :    end if
    1568              : 
    1569              : !Development for yy->0
    1570              : !J. Phys. A 39, 8613 (2006) - Eq. (28), (29), (30) [[cite:Angyan2006]]
    1571              : !------------------------------------------------------------------
    1572              :  case(2)
    1573    264125101 :    sqrtpi=sqrt(pi)
    1574            0 :    if (order==0) then
    1575              :      screened_coul_kernel = paw_derfc(xx)/xx + exp(-xx**2)/sqrtpi * &
    1576              : &            (two/three              *yy**2 &
    1577    113142729 : &           +(two*xx**2-three)/15._dp*yy**4)
    1578              :    else if(order==1) then
    1579              :      screened_coul_kernel = paw_derfc(xx)*yy/xx**2 + exp(-xx**2)/sqrtpi * &
    1580              : &            (two/xx                         *yy &
    1581              : &            +four*xx/5._dp                  *yy**3 &
    1582     55508225 : &            +two*xx*(two*xx**2-5._dp)/35._dp*yy**5)
    1583              :    else if (order==2) then
    1584              :      screened_coul_kernel = paw_derfc(xx)*yy**2/xx**3 + exp(-xx**2)/sqrtpi * &
    1585              : &            (two*(two*xx**2+three)/(three*xx**2) *yy**2 &
    1586              : &            +8._dp*xx**2/21._dp                  *yy**4 &
    1587     95474147 : &            +four*xx**2*(two*xx**2-7._dp)/189._dp*yy**6)
    1588              :    else if (order==3) then
    1589              :      screened_coul_kernel = paw_derfc(xx)*yy**3/xx**4 + exp(-xx**2)/sqrtpi * &
    1590              : &            (two*(four*xx**4+10._dp*xx**2+15._dp)/(15._dp*xx**3)*yy**3 &
    1591              : &            +16._dp*xx**3/135._dp                               *yy**5 &
    1592            0 : &            +8._dp*xx**3*(two*xx**2-9._dp)/1485._dp             *yy**7)
    1593              :    else if (order==4) then
    1594              :      screened_coul_kernel = paw_derfc(xx)*yy**4/xx**5 + exp(-xx**2)/sqrtpi * &
    1595              : &            (two*(8._dp*xx**6+28._dp*xx**4+70._dp*xx**2+105._dp)/(105._dp*xx**4)*yy**4 &
    1596              : &            +32._dp*xx**4/1155._dp                                              *yy**6 &
    1597            0 : &            +16._dp*xx**4*(two*xx**2-11._dp)/15015._dp                          *yy**8)
    1598              :    else if (order==5) then
    1599              :      screened_coul_kernel = paw_derfc(xx)*yy**5/xx**6 + exp(-xx**2)/sqrtpi * &
    1600              : &            (two*(16._dp*xx**8+72._dp*xx**6+252._dp*xx**4+630._dp*xx**2+945._dp)/(945._dp*xx**5)*yy**5 &
    1601              : &            +64._dp*xx**5/12285._dp                                                             *yy**7 &
    1602            0 : &            +32._dp*xx**5*(two*xx**2-13._dp)/184275._dp                                         *yy**9)
    1603              :    else if (order==6) then
    1604              :      screened_coul_kernel = paw_derfc(xx)*yy**6/xx**7 + exp(-xx**2)/sqrtpi * &
    1605              : &            (two*(32._dp*xx**10+176._dp*xx**8+792._dp*xx**6+2772._dp*xx**4+6930._dp*xx**2+10395._dp)/(10395._dp*xx**6)*yy**6 &
    1606              : &            +128._dp*xx**6/155925._dp                                                                                 *yy**8 &
    1607            0 : &            +64._dp*xx**6*(two*xx**2-15._dp)/2650725._dp                                                              *yy**10)
    1608              :    end if
    1609              : 
    1610              : !Development for xx*yy->0
    1611              : !J. Phys. A 39, 8613 (2006) - Eq. (24), (26) [[cite:Angyan2006]]
    1612              : !   Note: typo in the paper: (2n+3)! should be (2n+3)!!
    1613              : !------------------------------------------------------------------
    1614              :  case(3)
    1615            0 :    xy=xx*yy ; sqrtpi=sqrt(pi)
    1616            0 :    sumexp=exp(-(xx**2+yy**2))
    1617            0 :    erfcp=paw_derfc(xx+yy) ; erfcm=paw_derfc(xx-yy)
    1618    264125101 :    if (order==0) then
    1619            0 :      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
    1620            0 :      hh=((xx+yy)*erfcp-(xx-yy)*erfcm)/(two*xy)
    1621            0 :      screened_coul_kernel = hh + f0
    1622              :    else if(order==1) then
    1623            0 :      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
    1624            0 :      f1 = four   *xy   *(5._dp +two*xy**2)/(15._dp     *sqrtpi)*sumexp
    1625            0 :      hh=((xx**3+yy**3)*erfcp-(xx**3-yy**3)*erfcm)/(two*xy**2)
    1626            0 :      screened_coul_kernel = hh + f1 + f0*(xx**2+yy**2)/xy
    1627              :    else if (order==2) then
    1628            0 :      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
    1629            0 :      f1 = four   *xy   *(5._dp +two*xy**2)/(15._dp     *sqrtpi)*sumexp
    1630            0 :      f2 = 8._dp  *xy**2*(7._dp +two*xy**2)/(105._dp    *sqrtpi)*sumexp
    1631            0 :      hh=((xx**5+yy**5)*erfcp-(xx**5-yy**5)*erfcm)/(two*xy**3)
    1632            0 :      screened_coul_kernel = hh + f2 + f1*(xx**2+yy**2)/xy + f0*(xx**4+yy**4)/xy**2
    1633              :    else if (order==3) then
    1634            0 :      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
    1635            0 :      f1 = four   *xy   *(5._dp +two*xy**2)/(15._dp     *sqrtpi)*sumexp
    1636            0 :      f2 = 8._dp  *xy**2*(7._dp +two*xy**2)/(105._dp    *sqrtpi)*sumexp
    1637            0 :      f3 = 16._dp *xy**2*(9._dp +two*xy**2)/(945._dp    *sqrtpi)*sumexp
    1638            0 :      hh=((xx**7+yy**7)*erfcp-(xx**7-yy**7)*erfcm)/(two*xy**4)
    1639              :      screened_coul_kernel = hh + f3 + f2*(xx**2+yy**2)/xy    + f1*(xx**4+yy**4)/xy**2 &
    1640            0 : &                                   + f0*(xx**6+yy**6)/xy**3
    1641              :    else if (order==4) then
    1642            0 :      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
    1643            0 :      f1 = four   *xy   *(5._dp +two*xy**2)/(15._dp     *sqrtpi)*sumexp
    1644            0 :      f2 = 8._dp  *xy**2*(7._dp +two*xy**2)/(105._dp    *sqrtpi)*sumexp
    1645            0 :      f3 = 16._dp *xy**2*(9._dp +two*xy**2)/(945._dp    *sqrtpi)*sumexp
    1646            0 :      f4 = 32._dp *xy**2*(11._dp+two*xy**2)/(10395._dp  *sqrtpi)*sumexp
    1647            0 :      hh=((xx**9+yy**9)*erfcp-(xx**9-yy**9)*erfcm)/(two*xy**5)
    1648              :      screened_coul_kernel = hh + f4 + f3*(xx**2+yy**2)/xy    + f2*(xx**4+yy**4)/xy**2 &
    1649            0 : &                                   + f1*(xx**6+yy**6)/xy**3 + f0*(xx**8+yy**8)/xy**4
    1650              :    else if (order==5) then
    1651            0 :      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
    1652            0 :      f1 = four   *xy   *(5._dp +two*xy**2)/(15._dp     *sqrtpi)*sumexp
    1653            0 :      f2 = 8._dp  *xy**2*(7._dp +two*xy**2)/(105._dp    *sqrtpi)*sumexp
    1654            0 :      f3 = 16._dp *xy**2*(9._dp +two*xy**2)/(945._dp    *sqrtpi)*sumexp
    1655            0 :      f4 = 32._dp *xy**2*(11._dp+two*xy**2)/(10395._dp  *sqrtpi)*sumexp
    1656            0 :      f5 = 64._dp *xy**2*(13._dp+two*xy**2)/(135135._dp *sqrtpi)*sumexp
    1657            0 :      hh=((xx**11+yy**11)*erfcp-(xx**11-yy**11)*erfcm)/(two*xy**6)
    1658              :      screened_coul_kernel = hh + f5 + f4*(xx**2+yy**2)  /xy    + f3*(xx**4+yy**4)/xy**2 &
    1659              : &                                   + f2*(xx**6+yy**6)  /xy**3 + f1*(xx**8+yy**8)/xy**4 &
    1660            0 : &                                   + f0*(xx**10+yy**10)/xy**5
    1661              :    else if (order==6) then
    1662            0 :      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
    1663            0 :      f1 = four   *xy   *(5._dp +two*xy**2)/(15._dp     *sqrtpi)*sumexp
    1664            0 :      f2 = 8._dp  *xy**2*(7._dp +two*xy**2)/(105._dp    *sqrtpi)*sumexp
    1665            0 :      f3 = 16._dp *xy**2*(9._dp +two*xy**2)/(945._dp    *sqrtpi)*sumexp
    1666            0 :      f4 = 32._dp *xy**2*(11._dp+two*xy**2)/(10395._dp  *sqrtpi)*sumexp
    1667            0 :      f5 = 64._dp *xy**2*(13._dp+two*xy**2)/(135135._dp *sqrtpi)*sumexp
    1668            0 :      f6 = 128._dp*xy**2*(15._dp+two*xy**2)/(1027025._dp*sqrtpi)*sumexp
    1669            0 :      hh=((xx**13+yy**13)*erfcp-(xx**13-yy**13)*erfcm)/(two*xy**7)
    1670              :      screened_coul_kernel = hh + f6 + f5*(xx**2+yy**2)  /xy    + f4*(xx**4+yy**4)  /xy**2 &
    1671              : &                                   + f3*(xx**6+yy**6)  /xy**3 + f1*(xx**8+yy**8)  /xy**4 &
    1672            0 : &                                   + f1*(xx**10+yy**10)/xy**5 + f0*(xx**12+yy**12)/xy**6
    1673              :    end if
    1674              : 
    1675              :  end select
    1676              : 
    1677              : end function screened_coul_kernel
    1678              : !!***
    1679              : 
    1680              : !----------------------------------------------------------------------
    1681              : 
    1682              : !!****f* m_pawrad/calc_slatradl
    1683              : !! NAME
    1684              : !!  calc_slatradl
    1685              : !!
    1686              : !! FUNCTION
    1687              : !!  Calculate the radial part of Slater integrals. See below.
    1688              : !!
    1689              : !! INPUTS
    1690              : !!  ll= l quantum number in the expansion of the Coulomb term.
    1691              : !!  mesh_size=Number of points on the radial mesh.
    1692              : !!  ff1(radmesh), ff2(radmesh)= The two functions to be integrated.
    1693              : !!  Pawrad <type(pawrad_type)>=Structure containing radial grid information.
    1694              : !!
    1695              : !! OUTPUT
    1696              : !!  integral =
    1697              : !!   $ \dfrac{4\pi}{2L+1} \int ff1(r1) \dfrac{r_<^L}{r_>^{L+1}} ff2(r2) dr1 dr2 $
    1698              : !!  where $r_< = min(r1,r2)$ and $r_> = Max(r1,r2)$.
    1699              : !!
    1700              : !! SOURCE
    1701              : 
    1702          162 : subroutine calc_slatradl(ll,mesh_size,ff1,ff2,Pawrad,integral)
    1703              : 
    1704              : !scalars
    1705              :  integer,intent(in) :: mesh_size,ll
    1706              :  real(dp),intent(out) :: integral
    1707              : !arrays
    1708              :  real(dp),intent(in) :: ff1(mesh_size),ff2(mesh_size)
    1709              :  type(pawrad_type),intent(in) :: Pawrad
    1710              : 
    1711              : !Local variables ---------------------------------------
    1712              : !scalars
    1713              :  integer :: int_meshsz
    1714              :  character(len=100) :: msg
    1715              : !arrays
    1716          162 :  real(dp),allocatable :: hh(:),gg(:)
    1717              : 
    1718              : ! *************************************************************************
    1719              : 
    1720          162 :  if (mesh_size > Pawrad%mesh_size) then
    1721            0 :    msg='mesh_size > pawrad%mesh_size!'
    1722            0 :    LIBPAW_BUG(msg)
    1723              :  end if
    1724              : 
    1725          486 :  LIBPAW_ALLOCATE(hh,(mesh_size))
    1726          324 :  LIBPAW_ALLOCATE(gg,(mesh_size))
    1727              :  !hh = zero
    1728              :  !gg = zero
    1729              : 
    1730          162 :  int_meshsz=Pawrad%int_meshsz
    1731              :  !$int_meshsz=Pawrad%mesh_size
    1732              : 
    1733              :  ! the line below requires hh as work array.
    1734       224208 :  hh = ff2
    1735              : 
    1736              :  ! TODO find where int_meshsz is calculated and if it can affects the results.
    1737          162 :  if (int_meshsz<mesh_size) hh(int_meshsz+1:mesh_size)=zero
    1738              : 
    1739          162 :  call poisson(hh,ll,Pawrad,gg)
    1740              : 
    1741       223884 :  gg(2:mesh_size) = gg(2:mesh_size)/Pawrad%rad(2:mesh_size)
    1742              : 
    1743          162 :  hh(1)          = zero
    1744       223884 :  hh(2:mesh_size)= ff1(2:mesh_size) * gg(2:mesh_size)
    1745          162 :  LIBPAW_DEALLOCATE(gg)
    1746              : 
    1747          162 :  call simp_gen(integral,hh,Pawrad)
    1748          162 :  integral = four_pi * integral
    1749              : 
    1750          162 :  LIBPAW_DEALLOCATE(hh)
    1751              : 
    1752          162 : end subroutine calc_slatradl
    1753              : !!***
    1754              : 
    1755              : !----------------------------------------------------------------------
    1756              : 
    1757            0 : END MODULE m_pawrad
    1758              : !!***
        

Generated by: LCOV version 2.3-1