TABLE OF CONTENTS


ABINIT/m_pawrad [ Modules ]

[ Top ] [ Modules ]

NAME

 m_pawrad

FUNCTION

 Module containing all the functions related to the PAW radial meshes

COPYRIGHT

 Copyright (C) 2013-2018 ABINIT group (MT,FJ,MG)
 This file is distributed under the terms of the
 GNU General Public License, see ~abinit/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .

NOTES

  * Routines tagged with "@type_name" are strongly connected to the definition of the data type.
    Strongly connected means that the proper functioning of the implementation relies on the
    assumption that the tagged procedure is consistent with the type declaration.
    Every time a developer changes the structure "type_name" adding new entries, he/she has to make sure
    that all the strongly connected routines are changed accordingly to accommodate the modification of the data type
    Typical examples of strongly connected routines are creation, destruction or reset methods.

  * FOR DEVELOPERS: in order to preserve the portability of libPAW library,
    please consult ~abinit/src/??_libpaw/libpaw-coding-rules.txt

SOURCE

28 #include "libpaw.h"
29 
30 MODULE m_pawrad
31 
32  USE_DEFS
33  USE_MSG_HANDLING
34  USE_MPI_WRAPPERS
35  USE_MEMORY_PROFILING
36 
37  use m_paw_numeric, only : paw_derfc
38 
39  implicit none
40 
41  private
42 
43 !public procedures.
44  public :: pawrad_init          ! Main creation method
45  public :: pawrad_free          ! Free the allocated memory
46  public :: pawrad_print         ! Printout of the basic info
47  public :: pawrad_isame         ! Checks whether two meshes are equivalent or have the same equation.
48  public :: pawrad_copy          ! Returns a copy of the mesh.
49  public :: pawrad_ifromr        ! Retrieve the Index FROM a given R value in a radial grid.
50  public :: pawrad_deducer0      ! Extrapolate r=0 value of a function from values near r=0.
51  public :: pawrad_bcast         ! Broadcast pawrad datastructure over a given MPI communicator
52  public :: simp_gen             ! Performs integral on a given (generalized) grid using Simpson rule.
53  public :: nderiv_gen           ! Do corrected first (and 2nd) derivation on a given (generalized) grid.
54  public :: nderiv_lin           ! Do corrected first (and 2nd) derivation on a given linear grid.
55  public :: bound_deriv          ! Computes derivatives at boundaries of the mesh
56  public :: poisson              ! Solves Poisson eq. for angularly dependent charge distribution of angular momentum l
57  public :: screened_coul_kernel ! Kernel used to compute short-range screened Coulomb integrals
58  public :: calc_slatradl        ! Calculates the radial part of Slater integrals.
59 
60  interface pawrad_free
61    module procedure pawrad_free_0D
62    module procedure pawrad_free_1D
63  end interface pawrad_free
64 
65  ! TODO: Might use bit flags, but all radmesh stuff should be encapsulated here!
66  integer,private,parameter :: RMESH_LINEAR = 1
67  integer,private,parameter :: RMESH_LOG1   = 2
68  integer,private,parameter :: RMESH_LOG2   = 3
69  integer,private,parameter :: RMESH_LOG3   = 4
70  integer,private,parameter :: RMESH_NL     = 5

m_pawrad/bound_deriv [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

 bound_deriv

FUNCTION

 Computes derivatives of a function a boundaries of interval (first and last derivative)

INPUTS

  func(n)= array containing function
  mesh <type(pawrad_type)>= radial mesh and related data
  nn= size of intervall

OUTPUT

  yp1,ypn= derivatives of func at r(1) and r(n)

PARENTS

      m_paw_atom,m_pawpsp,m_pawxmlps,outscfcv

CHILDREN

      poisson,simp_gen

SOURCE

1292  subroutine bound_deriv(func,mesh,nn,yp1,ypn)
1293 
1294 
1295 !This section has been created automatically by the script Abilint (TD).
1296 !Do not modify the following lines by hand.
1297 #undef ABI_FUNC
1298 #define ABI_FUNC 'bound_deriv'
1299 !End of the abilint section
1300 
1301  implicit none
1302 
1303 !Arguments----------------------
1304  integer, intent(in) :: nn
1305  real(dp), intent(in) :: func(nn)
1306  real(dp), intent(out) :: yp1,ypn
1307  type(pawrad_type),intent(in) :: mesh
1308 
1309 !*************************************************************************
1310 
1311  if (mesh%radfact(1)>zero) then
1312    yp1=1._dp/12._dp/mesh%stepint/mesh%radfact(1) &
1313 &   *(-25._dp*func(1)+48._dp*func(2)-36._dp*func(3)+16._dp*func(4)-3._dp*func(5))
1314  else
1315    yp1=(func(2)-func(1))/(mesh%rad(2)-mesh%rad(1))
1316  end if
1317  ypn=1._dp/12._dp/mesh%stepint &
1318 & *( 3._dp*func(nn-4)-16._dp*func(nn-3)+36._dp*func(nn-2)-48._dp*func(nn-1) &
1319 & +25._dp*func(nn))/mesh%radfact(nn)
1320 
1321 end subroutine bound_deriv

m_pawrad/calc_slatradl [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

  calc_slatradl

FUNCTION

  Calculate the radial part of Slater integrals. See below.

INPUTS

  ll= l quantum number in the expansion of the Coulomb term.
  mesh_size=Number of points on the radial mesh.
  ff1(radmesh), ff2(radmesh)= The two functions to be integrated.
  Pawrad <type(pawrad_type)>=Structure containing radial grid information.

OUTPUT

  integral =
   $ \dfrac{4\pi}{2L+1} \int ff1(r1) \dfrac{r_<^L}{r_>^{L+1}} ff2(r2) dr1 dr2 $
  where $r_< = min(r1,r2)$ and $r_> = Max(r1,r2)$.

PARENTS

      m_paw_slater

CHILDREN

      poisson,simp_gen

SOURCE

1936 subroutine calc_slatradl(ll,mesh_size,ff1,ff2,Pawrad,integral)
1937 
1938 
1939 !This section has been created automatically by the script Abilint (TD).
1940 !Do not modify the following lines by hand.
1941 #undef ABI_FUNC
1942 #define ABI_FUNC 'calc_slatradl'
1943 !End of the abilint section
1944 
1945  implicit none
1946 
1947 !scalars
1948  integer,intent(in) :: mesh_size,ll
1949  real(dp),intent(out) :: integral
1950 !arrays
1951  real(dp),intent(in) :: ff1(mesh_size),ff2(mesh_size)
1952  type(pawrad_type),intent(in) :: Pawrad
1953 
1954 !Local variables ---------------------------------------
1955 !scalars
1956  integer :: int_meshsz
1957  character(len=100) :: msg
1958 !arrays
1959  real(dp),allocatable :: hh(:),gg(:)
1960 
1961 ! *************************************************************************
1962 
1963  if (mesh_size > Pawrad%mesh_size) then
1964    msg='mesh_size > pawrad%mesh_size!'
1965    MSG_BUG(msg)
1966  end if
1967 
1968  LIBPAW_ALLOCATE(hh,(mesh_size))
1969  LIBPAW_ALLOCATE(gg,(mesh_size))
1970  !hh = zero
1971  !gg = zero
1972 
1973  int_meshsz=Pawrad%int_meshsz
1974  !$int_meshsz=Pawrad%mesh_size
1975 
1976  ! the line below requires hh as work array.
1977  hh = ff2
1978 
1979  ! TODO find where int_meshsz is calculated and if it can affects the results.
1980  if (int_meshsz<mesh_size) hh(int_meshsz+1:mesh_size)=zero
1981 
1982  call poisson(hh,ll,Pawrad,gg)
1983 
1984  gg(2:mesh_size) = gg(2:mesh_size)/Pawrad%rad(2:mesh_size)
1985 
1986  hh(1)          = zero
1987  hh(2:mesh_size)= ff1(2:mesh_size) * gg(2:mesh_size)
1988  LIBPAW_DEALLOCATE(gg)
1989 
1990  call simp_gen(integral,hh,Pawrad)
1991  integral = four_pi * integral
1992 
1993  LIBPAW_DEALLOCATE(hh)
1994 
1995 end subroutine calc_slatradl

m_pawrad/nderiv_gen [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

 nderiv_gen

FUNCTION

 Do corrected first (and -if requested- second) derivation on a given (generalized) grid.
 This routine interfaces nderiv_lin (derivation on a linear grid).

INPUTS

  func(:)=input function
  radmesh <type(pawrad_type)>=data containing radial grid information

OUTPUT

  der(:)= 1st derivative of input function
  [der2(:)]= -- optional -- 2nd derivative of input function

PARENTS

      m_paw_pwaves_lmn,m_pawdij,m_pawpsp,m_pawxc,optics_paw,optics_paw_core
      pawinit,pawnabla_init,poslifetime,posratecore,spline_paw_fncs

CHILDREN

      poisson,simp_gen

NOTES

  Possible mesh types (radmesh%mesh_type)
   mesh_type=1 (regular grid): rad(i)=(i-1)*AA
   mesh_type=2 (logari. grid): rad(i)=AA*(exp[BB*(i-1)]-1)
   mesh_type=3 (logari. grid): rad(i>1)=AA*exp[BB*(i-2)] and rad(1)=0
   mesh_type=4 (logari. grid): rad(i)=-AA*ln[1-BB*(i-1)] with BB=1/n

SOURCE

1079 subroutine nderiv_gen(der,func,radmesh,der2)
1080 
1081 
1082 !This section has been created automatically by the script Abilint (TD).
1083 !Do not modify the following lines by hand.
1084 #undef ABI_FUNC
1085 #define ABI_FUNC 'nderiv_gen'
1086 !End of the abilint section
1087 
1088  implicit none
1089 
1090 !Arguments ------------------------------------
1091 !scalars
1092  type(pawrad_type),intent(in) :: radmesh
1093 !arrays
1094  real(dp),intent(in) :: func(:)
1095  real(dp),intent(out) :: der(:)
1096  real(dp),optional,intent(out) :: der2(:)
1097 
1098 !Local variables-------------------------------
1099 !scalars
1100  integer :: msz
1101  logical :: compute_2der
1102  character(len=500) :: msg
1103 
1104 ! *************************************************************************
1105 
1106  msz=size(func)
1107  if (size(der)/=msz.or.msz>radmesh%mesh_size) then
1108    msg='wrong sizes for in/out arrays!'
1109    MSG_BUG(msg)
1110  end if
1111 
1112  compute_2der=(present(der2))
1113 
1114  if (radmesh%mesh_type==1) then
1115 
1116    call nderiv_lin(radmesh%rstep,func,der,msz,1)
1117    if (compute_2der) then
1118      call nderiv_lin(radmesh%rstep,func,der2,msz,2)
1119    end if
1120 
1121  else if (radmesh%mesh_type==2) then
1122 
1123    call nderiv_lin(radmesh%lstep,func,der,msz,1)
1124    der(1:msz)=der(1:msz)/radmesh%radfact(1:msz)
1125    if (compute_2der)then
1126      call nderiv_lin(radmesh%lstep,func,der2,msz,2)
1127      der2(1:msz)=(der2(1:msz)/radmesh%radfact(1:msz)-der(1:msz))/radmesh%radfact(1:msz)
1128    end if
1129 
1130  else if (radmesh%mesh_type==3) then
1131 
1132    call nderiv_lin(radmesh%lstep,func(2:msz),der(2:msz),msz-1,1)
1133    der(2:msz)=der(2:msz)/radmesh%radfact(2:msz)
1134    call pawrad_deducer0(der,msz,radmesh)
1135    if (compute_2der)then
1136      call nderiv_lin(radmesh%lstep,func(2:msz),der2(2:msz),msz-1,2)
1137      der2(2:msz)=(der2(2:msz)/radmesh%radfact(2:msz)-der(2:msz))/radmesh%radfact(2:msz)
1138      call pawrad_deducer0(der2,msz,radmesh)
1139    end if
1140 
1141  else if (radmesh%mesh_type==4) then
1142 
1143    call nderiv_lin(radmesh%lstep,func,der,msz,1)
1144    der(1:msz)=der(1:msz)/radmesh%radfact(1:msz)
1145    if (compute_2der)then
1146      call nderiv_lin(radmesh%lstep,func,der2,msz,2)
1147      der2(1:msz)=der2(1:msz)/radmesh%radfact(1:msz)**2-der(1:msz)/radmesh%rstep
1148    end if
1149 
1150  else if (radmesh%mesh_type==5) then
1151 
1152    call nderiv_lin(one,func,der,msz,1)
1153    der(1:msz)=der(1:msz)/(radmesh%radfact(1:msz)*radmesh%rstep)
1154    if (compute_2der)then
1155      call nderiv_lin(one,func,der2,msz,2)
1156      der2(1:msz)=der2(1:msz)/(radmesh%radfact(1:msz)*radmesh%rstep)**2-two*der(1:msz)/&
1157 &                            (radmesh%rstep+radmesh%rad(1:msz))
1158    end if
1159  end if
1160 
1161 end subroutine nderiv_gen

m_pawrad/nderiv_lin [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

 nderiv_lin

FUNCTION

 Do corrected first (and -if requested- second) derivation on a given LINEAR grid.

INPUTS

  hh= radial step
  ndim= radial mesh size
  yy(ndim)= input function
  norder= order of derivation (1 or 2)

OUTPUT

  zz(ndim)= first or second derivative of y

PARENTS

      m_pawrad

CHILDREN

      poisson,simp_gen

SOURCE

1190 subroutine nderiv_lin(hh,yy,zz,ndim,norder)
1191 
1192 
1193 !This section has been created automatically by the script Abilint (TD).
1194 !Do not modify the following lines by hand.
1195 #undef ABI_FUNC
1196 #define ABI_FUNC 'nderiv_lin'
1197 !End of the abilint section
1198 
1199  implicit none
1200 
1201 !Arguments ---------------------------------------------
1202 !scalars
1203  integer,intent(in) :: ndim,norder
1204  real(dp),intent(in) :: hh
1205 !arrays
1206  real(dp),intent(in) :: yy(ndim)
1207  real(dp),intent(out) :: zz(ndim)
1208 
1209 !Local variables ---------------------------------------
1210 !scalars
1211  integer :: ier,ii
1212  real(dp) :: aa,bb,cc,h1,y1
1213 
1214 ! *************************************************************************
1215 
1216 !Initialization (common to 1st and 2nd derivative)
1217  h1=one/(12.d0*hh)
1218  y1=yy(ndim-4)
1219 
1220 !FIRST DERIVATIVE
1221 !================
1222  if (norder==1) then
1223 
1224 !  Prepare differentiation loop
1225    bb=h1*(-25.d0*yy(1)+48.d0*yy(2)-36.d0*yy(3)+16.d0*yy(4)-3.d0*yy(5))
1226    cc=h1*(-3.d0*yy(1)-10.d0*yy(2)+18.d0*yy(3)-6.d0*yy(4)+yy(5))
1227 !  Start differentiation loop
1228    do ii=5,ndim
1229      aa=bb;bb=cc
1230      cc=h1*(yy(ii-4)-yy(ii)+8.d0*(yy(ii-1)-yy(ii-3)))
1231      zz(ii-4)=aa
1232    end do
1233 !  Normal exit
1234    ier=0
1235    aa=h1*(-y1+6.d0*yy(ndim-3)-18.d0*yy(ndim-2)+10.d0*yy(ndim-1)+3.d0*yy(ndim))
1236    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))
1237    zz(ndim-1)=aa
1238    zz(ndim-2)=cc
1239    zz(ndim-3)=bb
1240 
1241 !  SECOND DERIVATIVE
1242 !  =================
1243  else
1244    h1=h1/hh
1245 !  Prepare differentiation loop
1246    bb=h1*(35.d0*yy(1)-104.d0*yy(2)+114.d0*yy(3)-56.d0*yy(4)+11.d0*yy(5))
1247    cc=h1*(11.d0*yy(1)-20.d0*yy(2)+6.d0*yy(3)+4.d0*yy(4)-yy(5))
1248 !  Start differentiation loop
1249    do ii=5,ndim
1250      aa=bb;bb=cc
1251      cc=h1*(-yy(ii-4)-yy(ii)+16.d0*(yy(ii-1)+yy(ii-3))-30.d0*yy(ii-2))
1252      zz(ii-4)=aa
1253    end do
1254 !  Normal exit
1255    ier=0
1256    aa=h1*(-y1+4.d0*yy(ndim-3)+6.d0*yy(ndim-2)-20.d0*yy(ndim-1)+11.d0*yy(ndim))
1257    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))
1258    zz(ndim-1)=aa
1259    zz(ndim-2)=cc
1260    zz(ndim-3)=bb
1261 
1262  end if !norder
1263 
1264 end subroutine nderiv_lin

m_pawrad/pawrad_bcast [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

 pawrad_bcast

FUNCTION

 Communicate pawrad data over a given MPI communicator

INPUTS

 comm_mpi= communicator used to broadcast data

SIDE EFFECTS

  pawrad=<type pawrad_type>= a radial mesh datastructure for PAW

PARENTS

      m_pawpsp

CHILDREN

      poisson,simp_gen

SOURCE

762 subroutine pawrad_bcast(pawrad,comm_mpi)
763 
764 
765 !This section has been created automatically by the script Abilint (TD).
766 !Do not modify the following lines by hand.
767 #undef ABI_FUNC
768 #define ABI_FUNC 'pawrad_bcast'
769 !End of the abilint section
770 
771  implicit none
772 
773 !Arguments ------------------------------------
774 !scalars
775  integer,intent(in) :: comm_mpi
776  type(pawrad_type),intent(inout) :: pawrad
777 
778 !Local variables-------------------------------
779 !scalars
780  integer :: ierr,indx,me,nn,isz1
781  integer :: if_rad,if_radfact,if_simfact !flags used to communicate
782  character(len=500) :: msg
783 !arrays
784  integer,allocatable :: list_int(:)
785  real(dp),allocatable :: list_dpr(:)
786 
787 !*************************************************************************
788 
789  me=xmpi_comm_rank(comm_mpi)
790 
791 !Initializations
792  if_rad=0; if_radfact=0; if_simfact=0
793 
794 !calculate the size of the reals
795  if(me==0) then
796    if (allocated(pawrad%rad)) then
797      if_rad=1 !communicate rad
798      isz1=size(pawrad%rad)
799      if(isz1/=pawrad%mesh_size) then
800        msg='rad: sz1 /= pawrad%mesh_size (1)'
801        MSG_BUG(msg)
802      end if
803    end if
804    if (allocated(pawrad%radfact)) then
805      if_radfact=1 !communicate radfact
806      isz1=size(pawrad%radfact)
807      if(isz1/=pawrad%mesh_size) then
808        msg='radfact: sz1 /= pawrad%mesh_size (2)'
809        MSG_BUG(msg)
810      end if
811    end if
812    if (allocated(pawrad%simfact)) then
813      if_simfact=1 !communicate simfact
814      isz1=size(pawrad%simfact)
815      if(isz1/=pawrad%mesh_size) then
816        msg='simfact: sz1 /= pawrad%mesh_size (3)'
817        MSG_BUG(msg)
818      end if
819    end if
820  end if
821 
822 !Brodcast the integers
823  LIBPAW_ALLOCATE(list_int,(6))
824  if(me==0) then
825    list_int(1)=pawrad%int_meshsz
826    list_int(2)=pawrad%mesh_size
827    list_int(3)=pawrad%mesh_type
828    list_int(4)=if_rad
829    list_int(5)=if_radfact
830    list_int(6)=if_simfact
831  end if
832  call xmpi_bcast(list_int,0,comm_mpi,ierr)
833  if(me/=0) then
834    pawrad%int_meshsz =list_int(1)
835    pawrad%mesh_size =list_int(2)
836    pawrad%mesh_type =list_int(3)
837    if_rad=list_int(4)
838    if_radfact=list_int(5)
839    if_simfact=list_int(6)
840  end if
841  LIBPAW_DEALLOCATE(list_int)
842 
843 !Broadcast the reals
844  nn=4+pawrad%mesh_size*(if_rad+if_radfact+if_simfact)
845  LIBPAW_ALLOCATE(list_dpr,(nn))
846  if(me==0) then
847    list_dpr(1)=pawrad%lstep
848    list_dpr(2)=pawrad%rmax
849    list_dpr(3)=pawrad%rstep
850    list_dpr(4)=pawrad%stepint
851    indx=5
852    if (if_rad==1) then
853      isz1=pawrad%mesh_size
854      list_dpr(indx:indx+isz1-1)=pawrad%rad(1:isz1)
855      indx=indx+isz1
856    end if
857    if (if_radfact==1) then
858      isz1=pawrad%mesh_size
859      list_dpr(indx:indx+isz1-1)=pawrad%radfact(1:isz1)
860      indx=indx+isz1
861    end if
862    if (if_simfact==1) then
863      isz1=pawrad%mesh_size
864      list_dpr(indx:indx+isz1-1)=pawrad%simfact(1:isz1)
865      indx=indx+isz1
866    end if
867  end if
868  call xmpi_bcast(list_dpr,0,comm_mpi,ierr)
869  if(me/=0) then
870    pawrad%lstep=list_dpr(1)
871    pawrad%rmax=list_dpr(2)
872    pawrad%rstep=list_dpr(3)
873    pawrad%stepint=list_dpr(4)
874    indx=5
875 !  Deallocate all arrays:
876    if (allocated(pawrad%rad)) then
877      LIBPAW_DEALLOCATE(pawrad%rad)
878    end if
879    if (allocated(pawrad%radfact)) then
880      LIBPAW_DEALLOCATE(pawrad%radfact)
881    end if
882    if (allocated(pawrad%simfact)) then
883      LIBPAW_DEALLOCATE(pawrad%simfact)
884    end if
885 !  Communicate if flag is set to 1:
886    if(if_rad==1) then
887      isz1=pawrad%mesh_size
888      LIBPAW_ALLOCATE(pawrad%rad,(isz1))
889      pawrad%rad(1:isz1)=list_dpr(indx:indx+isz1-1)
890      indx=indx+isz1
891    end if
892    if(if_radfact==1) then
893      isz1=pawrad%mesh_size
894      LIBPAW_ALLOCATE(pawrad%radfact,(isz1))
895      pawrad%radfact(1:isz1)=list_dpr(indx:indx+isz1-1)
896      indx=indx+isz1
897    end if
898    if(if_simfact==1) then
899      isz1=pawrad%mesh_size
900      LIBPAW_ALLOCATE(pawrad%simfact,(isz1))
901      pawrad%simfact(1:isz1)=list_dpr(indx:indx+isz1-1)
902      indx=indx+isz1
903    end if
904  end if
905  LIBPAW_DEALLOCATE(list_dpr)
906 
907 end subroutine pawrad_bcast

m_pawrad/pawrad_copy [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

 pawrad_copy

FUNCTION

 Copy one radial mesh (in a generalized format) to another

INPUTS

  mesh1 <type(pawrad_type)>=data containing radial grid information of input mesh

OUTPUT

  mesh2 <type(pawrad_type)>=data containing radial grid information of output mesh

PARENTS

      m_pawpsp,m_pawpwij

CHILDREN

      poisson,simp_gen

NOTES

  Possible mesh types (mesh%mesh_type)
   mesh_type=1 (regular grid): rad(i)=(i-1)*AA
   mesh_type=2 (logari. grid): rad(i)=AA*(exp[BB*(i-1)]-1)
   mesh_type=3 (logari. grid): rad(i>1)=AA*exp[BB*(i-2)] and rad(1)=0
   mesh_type=4 (logari. grid): rad(i)=-AA*ln[1-BB*(i-1)] with BB=1/n
   mesh_type=5 ( grid): rad(i)=AA*i/(n-i)

SOURCE

641 subroutine pawrad_copy(mesh1,mesh2)
642 
643 
644 !This section has been created automatically by the script Abilint (TD).
645 !Do not modify the following lines by hand.
646 #undef ABI_FUNC
647 #define ABI_FUNC 'pawrad_copy'
648 !End of the abilint section
649 
650  implicit none
651 
652 !Arguments ------------------------------------
653 !scalars
654  type(pawrad_type),intent(in) :: mesh1
655  type(pawrad_type),intent(out) :: mesh2
656 
657 !Local variables-------------------------------
658 !scalars
659  integer :: ir
660 
661 ! *************************************************************************
662 
663  mesh2%mesh_type =mesh1%mesh_type
664  mesh2%mesh_size =mesh1%mesh_size
665  mesh2%int_meshsz=mesh1%int_meshsz
666  mesh2%lstep     =mesh1%lstep
667  mesh2%rstep     =mesh1%rstep
668  mesh2%stepint   =mesh1%stepint
669  mesh2%rmax      =mesh1%rmax
670 
671  LIBPAW_ALLOCATE(mesh2%rad,(mesh1%mesh_size))
672  LIBPAW_ALLOCATE(mesh2%radfact,(mesh1%mesh_size))
673  LIBPAW_ALLOCATE(mesh2%simfact,(mesh1%mesh_size))
674  do ir=1,mesh1%mesh_size
675    mesh2%rad(ir)    =mesh1%rad(ir)
676    mesh2%radfact(ir)=mesh1%radfact(ir)
677    mesh2%simfact(ir)=mesh1%simfact(ir)
678  end do
679 
680 end subroutine pawrad_copy

m_pawrad/pawrad_deducer0 [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

 pawrad_deducer0

FUNCTION

 Extrapolate r=0 value of a function from values near r=0
 using a 3 points formula

INPUTS

  funcsz=size of array func
  radmesh <type(pawrad_type)>=data containing radial grid information

SIDE EFFECTS

  func(funcsz)=array containing values of function to extrapolate

PARENTS

      denfgr,m_paw_atom,m_paw_gaussfit,m_paw_pwaves_lmn,m_paw_slater,m_pawdij
      m_pawpsp,m_pawrad,m_pawxc,make_efg_onsite,optics_paw,optics_paw_core
      pawdenpot,pawdensities,pawnabla_init

CHILDREN

      poisson,simp_gen

SOURCE

710 subroutine pawrad_deducer0(func,funcsz,radmesh)
711 
712 
713 !This section has been created automatically by the script Abilint (TD).
714 !Do not modify the following lines by hand.
715 #undef ABI_FUNC
716 #define ABI_FUNC 'pawrad_deducer0'
717 !End of the abilint section
718 
719  implicit none
720 
721 !Arguments ------------------------------------
722 !scalars
723  integer,intent(in) :: funcsz
724  type(pawrad_type),intent(in) :: radmesh
725 !arrays
726  real(dp),intent(inout) :: func(funcsz)
727 
728 ! *************************************************************************
729 
730  if (radmesh%mesh_type==1.or.radmesh%mesh_type==2.or.radmesh%mesh_type==4.or.radmesh%mesh_type==5) then
731    func(1)=func(4)+3*(func(2)-func(3))
732  else if (radmesh%mesh_type==3) then
733    func(1)=func(4)+exp(two*radmesh%lstep)/(exp(radmesh%lstep)-one)*(func(2)-func(3))
734  end if
735 
736 end subroutine pawrad_deducer0

m_pawrad/pawrad_free_0D [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

  pawrad_free_0D

FUNCTION

  Frees all memory allocated in the object

PARENTS

      m_pawrad

CHILDREN

      poisson,simp_gen

SOURCE

335 subroutine pawrad_free_0D(Rmesh)
336 
337 
338 !This section has been created automatically by the script Abilint (TD).
339 !Do not modify the following lines by hand.
340 #undef ABI_FUNC
341 #define ABI_FUNC 'pawrad_free_0D'
342 !End of the abilint section
343 
344  implicit none
345 
346 !Arguments ------------------------------------
347 !arrays
348  type(pawrad_type),intent(inout) :: Rmesh
349 
350 !Local variables-------------------------------
351 
352 ! *************************************************************************
353 
354  !@Pawrad_type
355 
356  if (allocated(Rmesh%rad    ))  then
357    LIBPAW_DEALLOCATE(Rmesh%rad)
358  end if
359  if (allocated(Rmesh%radfact))  then
360    LIBPAW_DEALLOCATE(Rmesh%radfact)
361  end if
362  if (allocated(Rmesh%simfact))  then
363    LIBPAW_DEALLOCATE(Rmesh%simfact)
364  end if
365  Rmesh%int_meshsz=0
366  Rmesh%mesh_size=0
367  Rmesh%mesh_type=-1
368 
369 end subroutine pawrad_free_0D

m_pawrad/pawrad_free_1D [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

  pawrad_free_1D

FUNCTION

  Destroy all objects in an array of pawrad data structures

PARENTS

CHILDREN

      poisson,simp_gen

SOURCE

388 subroutine pawrad_free_1D(Rmesh)
389 
390 
391 !This section has been created automatically by the script Abilint (TD).
392 !Do not modify the following lines by hand.
393 #undef ABI_FUNC
394 #define ABI_FUNC 'pawrad_free_1D'
395 !End of the abilint section
396 
397  implicit none
398 
399 !Arguments ------------------------------------
400  type(pawrad_type),intent(inout) :: Rmesh(:)
401 
402 !Local variables-------------------------------
403  integer :: ii,nn
404 
405 ! *************************************************************************
406 
407  !@pawrad_type
408 
409  nn=size(Rmesh)
410  if (nn==0) return
411 
412  do ii=1,nn
413    call pawrad_free_0D(Rmesh(ii))
414  end do
415 
416 end subroutine pawrad_free_1D

m_pawrad/pawrad_ifromr [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

 pawrad_ifromr

FUNCTION

 Retreive Index FROM a given R value in a radial grid
 Grid can be regular or logarithimc

INPUTS

  rr=given input r value
  radmesh <type(pawrad_type)>=data containing radial grid information

OUTPUT

  pawrad_ifromr=index of rr in radial grid

PARENTS

CHILDREN

NOTES

  Possible mesh types (radmesh%mesh_type)
   mesh_type=1 (regular grid): rad(i)=(i-1)*AA
   mesh_type=2 (logari. grid): rad(i)=AA*(exp[BB*(i-1)]-1)
   mesh_type=3 (logari. grid): rad(i>1)=AA*exp[BB*(i-2)] and rad(1)=0
   mesh_type=4 (logari. grid): rad(i)=-AA*ln[1-BB*(i-1)] with BB=1/n
   mesh_type=5 ( grid): rad(i)=AA*i/(n-i)

SOURCE

1612 function pawrad_ifromr(radmesh,rr)
1613 
1614 
1615 !This section has been created automatically by the script Abilint (TD).
1616 !Do not modify the following lines by hand.
1617 #undef ABI_FUNC
1618 #define ABI_FUNC 'pawrad_ifromr'
1619 !End of the abilint section
1620 
1621  implicit none
1622 
1623 !Arguments ------------------------------------
1624 !scalars
1625  integer :: pawrad_ifromr
1626  real(dp),intent(in) :: rr
1627  type(pawrad_type),intent(in) :: radmesh
1628 
1629 !Local variables-------------------------------
1630  character(len=500) :: msg
1631 
1632 ! *************************************************************************
1633 
1634  if (radmesh%mesh_type==1) then
1635    pawrad_ifromr=int(tol8+rr/radmesh%rstep)+1
1636  else if (radmesh%mesh_type==2) then
1637    pawrad_ifromr=int(tol8+log(1.d0+rr/radmesh%rstep)/radmesh%lstep)+1
1638  else if (radmesh%mesh_type==3) then
1639    if (rr<radmesh%rstep) then
1640      pawrad_ifromr=1
1641    else
1642      pawrad_ifromr=int(tol8+log(rr/radmesh%rstep)/radmesh%lstep)+2
1643    end if
1644  else if (radmesh%mesh_type==4) then
1645    pawrad_ifromr=int(tol8+(1.d0-exp(-rr/radmesh%rstep))/radmesh%lstep)+1
1646  else if (radmesh%mesh_type==5) then
1647    pawrad_ifromr=int(tol8+(radmesh%lstep*rr)/(radmesh%rstep+rr))+1
1648  else
1649 !  Other values of mesh_type are not allowed (see psp7in.F90)
1650    write(msg,'(a,i0)')" Unknown value of %mesh_type ",radmesh%mesh_type
1651    MSG_ERROR(msg)
1652  end if
1653 
1654 end function pawrad_ifromr

m_pawrad/pawrad_init [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

  pawrad_init

FUNCTION

  Creation method for radial meshes.
  Compute all points (and related weights) of a radial mesh.
  Grid can be regular or logarithimc.

INPUTS

  [mesh_size]=Dimension of the radial mesh
              If not present, take mesh%mesh_size
  [mesh_type]=Type of mesh
              If not present, take mesh%mesh_type
  [rstep]=Radial step of the mesh (AA parameter above)
          If not present, take mesh%rstep
  [lstep]=Exponential step of the mesh (BB parameter above)
          If not present, take mesh%lstep
          Needed only if mesh type is logarithmic.
  [r_for_intg]=Mesh size used in integrals computation
               If not present, take mesh%r_for_intg
    Integrals will be computed up to rr(r_for_intg)
    (can be negative for an integration over the whole grid)

OUTPUT

SIDE EFFECTS

  mesh<pawrad_type>=The object completely initialized (containing radial grid information).
  The following quantities are calculated inside the routine:
    %stepint = Radial step used to convert any function from the
               present grid onto a regular grid in order to integrate it using trapeze method
    %rad(mesh_size) = Coordinates of all the points of the mesh.
    %radfact(mesh_size) = Factors used to compute radial integrals.
    %int_meshsz = Integrals will be computed up to r(int_meshsz)
    %simfact(mesh_size) = Factor used to compute radial integrals by the a Simpson scheme
                          Integral[f] = Sum_i [simfact(i)*f(i)]
    %rmax = Max. value of r = rad(mesh_size)

PARENTS

      dfpt_eltfrxc,m_atom,m_paw_gaussfit,m_pawpsp,m_pawpwij,m_pawxmlps,m_psps
      mkcore,mkcore_paw,mkcore_wvl,psp8in,psp9in,wvl_initro

CHILDREN

      poisson,simp_gen

NOTES

  Possible mesh types (mesh%mesh_type)
   mesh_type=1 (regular grid): rad(i)=(i-1)*AA
   mesh_type=2 (logari. grid): rad(i)=AA*(exp[BB*(i-1)]-1)
   mesh_type=3 (logari. grid): rad(i>1)=AA*exp[BB*(i-2)] and rad(1)=0
   mesh_type=4 (logari. grid): rad(i)=-AA*ln[1-BB*(i-1)] with BB=1/n
   mesh_type=5 ( grid): rad(i)=AA*i/(n-i)

SOURCE

198 subroutine pawrad_init(mesh,mesh_size,mesh_type,rstep,lstep,r_for_intg)
199 
200 
201 !This section has been created automatically by the script Abilint (TD).
202 !Do not modify the following lines by hand.
203 #undef ABI_FUNC
204 #define ABI_FUNC 'pawrad_init'
205 !End of the abilint section
206 
207  implicit none
208 
209 !Arguments ------------------------------------
210 !scalars
211  integer,intent(in),optional :: mesh_size,mesh_type
212  real(dp),intent(in),optional :: rstep,lstep
213  real(dp),intent(in),optional :: r_for_intg
214  type(pawrad_type),intent(inout) :: mesh
215 
216 !Local variables-------------------------------
217 !scalars
218  integer :: ir,ir_last,isim,mesh_size_,mesh_type_
219  real(dp) :: hh,lstep_,rstep_,r_for_intg_
220  character(len=500) :: msg
221 
222 ! *************************************************************************
223 
224  !@pawrad_type
225 
226 !Retrieve mesh data
227  mesh_size_ = mesh%mesh_size ; if (present(mesh_size)) mesh_size_ = mesh_size
228  mesh_type_ = mesh%mesh_type ; if (present(mesh_type)) mesh_type_ = mesh_type
229  rstep_ = mesh%rstep ; if (present(rstep)) rstep_ = rstep
230  lstep_ = mesh%lstep ; if (present(lstep)) lstep_ = lstep
231 
232  r_for_intg_=-1._dp;if (present(r_for_intg)) r_for_intg_=r_for_intg
233 
234  mesh%mesh_size = mesh_size_
235  mesh%mesh_type = mesh_type_
236  mesh%rstep     = rstep_
237  mesh%lstep     = lstep_
238  LIBPAW_ALLOCATE(mesh%rad    ,(mesh%mesh_size))
239  LIBPAW_ALLOCATE(mesh%radfact,(mesh%mesh_size))
240  LIBPAW_ALLOCATE(mesh%simfact,(mesh%mesh_size))
241  mesh%simfact=zero
242  if (mesh%mesh_type==1) then
243    isim=3
244    mesh%stepint=mesh%rstep
245    mesh%rad(1)=zero;mesh%radfact(1)=one
246    do ir=2,mesh%mesh_size
247      mesh%rad(ir) =mesh%rstep*dble(ir-1)
248      mesh%radfact(ir)=one
249    end do
250  else if (mesh%mesh_type==2) then
251    isim=3
252    mesh%stepint=mesh%lstep
253    mesh%rad(1)=zero;mesh%radfact(1)=mesh%rstep
254    do ir=2,mesh%mesh_size
255      mesh%rad(ir) =mesh%rstep*(exp(mesh%lstep*dble(ir-1))-one)
256      mesh%radfact(ir)=mesh%rad(ir)+mesh%rstep
257    end do
258  else if (mesh%mesh_type==3) then
259    isim=4
260    mesh%stepint=mesh%lstep
261    mesh%rad(1)=zero;mesh%radfact(1)=zero
262    do ir=2,mesh%mesh_size
263      mesh%rad(ir) =mesh%rstep*exp(mesh%lstep*dble(ir-2))
264      mesh%radfact(ir)=mesh%rad(ir)
265    end do
266  else if (mesh%mesh_type==4) then
267    isim=3
268    mesh%lstep=one/dble(mesh%mesh_size)
269    mesh%stepint=mesh%lstep
270    mesh%rad(1)=zero;mesh%radfact(1)=mesh%rstep
271    do ir=2,mesh%mesh_size
272      mesh%rad(ir) =-mesh%rstep*log(one-mesh%lstep*dble(ir-1))
273      mesh%radfact(ir)=mesh%rstep/(one-mesh%lstep*dble(ir-1))
274    end do
275  else if (mesh%mesh_type==5) then
276    isim=3
277    mesh%stepint=mesh%rstep
278    mesh%rad(1)=zero;mesh%radfact(1)=1/mesh%lstep
279    do ir=2,mesh%mesh_size
280      mesh%rad(ir) =mesh%rstep*dble(ir-1)/(mesh%lstep-dble(ir-1))
281      mesh%radfact(ir)=(mesh%rstep+mesh%rad(ir))/(mesh%lstep-dble(ir-1))/mesh%rstep
282    end do
283 
284  else !  Other values of mesh_type are not allowed (see psp7in.F90)
285   write(msg,'(a,i0)')" Unknown value of mesh_type: ",mesh%mesh_type
286   MSG_ERROR(msg)
287  end if
288 
289  mesh%int_meshsz=mesh%mesh_size
290  if (r_for_intg_>0.d0) then
291    ir=min(pawrad_ifromr(mesh,r_for_intg_),mesh%mesh_size)
292    if (ir<mesh%mesh_size) then
293      if (abs(mesh%rad(ir+1)-r_for_intg_)<abs(mesh%rad(ir)-r_for_intg_)) ir=ir+1
294    end if
295    if (ir>1) then
296      if (abs(mesh%rad(ir-1)-r_for_intg_)<abs(mesh%rad(ir)-r_for_intg_)) ir=ir-1
297    end if
298    mesh%int_meshsz=ir
299  end if
300 
301  hh=mesh%stepint/3.d0
302  mesh%simfact(mesh%int_meshsz)=hh*mesh%radfact(mesh%int_meshsz)
303  mesh%simfact(1:isim-2)=zero
304  ir_last=1
305  do ir=mesh%int_meshsz,isim,-2
306    mesh%simfact(ir-1)=4.d0*hh*mesh%radfact(ir-1)
307    mesh%simfact(ir-2)=2.d0*hh*mesh%radfact(ir-2)
308    ir_last=ir-2
309  end do
310  mesh%simfact(ir_last)=half*mesh%simfact(ir_last)
311  if (mesh%int_meshsz<mesh%mesh_size) mesh%simfact(mesh%int_meshsz+1:mesh%mesh_size)=zero
312 
313  mesh%rmax=mesh%rad(mesh%mesh_size)
314 
315 end subroutine pawrad_init

m_pawrad/pawrad_isame [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

  pawrad_isame

FUNCTION

  Check two radial meshes, returns a logical flag defining
  whether the meshes have the same equation and an integer
  flag

INPUTS

  Rmesh1,Rmesh2<pawrad_type>=The two radial meshes.

OUTPUT

  hasameq=.true. if the two meshes are defined by the same equation.
  whichdenser=
    * 0 if meshes are not compatible
    * 1 if Rmesh1 is denser than Rmesh2
    * 2 if Rmesh2 is denser than Rmesh1

PARENTS

      m_atom,m_paw_slater

CHILDREN

      poisson,simp_gen

SOURCE

550 subroutine pawrad_isame(Rmesh1,Rmesh2,hasameq,whichdenser)
551 
552 
553 !This section has been created automatically by the script Abilint (TD).
554 !Do not modify the following lines by hand.
555 #undef ABI_FUNC
556 #define ABI_FUNC 'pawrad_isame'
557 !End of the abilint section
558 
559  implicit none
560 
561 !Arguments ------------------------------------
562  integer,intent(out) :: whichdenser
563  logical,intent(out) :: hasameq
564  type(pawrad_type),intent(in) :: Rmesh1
565  type(pawrad_type),intent(in) :: Rmesh2
566 
567 !Local variables-------------------------------
568  character(len=50) :: msg
569 
570 ! *************************************************************************
571 
572  !@pawrad_type
573 
574  whichdenser =0 ; hasameq=.FALSE.
575 
576  if (Rmesh1%mesh_type /= Rmesh2%mesh_type) RETURN
577 
578  SELECT CASE (Rmesh1%mesh_type)
579 
580  CASE (RMESH_LINEAR) !check for linear meshes
581    hasameq = (Rmesh1%rstep == Rmesh2%rstep)
582 
583  CASE (RMESH_LOG1,&  !check for logarithmic meshes
584 &      RMESH_LOG2,&
585 &      RMESH_LOG3)
586 
587    hasameq = (    Rmesh1%rstep == Rmesh2%rstep &
588 &            .and.Rmesh1%lstep == Rmesh2%lstep )
589 
590  CASE (RMESH_NL) !check for linear meshes
591    hasameq = (Rmesh1%rstep == Rmesh2%rstep)
592 
593  CASE DEFAULT
594    msg='Unknown mesh type'
595    MSG_ERROR(msg)
596 
597  END SELECT
598 
599  ! === If meshes have same equation, check whether they are equal ===
600  ! * Note that also int_meshsz must be equal
601  if (hasameq) then
602    whichdenser= 1
603    if (Rmesh2%mesh_size  > Rmesh1%mesh_size ) whichdenser = 2
604    !if (Rmesh1%int_meshsz == Rmesh2%int_meshsz) whichdenser = 2
605  end if
606 
607 end subroutine pawrad_isame

m_pawrad/pawrad_print [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

  pawrad_print

FUNCTION

  Reports basic info on the object.

INPUTS

  Rmesh<pawrad_type>=Object defining the radial mesh
  header=String for the header provided by the user.
  [unit]=Unit number for output, defaults to std_out
  [prtvol]=Verbosity level, minimal if not specified.
  [mode_paral]=Either "COLL" or "PERS". Passed to wrtout. Defaults to "COLL"

OUTPUT

  Only writing.

PARENTS

      m_atom

CHILDREN

      poisson,simp_gen

SOURCE

446 subroutine pawrad_print(Rmesh,header,unit,prtvol,mode_paral)
447 
448 
449 !This section has been created automatically by the script Abilint (TD).
450 !Do not modify the following lines by hand.
451 #undef ABI_FUNC
452 #define ABI_FUNC 'pawrad_print'
453 !End of the abilint section
454 
455  implicit none
456 
457 !Arguments ------------------------------------
458  integer,intent(in),optional :: prtvol,unit
459  character(len=4),intent(in),optional :: mode_paral
460  character(len=*),intent(in),optional :: header
461  type(pawrad_type),intent(in) :: Rmesh
462 
463 !Local variables-------------------------------
464 !scalars
465  integer :: my_unt,my_prtvol
466  character(len=4) :: my_mode
467  character(len=500) :: msg
468 
469 ! *************************************************************************
470 
471  !@pawrad_type
472  my_unt   =std_out; if (PRESENT(unit      )) my_unt   =unit
473  my_prtvol=0      ; if (PRESENT(prtvol    )) my_prtvol=prtvol
474  my_mode  ='COLL' ; if (PRESENT(mode_paral)) my_mode  =mode_paral
475 
476  msg=ch10//' ==== Info on the Radial Mesh ==== '
477  if (PRESENT(header)) msg=ch10//' ==== '//TRIM(ADJUSTL(header))//' ==== '
478  call wrtout(my_unt,msg,my_mode)
479 
480  SELECT CASE (Rmesh%mesh_type)
481 
482  CASE (RMESH_LINEAR)
483    write(msg,'(a,i4,a,g12.5)')&
484 &    ' - Linear mesh: r(i)=step*(i-1), size=',Rmesh%mesh_size,', step=',Rmesh%rstep
485 
486  CASE (RMESH_LOG1)
487    write(msg,'(a,i4,2(a,g12.5))')&
488 &    ' - Logarithimc mesh: r(i)=AA*[exp(BB*(i-1))-1], size=',Rmesh%mesh_size,', AA=',Rmesh%rstep,' BB=',Rmesh%lstep
489 
490  CASE (RMESH_LOG2)
491    write(msg,'(a,i4,2(a,g12.5))')&
492 &    ' - Logarithimc mesh: r(i)=AA*exp(BB*(i-2)), size=',Rmesh%mesh_size,', AA=',Rmesh%rstep,' BB=',Rmesh%lstep
493 
494  CASE (RMESH_LOG3)
495    write(msg,'(a,i1,a,i4,a,g12.5)')&
496 &    ' - Logarithimc mesh: r(i)=-AA*ln(1-(i-1)/n), n=size=',Rmesh%mesh_size,', AA=',Rmesh%rstep
497 
498  CASE (RMESH_NL)
499    write(msg,'(a,i1,a,i4,a,g12.5)')&
500 &    ' - Non-linear mesh: r(i)=-AA*i/(n-i), n=size=',Rmesh%mesh_size,', AA=',Rmesh%rstep
501 
502  CASE DEFAULT
503    msg = ' Unknown mesh type! Action : check your pseudopotential or input file.'
504    MSG_ERROR(msg)
505  END SELECT
506 
507  call wrtout(my_unt,msg,my_mode)
508 
509  if (my_prtvol>1) then
510    write(msg,'(a,i4)')' Mesh size for integrals = ',Rmesh%int_meshsz
511    call wrtout(my_unt,msg,my_mode)
512    write(msg,'(a,g12.5)')' rmax=rad(mesh_size)     = ',Rmesh%rmax
513    call wrtout(my_unt,msg,my_mode)
514    write(msg,'(a,g12.5)')' Value of stepint        = ',Rmesh%stepint
515    call wrtout(my_unt,msg,my_mode)
516  end if
517 
518 end subroutine pawrad_print

m_pawrad/pawrad_type [ Types ]

[ Top ] [ m_pawrad ] [ Types ]

NAME

 pawrad_type

FUNCTION

 For PAW, RADial mesh discretization and related data

SOURCE

 84  type, public :: pawrad_type
 85 
 86 !Integer scalars
 87 
 88   integer :: int_meshsz=0
 89    ! Mesh size used in integrals computation
 90    ! Integrals will be computed up to r(int_meshsz)
 91 
 92   integer :: mesh_size=0
 93    ! Dimension of radial mesh
 94 
 95   integer :: mesh_type=-1
 96    ! Type of mesh
 97    !     1=regular grid: r(i)=(i-1)*AA
 98    !     2=logarithmic grid: r(i)=AA*(exp[BB*(i-1)]-1)
 99    !     3=logarithmic grid: r(i>1)=AA*exp[BB*(i-1)] and r(1)=0
100    !     4=logarithmic grid: r(i)=-AA*ln[1-BB*(i-1)] with BB=1/n
101 
102 !Real (real(dp)) scalars
103 
104   real(dp) :: lstep=zero
105    ! Exponential step of the mesh (BB parameter above)
106    ! Defined only if mesh type is logarithmic
107 
108   real(dp) :: rmax=zero
109    ! Max. value of r = rad(mesh_size)
110 
111   real(dp) :: rstep=zero
112    ! Radial step of the mesh (AA parameter above)
113 
114   real(dp) :: stepint=zero
115    ! Radial step used to convert any function from the
116    ! present grid onto a regular grid in order to
117    ! integrate it using trapeze method
118 
119 !Real (real(dp)) arrays
120 
121   real(dp), allocatable :: rad(:)
122    ! rad(mesh_size)
123    ! Coordinates of all the points of the mesh
124 
125   real(dp), allocatable :: radfact(:)
126    ! radfact(mesh_size)
127    ! Factor used to compute radial integrals
128    ! Before being integrated on the present mesh,
129    ! any function is multiplied by this factor
130 
131   real(dp), allocatable :: simfact(:)
132    ! simfact(mesh_size)
133    ! Factor used to compute radial integrals by the a Simpson scheme
134    ! Integral[f] = Sum_i [simfact(i)*f(i)]
135 
136  end type pawrad_type

m_pawrad/poisson [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

 poisson

FUNCTION

  Solve poisson equation for angularly dependent charge
  distribution of angular momentum l
  Densities and potentials are given on a (generalized) radial grid

INPUTS

  den(:)= electron density * (4*pi*r**2) appropriate for l
  ll= l quantum number
  radmesh <type(pawrad_type)>=data containing radial grid information
  [screened_sr_separation]= --optional-- separation for screened short-range kernel
                            no screening by default

OUTPUT

  [qq]= --optional-- lth moment of the charge; not compatible with screened Coulomb interaction
  rv(:)= electrostatic potential * r in (Hartree*Bohr) units
          where v(r)=\frac{1}{2l+1}(\frac{int[(r''^(l+2))g(r'')dr'']} {r^(l+1)}
                                   +(r^l) int[r''^(1-l)g(r'')dr''])

PARENTS

      calc_ubare,m_paw_atom,m_pawpsp,m_pawrad,pawdenpot,pawinit,pawpuxinit

CHILDREN

      poisson,simp_gen

SOURCE

1357 subroutine poisson(den,ll,radmesh,rv,screened_sr_separation,qq)
1358 
1359 
1360 !This section has been created automatically by the script Abilint (TD).
1361 !Do not modify the following lines by hand.
1362 #undef ABI_FUNC
1363 #define ABI_FUNC 'poisson'
1364 !End of the abilint section
1365 
1366  implicit none
1367 
1368 !Arguments ---------------------------------------------
1369 !scalars
1370  integer,intent(in) :: ll
1371  real(dp),intent(out),optional :: qq
1372  real(dp),intent(in),optional :: screened_sr_separation
1373  type(pawrad_type),intent(in) :: radmesh
1374 !arrays
1375  real(dp),intent(in) :: den(:)
1376  real(dp),intent(out) :: rv(:)
1377 
1378 !Local variables ---------------------------------------
1379 !scalars
1380  integer :: ir,jr,mesh_size,mm,nn
1381  logical :: use_numerov,use_screened
1382  real(dp) :: angm,hh,intg,qq_,ri,rj,rr,sr_omega
1383 !arrays
1384  real(dp) :: ee(4)
1385  real(dp),allocatable :: aa(:),bb(:),cc(:),dd(:),radl(:),radl1(:)
1386 
1387 ! ***************************************************************************
1388 
1389  mesh_size=size(den)
1390  if (size(rv)/=mesh_size.or.mesh_size>radmesh%mesh_size) then
1391    MSG_BUG('wrong sizes!')
1392  end if
1393 
1394  use_numerov=(radmesh%mesh_type==1)
1395 
1396  use_screened=.false.;sr_omega=zero
1397  if (present(screened_sr_separation)) then
1398    sr_omega=screened_sr_separation
1399    use_screened=(sr_omega>tol8)
1400 !  Numerov method not coded for screened Coulomb interaction
1401    if (use_numerov.and.use_screened) use_numerov=.false.
1402  end if
1403 
1404 !==============================================
1405 !UNIFORM GRID - NUMEROV ALGORITHM
1406 !==============================================
1407  if (use_numerov) then
1408    hh=radmesh%rstep
1409    nn=radmesh%int_meshsz-1
1410    LIBPAW_ALLOCATE(aa,(nn))
1411    LIBPAW_ALLOCATE(bb,(nn))
1412    LIBPAW_ALLOCATE(cc,(nn+1))
1413    do ir=1,nn
1414      aa(ir)=two*hh*den(ir+1)/(ir)
1415      bb(ir)=den(ir+1)*((ir*hh)**ll)
1416    end do
1417    cc(1)=zero
1418    cc(2:nn+1)=bb(1:nn)
1419    call simp_gen(qq_,cc,radmesh)
1420    qq_=qq_/dble(2*ll+1)
1421    rv(1)=aa(1)+0.1_dp*aa(2)
1422    do ir=2,nn-1
1423      rv(ir)=aa(ir)+0.1_dp*(aa(ir+1)+aa(ir-1))
1424    end do
1425    rv(nn)=aa(nn)+0.1_dp*aa(nn-1)
1426    angm=dble(ll*(ll+1))
1427    rr=(nn+1)*hh
1428    rv(nn)=rv(nn)+(2.4_dp-0.2_dp*angm/((nn+1)**2))*qq_/(rr**ll)
1429    do ir=1,nn
1430      aa(ir)=angm/(ir*ir)
1431      bb(ir)=2.4_dp+aa(ir)
1432    end do
1433    do ir=1,nn-1
1434      cc(ir)=-1.2_dp+0.1_dp*aa(ir+1)
1435    end do
1436    do ir=nn,2,-1
1437      aa(ir)=-1.2_dp+0.1_dp*aa(ir-1)
1438    end do
1439    if (nn.eq.1) then
1440      rv(2)=rv(1)/bb(1)
1441      rv(1)=zero
1442    else
1443      do ir=2,nn
1444        bb(ir)=bb(ir)-aa(ir)*cc(ir-1)/bb(ir-1)
1445      end do
1446      rv(1)=rv(1)/bb(1)
1447      do ir=2,nn
1448        rv(ir)=(rv(ir)-aa(ir)*rv(ir-1))/bb(ir)
1449      end do
1450      do ir=nn-1,1,-1
1451        rv(ir)=rv(ir)-cc(ir)*rv(ir+1)/bb(ir)
1452      end do
1453      do ir=nn+1,2,-1
1454        rv(ir)=rv(ir-1)
1455      end do
1456      rv(1)=zero
1457      if (nn+1<mesh_size) rv(nn+2:mesh_size)=zero
1458    end if
1459    rv(:)=half*rv(:)
1460    if (present(qq)) qq=qq_
1461    LIBPAW_DEALLOCATE(aa)
1462    LIBPAW_DEALLOCATE(bb)
1463    LIBPAW_DEALLOCATE(cc)
1464 
1465 !  ==============================================
1466 !  ANY OTHER GRID - SIMPSON ALGORITHM
1467 !  ==============================================
1468  else
1469    nn=mesh_size;hh=third*radmesh%stepint
1470    do while (abs(den(nn))<tol16.and.nn>radmesh%int_meshsz)
1471      nn=nn-1
1472    end do
1473    mm=nn;if (radmesh%mesh_type==3) mm=mm-1
1474    LIBPAW_ALLOCATE(aa,(nn))
1475    LIBPAW_ALLOCATE(bb,(nn))
1476    LIBPAW_ALLOCATE(cc,(nn))
1477    LIBPAW_ALLOCATE(dd,(nn))
1478 
1479    if (.not.use_screened) then
1480 
1481 !    Standard Coulomb integral
1482      LIBPAW_ALLOCATE(radl,(nn))
1483      LIBPAW_ALLOCATE(radl1,(nn))
1484      do jr=nn,2,-1
1485        ir=nn-jr+1
1486        radl(jr) =radmesh%rad(jr)**ll
1487        radl1(jr)=radmesh%rad(jr)*radl(jr)
1488        aa(ir)=den(jr)*radmesh%radfact(jr)*radl(jr)
1489        bb(ir)=den(jr)*radmesh%radfact(jr)/radl1(jr)
1490      end do
1491      radl(1)=zero;radl1(1)=zero
1492      ee(2)=aa(nn-1);ee(3)=aa(nn-2);ee(4)=aa(nn-3)
1493      call pawrad_deducer0(ee,4,radmesh)
1494      aa(nn)=ee(1)
1495      ee(2)=bb(nn-1);ee(3)=bb(nn-2);ee(4)=bb(nn-3)
1496      call pawrad_deducer0(ee,4,radmesh)
1497      bb(nn)=ee(1)
1498      cc(1)=zero;dd(1)=zero
1499      do ir=3,mm,2
1500        cc(ir)  =cc(ir-2)+hh*(aa(ir-2)+four*aa(ir-1)+aa(ir))
1501        cc(ir-1)=cc(ir-2)+hh*(1.25_dp*aa(ir-2)+two*aa(ir-1)-quarter*aa(ir))
1502        dd(ir)  =dd(ir-2)+hh*(bb(ir-2)+four*bb(ir-1)+bb(ir))
1503        dd(ir-1)=dd(ir-2)+hh*(1.25_dp*bb(ir-2)+two*bb(ir-1)-quarter*bb(ir))
1504      end do
1505      if (mod(mm,2)==0) then
1506 !      cc(mm)=cc(mm-2)+hh*(aa(mm-2)+four*aa(mm-1)+aa(mm))
1507 !      dd(mm)=dd(mm-2)+hh*(bb(mm-2)+four*bb(mm-1)+bb(mm))
1508        cc(mm)=cc(mm-1)+hh*(1.25_dp*aa(mm-2)+two*aa(mm-1)-quarter*aa(mm))
1509        dd(mm)=dd(mm-1)+hh*(1.25_dp*bb(mm-2)+two*bb(mm-1)-quarter*bb(mm))
1510      end if
1511      if (mm<nn) then
1512        cc(nn)=cc(mm)+half*(aa(mm)+aa(nn))*(radmesh%rad(1+nn-mm)-radmesh%rad(1))
1513        dd(nn)=dd(mm)+half*(bb(mm)+bb(nn))*(radmesh%rad(1+nn-mm)-radmesh%rad(1))
1514      end if
1515      rv(1)=zero
1516      do ir=2,nn
1517        jr=nn-ir+1
1518        rv(ir)=(dd(jr)*radl1(ir)+(cc(nn)-cc(jr))/radl(ir))/(two*ll+one)
1519      end do
1520      if (nn<mesh_size) rv(nn+1:mesh_size)=rv(nn)
1521      if (present(qq)) qq=cc(nn)/(two*ll+one)
1522      LIBPAW_DEALLOCATE(radl)
1523      LIBPAW_DEALLOCATE(radl1)
1524    else
1525 
1526 !    Short-range screened Coulomb integral
1527      rv(1)=zero
1528      do ir=2,nn
1529        ri=sr_omega*radmesh%rad(ir)
1530        do jr=2,nn
1531          rj=sr_omega*radmesh%rad(jr)
1532          aa(jr)=den(jr)*radmesh%radfact(jr)*sr_omega*screened_coul_kernel(ll,ri,rj)
1533        end do
1534        call pawrad_deducer0(aa(1:4),4,radmesh)
1535        intg=zero
1536 !      Compute the integral in 2 parts because the function is not differentiable at r(ir)
1537 !      Integral from zero to r(ir)
1538        if (ir>2) then
1539          do jr=ir-2,1,-2
1540            intg=intg+hh*(aa(jr)+four*aa(jr+1)+aa(jr+2))
1541          end do
1542          if (mod(ir,2)==0) intg=intg+hh*(-quarter*aa(1)+two*aa(2)+1.25_dp*aa(3))
1543        else if (ir==2) then
1544         if (nn >2) intg=intg+hh*(+1.25_dp*aa(1)+two*aa(2)-quarter*aa(3))
1545         if (nn==2) intg=intg+(aa(1)+aa(2))*hh*half
1546        end if
1547        if (mm<nn) intg=intg+half*(aa(1+nn-mm)+aa(nn))*(radmesh%rad(1+nn-mm)-radmesh%rad(1))
1548 !      Integral from r(ir) to rmax
1549        if (ir<nn-2) then
1550          do jr=ir+2,nn,2
1551            intg=intg+hh*(aa(jr-2)+four*aa(jr-1)+aa(jr))
1552          end do
1553          if (mod(nn-ir,2)==1) then
1554            if (ir<=nn-4) then
1555              !Use a high-order formula because points are spaced
1556              intg=intg+hh*(251._dp*aa(nn)+646._dp*aa(nn-1)-264._dp*aa(nn-2) &
1557 &                         +106._dp*aa(nn-3)-19._dp*aa(nn-4))/240._dp
1558            else
1559              intg=intg+hh*(1.25_dp*aa(nn)+two*aa(nn-1)-quarter*aa(nn-2))
1560            endif
1561          end if
1562        else if (ir==nn-1) then
1563          intg=intg+(aa(nn-1)+aa(nn))*hh*half
1564        end if
1565        rv(ir)=intg/(two*ll+one)*radmesh%rad(ir)
1566      end do
1567      if (nn<mesh_size) rv(nn+1:mesh_size)=rv(nn)
1568      if (present(qq)) qq=zero ! Not relevant
1569 
1570    end if
1571    LIBPAW_DEALLOCATE(aa)
1572    LIBPAW_DEALLOCATE(bb)
1573    LIBPAW_DEALLOCATE(cc)
1574    LIBPAW_DEALLOCATE(dd)
1575 
1576  end if
1577 
1578 end subroutine poisson

m_pawrad/screened_coul_kernel [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

 screened_coul_kernel

FUNCTION

  Evaluates the kernel function used to compute the integral
  of a screened Coulomb potential (with erfc function)
  See Angyan, Gerber, Marsman, J. Phys. A: Math. Gen. 39, 8613 (2006) [[cite:Angyan2006]]

INPUTS

  [formula]=optional; used to force formula (1=full; 2=dev. near r2=0; 3=dev near r1*r2=0)
  order= order of the function (typically l quantum number)
  r1,r2=input arguments

OUTPUT

  screened_coul_kernel=output radial function

PARENTS

CHILDREN

SOURCE

1682 function screened_coul_kernel(order,r1,r2,formula)
1683 
1684 
1685 !This section has been created automatically by the script Abilint (TD).
1686 !Do not modify the following lines by hand.
1687 #undef ABI_FUNC
1688 #define ABI_FUNC 'screened_coul_kernel'
1689 !End of the abilint section
1690 
1691  implicit none
1692 
1693 !Arguments ------------------------------------
1694 !scalars
1695  integer,intent(in) :: order
1696  integer,optional :: formula
1697  real(dp),intent(in) :: r1,r2
1698  real(dp) :: screened_coul_kernel
1699 !Local variables-------------------------------
1700  integer :: formula_
1701  real(dp) :: difexp,erfcp,erfcm,f0,f1,f2,f3,f4,f5,f6,hh,sqrtpi,sumexp,xx,xy,yy
1702  character(len=100) :: msg
1703 
1704 !******************************************************************
1705 
1706  if (order>6) then
1707    msg='PAW screened exchange not coded for l>2!'
1708    MSG_ERROR(msg)
1709  end if
1710 
1711 !Use max and min of arguments
1712  xx=max(r1,r2) ; yy=min(r1,r2)
1713 
1714 !Unscreened Coulomb interaction for very small (or negative) arguments
1715  if (xx<tol8) then
1716   screened_coul_kernel=yy**order/xx**(order+1) ; return
1717  end if
1718 
1719 !Choice of formula
1720 !Empirical criterion, inspired by J. Phys. A 39, pp8624 [[cite:Angyan2006]] and adjusted
1721  formula_=1;if (xx<0.25_dp.and.yy<0.25_dp) formula_=2
1722  if (present(formula)) formula_=formula
1723  select case (formula_)
1724 
1725 !Full formula
1726 !J. Phys. A 39, 8613 (2006) - Eq. (21), (22), (24) [[cite:Angyan2006]]
1727 !   Note: typo in the paper: in eq (22), the sum begins at p=0
1728 !------------------------------------------------------------------
1729  case(1)
1730    xy=xx*yy ; sqrtpi=sqrt(pi)
1731    sumexp=exp(-(xx+yy)**2)+exp(-(xx-yy)**2)
1732    difexp=exp(-(xx+yy)**2)-exp(-(xx-yy)**2)
1733    erfcp=paw_derfc(xx+yy) ; erfcm=paw_derfc(xx-yy)
1734    if (order==0) then
1735      f0=-difexp/(two*sqrtpi*xy)
1736      hh=((xx+yy)*erfcp-(xx-yy)*erfcm)/(two*xy)
1737      screened_coul_kernel = hh + f0
1738    else if(order==1) then
1739      f0=-difexp/(two*sqrtpi*xy)
1740      f1=(difexp+two*xy*sumexp)/(sqrtpi*(two*xy)**2)
1741      hh=((xx**3+yy**3)*erfcp-(xx**3-yy**3)*erfcm)/(two*xy**2)
1742      screened_coul_kernel = hh + f1 + f0*(xx**2+yy**2)/xy
1743    else if (order==2) then
1744      f0=-difexp/(two*sqrtpi*xy)
1745      f1=(difexp+two*xy*sumexp)/(sqrtpi*(two*xy)**2)
1746      f2= -((four*xy**2+three)*difexp+6._dp*xy*sumexp)/(sqrtpi*(two*xy)**3)
1747      hh=((xx**5+yy**5)*erfcp-(xx**5-yy**5)*erfcm)/(two*xy**3)
1748      screened_coul_kernel = hh + f2 + f1*(xx**2+yy**2)/xy + f0*(xx**4+yy**4)/xy**2
1749    else if (order==3) then
1750      f0=-difexp/(two*sqrtpi*xy)
1751      f1=(difexp+two*xy*sumexp)/(sqrtpi*(two*xy)**2)
1752      f2= -((four*xy**2+three)*difexp+6._dp*xy*sumexp)/(sqrtpi*(two*xy)**3)
1753      f3=((24._dp*xy**2+15._dp)*difexp+(8._dp*xy**3+30._dp*xy)*sumexp)/(sqrtpi*(two*xy)**4)
1754      hh=((xx**7+yy**7)*erfcp-(xx**7-yy**7)*erfcm)/(two*xy**4)
1755      screened_coul_kernel = hh + f3 + f2*(xx**2+yy**2)/xy    + f1*(xx**4+yy**4)/xy**2 &
1756 &                                   + f0*(xx**6+yy**6)/xy**3
1757    else if (order==4) then
1758      f0=-difexp/(two*sqrtpi*xy)
1759      f1=(difexp+two*xy*sumexp)/(sqrtpi*(two*xy)**2)
1760      f2= -((four*xy**2+three)*difexp+6._dp*xy*sumexp)/(sqrtpi*(two*xy)**3)
1761      f3=((24._dp*xy**2+15._dp)*difexp+(8._dp*xy**3+30._dp*xy)*sumexp)/(sqrtpi*(two*xy)**4)
1762      f4=-((16._dp*xy**4+180._dp*xy**2+105._dp)*difexp &
1763 &        +(80._dp*xy**3+210._dp*xy)*sumexp)/(sqrtpi*(two*xy)**5)
1764      hh=((xx**9+yy**9)*erfcp-(xx**9-yy**9)*erfcm)/(two*xy**5)
1765      screened_coul_kernel = hh + f4 + f3*(xx**2+yy**2)/xy    + f2*(xx**4+yy**4)/xy**2 &
1766 &                                   + f1*(xx**6+yy**6)/xy**3 + f0*(xx**8+yy**8)/xy**4
1767    else if (order==5) then
1768      f0=-difexp/(two*sqrtpi*xy)
1769      f1=(difexp+two*xy*sumexp)/(sqrtpi*(two*xy)**2)
1770      f2= -((four*xy**2+three)*difexp+6._dp*xy*sumexp)/(sqrtpi*(two*xy)**3)
1771      f3=((24._dp*xy**2+15._dp)*difexp+(8._dp*xy**3+30._dp*xy)*sumexp)/(sqrtpi*(two*xy)**4)
1772      f4=-((16._dp*xy**4+180._dp*xy**2+105._dp)*difexp &
1773 &        +(80._dp*xy**3+210._dp*xy)*sumexp)/(sqrtpi*(two*xy)**5)
1774      f5=((240._dp*xy**4+1680._dp*xy**2+945._dp)*difexp &
1775 &       +(32._dp*xy**5+840._dp*xy**3+1890._dp*xy)*sumexp)/(sqrtpi*(two*xy)**6)
1776      hh=((xx**11+yy**11)*erfcp-(xx**11-yy**11)*erfcm)/(two*xy**6)
1777      screened_coul_kernel = hh + f5 + f4*(xx**2+yy**2)  /xy    + f3*(xx**4+yy**4)/xy**2 &
1778 &                                   + f2*(xx**6+yy**6)  /xy**3 + f1*(xx**8+yy**8)/xy**4 &
1779 &                                   + f0*(xx**10+yy**10)/xy**5
1780    else if (order==6) then
1781      f0=-difexp/(two*sqrtpi*xy)
1782      f1=(difexp+two*xy*sumexp)/(sqrtpi*(two*xy)**2)
1783      f2= -((four*xy**2+three)*difexp+6._dp*xy*sumexp)/(sqrtpi*(two*xy)**3)
1784      f3=((24._dp*xy**2+15._dp)*difexp+(8._dp*xy**3+30._dp*xy)*sumexp)/(sqrtpi*(two*xy)**4)
1785      f4=-((16._dp*xy**4+180._dp*xy**2+105._dp)*difexp &
1786 &        +(80._dp*xy**3+210._dp*xy)*sumexp)/(sqrtpi*(two*xy)**5)
1787      f5=((240._dp*xy**4+1680._dp*xy**2+945._dp)*difexp &
1788 &       +(32._dp*xy**5+840._dp*xy**3+1890._dp*xy)*sumexp)/(sqrtpi*(two*xy)**6)
1789      f6=-((64._dp*xy**6+3360._dp*xy**4+18900._dp*xy**2+10395._dp)*difexp+ &
1790 &         (672._dp*xy**5+10080._dp*xy**3+20790._dp*xy)*sumexp)/(sqrtpi*(two*xy)**7)
1791      hh=((xx**13+yy**13)*erfcp-(xx**13-yy**13)*erfcm)/(two*xy**7)
1792      screened_coul_kernel = hh + f6 + f5*(xx**2+yy**2)  /xy    + f4*(xx**4+yy**4)  /xy**2 &
1793 &                                   + f3*(xx**6+yy**6)  /xy**3 + f1*(xx**8+yy**8)  /xy**4 &
1794 &                                   + f1*(xx**10+yy**10)/xy**5 + f0*(xx**12+yy**12)/xy**6
1795    end if
1796 
1797 !Development for yy->0
1798 !J. Phys. A 39, 8613 (2006) - Eq. (28), (29), (30) [[cite:Angyan2006]]
1799 !------------------------------------------------------------------
1800  case(2)
1801    sqrtpi=sqrt(pi)
1802    if (order==0) then
1803      screened_coul_kernel = paw_derfc(xx)/xx + exp(-xx**2)/sqrtpi * &
1804 &            (two/three              *yy**2 &
1805 &           +(two*xx**2-three)/15._dp*yy**4)
1806    else if(order==1) then
1807      screened_coul_kernel = paw_derfc(xx)*yy/xx**2 + exp(-xx**2)/sqrtpi * &
1808 &            (two/xx                         *yy &
1809 &            +four*xx/5._dp                  *yy**3 &
1810 &            +two*xx*(two*xx**2-5._dp)/35._dp*yy**5)
1811    else if (order==2) then
1812      screened_coul_kernel = paw_derfc(xx)*yy**2/xx**3 + exp(-xx**2)/sqrtpi * &
1813 &            (two*(two*xx**2+three)/(three*xx**2) *yy**2 &
1814 &            +8._dp*xx**2/21._dp                  *yy**4 &
1815 &            +four*xx**2*(two*xx**2-7._dp)/189._dp*yy**6)
1816    else if (order==3) then
1817      screened_coul_kernel = paw_derfc(xx)*yy**3/xx**4 + exp(-xx**2)/sqrtpi * &
1818 &            (two*(four*xx**4+10._dp*xx**2+15._dp)/(15._dp*xx**3)*yy**3 &
1819 &            +16._dp*xx**3/135._dp                               *yy**5 &
1820 &            +8._dp*xx**3*(two*xx**2-9._dp)/1485._dp             *yy**7)
1821    else if (order==4) then
1822      screened_coul_kernel = paw_derfc(xx)*yy**4/xx**5 + exp(-xx**2)/sqrtpi * &
1823 &            (two*(8._dp*xx**6+28._dp*xx**4+70._dp*xx**2+105._dp)/(105._dp*xx**4)*yy**4 &
1824 &            +32._dp*xx**4/1155._dp                                              *yy**6 &
1825 &            +16._dp*xx**4*(two*xx**2-11._dp)/15015._dp                          *yy**8)
1826    else if (order==5) then
1827      screened_coul_kernel = paw_derfc(xx)*yy**5/xx**6 + exp(-xx**2)/sqrtpi * &
1828 &            (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 &
1829 &            +64._dp*xx**5/12285._dp                                                             *yy**7 &
1830 &            +32._dp*xx**5*(two*xx**2-13._dp)/184275._dp                                         *yy**9)
1831    else if (order==6) then
1832      screened_coul_kernel = paw_derfc(xx)*yy**6/xx**7 + exp(-xx**2)/sqrtpi * &
1833 &            (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 &
1834 &            +128._dp*xx**6/155925._dp                                                                                 *yy**8 &
1835 &            +64._dp*xx**6*(two*xx**2-15._dp)/2650725._dp                                                              *yy**10)
1836    end if
1837 
1838 !Development for xx*yy->0
1839 !J. Phys. A 39, 8613 (2006) - Eq. (24), (26) [[cite:Angyan2006]]
1840 !   Note: typo in the paper: (2n+3)! should be (2n+3)!!
1841 !------------------------------------------------------------------
1842  case(3)
1843    xy=xx*yy ; sqrtpi=sqrt(pi)
1844    sumexp=exp(-(xx**2+yy**2))
1845    erfcp=paw_derfc(xx+yy) ; erfcm=paw_derfc(xx-yy)
1846    if (order==0) then
1847      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
1848      hh=((xx+yy)*erfcp-(xx-yy)*erfcm)/(two*xy)
1849      screened_coul_kernel = hh + f0
1850    else if(order==1) then
1851      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
1852      f1 = four   *xy   *(5._dp +two*xy**2)/(15._dp     *sqrtpi)*sumexp
1853      hh=((xx**3+yy**3)*erfcp-(xx**3-yy**3)*erfcm)/(two*xy**2)
1854      screened_coul_kernel = hh + f1 + f0*(xx**2+yy**2)/xy
1855    else if (order==2) then
1856      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
1857      f1 = four   *xy   *(5._dp +two*xy**2)/(15._dp     *sqrtpi)*sumexp
1858      f2 = 8._dp  *xy**2*(7._dp +two*xy**2)/(105._dp    *sqrtpi)*sumexp
1859      hh=((xx**5+yy**5)*erfcp-(xx**5-yy**5)*erfcm)/(two*xy**3)
1860      screened_coul_kernel = hh + f2 + f1*(xx**2+yy**2)/xy + f0*(xx**4+yy**4)/xy**2
1861    else if (order==3) then
1862      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
1863      f1 = four   *xy   *(5._dp +two*xy**2)/(15._dp     *sqrtpi)*sumexp
1864      f2 = 8._dp  *xy**2*(7._dp +two*xy**2)/(105._dp    *sqrtpi)*sumexp
1865      f3 = 16._dp *xy**2*(9._dp +two*xy**2)/(945._dp    *sqrtpi)*sumexp
1866      hh=((xx**7+yy**7)*erfcp-(xx**7-yy**7)*erfcm)/(two*xy**4)
1867      screened_coul_kernel = hh + f3 + f2*(xx**2+yy**2)/xy    + f1*(xx**4+yy**4)/xy**2 &
1868 &                                   + f0*(xx**6+yy**6)/xy**3
1869    else if (order==4) then
1870      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
1871      f1 = four   *xy   *(5._dp +two*xy**2)/(15._dp     *sqrtpi)*sumexp
1872      f2 = 8._dp  *xy**2*(7._dp +two*xy**2)/(105._dp    *sqrtpi)*sumexp
1873      f3 = 16._dp *xy**2*(9._dp +two*xy**2)/(945._dp    *sqrtpi)*sumexp
1874      f4 = 32._dp *xy**2*(11._dp+two*xy**2)/(10395._dp  *sqrtpi)*sumexp
1875      hh=((xx**9+yy**9)*erfcp-(xx**9-yy**9)*erfcm)/(two*xy**5)
1876      screened_coul_kernel = hh + f4 + f3*(xx**2+yy**2)/xy    + f2*(xx**4+yy**4)/xy**2 &
1877 &                                   + f1*(xx**6+yy**6)/xy**3 + f0*(xx**8+yy**8)/xy**4
1878    else if (order==5) then
1879      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
1880      f1 = four   *xy   *(5._dp +two*xy**2)/(15._dp     *sqrtpi)*sumexp
1881      f2 = 8._dp  *xy**2*(7._dp +two*xy**2)/(105._dp    *sqrtpi)*sumexp
1882      f3 = 16._dp *xy**2*(9._dp +two*xy**2)/(945._dp    *sqrtpi)*sumexp
1883      f4 = 32._dp *xy**2*(11._dp+two*xy**2)/(10395._dp  *sqrtpi)*sumexp
1884      f5 = 64._dp *xy**2*(13._dp+two*xy**2)/(135135._dp *sqrtpi)*sumexp
1885      hh=((xx**11+yy**11)*erfcp-(xx**11-yy**11)*erfcm)/(two*xy**6)
1886      screened_coul_kernel = hh + f5 + f4*(xx**2+yy**2)  /xy    + f3*(xx**4+yy**4)/xy**2 &
1887 &                                   + f2*(xx**6+yy**6)  /xy**3 + f1*(xx**8+yy**8)/xy**4 &
1888 &                                   + f0*(xx**10+yy**10)/xy**5
1889    else if (order==6) then
1890      f0 = two          *(three +two*xy**2)/(three      *sqrtpi)*sumexp
1891      f1 = four   *xy   *(5._dp +two*xy**2)/(15._dp     *sqrtpi)*sumexp
1892      f2 = 8._dp  *xy**2*(7._dp +two*xy**2)/(105._dp    *sqrtpi)*sumexp
1893      f3 = 16._dp *xy**2*(9._dp +two*xy**2)/(945._dp    *sqrtpi)*sumexp
1894      f4 = 32._dp *xy**2*(11._dp+two*xy**2)/(10395._dp  *sqrtpi)*sumexp
1895      f5 = 64._dp *xy**2*(13._dp+two*xy**2)/(135135._dp *sqrtpi)*sumexp
1896      f6 = 128._dp*xy**2*(15._dp+two*xy**2)/(1027025._dp*sqrtpi)*sumexp
1897      hh=((xx**13+yy**13)*erfcp-(xx**13-yy**13)*erfcm)/(two*xy**7)
1898      screened_coul_kernel = hh + f6 + f5*(xx**2+yy**2)  /xy    + f4*(xx**4+yy**4)  /xy**2 &
1899 &                                   + f3*(xx**6+yy**6)  /xy**3 + f1*(xx**8+yy**8)  /xy**4 &
1900 &                                   + f1*(xx**10+yy**10)/xy**5 + f0*(xx**12+yy**12)/xy**6
1901    end if
1902 
1903  end select
1904 
1905 end function screened_coul_kernel

m_pawrad/simp_gen [ Functions ]

[ Top ] [ m_pawrad ] [ Functions ]

NAME

 simp_gen

FUNCTION

 Do integral on a given (generalized) grid using Simpson rule

INPUTS

  radmesh <type(pawrad_type)>=data containing radial grid information
  func(:)=integrand values
  r_for_intg=upper boundary for (future) integration over the radial grid
            (can be negative for an integration over the whole grid)

OUTPUT

  intg=resulting integral by Simpson rule

PARENTS

      calc_ubare,m_atom,m_paw_atom,m_paw_slater,m_pawdij,m_pawhr,m_pawpsp
      m_pawpwij,m_pawrad,m_pawxc,m_plowannier,m_psps,make_efg_onsite
      mlwfovlp_projpaw,optics_paw,optics_paw_core,partial_dos_fractions_paw
      pawdensities,pawinit,pawnabla_init,pawpuxinit,posdoppler,poslifetime
      posratecore,qijb_kk,smatrix_pawinit

CHILDREN

      poisson,simp_gen

NOTES

  Possible mesh types (radmesh%mesh_type)
   mesh_type=1 (regular grid): rad(i)=(i-1)*AA
   mesh_type=2 (logari. grid): rad(i)=AA*(exp[BB*(i-1)]-1)
   mesh_type=3 (logari. grid): rad(i>1)=AA*exp[BB*(i-2)] and rad(1)=0
   mesh_type=4 (logari. grid): rad(i)=-AA*ln[1-BB*(i-1)] with BB=1/n
   mesh_type=5 ( grid): rad(i)=AA*i/(n-i)

SOURCE

 948 subroutine simp_gen(intg,func,radmesh,r_for_intg)
 949 
 950 #if defined HAVE_AVX_SAFE_MODE
 951 !DEC$ NOOPTIMIZE
 952 #endif
 953 
 954 !This section has been created automatically by the script Abilint (TD).
 955 !Do not modify the following lines by hand.
 956 #undef ABI_FUNC
 957 #define ABI_FUNC 'simp_gen'
 958 !End of the abilint section
 959 
 960  implicit none
 961 
 962 !Arguments ------------------------------------
 963 !scalars
 964  real(dp),intent(out) :: intg
 965  real(dp),intent(in),optional :: r_for_intg
 966  type(pawrad_type),intent(in) :: radmesh
 967 !arrays
 968  real(dp),intent(in) :: func(:)
 969 
 970 !Local variables-------------------------------
 971 !scalars
 972  integer :: ii,int_meshsz,ir,ir_last,isim,nn
 973  real(dp) :: hh,resid,simp
 974  real(dp),allocatable :: simfact(:)
 975  character(len=500) :: msg
 976 
 977 ! *************************************************************************
 978 
 979  if (present(r_for_intg)) then
 980    if (r_for_intg>0.d0) then
 981      ir=min(pawrad_ifromr(radmesh,r_for_intg),radmesh%mesh_size)
 982      if (ir<radmesh%mesh_size) then
 983        if (abs(radmesh%rad(ir+1)-r_for_intg)<abs(radmesh%rad(ir)-r_for_intg)) ir=ir+1
 984      end if
 985      if (ir>1) then
 986        if (abs(radmesh%rad(ir-1)-r_for_intg)<abs(radmesh%rad(ir)-r_for_intg)) ir=ir-1
 987      end if
 988      int_meshsz=ir
 989    else
 990      int_meshsz=radmesh%mesh_size
 991    end if
 992    if (int_meshsz>radmesh%mesh_size.or.int_meshsz>size(func)) then
 993      write(msg,'(3(a,i4))')"int_meshsz= ",int_meshsz," > mesh_size=",radmesh%mesh_size,&
 994 &                          ", size(func)=",size(func)
 995      MSG_BUG(msg)
 996    end if
 997    isim=3; if (radmesh%mesh_type==3)isim=4
 998    LIBPAW_ALLOCATE(simfact,(radmesh%mesh_size))
 999    hh=radmesh%stepint/3.d0
1000    simfact(int_meshsz)=hh*radmesh%radfact(int_meshsz)
1001    simfact(1:isim-2)=zero
1002    ir_last=1
1003    do ir=int_meshsz,isim,-2
1004      simfact(ir-1)=4.d0*hh*radmesh%radfact(ir-1)
1005      simfact(ir-2)=2.d0*hh*radmesh%radfact(ir-2)
1006      ir_last=ir-2
1007    end do
1008    simfact(ir_last)=half*simfact(ir_last)
1009    if (int_meshsz<radmesh%mesh_size) simfact(int_meshsz+1:radmesh%mesh_size)=zero
1010 
1011    nn=int_meshsz
1012    simp=zero
1013    do ii=1,nn
1014      simp=simp+func(ii)*simfact(ii)
1015    end do
1016    LIBPAW_DEALLOCATE(simfact)
1017 
1018  else
1019    if (radmesh%int_meshsz>size(func)) then
1020      write(msg,'(2(a,i4))')"int_meshsz= ",int_meshsz," > size(func)=",size(func)
1021      MSG_BUG(msg)
1022    end if
1023    nn=radmesh%int_meshsz
1024    simp=zero
1025    do ii=1,nn
1026      simp=simp+func(ii)*radmesh%simfact(ii)
1027    end do
1028  end if
1029 
1030  resid=zero
1031  if (radmesh%mesh_type==3) then
1032    resid=half*(func(2)+func(1))*(radmesh%rad(2)-radmesh%rad(1))
1033    if (mod(nn,2)==1) resid=resid+radmesh%stepint/3.d0*(1.25d0*func(2)*radmesh%radfact(2) &
1034 &   +2.d0*func(3)*radmesh%radfact(3)-0.25d0*func(4)*radmesh%radfact(4))
1035  else if (mod(nn,2)==0) then
1036    resid=radmesh%stepint/3.d0*(1.25d0*func(1)*radmesh%radfact(1)+2.d0*func(2)*radmesh%radfact(2) &
1037 &   -0.25d0*func(3)*radmesh%radfact(3))
1038  end if
1039 
1040  intg=simp+resid
1041 
1042 end subroutine simp_gen