******************************************************************************** * * * 2DHF version 1-2003 * * Copyright (C) 1996 Jacek Kobus, Leif Laaksonen, Dage Sundholm * * * * This software may be used and distributed according to the terms * * of the GNU General Public License, see README and COPYING. * * * ******************************************************************************** c ### locenergy ### c c Calculates the locale energy for a given orbital. c subroutine locenergy (iorb,psi,pot,excp,e,f0,f4,wgt1,wgt2, & wk0,wk1,wk2,wk3) implicit integer*4 (i-n) implicit real*8 (a-h,o-z) character*13 fn include 'commons8.inc' dimension psi(*),pot(*),excp(*),e(*),f0(*),wgt1(*),wgt2(*), & wk0(*),wk1(*),wk2(*),wk3(*),f4(*) ioutmat=30 open(ioutmat,file='vni',status='unknown',form='formatted') write(ioutmat,*) nni write(ioutmat,1000) (vni(in),in=1,nni) close(ioutmat) open(ioutmat,file='vmu',status='unknown',form='formatted') write(ioutmat,*) i1mu(1) write(ioutmat,1000) (vmu(im),im=1,i1mu(1)) close(ioutmat) 01000 format(F25.15) wtwoel=0.d0 i1beg=i1b(iorb) i2beg=i2b(iorb) nmut=i1mu(iorb) ngorb=i1si(iorb) ngpot=i2si(iorb) isd=iorb+(iorb-1)*norb engo(isd)=0.0d0 ipe=mgx(6,iorb) ipex=ipe-2*(ipe/2) c calculate derivatives over mu and ni if (ipex.eq.0) then isym= 1 else isym=-1 endif call fill (nni,nmut,isym,psi(i1beg),wk3) call difni (nmut,wk3,wk0,wk1,wk2) call refill(nni,nmut,wk1,wk0) call difmu (nmut,wk3,wk2) call refill(nni,nmut,wk0,wk2) c add contribution from derivatives over mu and ni call add (ngorb,wk0,wk1) if (ipe.eq.0) then call dcopy (ngorb,f0,1,wk0,1) else c e enter the expression with minus sign which is already c incorporated in e w=dble(ipe*ipe) call dcopy (ngorb,f0,1,wk0,1) call daxpy (ngorb,w,e,1,wk0,1) endif call proda (ngorb,psi(i1beg),wk0,wk1) call prod (ngorb,wgt1,wk1) c now wk1 contains (T+V)|psi> c call prod (ngorb,psi(i1beg),wk1) c w=ddot(ngorb,wgt1,1,wk1,1) c write(*,*) ' ',w c stop do i=1,ngorb wk2(i)=0.d0 enddo if (nel.gt.1) then if (norb.eq.1) then c contribution from coulomb potential of one sigma orbital call dcopy (ngpot,pot(i2beg),1,wk2,1) call prod (ngorb,psi(i1beg),wk2) else do i=1,mxsize wk2(i)=0.d0 enddo c add contributions from coulomb and exchange potentials do iorb1=1,norb i1beg1=i1b(iorb1) i2beg1=i2b(iorb1) ngorb1=i1si(iorb1) ngpot1=i2si(iorb1) oc=occ(iorb1) kex=iorb+norb*(iorb1-1) if (iorb.le.iorb1) then ihc=iorb+iorb1*(iorb1-1)/2 else ihc=iorb1+iorb*(iorb-1)/2 endif i3beg=i3b(ihc) ngex =i3si(ihc) ngrid=min(ngorb,ngpot1) do i=1,mxsize wk0(i)=0.d0 enddo call dcopy (ngpot1,pot(i2beg1),1,wk0,1) call prod (ngrid,psi(i1beg),wk0) if (iorb.eq.iorb1) oc=oc-1.d0 if (oc.ne.1.d0) then call dscal (ngrid,oc,wk0,1) endif if (iorb1.ne.iorb) then ngrid2=min(ngorb1,ngex,ngorb) oc=gec(kex) call prodas (ngrid2,-oc,psi(i1beg1),excp(i3beg),wk0) if (ilc(ihc).gt.1) then oc=gec(kex+norb*norb) call prodas (ngrid2,-oc,psi(i1beg1), & excp(i3beg+ngex),wk0) endif else if ((ipe.gt.0).and.(ilc(ihc).gt.0)) then ngrid2=min(ngorb1,ngex,ngorb) oc=gec(kex) call prodas (ngrid2,-oc,psi(i1beg1), & excp(i3beg),wk0) endif endif if (iorb1.eq.1) then call dcopy (ngrid,wk0,1,wk2,1) else call add (ngrid,wk0,wk2) endif enddo endif c to complete the integrand wk2 has to be multiplied by psi(i1beg) call prod (ngorb,wgt2,wk2) endif c wk2 contains V(fock)|psi> i1beg=i1b(iorb) ngorb=i1si(iorb) call add (ngorb,wk1,wk2) call dcopy (ngorb,wk2,1,wk3,1) c call prod (ngorb,psi(i1beg),wk2) c w=ddot(ngorb,wgt1,1,wk2,1) c write(*,*) ' ',w w=-eng(iorb) call dcopy(ngorb,f4,1,wk1,1) call prod(ngorb,psi(i1beg),wk1) call prod(ngorb,wgt2,wk1) call dcopy (ngorb,wk1,1,wk0,1) call daxpy(ngorb,w,wk1,1,wk2,1) w=0.d0 w1=0.d0 w2=0.d0 wk2max=0.d0 do i=1,ngorb c exclude grid points where nuclei are located if (abs(wk2(i)).gt.wk2max) then wk2max=abs(wk2(i)) imax=i endif if (.not.(i.eq.1.or.i.eq.(ngrid-mxnmu))) then w=w+wk2(i)*wk2(i) w1=w1+wk2(i)*wk2(i)*f4(i)*wgt2(i) c w2=w2+wk2(i)*wk2(i)*f4(i) endif enddo write(*,*) 'imax, wk2max',imax,wk2max if (idbg(496).ne.0) then go to ( 11, 12, 13, 14, 15, 16), iorb 00011 fn='bf-1p.lenergy' goto 100 00012 fn='bf-5s.lenergy' goto 100 00013 fn='bf-4s.lenergy' goto 100 00014 fn='bf-3s.lenergy' goto 100 00015 fn='bf-2s.lenergy' goto 100 00016 fn='bf-1s.lenergy' 00100 continue open(ioutmat,file=fn,status='unknown',form='formatted') ibeg=i1b(iorb) call prtmat (nni,i1mu(1),wk2,ioutmat) close(ioutmat) endif c write(*,1010) iorn(iorb),bond(iorb),w,sqrt(w),w1,w2,sqrt(w2) c write(*,1010) iorn(iorb),bond(iorb),w,sqrt(w),w1,sqrt(w1) write(*,1010) iorn(iorb),bond(iorb),w1,sqrt(w1), & sqrt(w1)/(-eng(iorb)) c01010 format(10x,i2,1x,a5,' ',2d15.5/16x,d15.5/16x,2d15.5) 01010 format(10x,i2,1x,a5,' ',4d15.5) c call enrradius(wk2) if (idbg(497).ne.0) then call leexact1(wk3,wk0) c call divide(wk0,psi(i1beg)) else c call leexact(wk1,wk2) endif return end c Several auxiliary routines follow. c ### prtmatle ### c subroutine prtmatle (m,n,a,ioutmat) implicit integer*4 (i-n) implicit real*8 (a-h,o-z) dimension a(m,n) c loop over grid points if (n.gt.500) then print *,'prtmatle: nonadequate format' stop endif do im=1,m write(ioutmat,1000) (a(im,in),in=1,n) enddo 01000 format(500F25.15) return end c ### enrradius ### c subroutine enrradius (vt) implicit integer*4 (i-n) implicit real*8 (a-h,o-z) dimension vt(nni,mxnmu) include 'commons8.inc' dev1=0.d0 dev2=0.d0 idev2=0 r1max=0.2d0 ipoints=0 izero=0 do ini=1,nni do imu=1,mxnmu r1=(r/2.d0)*(vxi(imu)+veta(ini)) t=vt(ini,imu)**2 dev1=dev1+t if (abs(r1).gt.r1max) then dev2=dev2+t idev2=idev2+1 endif enddo enddo write(*,*) 'Eucleadian norm ',sqrt(dev1),-0.5d0-eng(1) write(*,*) 'Eucleadian norm for r>rmax ',idev2,r1max,sqrt(dev2) return end c ### leexact ### c subroutine leexact (a,b) implicit integer*4 (i-n) implicit real*8 (a-h,o-z) dimension a(nni,mxnmu),b(nni,mxnmu) include 'commons8.inc' iorb=1 dev1=0.d0 dev2=0.d0 dev3=0.d0 ipoints=0 izero=0 do ini=1,nni do imu=1,mxnmu r1=(r/2.d0)*(vxi(imu)+veta(ini)) dnum=0.d0 ddnom=0.d0 a(ini,imu)=0.d0 s1=0.d0 s2=0.d0 s3=0.d0 if (abs(r1).gt.precis) then do ipb=npbasis,1,-1 d1=primexp(ipb) c1=primcoef(iorb,ipb) e=(2.d0*d1/pii)**(3.d0/4.d0)*exp(-d1*r1*r1) s1=s1+c1*(-2.d0*d1*d1*r1*r1)*e s2=s2+c1*(3.d0*d1)*e if (abs(r1).gt.precis) s3=s3+c1*(-z1/r1)*e ddnom=ddnom+c1*e enddo dnum=s1+s2+s3 if (idbg(497).ne.0) then a(ini,imu)=dnum else a(ini,imu)=dnum+0.5d0*ddnom endif ipoints=ipoints+1 dev1=dev1+(a(ini,imu))**2 else izero=izero+1 endif enddo enddo write(*,*) 'deviation of gaussian approximation from -Z**2/2' write(*,*) ipoints,sqrt(dev1),sqrt(dev1/dble(ipoints)) dev2=0.d0 dev3=0.d0 do inii=1,nni do imu=1,mxnmu c dev2=dev2+(a(ini,imu)+z1*z1/2.d0-b(ini,imu))**2 dev2=dev2+(a(ini,imu)-b(ini,imu))**2 enddo enddo write(*,*) 'deviation of gaussian approximation from exact one' write(*,*) sqrt(dev2) write(*,'(2d20.6,2i10)') sqrt(dev1), sqrt(dev2), ipoints, izero stop dev1=0.d0 dev2=0.d0 dev3=0.d0 ipoints=0 do ini=1,nni do imu=1,mxnmu r1=(r/2.d0)*(vxi(imu)+veta(ini)) dnum=0.d0 ddnom=0.d0 a(ini,imu)=0.d0 do ipb=1,npbasis ic1 =icgau(ipb) d1 =primexp(ipb) c1 =primcoef(iorb,ipb) if (abs(r1).gt.precis.and.(d1*r1*r1).lt.200.0d0) then dnum=dnum+c1*(-2.d0*d1*d1*r1*r1+3.d0*d1-z1/r1)* & (2.d0*d1/pii)**(3.d0/4.d0)*exp(-d1*r1*r1) ddnom=ddnom+c1*(2.d0*d1/pii)**(3.d0/4.d0)* & exp(-d1*r1*r1) endif enddo if (abs(ddnom).gt.precis) then a(ini,imu)=dnum+0.5d0*ddnom else a(ini,imu)=0.d0 endif ipoints=ipoints+1 dev1=dev1+(a(ini,imu))**2 enddo enddo write(*,*) 'deviation of gaussian approximation from -Z**2/2' write(*,*) ipoints,sqrt(dev1),sqrt(dev1/dble(ipoints)) dev2=0.d0 dev3=0.d0 do ini=1,nni do imu=1,mxnmu dev2=dev2+(a(ini,imu)-b(ini,imu))**2 enddo enddo write(*,*) 'deviation of gaussian approximation from exact one' write(*,*) sqrt(dev2) write(*,'(3d20.6,i10)') sqrt(dev1), sqrt(dev2), sqrt(dev3),ipoints return end c ### leexact1 ### c subroutine leexact1 (vt,orb) implicit integer*4 (i-n) implicit real*8 (a-h,o-z) dimension vt(nni,mxnmu),orb(nni,mxnmu) include 'commons8.inc' iorb=1 w=eng(iorb) dev1=0.d0 dev2=0.d0 idev2=0 r1max=0.2d0 ipoints=0 izero=0 do ini=1,nni do imu=1,mxnmu r1=(r/2.d0)*(vxi(imu)+veta(ini)) dnum=0.d0 ddnom=0.d0 s1=0.d0 s2=0.d0 s3=0.d0 if (abs(r1).gt.precis) then do ipb=npbasis,1,-1 d1=primexp(ipb) c1=primcoef(iorb,ipb) e=(2.d0*d1/pii)**(3.d0/4.d0)*exp(-d1*r1*r1) s1=s1+c1*(-2.d0*d1*d1*r1*r1)*e s2=s2+c1*(3.d0*d1)*e if (abs(r1).gt.precis) s3=s3+c1*(-z1/r1)*e ddnom=ddnom+c1*e enddo dnum=s1+s2+s3 if (idbg(497).ne.0.and.abs(ddnom).gt.precis) then t=(vt(ini,imu)-dnum/ddnom*orb(ini,imu))**2 dev1=dev1+(vt(ini,imu)-dnum/ddnom*orb(ini,imu))**2 endif if (abs(r1).gt.r1max) then dev2=dev2+t idev2=idev2+1 endif endif enddo enddo write(*,*) 'deviation from exact local energy',sqrt(dev1) write(*,*) 'deviation from exact local energy outside radius' write(*,*) idev2,r1max,sqrt(dev2) return end c ### divide ### c subroutine divide (a,b) implicit integer*4 (i-n) implicit real*8 (a-h,o-z) dimension a(nni,mxnmu),b(nni,mxnmu) include 'commons8.inc' iorb=1 dev1=0.d0 dev2=0.d0 dev3=0.d0 ipoints=0 izero=0 do ini=1,nni do imu=1,mxnmu if (abs(b(ini,imu)).gt.precis) then a(ini,imu)=a(ini,imu)/b(ini,imu) else a(ini,imu)=0.d0 izero=izero+1 endif enddo enddo write(*,*) 'deviation of gaussian approximation from -Z**2/2' write(*,*) sqrt(dev1),izero return end c ### exorbitals ### c C This subroutine prints out orbitals c subroutine exorbitals (ioutmat,psi) implicit integer*4 (i-n) implicit real*8 (a-h,o-z) character*13 fn include 'commons8.inc' dimension psi(*) open(ioutmat,file='vni',status='unknown',form='formatted') write(ioutmat,*) nni write(ioutmat,1000) (vni(in),in=1,nni) close(ioutmat) open(ioutmat,file='vmu',status='unknown',form='formatted') write(ioutmat,*) i1mu(1) write(ioutmat,1000) (vmu(im),im=1,i1mu(1)) close(ioutmat) 01000 format(F25.15) do iorb=1,norb iout=ioutmat+norb-iorb+1 open(iout,status='unknown',form='formatted') ibeg=i1b(iorb) call prtmat (nni,i1mu(1),psi(ibeg),iout) close(iout) write(*,*) 'exorbitals: ',iout enddo 01010 format(10x,i2,1x,a5,' ',4d15.5) return end