TABLE OF CONTENTS
- ABINIT/m_paw_numeric
- m_paw_numeric/paw_derfc
- m_paw_numeric/paw_jbessel
- m_paw_numeric/paw_smooth
- m_paw_numeric/paw_solvbes
- m_paw_numeric/paw_sort_dp
- m_paw_numeric/paw_spline
- m_paw_numeric/paw_splint
- m_paw_numeric/paw_splint_der
- m_paw_numeric/paw_uniform_splfit
- m_special_funcs/paw_jbessel_4spline
ABINIT/m_paw_numeric [ Modules ]
NAME
m_paw_numeric
FUNCTION
Wrappers for various numeric operations (spline, sort, ...)
COPYRIGHT
Copyright (C) 2012-2018 ABINIT group (MT,TR) 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
FOR DEVELOPPERS: in order to preserve the portability of libPAW library, please consult ~abinit/src/??_libpaw/libpaw-coding-rules.txt
SOURCE
21 #include "libpaw.h" 22 23 module m_paw_numeric 24 25 USE_DEFS 26 USE_MSG_HANDLING 27 USE_MEMORY_PROFILING 28 29 implicit none 30 31 private 32 33 !public procedures 34 public:: paw_spline 35 public:: paw_splint 36 public:: paw_splint_der 37 public:: paw_uniform_splfit 38 public:: paw_smooth 39 public:: paw_sort_dp 40 public:: paw_jbessel 41 public:: paw_solvbes 42 public:: paw_jbessel_4spline 43 public:: paw_derfc
m_paw_numeric/paw_derfc [ Functions ]
[ Top ] [ m_paw_numeric ] [ Functions ]
NAME
paw_derfc
FUNCTION
Evaluates the complementary error function in real(dp).
INPUTS
yy
OUTPUT
derfc_yy=complementary error function of yy
PARENTS
screened_coul_kernel
CHILDREN
SOURCE
1143 elemental function paw_derfc(yy) result(derfc_yy) 1144 1145 1146 !This section has been created automatically by the script Abilint (TD). 1147 !Do not modify the following lines by hand. 1148 #undef ABI_FUNC 1149 #define ABI_FUNC 'paw_derfc' 1150 !End of the abilint section 1151 1152 implicit none 1153 1154 !Arguments ------------------------------------ 1155 !scalars 1156 real(dp),intent(in) :: yy 1157 real(dp) :: derfc_yy 1158 1159 !Local variables------------------------------- 1160 integer :: done,ii,isw 1161 ! coefficients for 0.0 <= yy < .477 1162 real(dp), parameter :: & 1163 & pp(5)=(/ 113.8641541510502e0_dp, 377.4852376853020e0_dp, & 1164 & 3209.377589138469e0_dp, .1857777061846032e0_dp, & 1165 & 3.161123743870566e0_dp /) 1166 real(dp), parameter :: & 1167 & qq(4)=(/ 244.0246379344442e0_dp, 1282.616526077372e0_dp, & 1168 & 2844.236833439171e0_dp, 23.60129095234412e0_dp/) 1169 ! coefficients for .477 <= yy <= 4.0 1170 real(dp), parameter :: & 1171 & p1(9)=(/ 8.883149794388376e0_dp, 66.11919063714163e0_dp, & 1172 & 298.6351381974001e0_dp, 881.9522212417691e0_dp, & 1173 & 1712.047612634071e0_dp, 2051.078377826071e0_dp, & 1174 & 1230.339354797997e0_dp, 2.153115354744038e-8_dp, & 1175 & .5641884969886701e0_dp /) 1176 real(dp), parameter :: & 1177 & q1(8)=(/ 117.6939508913125e0_dp, 537.1811018620099e0_dp, & 1178 & 1621.389574566690e0_dp, 3290.799235733460e0_dp, & 1179 & 4362.619090143247e0_dp, 3439.367674143722e0_dp, & 1180 & 1230.339354803749e0_dp, 15.74492611070983e0_dp/) 1181 ! coefficients for 4.0 < y, 1182 real(dp), parameter :: & 1183 & p2(6)=(/ -3.603448999498044e-01_dp, -1.257817261112292e-01_dp, & 1184 & -1.608378514874228e-02_dp, -6.587491615298378e-04_dp, & 1185 & -1.631538713730210e-02_dp, -3.053266349612323e-01_dp/) 1186 real(dp), parameter :: & 1187 & q2(5)=(/ 1.872952849923460e0_dp , 5.279051029514284e-01_dp, & 1188 & 6.051834131244132e-02_dp , 2.335204976268692e-03_dp, & 1189 & 2.568520192289822e0_dp /) 1190 real(dp), parameter :: & 1191 & sqrpi=.5641895835477563e0_dp, xbig=13.3e0_dp, xlarge=6.375e0_dp, xmin=1.0e-10_dp 1192 real(dp) :: res,xden,xi,xnum,xsq,xx 1193 1194 !****************************************************************** 1195 1196 xx = yy 1197 isw = 1 1198 !Here change the sign of xx, and keep track of it thanks to isw 1199 if (xx<0.0e0_dp) then 1200 isw = -1 1201 xx = -xx 1202 end if 1203 1204 done=0 1205 1206 !Residual value, if yy < -6.375e0_dp 1207 res=2.0e0_dp 1208 1209 !abs(yy) < .477, evaluate approximation for erfc 1210 if (xx<0.477e0_dp) then 1211 ! xmin is a very small number 1212 if (xx<xmin) then 1213 res = xx*pp(3)/qq(3) 1214 else 1215 xsq = xx*xx 1216 xnum = pp(4)*xsq+pp(5) 1217 xden = xsq+qq(4) 1218 do ii = 1,3 1219 xnum = xnum*xsq+pp(ii) 1220 xden = xden*xsq+qq(ii) 1221 end do 1222 res = xx*xnum/xden 1223 end if 1224 if (isw==-1) res = -res 1225 res = 1.0e0_dp-res 1226 done=1 1227 end if 1228 1229 !.477 < abs(yy) < 4.0 , evaluate approximation for erfc 1230 if (xx<=4.0e0_dp .and. done==0 ) then 1231 xsq = xx*xx 1232 xnum = p1(8)*xx+p1(9) 1233 xden = xx+q1(8) 1234 do ii=1,7 1235 xnum = xnum*xx+p1(ii) 1236 xden = xden*xx+q1(ii) 1237 end do 1238 res = xnum/xden 1239 res = res* exp(-xsq) 1240 if (isw.eq.-1) res = 2.0e0_dp-res 1241 done=1 1242 end if 1243 1244 !y > 13.3e0_dp 1245 if (isw > 0 .and. xx > xbig .and. done==0 ) then 1246 res = 0.0e0_dp 1247 done=1 1248 end if 1249 1250 !4.0 < yy < 13.3e0_dp .or. -6.375e0_dp < yy < -4.0 1251 !evaluate minimax approximation for erfc 1252 if ( ( isw > 0 .or. xx < xlarge ) .and. done==0 ) then 1253 xsq = xx*xx 1254 xi = 1.0e0_dp/xsq 1255 xnum= p2(5)*xi+p2(6) 1256 xden = xi+q2(5) 1257 do ii = 1,4 1258 xnum = xnum*xi+p2(ii) 1259 xden = xden*xi+q2(ii) 1260 end do 1261 res = (sqrpi+xi*xnum/xden)/xx 1262 res = res* exp(-xsq) 1263 if (isw.eq.-1) res = 2.0e0_dp-res 1264 end if 1265 1266 !All cases have been investigated 1267 derfc_yy = res 1268 1269 end function paw_derfc
m_paw_numeric/paw_jbessel [ Functions ]
[ Top ] [ m_paw_numeric ] [ Functions ]
NAME
paw_jbessel
FUNCTION
Compute spherical Bessel function j_l(x) and derivative(s)
INPUTS
ll=l-order of the Bessel function order=1 if first derivative is requested 2 if first and second derivatives are requested xx=where to compute j_l
OUTPUT
bes= Bessel function j_l at xx besp= first derivative of j_l at xx (only if order>=1) bespp= second derivative of j_l at xx (only if order=2)
PARENTS
m_paw_atom,m_paw_finegrid,m_paw_numeric,m_vcoul
CHILDREN
paw_jbessel
SOURCE
782 subroutine paw_jbessel(bes,besp,bespp,ll,order,xx) 783 784 785 !This section has been created automatically by the script Abilint (TD). 786 !Do not modify the following lines by hand. 787 #undef ABI_FUNC 788 #define ABI_FUNC 'paw_jbessel' 789 !End of the abilint section 790 791 implicit none 792 793 !Arguments --------------------------------------------- 794 !scalars 795 integer,intent(in) :: ll,order 796 real(dp),intent(in) :: xx 797 real(dp),intent(out) :: bes,besp,bespp 798 799 !Local variables --------------------------------------- 800 !scalars 801 integer,parameter :: imax=40 802 integer :: ii,il 803 real(dp),parameter :: prec=1.d-15 804 real(dp) :: besp1,fact,factp,factpp,jn,jnp,jnpp,jr,xx2,xxinv 805 character(len=200) :: msg 806 807 ! ********************************************************************* 808 809 if (order>2) then 810 msg='Wrong order in paw_jbessel!' 811 MSG_ERROR(msg) 812 end if 813 814 if (abs(xx)<prec) then 815 bes=zero;if (ll==0) bes=one 816 if (order>=1) then 817 besp=zero;if (ll==1) besp=third 818 end if 819 if (order==2) then 820 bespp=zero 821 if (ll==0) bespp=-third 822 if (ll==2) bespp=2._dp/15._dp 823 end if 824 return 825 end if 826 827 xxinv=one/xx 828 if (order==0) then 829 factp=zero 830 factpp=zero 831 jnp=zero 832 jnpp=zero 833 end if 834 835 if (xx<one) then 836 xx2=0.5_dp*xx*xx 837 fact=one 838 do il=1,ll 839 fact=fact*xx/dble(2*il+1) 840 end do 841 jn=one;jr=one;ii=0 842 do while(abs(jr)>=prec.and.ii<imax) 843 ii=ii+1;jr=-jr*xx2/dble(ii*(2*(ll+ii)+1)) 844 jn=jn+jr 845 end do 846 bes=jn*fact 847 if (abs(jr)>prec) then 848 msg='Bessel function did not converge!' 849 MSG_ERROR(msg) 850 end if 851 if (order>=1) then 852 factp=fact*xx/dble(2*ll+3) 853 jnp=one;jr=one;ii=0 854 do while(abs(jr)>=prec.AND.ii<imax) 855 ii=ii+1;jr=-jr*xx2/dble(ii*(2*(ll+ii)+3)) 856 jnp=jnp+jr 857 end do 858 besp=-jnp*factp+jn*fact*xxinv*dble(ll) 859 if (abs(jr)>prec) then 860 msg='1st der. of Bessel function did not converge!' 861 MSG_ERROR(msg) 862 end if 863 end if 864 if (order==2) then 865 factpp=factp*xx/dble(2*ll+5) 866 jnpp=one;jr=one;ii=0 867 do while(abs(jr)>=prec.AND.ii<imax) 868 ii=ii+1;jr=-jr*xx2/dble(ii*(2*(ll+ii)+5)) 869 jnpp=jnpp+jr 870 end do 871 besp1=-jnpp*factpp+jnp*factp*xxinv*dble(ll+1) 872 if (abs(jr)>prec) then 873 msg='2nd der. of Bessel function did not converge !' 874 MSG_ERROR(msg) 875 end if 876 end if 877 else 878 jn =sin(xx)*xxinv 879 jnp=(-cos(xx)+jn)*xxinv 880 do il=2,ll+1 881 jr=-jn+dble(2*il-1)*jnp*xxinv 882 jn=jnp;jnp=jr 883 end do 884 bes=jn 885 if (order>=1) besp =-jnp+jn *xxinv*dble(ll) 886 if (order==2) besp1= jn -jnp*xxinv*dble(ll+2) 887 end if 888 889 if (order==2) bespp=-besp1+besp*ll*xxinv-bes*ll*xxinv*xxinv 890 891 end subroutine paw_jbessel
m_paw_numeric/paw_smooth [ Functions ]
[ Top ] [ m_paw_numeric ] [ Functions ]
NAME
paw_smooth
FUNCTION
Smooth an array of given ordinates (y's) that are in order of increasing abscissas (x's), but without using the abscissas themselves supposed to be equally spaced.
INPUTS
it=number of abscissas to treat mesh=size of the array (number of abscissas)
OUTPUT
SIDE EFFECTS
a(mesh)=array to be smoothed
PARENTS
m_pawpsp
CHILDREN
paw_jbessel
SOURCE
592 subroutine paw_smooth(a,mesh,it) 593 594 595 !This section has been created automatically by the script Abilint (TD). 596 !Do not modify the following lines by hand. 597 #undef ABI_FUNC 598 #define ABI_FUNC 'paw_smooth' 599 !End of the abilint section 600 601 implicit none 602 603 !Arguments ------------------------------------ 604 !scalars 605 integer, intent(in) :: it,mesh 606 !arrays 607 real(dp), intent(inout) :: a(mesh) 608 609 !Local variables------------------------------- 610 !scalars 611 integer :: i,k 612 !arrays 613 real(dp) :: asm(mesh) 614 615 ! ************************************************************************* 616 617 asm(1:4) = zero ! ?? Correct me ... 618 do k=1,it 619 asm(5)=0.2_dp*(a(3)+a(4)+a(5)+a(6)+a(7)) 620 asm(mesh-4)=0.2_dp*(a(mesh-2)+a(mesh-3)+a(mesh-4)+& 621 & a(mesh-5)+a(mesh-6)) 622 asm(mesh-3)=0.2_dp*(a(mesh-1)+a(mesh-2)+a(mesh-3)+& 623 & a(mesh-4)+a(mesh-5)) 624 asm(mesh-2)=0.2_dp*(a(mesh)+a(mesh-1)+a(mesh-2)+& 625 & a(mesh-3)+a(mesh-4)) 626 asm(mesh-1)=0.25_dp*(a(mesh)+a(mesh-1)+a(mesh-2)+a(mesh-3)) 627 asm(mesh)=1.0_dp/3.0_dp*(a(mesh)+a(mesh-1)+a(mesh-2)) 628 do i=6,mesh-5 629 asm(i)=0.1_dp *a(i)+0.1_dp*(a(i+1)+a(i-1))+& 630 & 0.1_dp *(a(i+2)+a(i-2))+& 631 & 0.1_dp *(a(i+3)+a(i-3))+& 632 & 0.1_dp *(a(i+4)+a(i-4))+& 633 & 0.05_dp*(a(i+5)+a(i-5)) 634 end do 635 do i=1,mesh 636 a(i)=asm(i) 637 end do 638 end do 639 640 end subroutine paw_smooth
m_paw_numeric/paw_solvbes [ Functions ]
[ Top ] [ m_paw_numeric ] [ Functions ]
NAME
paw_solvbes
FUNCTION
Find nq first roots of instrinsic equation: alpha.jl(Q) + beta.Q.djl/dr(Q) = 0
INPUTS
alpha,beta= factors in intrinsic equation ll= l quantum number nq= number of roots to find
OUTPUT
root(nq)= roots of instrinsic equation
PARENTS
m_paw_atom
CHILDREN
paw_jbessel
SOURCE
920 subroutine paw_solvbes(root,alpha,beta,ll,nq) 921 922 923 !This section has been created automatically by the script Abilint (TD). 924 !Do not modify the following lines by hand. 925 #undef ABI_FUNC 926 #define ABI_FUNC 'paw_solvbes' 927 !End of the abilint section 928 929 implicit none 930 931 !Arguments ------------------------------------ 932 !scalars 933 integer :: ll,nq 934 real(dp) :: alpha,beta 935 !arrays 936 real(dp) :: root(nq) 937 938 !Local variables------------------------------- 939 !scalars 940 integer :: nroot 941 real(dp),parameter :: dh=0.1_dp,tol=tol14 942 real(dp) :: dum,hh,jbes,jbesp,qq,qx,y1,y2 943 944 ! ************************************************************************* 945 946 qq=dh;nroot=0 947 948 do while (nroot<nq) 949 call paw_jbessel(jbes,jbesp,dum,ll,1,qq) 950 y1=alpha*jbes+beta*qq*jbesp 951 qq=qq+dh 952 call paw_jbessel(jbes,jbesp,dum,ll,1,qq) 953 y2=alpha*jbes+beta*qq*jbesp 954 955 do while (y1*y2>=zero) 956 qq=qq+dh 957 call paw_jbessel(jbes,jbesp,dum,ll,1,qq) 958 y2=alpha*jbes+beta*qq*jbesp 959 end do 960 961 hh=dh;qx=qq 962 do while (hh>tol) 963 hh=half*hh 964 if (y1*y2<zero) then 965 qx=qx-hh 966 else 967 qx=qx+hh 968 end if 969 call paw_jbessel(jbes,jbesp,dum,ll,1,qx) 970 y2=alpha*jbes+beta*qx*jbesp 971 end do 972 nroot=nroot+1 973 root(nroot)=qx 974 975 end do 976 977 end subroutine paw_solvbes
m_paw_numeric/paw_sort_dp [ Functions ]
[ Top ] [ m_paw_numeric ] [ Functions ]
NAME
paw_sort_dp
FUNCTION
Sort real(dp) array list(n) into ascending numerical order using Heapsort algorithm, while making corresponding rearrangement of the integer array iperm. Consider that two real(dp) numbers within tolerance tol are equal.
INPUTS
n intent(in) dimension of the list tol intent(in) numbers within tolerance are equal list(n) intent(inout) list of real(dp) numbers to be sorted iperm(n) intent(inout) iperm(i)=i (very important)
OUTPUT
list(n) sorted list iperm(n) index of permutation given the right ascending order
PARENTS
m_paw_finegrid
CHILDREN
paw_jbessel
SOURCE
673 subroutine paw_sort_dp(n,list,iperm,tol) 674 675 676 !This section has been created automatically by the script Abilint (TD). 677 !Do not modify the following lines by hand. 678 #undef ABI_FUNC 679 #define ABI_FUNC 'paw_sort_dp' 680 !End of the abilint section 681 682 implicit none 683 684 !Arguments ------------------------------------ 685 !scalars 686 integer, intent(in) :: n 687 real(dp), intent(in) :: tol 688 !arrays 689 integer, intent(inout) :: iperm(n) 690 real(dp), intent(inout) :: list(n) 691 692 !Local variables------------------------------- 693 !scalars 694 integer :: l,ir,iap,i,j 695 real(dp) :: ap 696 character(len=500) :: msg 697 !arrays 698 699 ! ************************************************************************* 700 701 !Accomodate case of array of length 1: already sorted! 702 if (n==1) return 703 704 !Should not call with n<1 705 if (n<1) then 706 write(msg,'(a,i12,2a)') & 707 & 'paw_sort_dp has been called with array length n=',n, ch10, & 708 & ' having a value less than 1. This is not allowed.' 709 MSG_ERROR(msg) 710 end if 711 712 !Conduct the usual sort 713 l=n/2+1 ; ir=n 714 do ! Infinite do-loop 715 if (l>1) then 716 l=l-1 717 ap=list(l) 718 iap=iperm(l) 719 else ! l<=1 720 ap=list(ir) 721 iap=iperm(ir) 722 list(ir)=list(1) 723 iperm(ir)=iperm(1) 724 ir=ir-1 725 if (ir==1) then 726 list(1)=ap 727 iperm(1)=iap 728 exit ! This is the end of this algorithm 729 end if 730 end if ! l>1 731 i=l 732 j=l+l 733 do while (j<=ir) 734 if (j<ir) then 735 if ( list(j)<list(j+1)-tol .or. & 736 & (list(j)<list(j+1)+tol.and.iperm(j)<iperm(j+1))) j=j+1 737 endif 738 if (ap<list(j)-tol.or.(ap<list(j)+tol.and.iap<iperm(j))) then 739 list(i)=list(j) 740 iperm(i)=iperm(j) 741 i=j 742 j=j+j 743 else 744 j=ir+1 745 end if 746 end do 747 list(i)=ap 748 iperm(i)=iap 749 end do ! End infinite do-loop 750 751 end subroutine paw_sort_dp
m_paw_numeric/paw_spline [ Functions ]
[ Top ] [ m_paw_numeric ] [ Functions ]
NAME
paw_spline
FUNCTION
Computes the second derivatives of a cubic spline
INPUTS
* Input, integer N, the number of data points; N must be at least 2. In the special case where N = 2 and IBCBEG = IBCEND = 0, the spline will actually be linear. * Input, real(dp) T(N), the knot values, that is, the points where data is specified. The knot values should be distinct, and increasing. * Input, real(dp) Y(N), the data values to be interpolated. * Input, real(dp) YBCBEG, YBCEND, the values to be used in the boundary conditions if IBCBEG or IBCEND is equal to 1 or 2.
OUTPUT
Output, real(dp) YPP(N), the second derivatives of the cubic spline. Work space, real(dp) DIAG(N) - should be removed ...
PARENTS
dfpt_eltfrxc,m_paw_atom,m_paw_gaussfit,m_paw_pwaves_lmn,m_pawpsp m_pawpwij,m_pawxmlps,m_psps
CHILDREN
paw_jbessel
SOURCE
82 subroutine paw_spline(t,y,n,ybcbeg,ybcend,ypp) 83 84 !******************************************************************************* 85 ! Discussion: 86 ! For data interpolation, the user must call SPLINE_CUBIC_SET to 87 ! determine the second derivative data, passing in the data to be 88 ! interpolated, and the desired boundary conditions. 89 ! The data to be interpolated, plus the SPLINE_CUBIC_SET output, 90 ! defines the spline. The user may then call SPLINE_CUBIC_VAL to 91 ! evaluate the spline at any point. 92 ! The cubic spline is a piecewise cubic polynomial. The intervals 93 ! are determined by the "knots" or abscissas of the data to be 94 ! interpolated. The cubic spline has continous first and second 95 ! derivatives over the entire interval of interpolation. 96 ! For any point T in the interval T(IVAL), T(IVAL+1), the form of 97 ! the spline is 98 ! SPL(T) = A(IVAL) 99 ! + B(IVAL) * ( T - T(IVAL) ) 100 ! + C(IVAL) * ( T - T(IVAL) )**2 101 ! + D(IVAL) * ( T - T(IVAL) )**3 102 ! If we assume that we know the values Y(*) and YPP(*), which represent 103 ! the values and second derivatives of the spline at each knot, then 104 ! the coefficients can be computed as: 105 ! A(IVAL) = Y(IVAL) 106 ! B(IVAL) = ( Y(IVAL+1) - Y(IVAL) ) / ( T(IVAL+1) - T(IVAL) ) 107 ! - ( YPP(IVAL+1) + 2 * YPP(IVAL) ) * ( T(IVAL+1) - T(IVAL) ) / 6 108 ! C(IVAL) = YPP(IVAL) / 2 109 ! D(IVAL) = ( YPP(IVAL+1) - YPP(IVAL) ) / ( 6 * ( T(IVAL+1) - T(IVAL) ) ) 110 ! Since the first derivative of the spline is 111 ! SPL'(T) = B(IVAL) 112 ! + 2 * C(IVAL) * ( T - T(IVAL) ) 113 ! + 3 * D(IVAL) * ( T - T(IVAL) )**2, 114 ! the requirement that the first derivative be continuous at interior 115 ! knot I results in a total of N-2 equations, of the form: 116 ! B(IVAL-1) + 2 C(IVAL-1) * (T(IVAL)-T(IVAL-1)) 117 ! + 3 * D(IVAL-1) * (T(IVAL) - T(IVAL-1))**2 = B(IVAL) 118 ! or, setting H(IVAL) = T(IVAL+1) - T(IVAL) 119 ! ( Y(IVAL) - Y(IVAL-1) ) / H(IVAL-1) 120 ! - ( YPP(IVAL) + 2 * YPP(IVAL-1) ) * H(IVAL-1) / 6 121 ! + YPP(IVAL-1) * H(IVAL-1) 122 ! + ( YPP(IVAL) - YPP(IVAL-1) ) * H(IVAL-1) / 2 123 ! = 124 ! ( Y(IVAL+1) - Y(IVAL) ) / H(IVAL) 125 ! - ( YPP(IVAL+1) + 2 * YPP(IVAL) ) * H(IVAL) / 6 126 ! or 127 ! YPP(IVAL-1) * H(IVAL-1) + 2 * YPP(IVAL) * ( H(IVAL-1) + H(IVAL) ) 128 ! + YPP(IVAL) * H(IVAL) 129 ! = 130 ! 6 * ( Y(IVAL+1) - Y(IVAL) ) / H(IVAL) 131 ! - 6 * ( Y(IVAL) - Y(IVAL-1) ) / H(IVAL-1) 132 ! Boundary conditions must be applied at the first and last knots. 133 ! The resulting tridiagonal system can be solved for the YPP values. 134 ! 135 ! Author: 136 ! John Burkardt, modified by Xavier Gonze 137 138 !This section has been created automatically by the script Abilint (TD). 139 !Do not modify the following lines by hand. 140 #undef ABI_FUNC 141 #define ABI_FUNC 'paw_spline' 142 !End of the abilint section 143 144 implicit none 145 146 !Arguments ------------------------------------ 147 !scalars 148 integer,intent(in) :: n 149 real(dp),intent(in) :: ybcbeg,ybcend 150 !arrays 151 real(dp),intent(in) :: t(n),y(n) 152 real(dp),intent(out) :: ypp(n) 153 154 !Local variables------------------------------- 155 !scalars 156 integer :: ibcbeg,ibcend,i,k 157 real(dp) :: ratio,pinv 158 character(len=500) :: msg 159 !arrays 160 real(dp),allocatable :: tmp(:) 161 162 ! ************************************************************************* 163 164 !Check 165 if (n<=1) then 166 write(msg,'(6a,i8)') ch10, & 167 & 'SPLINE_CUBIC_SET - Fatal error!',ch10, & 168 & ' The number of knots must be at least 2.',ch10, & 169 & ' The input value of N = ', n 170 MSG_ERROR(msg) 171 end if 172 173 LIBPAW_ALLOCATE(tmp,(n)) 174 175 do i=1,n-1 176 if (t(i)>=t(i+1)) then 177 write(msg,'(6a,i8,a,es19.12,2a,i8,a,es19.12)') ch10, & 178 & 'SPLINE_CUBIC_SET - Fatal error!',ch10, & 179 & ' The knots must be strictly increasing, but',ch10, & 180 & ' T(', i,') = ', t(i), ch10, & 181 & ' T(',i+1,') = ', t(i+1) 182 MSG_ERROR(msg) 183 end if 184 end do 185 186 ibcbeg=1;if(ybcbeg>1.0d+30)ibcbeg=0 187 ibcend=1;if(ybcend>1.0d+30)ibcend=0 188 189 !Set the first and last equations 190 if (ibcbeg==0) then 191 ypp(1) = 0._dp 192 tmp(1) = 0._dp 193 else if ( ibcbeg == 1 ) then 194 ypp(1) = -0.5_dp 195 tmp(1) = (3._dp/(t(2)-t(1)))*((y(2)-y(1))/(t(2)-t(1))-ybcbeg) 196 end if 197 if (ibcend==0) then 198 ypp(n) = 0._dp 199 tmp(n) = 0._dp 200 else if ( ibcend == 1 ) then 201 ypp(n) = 0.5_dp 202 tmp(n) = (3._dp/(t(n)-t(n-1)))*(ybcend-(y(n)-y(n-1))/(t(n)-t(n-1))) 203 end if 204 205 !Set the intermediate equations 206 do i=2,n-1 207 ratio=(t(i)-t(i-1))/(t(i+1)-t(i-1)) 208 pinv = 1.0_dp/(ratio*ypp(i-1) + 2.0_dp) 209 ypp(i) = (ratio-1.0_dp)*pinv 210 tmp(i)=(6.0_dp*((y(i+1)-y(i))/(t(i+1)-t(i))-(y(i)-y(i-1)) & 211 & /(t(i)-t(i-1)))/(t(i+1)-t(i-1))-ratio*tmp(i-1))*pinv 212 if (abs(tmp(i))<1.d5*tiny(0._dp)) tmp(i)=0._dp 213 end do 214 215 !Solve the equations 216 ypp(n) = (tmp(n)-ypp(n)*tmp(n-1))/(ypp(n)*ypp(n-1)+1.0_dp) 217 do k=n-1,1,-1 218 ypp(k)=ypp(k)*ypp(k+1)+tmp(k) 219 end do 220 221 LIBPAW_DEALLOCATE(tmp) 222 223 end subroutine paw_spline
m_paw_numeric/paw_splint [ Functions ]
[ Top ] [ m_paw_numeric ] [ Functions ]
NAME
paw_splint
FUNCTION
Compute spline interpolation of a tabulated function. There is no hypothesis about the spacing of the input grid points.
INPUTS
nspline: number of grid points of input mesh xspline(nspline): input mesh yspline(nspline): function on input mesh ysplin2(nspline): second derivative of yspline on input mesh nfit: number of points of output mesh xfit(nfit): output mesh
OUTPUT
yfit(nfit): function on output mesh [ierr]=A non-zero value is used to signal that some points in xfit exceed xspline(nspline). The input value is incremented by the number of such points.
PARENTS
m_paw_atom,m_paw_finegrid,m_paw_gaussfit,m_paw_pwaves_lmn,m_pawpsp m_pawxmlps,mkcore,mkcore_inner,mkcore_wvl,mklocl_realspace
CHILDREN
paw_jbessel
SOURCE
258 subroutine paw_splint(nspline,xspline,yspline,ysplin2,nfit,xfit,yfit,ierr) 259 260 261 !This section has been created automatically by the script Abilint (TD). 262 !Do not modify the following lines by hand. 263 #undef ABI_FUNC 264 #define ABI_FUNC 'paw_splint' 265 !End of the abilint section 266 267 implicit none 268 269 !Arguments ------------------------------------ 270 !scalars 271 integer,intent(in) :: nfit, nspline 272 integer,optional,intent(out) :: ierr 273 !arrays 274 real(dp),intent(in) :: xspline(nspline),yspline(nspline) 275 real(dp),intent(in) :: ysplin2(nspline),xfit(nfit) 276 real(dp),intent(out) :: yfit(nfit) 277 278 !Local variables------------------------------- 279 !scalars 280 integer :: left,i,k,right,my_err 281 real(dp) :: delarg,invdelarg,aa,bb 282 character(len=50) :: msg 283 !arrays 284 285 ! ************************************************************************* 286 287 my_err=0 288 left=1 289 do i=1,nfit 290 yfit(i)=0._dp ! Initialize for the unlikely event that rmax exceed r(mesh) 291 do k=left+1, nspline 292 if(xspline(k) >= xfit(i)) then 293 if(xspline(k-1) <= xfit(i)) then 294 right = k 295 left = k-1 296 else 297 if (k-1.eq.1 .and. i.eq.1) then 298 msg='xfit(1) < xspline(1)' 299 else 300 msg='xfit not properly ordered' 301 end if 302 MSG_ERROR(msg) 303 end if 304 delarg= xspline(right) - xspline(left) 305 invdelarg= 1.0_dp/delarg 306 aa= (xspline(right)-xfit(i))*invdelarg 307 bb= (xfit(i)-xspline(left))*invdelarg 308 yfit(i) = aa*yspline(left)+bb*yspline(right) & 309 & +( (aa*aa*aa-aa)*ysplin2(left) + & 310 & (bb*bb*bb-bb)*ysplin2(right) ) *delarg*delarg/6.0_dp 311 exit 312 end if 313 end do ! k 314 if (k==nspline+1) my_err=my_err+1 ! xfit not found 315 end do ! i 316 if (present(ierr)) ierr=my_err 317 318 end subroutine paw_splint
m_paw_numeric/paw_splint_der [ Functions ]
[ Top ] [ m_paw_numeric ] [ Functions ]
NAME
paw_splint_der
FUNCTION
Compute spline interpolation of the derivative of a tabulated function. There is no hypothesis about the spacing of the input grid points.
INPUTS
nspline: number of grid points of input mesh xspline(nspline): input mesh yspline(nspline): function on input mesh ysplin2(nspline): second derivative of yspline on input mesh nfit: number of points of output mesh xfit(nfit): output mesh
OUTPUT
dydxfit(nfit): 1st-derivative of function on output mesh [ierr]=A non-zero value is used to signal that some points in xfit exceed xspline(nspline). The input value is incremented by the number of such points.
PARENTS
mkcore_inner,mklocl_realspace,mklocl_wavelets
CHILDREN
paw_jbessel
SOURCE
352 subroutine paw_splint_der(nspline,xspline,yspline,ysplin2,nfit,xfit,dydxfit,ierr) 353 354 355 !This section has been created automatically by the script Abilint (TD). 356 !Do not modify the following lines by hand. 357 #undef ABI_FUNC 358 #define ABI_FUNC 'paw_splint_der' 359 !End of the abilint section 360 361 implicit none 362 363 !Arguments ------------------------------------ 364 !scalars 365 integer,intent(in) :: nfit, nspline 366 integer,optional,intent(out) :: ierr 367 !arrays 368 real(dp),intent(in) :: xspline(nspline),yspline(nspline) 369 real(dp),intent(in) :: ysplin2(nspline),xfit(nfit) 370 real(dp),intent(out) :: dydxfit(nfit) 371 372 !Local variables------------------------------- 373 !scalars 374 integer :: left,i,k,right,my_err 375 real(dp) :: delarg,invdelarg,aa,bb 376 character(len=50) :: msg 377 !arrays 378 379 ! ************************************************************************* 380 381 my_err=0 382 left=1 383 do i=1,nfit 384 dydxfit(i)=0._dp ! Initialize for the unlikely event that rmax exceed r(mesh) 385 do k=left+1, nspline 386 if(xspline(k) >= xfit(i)) then 387 if(xspline(k-1) <= xfit(i)) then 388 right = k 389 left = k-1 390 else 391 if (k-1.eq.1 .and. i.eq.1) then 392 msg='xfit(1) < xspline(1)' 393 else 394 msg='xfit not properly ordered' 395 end if 396 MSG_ERROR(msg) 397 end if 398 delarg= xspline(right) - xspline(left) 399 invdelarg= 1.0_dp/delarg 400 aa= (xspline(right)-xfit(i))*invdelarg 401 bb= (xfit(i)-xspline(left))*invdelarg 402 dydxfit(i) = (yspline(right)-yspline(left))*invdelarg & 403 & -( (3.0_dp*(aa*aa)-1.0_dp) *ysplin2(left) & 404 & -(3.0_dp*(bb*bb)-1.0_dp) *ysplin2(right) ) *delarg/6.0_dp 405 exit 406 end if 407 end do ! k 408 if (k==nspline+1) my_err=my_err+1 ! xfit not found 409 end do ! i 410 if (present(ierr)) ierr=my_err 411 412 end subroutine paw_splint_der
m_paw_numeric/paw_uniform_splfit [ Functions ]
[ Top ] [ m_paw_numeric ] [ Functions ]
NAME
paw_uniform_splfit
FUNCTION
Evaluate cubic spline fit to get function values on input set of ORDERED, UNIFORMLY SPACED points. Optionally gives derivatives (first and second) at those points too. If point lies outside the range of arg, assign the extremal point values to these points, and zero derivative.
INPUTS
arg(numarg)=equally spaced arguments (spacing delarg) for data to which spline was fit. fun(numarg,2)=function values to which spline was fit and spline fit to second derivatives (from Numerical Recipes spline). ider= see above newarg(numnew)=new values of arguments at which function is desired. numarg=number of arguments at which spline was fit. numnew=number of arguments at which function values are desired.
OUTPUT
derfun(numnew)=(optional) values of first or second derivative of function. This is only computed for ider=1 or 2; otherwise derfun not used. newfun(numnew)=values of function at newarg(numnew). This is only computed for ider=0 or 1.
NOTES
if ider=0, compute only the function (contained in fun) if ider=1, compute the function (contained in fun) and its first derivative (in derfun) if ider=2, compute only the second derivative of the function (in derfun)
PARENTS
CHILDREN
SOURCE
455 subroutine paw_uniform_splfit(arg,derfun,fun,ider,newarg,newfun,numarg,numnew) 456 457 458 !This section has been created automatically by the script Abilint (TD). 459 !Do not modify the following lines by hand. 460 #undef ABI_FUNC 461 #define ABI_FUNC 'paw_uniform_splfit' 462 !End of the abilint section 463 464 implicit none 465 466 !Arguments ------------------------------------ 467 !scalars 468 integer, intent(in) :: ider,numarg,numnew 469 !arrays 470 real(dp), intent(in) :: arg(numarg),fun(numarg,2),newarg(numnew) 471 real(dp), intent(out) :: derfun(numnew) 472 real(dp), intent(inout) :: newfun(numnew) 473 474 !Local variables------------------------------- 475 !scalars 476 integer :: i,jspl 477 real(dp) :: argmin,delarg,d,aa,bb,cc,dd 478 character(len=500) :: msg 479 !arrays 480 481 ! ************************************************************************* 482 483 !argmin is smallest x value in spline fit; delarg is uniform spacing of spline argument 484 argmin=arg(1) 485 delarg=(arg(numarg)-argmin)/dble(numarg-1) 486 487 if(delarg<tol12)then 488 write(msg,'(a,es16.8)') 'delarg should be strictly positive, while delarg= ',delarg 489 MSG_ERROR(msg) 490 endif 491 492 jspl=-1 493 494 !Do one loop for no grads, other for grads: 495 if (ider==0) then 496 497 ! Spline index loop for no grads: 498 do i=1,numnew 499 if (newarg(i).ge.arg(numarg)) then 500 newfun(i)=fun(numarg,1) 501 else if (newarg(i).le.arg(1)) then 502 newfun(i)=fun(1,1) 503 else 504 jspl=1+int((newarg(i)-argmin)/delarg) 505 d=newarg(i)-arg(jspl) 506 bb = d/delarg 507 aa = 1.0d0-bb 508 cc = aa*(aa**2-1.0d0)*(delarg**2/6.0d0) 509 dd = bb*(bb**2-1.0d0)*(delarg**2/6.0d0) 510 newfun(i)=aa*fun(jspl,1)+bb*fun(jspl+1,1)+cc*fun(jspl,2)+dd*fun(jspl+1,2) 511 end if 512 end do 513 514 else if(ider==1)then 515 516 ! Spline index loop includes grads: 517 do i=1,numnew 518 if (newarg(i).ge.arg(numarg)) then 519 newfun(i)=fun(numarg,1) 520 derfun(i)=0.0d0 521 else if (newarg(i).le.arg(1)) then 522 newfun(i)=fun(1,1) 523 derfun(i)=0.0d0 524 else 525 ! cubic spline interpolation: 526 jspl=1+int((newarg(i)-arg(1))/delarg) 527 d=newarg(i)-arg(jspl) 528 bb = d/delarg 529 aa = 1.0d0-bb 530 cc = aa*(aa**2-1.0d0)*(delarg**2/6.0d0) 531 dd = bb*(bb**2-1.0d0)*(delarg**2/6.0d0) 532 newfun(i)=aa*fun(jspl,1)+bb*fun(jspl+1,1)+cc*fun(jspl,2)+dd*fun(jspl+1,2) 533 ! spline fit to first derivative: 534 ! note correction of Numerical Recipes sign error 535 derfun(i) = (fun(jspl+1,1)-fun(jspl,1))/delarg + & 536 & (-(3.d0*aa**2-1.d0)*fun(jspl,2)+ & 537 & (3.d0*bb**2-1.d0)*fun(jspl+1,2)) * delarg/6.0d0 538 end if 539 end do 540 541 else if (ider==2) then 542 543 do i=1,numnew 544 if (newarg(i).ge.arg(numarg)) then 545 derfun(i)=0.0d0 546 else if (newarg(i).le.arg(1)) then 547 derfun(i)=0.0d0 548 else 549 ! cubic spline interpolation: 550 jspl=1+int((newarg(i)-argmin)/delarg) 551 d=newarg(i)-arg(jspl) 552 bb = d/delarg 553 aa = 1.0d0-bb 554 ! second derivative of spline (piecewise linear function) 555 derfun(i) = aa*fun(jspl,2)+bb*fun(jspl+1,2) 556 end if 557 end do 558 559 end if 560 561 end subroutine paw_uniform_splfit
m_special_funcs/paw_jbessel_4spline [ Functions ]
[ Top ] [ m_special_funcs ] [ Functions ]
NAME
paw_jbessel_4spline
FUNCTION
Compute spherical Bessel functions and derivatives. A polynomial approximation is employed for q-->0.
INPUTS
ll=l-order of the Bessel function tol=tolerance below which a Polynomial approximation is employed both for jl and its derivative (if required) order=1 if only first derivative is requested 2 if first and second derivatives are requested xx=where to compute j_l
OUTPUT
bes=Spherical Bessel function j_l at xx besp= first derivative of j_l at xx (only if order>=1)
TODO
Remove inline definitions, they are obsolete in F2003
PARENTS
m_pawpsp,m_pawpwij
CHILDREN
paw_jbessel
SOURCE
1013 subroutine paw_jbessel_4spline(bes,besp,ll,order,xx,tol) 1014 1015 1016 !This section has been created automatically by the script Abilint (TD). 1017 !Do not modify the following lines by hand. 1018 #undef ABI_FUNC 1019 #define ABI_FUNC 'paw_jbessel_4spline' 1020 !End of the abilint section 1021 1022 implicit none 1023 1024 !This section has been created automatically by the script Abilint (TD). 1025 !Do not modify the following lines by hand. 1026 #undef ABI_FUNC 1027 #define ABI_FUNC 'paw_jbessel_4spline' 1028 !End of the abilint section 1029 1030 !Arguments --------------------------------------------- 1031 !scalars 1032 integer,intent(in) :: ll,order 1033 real(dp),intent(in) :: xx,tol 1034 real(dp),intent(out) :: bes,besp 1035 1036 !Local variables --------------------------------------- 1037 !scalars 1038 real(dp) :: bespp 1039 !real(dp) :: arg,bes0a,bes0ap,bes0b,bes0bp,bes1a,bes1ap,bes1b,bes1bp 1040 !real(dp) :: bes2a,bes2ap,bes2b,bes2bp,bes3a,bes3ap,bes3b,bes3bp 1041 character(len=100) :: msg 1042 1043 ! ********************************************************************* 1044 1045 ! === l=0,1,2 and 3 spherical Bessel functions (and derivatives) === 1046 ! Statement functions are obsolete. Sorry ... 1047 !bes0a(arg)=1.0_dp-arg**2/6.0_dp*(1.0_dp-arg**2/20.0_dp) 1048 !bes0b(arg)=sin(arg)/arg 1049 !bes1a(arg)=(10.0_dp-arg*arg)*arg/30.0_dp 1050 !bes1b(arg)=(sin(arg)-arg*cos(arg))/arg**2 1051 !bes2a(arg)=arg*arg/15.0_dp-arg**4/210.0_dp 1052 !bes2b(arg)=((3.0_dp-arg**2)*sin(arg)-3.0_dp*arg*cos(arg))/arg**3 1053 !bes3a(arg)=arg*arg*arg/105.0_dp-arg**5/1890.0_dp+arg**7/83160.0_dp 1054 !bes3b(arg)=(15.0_dp*sin(arg)-15.0_dp*arg*cos(arg)-6.0_dp*arg**2*sin(arg)+arg**3*cos(arg))/arg**4 1055 !bes0ap(arg)=(-10.0_dp+arg*arg)*arg/30.0_dp 1056 !bes0bp(arg)=-(sin(arg)-arg*cos(arg))/arg**2 1057 !bes1ap(arg)=(10.0_dp-3.0_dp*arg*arg)/30.0_dp 1058 !bes1bp(arg)=((arg*arg-2.0_dp)*sin(arg)+2.0_dp*arg*cos(arg))/arg**3 1059 !bes2ap(arg)=(1.0_dp-arg*arg/7.0_dp)*2.0_dp*arg/15.0_dp 1060 !bes2bp(arg)=((4.0_dp*arg*arg-9.0_dp)*sin(arg)+(9.0_dp-arg*arg)*arg*cos(arg))/arg**4 1061 !bes3ap(arg)=(1.0_dp/35-arg*arg/378.0_dp+arg**4/11880.0_dp)*arg*arg 1062 !bes3bp(arg)=((-60.0_dp+27.0_dp*arg*arg-arg**4)*sin(arg)+(60.0_dp*arg-7.0_dp*arg**3)*cos(arg))/arg**5 1063 1064 ! This is to test paw_jbessel calculation without polynomial approximation for q-->0. 1065 ! call paw_jbessel(bes,besp,bespp,ll,order,xx) 1066 ! RETURN 1067 1068 if (order>2) then 1069 msg='Wrong order in paw_jbessel_4spline' 1070 MSG_ERROR(msg) 1071 end if 1072 1073 select case (ll) 1074 case (0) 1075 if (xx<TOL) then 1076 bes=1.0_dp-xx**2/6.0_dp*(1.0_dp-xx**2/20.0_dp) 1077 if (order>=1) besp=(-10.0_dp+xx*xx)*xx/30.0_dp 1078 else 1079 bes=sin(xx)/xx 1080 if (order>=1) besp=-(sin(xx)-xx*cos(xx))/xx**2 1081 end if 1082 1083 case (1) 1084 if (xx<TOL) then 1085 bes=(10.0_dp-xx*xx)*xx/30.0_dp 1086 if (order>=1) besp=(10.0_dp-3.0_dp*xx*xx)/30.0_dp 1087 else 1088 bes=(sin(xx)-xx*cos(xx))/xx**2 1089 if (order>=1) besp=((xx*xx-2.0_dp)*sin(xx)+2.0_dp*xx*cos(xx))/xx**3 1090 end if 1091 1092 case (2) 1093 if (xx<TOL) then 1094 bes=xx*xx/15.0_dp-xx**4/210.0_dp 1095 if (order>=1) besp=(1.0_dp-xx*xx/7.0_dp)*2.0_dp*xx/15.0_dp 1096 else 1097 bes=((3.0_dp-xx**2)*sin(xx)-3.0_dp*xx*cos(xx))/xx**3 1098 if (order>=1) besp=((4.0_dp*xx*xx-9.0_dp)*sin(xx)+(9.0_dp-xx*xx)*xx*cos(xx))/xx**4 1099 end if 1100 1101 case (3) 1102 if (xx<TOL) then 1103 bes=xx*xx*xx/105.0_dp-xx**5/1890.0_dp+xx**7/83160.0_dp 1104 if (order>=1) besp=(1.0_dp/35-xx*xx/378.0_dp+xx**4/11880.0_dp)*xx*xx 1105 else 1106 bes=(15.0_dp*sin(xx)-15.0_dp*xx*cos(xx)-6.0_dp*xx**2*sin(xx)+xx**3*cos(xx))/xx**4 1107 if (order>=1) besp=((-60.0_dp+27.0_dp*xx*xx-xx**4)*sin(xx)+(60.0_dp*xx-7.0_dp*xx**3)*cos(xx))/xx**5 1108 end if 1109 1110 case (4:) 1111 call paw_jbessel(bes,besp,bespp,ll,order,xx) 1112 1113 case default 1114 write(msg,'(a,i4)')' wrong value for ll = ',ll 1115 MSG_BUG(msg) 1116 end select 1117 1118 end subroutine paw_jbessel_4spline