10
0
mirror of https://gitlab.com/scemama/eplf synced 2024-06-01 19:05:27 +02:00
eplf/eplf.irp.f

316 lines
8.1 KiB
FortranFixed
Raw Normal View History

BEGIN_PROVIDER [ real, eplf_gamma ]
implicit none
BEGIN_DOC
! Value of the gaussian for the EPLF
END_DOC
eplf_gamma = 10.
END_PROVIDER
2009-05-15 17:18:39 +02:00
BEGIN_PROVIDER [ double precision, ao_eplf_integral_matrix, (ao_num,ao_num) ]
implicit none
BEGIN_DOC
! Array of all the <chi_i chi_j | exp(-gamma r^2)> for EPLF
END_DOC
integer :: i, j
2009-05-15 17:18:39 +02:00
double precision :: ao_eplf_integral
do i=1,ao_num
do j=i,ao_num
2009-05-15 17:18:39 +02:00
ao_eplf_integral_matrix(j,i) = ao_eplf_integral(j,i,eplf_gamma,point)
ao_eplf_integral_matrix(i,j) = ao_eplf_integral_matrix(j,i)
enddo
enddo
END_PROVIDER
BEGIN_PROVIDER [ double precision, mo_eplf_integral_matrix, (mo_num,mo_num) ]
2009-05-15 17:18:39 +02:00
implicit none
BEGIN_DOC
! Array of all the <chi_i chi_j | exp(-gamma r^2)> for EPLF
END_DOC
integer :: i, j, k, l
2009-05-15 17:43:02 +02:00
PROVIDE ao_eplf_integral_matrix
PROVIDE mo_coef
do i=1,mo_num
do j=i,mo_num
2009-05-15 17:18:39 +02:00
mo_eplf_integral_matrix(j,i) = 0.
2009-05-15 17:43:02 +02:00
enddo
do k=1,ao_num
if (mo_coef(k,i) /= 0.) then
do j=i,mo_num
2009-05-15 17:43:02 +02:00
do l=1,ao_num
mo_eplf_integral_matrix(j,i) = mo_eplf_integral_matrix(j,i) + &
mo_coef(k,i)*mo_coef(l,j)*ao_eplf_integral_matrix(k,l)
enddo
2009-05-15 17:18:39 +02:00
enddo
2009-05-15 17:43:02 +02:00
endif
enddo
do j=i,mo_num
2009-05-15 17:18:39 +02:00
mo_eplf_integral_matrix(i,j) = mo_eplf_integral_matrix(j,i)
enddo
enddo
END_PROVIDER
BEGIN_PROVIDER [ double precision, eplf_up_up ]
&BEGIN_PROVIDER [ double precision, eplf_up_dn ]
implicit none
BEGIN_DOC
! Value of the d_upup and d_updn quantities needed for EPLF
END_DOC
integer :: i, j, k, l, m, n
2009-05-15 01:01:27 +02:00
double precision :: thr
2009-05-15 01:01:27 +02:00
thr = 1.d-12 / eplf_gamma
eplf_up_up = 0.
eplf_up_dn = 0.
PROVIDE mo_coef_transp
2009-05-15 17:43:02 +02:00
do j=1,elec_beta_num
do i=1,elec_beta_num
eplf_up_up = eplf_up_up + 2.d0*mo_value_p(i)* ( &
mo_value_p(i)*mo_eplf_integral_matrix(j,j) - &
mo_value_p(j)*mo_eplf_integral_matrix(i,j) )
enddo
do i=elec_beta_num+1,elec_alpha_num
2009-05-15 17:18:39 +02:00
eplf_up_up = eplf_up_up + mo_value_p(i)* ( &
mo_value_p(i)*mo_eplf_integral_matrix(j,j) - &
mo_value_p(j)*mo_eplf_integral_matrix(i,j) )
enddo
enddo
2009-05-15 17:43:02 +02:00
do j=elec_beta_num+1,elec_alpha_num
do i=1,elec_alpha_num
2009-05-15 17:18:39 +02:00
eplf_up_up = eplf_up_up + mo_value_p(i)* ( &
mo_value_p(i)*mo_eplf_integral_matrix(j,j) - &
mo_value_p(j)*mo_eplf_integral_matrix(i,j) )
enddo
enddo
2009-05-15 17:18:39 +02:00
do j=1,elec_beta_num
do i=1,elec_alpha_num
eplf_up_dn = eplf_up_dn + mo_value_p(i)**2 * &
mo_eplf_integral_matrix(j,j)
enddo
enddo
2009-05-15 17:18:39 +02:00
eplf_up_dn = 2.d0*eplf_up_dn
END_PROVIDER
BEGIN_PROVIDER [ real, eplf_value ]
implicit none
BEGIN_DOC
! Value of the EPLF at the current point.
END_DOC
double precision :: aa, ab
aa = eplf_up_up
ab = eplf_up_dn
aa = min(1.d0,aa)
ab = min(1.d0,ab)
aa = max(tiny(1.d0),aa)
ab = max(tiny(1.d0),ab)
aa = -(dlog(aa)/eplf_gamma)+tiny(1.d0)
ab = -(dlog(ab)/eplf_gamma)+tiny(1.d0)
aa = dsqrt(aa)
ab = dsqrt(ab)
eplf_value = (aa-ab)/(aa+ab)
END_PROVIDER
2009-05-15 17:18:39 +02:00
double precision function ao_eplf_integral_primitive_oneD_numeric(a,xa,i,b,xb,j,gmma,xr)
implicit none
include 'constants.F'
real, intent(in) :: a,b,gmma ! Exponents
real, intent(in) :: xa,xb,xr ! Centers
integer, intent(in) :: i,j ! Powers of xa and xb
integer,parameter :: Npoints=1000
real :: x, xmin, xmax, dx
ASSERT (a>0.)
ASSERT (b>0.)
ASSERT (i>=0)
ASSERT (j>=0)
xmin = min(xa,xb)
xmax = max(xa,xb)
xmin = min(xmin,xr) - 10.
xmax = max(xmax,xr) + 10.
dx = (xmax-xmin)/real(Npoints)
real :: dtemp
dtemp = 0.
x = xmin
integer :: k
do k=1,Npoints
dtemp = dtemp + &
(x-xa)**i * (x-xb)**j * exp(-(a*(x-xa)**2+b*(x-xb)**2+gmma*(x-xr)**2))
x = x+dx
enddo
2009-05-15 17:18:39 +02:00
ao_eplf_integral_primitive_oneD_numeric = dtemp*dx
end function
2009-05-15 17:18:39 +02:00
double precision function ao_eplf_integral_numeric(i,j,gmma,center)
implicit none
integer, intent(in) :: i, j
integer :: p,q,k
double precision :: integral
2009-05-15 17:18:39 +02:00
double precision :: ao_eplf_integral_primitive_oneD_numeric
real :: gmma, center(3)
ao_eplf_integral_numeric = 0.
do q=1,ao_prim_num(j)
do p=1,ao_prim_num(i)
integral = &
2009-05-15 17:18:39 +02:00
ao_eplf_integral_primitive_oneD_numeric( &
ao_expo(p,i), &
nucl_coord(ao_nucl(i),1), &
ao_power(i,1), &
ao_expo(q,j), &
nucl_coord(ao_nucl(j),1), &
ao_power(j,1), &
gmma, &
center(1)) * &
2009-05-15 17:18:39 +02:00
ao_eplf_integral_primitive_oneD_numeric( &
ao_expo(p,i), &
nucl_coord(ao_nucl(i),2), &
ao_power(i,2), &
ao_expo(q,j), &
nucl_coord(ao_nucl(j),2), &
ao_power(j,2), &
gmma, &
center(2)) * &
2009-05-15 17:18:39 +02:00
ao_eplf_integral_primitive_oneD_numeric( &
ao_expo(p,i), &
nucl_coord(ao_nucl(i),3), &
ao_power(i,3), &
ao_expo(q,j), &
nucl_coord(ao_nucl(j),3), &
ao_power(j,3), &
gmma, &
center(3))
ao_eplf_integral_numeric = ao_eplf_integral_numeric + integral*ao_coef(p,i)*ao_coef(q,j)
enddo
enddo
end function
2009-05-15 17:18:39 +02:00
double precision function ao_eplf_integral_primitive_oneD(a,xa,i,b,xb,j,gmma,xr)
implicit none
include 'constants.F'
real, intent(in) :: a,b,gmma ! Exponents
real, intent(in) :: xa,xb,xr ! Centers
integer, intent(in) :: i,j ! Powers of xa and xb
integer :: ii, jj, kk, ll
real :: xp1,xp
real :: p1,p
double precision :: S(0:i+1,0:j)
double precision :: inv_p, di(max(i,j)), dj(j), c, c1
ASSERT (a>0.)
ASSERT (b>0.)
ASSERT (i>=0)
ASSERT (j>=0)
! Gaussian product
call gaussian_product(a,xa,b,xb,c1,p1,xp1)
call gaussian_product(p1,xp1,gmma,xr,c,p,xp)
inv_p = 1.d0/p
S(0,0) = dsqrt(pi*inv_p)*c*c1
! Obara-Saika recursion
if (i>0) then
S(1,0) = (xp-xa) * S(0,0)
endif
if (j>0) then
S(0,1) = (xp-xb) * S(0,0)
endif
do ii=1,max(i,j)
di(ii) = 0.5d0*inv_p*dble(ii)
enddo
if (i>1) then
do ii=1,i-1
S(ii+1,0) = (xp-xa) * S(ii,0) + di(ii)*S(ii-1,0)
enddo
endif
if (j>1) then
do jj=1,j-1
S(0,jj+1) = (xp-xb) * S(0,jj) + di(jj)*S(0,jj-1)
enddo
endif
do jj=1,j
S(1,jj) = (xp-xa) * S(0,jj) + di(jj) * S(0,jj-1)
do ii=2,i
S(ii,jj) = (xp-xa) * S(ii-1,jj) + di(ii-1) * S(ii-2,jj) + di(jj) * S(ii-1,jj-1)
enddo
enddo
2009-05-15 17:18:39 +02:00
ao_eplf_integral_primitive_oneD = S(i,j)
end function
2009-05-15 17:18:39 +02:00
double precision function ao_eplf_integral(i,j,gmma,center)
implicit none
integer, intent(in) :: i, j
integer :: p,q,k
double precision :: integral
2009-05-15 17:18:39 +02:00
double precision :: ao_eplf_integral_primitive_oneD
real :: gmma, center(3)
ASSERT(i>0)
ASSERT(j>0)
ASSERT(i<=ao_num)
ASSERT(j<=ao_num)
ao_eplf_integral = 0.
do q=1,ao_prim_num(j)
do p=1,ao_prim_num(i)
integral = &
ao_eplf_integral_primitive_oneD( &
ao_expo(p,i), &
nucl_coord(ao_nucl(i),1), &
ao_power(i,1), &
ao_expo(q,j), &
nucl_coord(ao_nucl(j),1), &
ao_power(j,1), &
gmma, &
center(1)) * &
ao_eplf_integral_primitive_oneD( &
ao_expo(p,i), &
nucl_coord(ao_nucl(i),2), &
ao_power(i,2), &
ao_expo(q,j), &
nucl_coord(ao_nucl(j),2), &
ao_power(j,2), &
gmma, &
center(2)) * &
ao_eplf_integral_primitive_oneD( &
ao_expo(p,i), &
nucl_coord(ao_nucl(i),3), &
ao_power(i,3), &
ao_expo(q,j), &
nucl_coord(ao_nucl(j),3), &
ao_power(j,3), &
gmma, &
center(3))
ao_eplf_integral = ao_eplf_integral + integral*ao_coef(p,i)*ao_coef(q,j)
enddo
enddo
end function