mirror of
https://code.it4i.cz/sccs/easyconfigs-it4i.git
synced 2025-04-16 03:38:05 +01:00
2353 lines
88 KiB
Fortran
2353 lines
88 KiB
Fortran
************************************************************************
|
|
SUBROUTINE FOCK_BUILD(PA,PB,FOCKA,FOCKB,QMAT,INDEXIRREP,OFFSET,
|
|
$SQROFFSET,npos,intpos,step,cmat,lfin,exc,dft,cchfx,lwdfn,embed,
|
|
$scfdamp,route,nfr,nc,ncorenew,devparr,symtra,nact,cclrhfx,ccsrhfx,
|
|
$omega,rs,qscf_hess,ica,icb,pcm,excha,exchb,lscrohfldf)
|
|
************************************************************************
|
|
* CONSTRUCTION OF THE FOCK-MATRIX
|
|
************************************************************************
|
|
#if defined (LIBXC)
|
|
use xc_f03_lib_m
|
|
#endif
|
|
#include "MRCCCOMMON"
|
|
#include "SCFCOMMON"
|
|
#if defined (LIBXC)
|
|
type(xc_f03_func_t) :: xc_func
|
|
type(xc_f03_func_info_t) :: xc_info
|
|
integer*4 func_id
|
|
#endif
|
|
C ARRAYS
|
|
REAL*8 PA(NBASIS,NBASIS),cmat(*),devparr(2),cchfx,rs(*)
|
|
REAL*8 PB(NBASIS,NBASIS),symtra(nbasis,nbasis)
|
|
REAL*8 QMAT(NBASIS,NBASIS)
|
|
REAL*8 FOCKA(NBASIS,NBASIS),excha(nbasis,nbasis)
|
|
REAL*8 FOCKB(NBASIS,NBASIS),exchb(nbasis,nbasis)
|
|
integer nact
|
|
INTEGER INDEXIRREP(*),nfr,nalf,nbef
|
|
INTEGER INTPOS(3,(nbasis+1)*nbasis/2)
|
|
INTEGER TEINTF(10)
|
|
INTEGER OFFSET(*)
|
|
INTEGER SQROFFSET(*)
|
|
C SCALARS
|
|
INTEGER T,Q
|
|
INTEGER I,J,K,L
|
|
integer*2 ii2,kk2
|
|
INTEGER NPOS
|
|
INTEGER IPOS
|
|
INTEGER IMEM1
|
|
INTEGER STEP
|
|
INTEGER NINTEG
|
|
INTEGER NNINTEG
|
|
INTEGER IPOSLO
|
|
INTEGER IP
|
|
INTEGER MAXM
|
|
integer ii,intalloc,dblalloc,imoa,imob,icmo,icpr,iroute,imemold,n
|
|
integer ii4core,ix,nos,id,iimoa,iimob,iss,isi,nmobasis_ptr,locfit
|
|
integer nmoat_ptr,moat_ptr,ijpvt,natdom_ptr,naoat_ptr,aoat_ptr
|
|
integer dfnmobasis_ptr,moadd_ptr,atmo_ptr,lfin,atind_ptr
|
|
integer natmo_ptr,hailen,nc,ncorenew,idaa,icaa,lsexc,atdom_ptr
|
|
integer ifocka_tmp
|
|
integer ica,icb !memory address of MO coefficients for QSCF Hessian construcion
|
|
integer incorb,iactive_atoms
|
|
character*4 route
|
|
character*5 cscftype
|
|
character*7 scfiguess
|
|
character*8 embed,cpssp
|
|
character*16 scfdamp,c16
|
|
character*32 dft,cdft,pcm
|
|
real*8 temp,exc,chfx,dtol,excl,trpfa,trpfb,ddot,excrad,excrad_fin
|
|
real*8 chfxold,clrhfx,csrhfx,omega,cclrhfx,ccsrhfx,chfxa,clrhfxa
|
|
real*8 csrhfxa,epol
|
|
logical lbeta,lscale,lwdfn,llc,sclroute,linv,lmcl,lfdm,lpssp,lexc
|
|
logical qscf_hess,lscrohfldf
|
|
COMMON/MEMCOM/ IMEM1
|
|
C
|
|
call getkey('pssp',4,cpssp,8)
|
|
if(cpssp.eq.'off ') then
|
|
lpssp = .false.
|
|
else
|
|
lpssp=.true. ! integ.f
|
|
endif
|
|
lscale=.false.
|
|
llc=.false.
|
|
lsexc=0
|
|
sclroute=.false.
|
|
iroute=2
|
|
lfdm=trim(embed).eq.'fdm'.and.(route.eq.'em2 '.or.route.eq.'em3 ')
|
|
call getkey('scfiguess',9,scfiguess,7)
|
|
chfx=cchfx
|
|
clrhfx=cclrhfx
|
|
csrhfx=ccsrhfx
|
|
chfxa=0.d0
|
|
clrhfxa=0.d0
|
|
csrhfxa=0.d0
|
|
if(route.eq.'em1 '.or.route.eq.'em2 '.or.route.eq.'emft'.or.
|
|
$(route.eq.'sml '.and.trim(embed).ne.'off').or.route.eq.'sch ')then
|
|
chfx=0.d0
|
|
clrhfx=0.d0
|
|
csrhfx=0.d0
|
|
if(trim(dft).eq.'bhlyp') then
|
|
chfx=-0.5d0
|
|
else if(trim(dft).eq.'b3lyp') then
|
|
chfx=-0.2d0
|
|
else if(trim(dft).eq.'b3pw91') then
|
|
chfx=-0.2d0
|
|
else if(trim(dft).eq.'b3lyp3') then
|
|
chfx=-0.2d0
|
|
else if(trim(dft).eq.'b97') then
|
|
chfx=-0.1943d0
|
|
else if(trim(dft).eq.'pbe0') then
|
|
chfx=-0.25d0
|
|
else if(trim(dft).eq.'b2plyp') then
|
|
chfx=-0.53d0
|
|
else if(trim(dft).eq.'b2gpplyp') then
|
|
chfx=-0.65d0
|
|
else if(trim(dft).eq.'dsdpbep86') then
|
|
chfx=-0.70d0
|
|
else if(trim(dft).eq.'xyg3') then
|
|
chfx=-0.20d0
|
|
else if(trim(dft).eq.'scan0-2') then
|
|
chfx=-0.793701d0
|
|
else if(trim(dft).eq.'drpa75') then
|
|
chfx=-0.75d0
|
|
else if(trim(dft).eq.'scs-drpa75') then
|
|
chfx=-0.75d0
|
|
else if(trim(dft).eq.'m06-2x') then
|
|
chfx=-0.54d0
|
|
else if(trim(dft).eq.'m06-hf') then
|
|
chfx=-1.d0
|
|
else if(trim(dft).eq.'m08-hx') then
|
|
chfx=-0.5223d0
|
|
else if(trim(dft).eq.'m08-so') then
|
|
chfx=-0.5679d0
|
|
else if(trim(dft).eq.'dsdpbehb95') then
|
|
chfx=-0.66d0
|
|
else if(trim(dft).eq.'scan0') then
|
|
chfx=-0.25d0
|
|
else if(trim(dft).eq.'off') then
|
|
chfx=-1.d0
|
|
else if(trim(dft).eq.'cam-b3lyp') then
|
|
chfx=-0.19d0
|
|
clrhfx=-0.46d0
|
|
else if(trim(dft).eq.'m11') then
|
|
chfx=-1.d0
|
|
csrhfx=0.572d0
|
|
else if(trim(dft).eq.'mn12-sx') then
|
|
csrhfx=-0.25d0
|
|
else if(trim(dft).eq.'mn15') then
|
|
chfx=-0.44d0
|
|
else if(trim(dft).eq.'wb97') then
|
|
clrhfx=-1.d0
|
|
else if(trim(dft).eq.'wb97x') then
|
|
chfx=-0.157706d0
|
|
clrhfx=-0.842294d0
|
|
else if(trim(dft).eq.'wb97x-v') then
|
|
chfx=-0.167d0
|
|
clrhfx=-0.833d0
|
|
else if(trim(dft).eq.'wb97m-v') then
|
|
chfx=-0.15d0
|
|
clrhfx=-0.85d0
|
|
else if(trim(dft).eq.'hse06') then
|
|
csrhfx=-0.25d0
|
|
else if(trim(dft).eq.'lc-wpbe') then
|
|
csrhfx=-1.d0
|
|
else if(trim(dft(1:2)).eq.'rs') then
|
|
c clrhfx=-1.d0
|
|
c csrhfx=-0.5d0
|
|
write(6,*) 'Not tested!'
|
|
call mrccend(1)
|
|
else if(trim(dft).eq.'user') then
|
|
open(minpfile,file='MINP')
|
|
call getkeym('embed',5,embed,8)
|
|
read(minpfile,*)
|
|
read(minpfile,*)
|
|
read(minpfile,*) n
|
|
do i=1,n
|
|
read(minpfile,*) temp,cdft
|
|
cdft=adjustl(cdft)
|
|
call lowercase(cdft,cdft,32)
|
|
if(trim(cdft).eq.'hfx') then
|
|
chfx=-temp
|
|
else if(trim(cdft).eq.'lrhfx') then
|
|
clrhfx=-temp
|
|
else if(trim(cdft).eq.'srhfx') then
|
|
csrhfx=-temp
|
|
endif
|
|
enddo
|
|
close(minpfile)
|
|
#if defined (LIBXC)
|
|
else if(xc_f03_functional_get_number(dft).gt.0) then
|
|
func_id=xc_f03_functional_get_number(dft)
|
|
call xc_f03_func_init(xc_func,func_id,XC_UNPOLARIZED)
|
|
xc_info=xc_f03_func_get_info(xc_func)
|
|
chfx=xc_f03_hyb_exx_coef(xc_func)
|
|
call xc_f03_func_end(xc_func)
|
|
chfx=-chfx
|
|
#endif
|
|
endif
|
|
if(route.eq.'emft') then
|
|
if(chfx.eq.0.d0) then
|
|
call getvar('chfx ',chfx) !No HFx in low-level method
|
|
else
|
|
call getvar('chfx ',temp) !HFx in low-level method
|
|
if(temp.ne.0.d0) then
|
|
lsexc=1 !HFx in both the high- and the low-level method
|
|
else
|
|
lsexc=2 !HFx only in the low-level method
|
|
c chfx=0.d0
|
|
endif
|
|
endif
|
|
endif
|
|
if(route.eq.'sch ') then
|
|
call getvar('chfx ',chfxa)
|
|
call getvar('clrhfx ',clrhfxa)
|
|
call getvar('csrhfx ',csrhfxa)
|
|
endif
|
|
if(route.eq.'em2 ') then
|
|
open(scrfile1,file='CHFX')
|
|
write(scrfile1,'(ES30.16)') chfx
|
|
write(scrfile1,'(2ES30.16)') clrhfx,csrhfx
|
|
write(scrfile1,'(3ES30.16)') chfxa,clrhfxa,csrhfxa
|
|
close(scrfile1)
|
|
endif
|
|
endif
|
|
chfxold=chfx
|
|
if(lpssp) chfx=0.d0
|
|
lexc=chfx.ne.0.d0.or.clrhfx.ne.0.d0.or.csrhfx.ne.0.d0.or.
|
|
$chfxa.ne.0.d0.or.clrhfxa.ne.0.d0.or.csrhfxa.ne.0.d0.or.lsexc.gt.0
|
|
if(lexc) istore=0
|
|
C Clean up memory for exchange, do not perform memory operation before
|
|
if(dfbasis_scf.ne.'none ') then
|
|
call getvar('nbf ',nbf)
|
|
dfnbasis=nbf(2)
|
|
endif
|
|
imemold=imem
|
|
lmcl=(lexc.or.lsexc.gt.0).and.
|
|
$dfbasis_scf.ne.'none '.and.
|
|
$nbasis*max(nal,nbe)*dfnbasis.gt.maxcor-(imem-imem1)
|
|
if(lmcl.and.qscf_hess) then
|
|
write(*,'(1X,A)') 'Not enough memory for the Hessian'
|
|
call mrccend(1)
|
|
elseif(lmcl) then
|
|
if(verblevel.ge.3) write(iout,*) 'Cleaning up memory...'
|
|
open(unit=scrfile6,file='SCFSCR',form='unformatted')
|
|
write(scrfile6) dcore(c_ptr:imem-1)
|
|
close(scrfile6)
|
|
call dbldealloc(c_ptr)
|
|
endif
|
|
C
|
|
if(route.eq.'emft'.or.route.eq.'sch '.or.lfdm) then
|
|
idaa=dblalloc(nbasis**2)
|
|
icaa=dblalloc(nbasis**2)
|
|
else
|
|
idaa=imem
|
|
icaa=imem
|
|
endif
|
|
if(scftype.eq.1) then
|
|
cscftype='rhf '
|
|
else if(scftype.eq.2) then
|
|
cscftype='uhf '
|
|
else
|
|
cscftype='rohf '
|
|
endif
|
|
C Cholesky-decompose density matrix
|
|
if(scftype .eq. _MCSCF_ .or.
|
|
& (scftype .eq. _RHF_ .and. qscf_hess)) then
|
|
if(nact .eq. 0) then
|
|
nalf = 0
|
|
do i = 1, nir
|
|
nalf = nalf + orbperir(i)
|
|
enddo
|
|
nalf = nalf - nfr
|
|
nbef = nalf
|
|
else
|
|
nalf = nact
|
|
nbef = nact
|
|
endif
|
|
elseif(scftype .ge. 3 .and. qscf_hess) then
|
|
nalf = nact
|
|
nbef = nact
|
|
else
|
|
nalf=nal-nfr
|
|
nbef=nbe-nfr
|
|
endif
|
|
if(qscf_hess) then
|
|
nalf=2*nalf
|
|
nbef=2*nbef
|
|
endif
|
|
nc=0
|
|
imoa=imem
|
|
imob=imem
|
|
ix=imem
|
|
if(dfbasis_scf.ne.'none '.or.trim(dft).ne.'off'
|
|
$.or.route.eq.'den1'.or.route.eq.'den2'.or.lpssp) then
|
|
llc=(nir.eq.1.and.(step.gt.1.or.scfiguess.eq.'sad '.or.
|
|
$scfiguess.eq.'mo '.or.scfiguess.eq.'restart').and.
|
|
$.not.ldens.and.scftype.le.2.and.scfdamp.eq.'off ').or.
|
|
$route.eq.'sch '
|
|
if(lmcl.and.llc) then
|
|
call dcopy(nbasis*nalf,cmat,1,focka,1)
|
|
if(scftype.ge.2)
|
|
$ call dcopy(nbasis*nbef,cmat(sqrsize+1),1,fockb,1)
|
|
endif
|
|
if(dfbasis_scf.ne.'none ') then
|
|
ix=dblalloc(dfnbasis)
|
|
call dfillzero(dcore(ix),dfnbasis)
|
|
endif
|
|
nos=max(nalf,nbef)-min(nalf,nbef)
|
|
nocc=max(nalf,nbef)
|
|
if(route.eq.'emft'.or.route.eq.'sch '.or.lfdm) nocc=nbasis!schszemet
|
|
dtol=pepsilon/dfloat(nbasis*nocc)
|
|
if(qscf.ne.'off ') dtol=min(dtol,1.0d-8/dfloat(nbasis*nocc))
|
|
if(scftype.ge.3 .and. .not. qscf_hess) nbef=nos
|
|
if(qscf_hess) then
|
|
imoa=ica
|
|
if(scftype.ge.2) then
|
|
imob=icb
|
|
else
|
|
imob=ica
|
|
endif
|
|
else
|
|
imoa=dblalloc(nocc*nbasis)
|
|
imob=imoa
|
|
if(scftype.ge.2) imob=dblalloc(nocc*nbasis)
|
|
endif
|
|
icmo=dblalloc(nbasis**2)
|
|
ijpvt=intalloc(nbasis)
|
|
if(scftype.ge.3 .and. .not. qscf_hess) then
|
|
nbef=nos
|
|
call daxpy(nbasis**2,-1.d0,pb,1,pa,1)
|
|
endif
|
|
if(.not.qscf_hess) then
|
|
if(lmcl.and.llc) then
|
|
call denschol(nbasis,nalf,pa,dcore(icmo),dcore(imoa),
|
|
$dcore(imem),icore(ijpvt),llc,focka,scftype,i,' ')
|
|
if(scftype.ge.2)
|
|
$ call denschol(nbasis,nbef,pb,dcore(icmo),dcore(imob),
|
|
$dcore(imem),icore(ijpvt),llc,fockb,scftype,i,' ')
|
|
else
|
|
call denschol(nbasis,nalf,pa,dcore(icmo),dcore(imoa),
|
|
$dcore(imem),icore(ijpvt),llc,cmat,scftype,i,' ')
|
|
if(scftype.ge.2)
|
|
$ call denschol(nbasis,nbef,pb,dcore(icmo),dcore(imob),
|
|
$dcore(imem),icore(ijpvt),llc,cmat(sqrsize+1),scftype,i,' ')
|
|
endif
|
|
endif
|
|
if(scftype.ge.3 .and. .not. qscf_hess) then
|
|
call daxpy(nbasis**2,1.d0,pb,1,pa,1)
|
|
ii=0
|
|
do j=1,nbasis
|
|
do i=1,nbef
|
|
dcore(imoa+(j-1)*nalf+nbe+i-1)=dcore(imob+ii)
|
|
ii=ii+1
|
|
enddo
|
|
enddo
|
|
endif
|
|
if(route.eq.'sch ') then
|
|
call moatransp(nalf,nbasis,dcore(imoa),dcore(icaa),nfroz)
|
|
call motransp(nalf,nbasis,dcore(imoa),dcore(icaa),.true.)
|
|
else if(route.eq.'emft'.or.lfdm) then
|
|
if(embed.eq.'scl ') then
|
|
open(scrfile1,file='SROOT',form='unformatted')
|
|
iss=dblalloc(nbasis**2)
|
|
call roeint(dcore(imem),dcore(imem),dcore(iss),scrfile1,
|
|
$nbasis)
|
|
if(.true.) then
|
|
call motransp(nalf,nbasis,dcore(imoa),dcore(icaa),.true.)
|
|
call dscal(nbasis*nalf,1.d0/dsqrt(2.d0),dcore(icaa),1)
|
|
call spade(nbasis,nalf,nc,dcore(icaa),dcore(idaa),
|
|
$dcore(imem+nalf+1),dcore(imem),dcore(iss),natoms,minpfile,
|
|
$icore(inatrange),verblevel,ncorenew,incorb,iactive_atoms,
|
|
$.true.,'o') !HB
|
|
else
|
|
isi=dblalloc(nbasis**2)
|
|
call roeint(dcore(imem),dcore(imem),dcore(isi),scrfile1,
|
|
$nbasis)
|
|
call fragloc(nbasis,pa,dcore(imem+nbasis+nbasis**2),
|
|
$dcore(imem),dcore(isi),dcore(iss),dcore(icaa),dcore(idaa),natoms,
|
|
$minpfile,icore(inatrange),nalf,nc,2.d0,i,verblevel,
|
|
$dcore(imem+nbasis),.true.,ncorenew,dcore(imem+nbasis+2*nbasis**2),
|
|
$nbf(4),dcore(imem+nbasis+3*nbasis**2),
|
|
$dcore(imem+nbasis+4*nbasis**2),scrfile2)
|
|
endif
|
|
close(scrfile1)
|
|
call dbldealloc(isi)
|
|
call dscal(nbasis*nalf,dsqrt(2.d0),dcore(icaa),1)
|
|
c write(6,*) 'cca'
|
|
c write(6,"(13f10.6)") (dcore(icaa+i),i=0,nbasis*nc-1)
|
|
else
|
|
call emftdens(nbasis,natoms,minpfile,icore(inatrange),
|
|
$icore(ijpvt),iout,pa,dcore(idaa),dcore(icaa),nalf,dcore(imoa),
|
|
$.true.,.false.)
|
|
call denschol(nbasis,nalf,dcore(idaa),dcore(icmo),
|
|
$dcore(icaa),dcore(imem),icore(ijpvt),.false.,dcore(icaa),scftype,
|
|
$nc,route)
|
|
endif
|
|
write(iout,
|
|
$"(' Number of orbitals in embedded subsystem:',i5)") nc
|
|
write(iout,*)
|
|
if(lfdm) then
|
|
call dcopy(nbasis**2,dcore(idaa),1,pa,1)
|
|
ii=0
|
|
do j=1,nbasis
|
|
do i=1,nc
|
|
dcore(imoa+ii)=dcore(icaa+(i-1)*nbasis+j-1)
|
|
ii=ii+1
|
|
enddo
|
|
enddo
|
|
nalf=nc
|
|
nc=0
|
|
else
|
|
nc=nalf-nc
|
|
endif
|
|
endif
|
|
call dbldealloc(icmo)
|
|
if(scftype.eq.2) then
|
|
id=dblalloc(nbasis**2)
|
|
call dcopy(nbasis**2,pa,1,dcore(id),1)
|
|
call daxpy(nbasis**2,1.d0,pb,1,dcore(id),1)
|
|
endif
|
|
endif
|
|
C Local exchange?
|
|
call getkey('excrad',6,c16,16)
|
|
read(c16,*) excrad
|
|
call getkey('excrad_fin',10,c16,16)
|
|
read(c16,*) excrad_fin
|
|
if(lfin.eq.2) then
|
|
excrad=excrad_fin
|
|
else
|
|
lfin=0
|
|
endif
|
|
locfit=0
|
|
if(excrad.gt.0.d0.and.lexc) then
|
|
locfit=1
|
|
if(trim(scfalg).eq.'locfit2') locfit=2
|
|
endif
|
|
C
|
|
iimoa=imoa
|
|
iimob=imob
|
|
if(route.eq.'emft'.or.route.eq.'sch ') then
|
|
iimoa=dblalloc(nbasis**2)
|
|
endif
|
|
nmoat_ptr=imem
|
|
moat_ptr=imem
|
|
dfnmobasis_ptr=imem
|
|
moadd_ptr=imem
|
|
atmo_ptr=imem
|
|
natmo_ptr=imem
|
|
nmobasis_ptr=imem
|
|
natdom_ptr=imem
|
|
atdom_ptr=imem
|
|
naoat_ptr=imem
|
|
aoat_ptr=imem
|
|
atind_ptr=imem
|
|
if(dfbasis_scf.ne.'none '.and.(step.gt.1.or.
|
|
$scfiguess.eq.'restart'.or.scfiguess.eq.'sad '.or.
|
|
$scfiguess.eq.'mo ')) then
|
|
moadd_ptr= intalloc(nocc)
|
|
nmobasis_ptr =intalloc(nocc)
|
|
dfnmobasis_ptr=intalloc(nocc)
|
|
if(excrad.gt.0.d0) then
|
|
nmoat_ptr= intalloc(natoms)
|
|
moat_ptr= intalloc(nocc*natoms)
|
|
atmo_ptr= intalloc(nocc*natoms)
|
|
natmo_ptr= intalloc(nocc)
|
|
if(locfit.ge.2) then
|
|
natdom_ptr= intalloc(nocc)
|
|
atdom_ptr= intalloc(nocc*natoms)
|
|
naoat_ptr= intalloc(2*natoms)
|
|
aoat_ptr= intalloc(nocc*natoms)
|
|
atind_ptr= intalloc(natoms*nocc)
|
|
endif
|
|
endif
|
|
endif
|
|
C Initialize Fock matrix
|
|
focka=0.d0
|
|
if(scftype.eq.2) then
|
|
fockb=0.d0
|
|
else if(scftype.ge.3) then
|
|
qmat=0.d0
|
|
endif
|
|
1235 continue
|
|
IF(trim(scfalg).ne.'disk'.or.(trim(dfbasis_scf).ne.'none'
|
|
$.and.step.eq.1.and.scfiguess.ne.'restart'
|
|
$.and.scfiguess.ne.'sad '.and.scfiguess.ne.'mo '
|
|
$)) THEN
|
|
C INTEGRAL-DIRECT FOCK-MATRIX CONSTRUCTION
|
|
C Density-fitting algorithm
|
|
if(dfbasis_scf.ne.'none '.and.(step.gt.1.or.
|
|
$scfiguess.eq.'restart'.or.scfiguess.eq.'sad '.or.
|
|
$scfiguess.eq.'mo ')) then
|
|
lscale=.true.
|
|
if(scftype.eq.2) then
|
|
if(.not. qscf_hess) then
|
|
chfx=2.d0*chfx
|
|
clrhfx=2.d0*clrhfx
|
|
csrhfx=2.d0*csrhfx
|
|
endif
|
|
if(.not. qscf_hess)
|
|
$ write(iout,*) 'Constructing alpha Fock-matrix...'
|
|
call df_direct_fock(focka,fockb,dcore(id),nbasis,dfnbasis,
|
|
$pepsilon,nalf,dcore(iimoa),step,iout,icore(inatrange),oeintfile,
|
|
$natoms,dcore,icore,imem,icore(nmoat_ptr),icore(moat_ptr),
|
|
$icore(dfnmobasis_ptr),icore(moadd_ptr),icore(atmo_ptr),
|
|
$icore(natmo_ptr),scrfile3,iimem,scrfile4,lfin,dcore(imoa),
|
|
$dcore(ix),1,chfx,varsfile,nbset,scrfile3,maxcor,tedatfile,lwdfn,
|
|
$minpfile,irecln,sclroute,route,hailen,linv,nc,lsexc,ncorenew,
|
|
$dcore(icaa),devparr,excrad,excrad_fin,llc,cscftype,scfiguess,
|
|
$locfit,icore(nmobasis_ptr),icore(natdom_ptr),icore(atdom_ptr),
|
|
$icore(naoat_ptr),icore(aoat_ptr),icore(atind_ptr),clrhfx,csrhfx,
|
|
$omega,qscf_hess,lf12,excha,exchb,lscrohfldf,istore,intpos,loccri)
|
|
if(lexc) then!.and.nbef.gt.0) then
|
|
if(.not. qscf_hess)
|
|
$ write(iout,*) 'Constructing beta Fock-matrix...'
|
|
call df_direct_fock(fockb,focka,dcore(id),nbasis,dfnbasis,
|
|
$pepsilon,nbef,dcore(iimob),step,iout,icore(inatrange),oeintfile,
|
|
$natoms,dcore,icore,imem,icore(nmoat_ptr),icore(moat_ptr),
|
|
$icore(dfnmobasis_ptr),icore(moadd_ptr),icore(atmo_ptr),
|
|
$icore(natmo_ptr),scrfile3,iimem,scrfile4,lfin,dcore(imob),
|
|
$dcore(ix),2,chfx,varsfile,nbset,scrfile3,maxcor,tedatfile,lwdfn,
|
|
$minpfile,irecln,sclroute,route,hailen,linv,nc,lsexc,ncorenew,
|
|
$dcore(icaa),devparr,excrad,excrad_fin,llc,cscftype,scfiguess,
|
|
$locfit,icore(nmobasis_ptr),icore(natdom_ptr),icore(atdom_ptr),
|
|
$icore(naoat_ptr),icore(aoat_ptr),icore(atind_ptr),clrhfx,csrhfx,
|
|
$omega,qscf_hess,lf12,exchb,excha,lscrohfldf,istore,intpos,loccri)
|
|
endif
|
|
else if(scftype.ge.3.and.nbef.gt.0) then
|
|
if(.not.qscf_hess) write(iout,*) 'Constructing Fock-matrix...'
|
|
if(.not.qscf_hess) call df_direct_fock(focka,qmat,pa,nbasis,
|
|
$dfnbasis,pepsilon,nalf,dcore(iimoa),step,iout,icore(inatrange),
|
|
$oeintfile,natoms,dcore,icore,imem,icore(nmoat_ptr),
|
|
$icore(moat_ptr),icore(dfnmobasis_ptr),icore(moadd_ptr),
|
|
$icore(atmo_ptr),icore(natmo_ptr),scrfile3,iimem,scrfile4,lfin,
|
|
$dcore(imoa),dcore(ix),1,chfx,varsfile,nbset,scrfile3,maxcor,
|
|
$tedatfile,lwdfn,minpfile,irecln,sclroute,route,hailen,linv,nc,
|
|
$lsexc,ncorenew,dcore(icaa),devparr,excrad,excrad_fin,llc,cscftype,
|
|
$scfiguess,locfit,icore(nmobasis_ptr),icore(natdom_ptr),
|
|
$icore(atdom_ptr),icore(naoat_ptr),icore(aoat_ptr),
|
|
$icore(atind_ptr),clrhfx,csrhfx,omega,qscf_hess,lf12,excha,exchb,
|
|
$lscrohfldf,istore,intpos,loccri)
|
|
if(lexc) then
|
|
if(.not.qscf_hess)write(iout,*) 'Constructing Q matrix...'
|
|
call df_direct_fock(qmat,focka,pb,nbasis,dfnbasis,
|
|
$pepsilon,nbef,dcore(iimob),step,iout,icore(inatrange),oeintfile,
|
|
$natoms,dcore,icore,imem,icore(nmoat_ptr),icore(moat_ptr),
|
|
$icore(dfnmobasis_ptr),icore(moadd_ptr),icore(atmo_ptr),
|
|
$icore(natmo_ptr),scrfile3,iimem,scrfile4,lfin,dcore(imob),
|
|
$dcore(ix),2,-chfx,varsfile,nbset,scrfile3,maxcor,tedatfile,lwdfn,
|
|
$minpfile,irecln,sclroute,route,hailen,linv,nc,lsexc,ncorenew,
|
|
$dcore(icaa),devparr,excrad,excrad_fin,llc,cscftype,scfiguess,
|
|
$locfit,icore(nmobasis_ptr),icore(natdom_ptr),icore(atdom_ptr),
|
|
$icore(naoat_ptr),icore(aoat_ptr),icore(atind_ptr),-clrhfx,-csrhfx,
|
|
$omega,qscf_hess,lf12,excha,exchb,lscrohfldf,istore,intpos,loccri)
|
|
else
|
|
call daxpy(nbasis**2,1.d0,qmat,1,focka,1)
|
|
qmat=0.d0
|
|
endif
|
|
else
|
|
if(.not.qscf_hess) write(iout,*) 'Constructing Fock-matrix...'
|
|
call df_direct_fock(focka,fockb,pa,nbasis,dfnbasis,
|
|
$pepsilon,nalf,dcore(iimoa),step,iout,icore(inatrange),oeintfile,
|
|
$natoms,dcore,icore,imem,icore(nmoat_ptr),icore(moat_ptr),
|
|
$icore(dfnmobasis_ptr),icore(moadd_ptr),icore(atmo_ptr),
|
|
$icore(natmo_ptr),scrfile3,iimem,scrfile4,lfin,dcore(imoa),
|
|
$dcore(ix),0,chfx,varsfile,nbset,scrfile3,maxcor,tedatfile,lwdfn,
|
|
$minpfile,irecln,sclroute,route,hailen,linv,nc,lsexc,ncorenew,
|
|
$dcore(icaa),devparr,excrad,excrad_fin,llc,cscftype,scfiguess,
|
|
$locfit,icore(nmobasis_ptr),icore(natdom_ptr),icore(atdom_ptr),
|
|
$icore(naoat_ptr),icore(aoat_ptr),icore(atind_ptr),clrhfx,csrhfx,
|
|
$omega,qscf_hess,lf12,excha,exchb,lscrohfldf,istore,intpos,loccri)
|
|
endif
|
|
if(qscf_hess) return
|
|
else
|
|
C Conventional direct SCF, no density-fitting
|
|
call direct_fock_build(pa,pb,focka,fockb,qmat,step,cscftype,
|
|
$iroute,0,1,dcore,dcore,dcore,.false.,dcore,dcore,dcore,dcore,ii,
|
|
$ii,ii,ii,ii,dcore,.false.,dcore,0,chfx,iout,varsfile,
|
|
$icore,dcore,nbset,oeintfile,nocc,scrfile3,scrfile4,maxcor,
|
|
$imem,tedatfile,dfnbasis,nbasis,0,dcore,minpfile,.false.,1,dcore,
|
|
$irecln,1,.false.,0,0,0,devparr(1)+devparr(2),pa,1,dcore,0,0,
|
|
$i,i,i,i,i,i,i,i,clrhfx,csrhfx,omega,.false.,dcore,dcore,dcore,i,
|
|
$qscf_hess,.false.,dcore,.false.,.false.,istore,intpos,.false.,
|
|
$excha,exchb,lf12,loccri,i)
|
|
endif
|
|
ELSE
|
|
C CONVENTIONAL FOCK-MATRIX CONSTRUCTION
|
|
call intopenrsq(teintf)
|
|
C
|
|
if(dfbasis_scf.ne.'none ') then
|
|
lscale=.true.
|
|
nocc=max(nalf,nbef)
|
|
icpr=dblalloc(nbasis)
|
|
ii=3*dfnbasis
|
|
ii=(ii+mod(ii,2))/2
|
|
ii4core=dblalloc(ii)
|
|
maxm=maxcor-(imem-imem1)
|
|
if(scftype.eq.2) then
|
|
write(iout,*) 'Constructing alpha Fock-matrix...'
|
|
chfx=2.d0*chfx
|
|
call df_disk_fock(focka,fockb,dcore(id),dcore(id),nbasis,
|
|
$dfnbasis,npos,ipos,dcore(imem),dcore(ix),dcore(ix),dcore(icpr),
|
|
$dcore(ii4core),intpos,teintf,nalf,nbef,dcore(imoa),dcore(imob),
|
|
$step,maxm,iout,icore(inatrange),dcore(imem),oeintfile,natoms,dft,
|
|
$chfx,scftype,dtol,.false.,lbeta,'f')
|
|
if(lbeta.and.dabs(chfx).gt.dtol.and.nbef.gt.0) then
|
|
call timer
|
|
write(iout,*) 'Constructing beta Fock-matrix...'
|
|
call df_disk_fock(fockb,focka,pb,pb,nbasis,dfnbasis,npos,
|
|
$ipos,dcore(imem),dcore(ix),dcore(ix),dcore(icpr),dcore(ii4core),
|
|
$intpos,teintf,nbef,nalf,dcore(imob),dcore(imoa),step,maxm,iout,
|
|
$icore(inatrange),dcore(imem),oeintfile,natoms,dft,chfx,scftype,
|
|
$dtol,.true.,lbeta,'f')
|
|
endif
|
|
else if(scftype.ge.3) then
|
|
write(iout,*) 'Constructing Fock-matrix...'
|
|
call df_disk_fock(focka,qmat,pa,pa,nbasis,dfnbasis,npos,ipos,
|
|
$dcore(imem),dcore(ix),dcore(ix),dcore(icpr),dcore(ii4core),intpos,
|
|
$teintf,nalf,nbef,dcore(imoa),dcore(imob),step,maxm,iout,
|
|
$icore(inatrange),dcore(imem),oeintfile,natoms,dft,chfx,scftype,
|
|
$dtol,.false.,lbeta,'f')
|
|
if(lbeta.and.dabs(chfx).gt.dtol.and.nos.gt.0) then
|
|
call timer
|
|
write(iout,*) 'Constructing Q matrix...'
|
|
call df_disk_fock(qmat,focka,pb,pb,nbasis,dfnbasis,npos,
|
|
$ipos,dcore(imem),dcore(ix),dcore(ix),dcore(icpr),dcore(ii4core),
|
|
$intpos,teintf,nbef,nalf,dcore(imob),dcore(imoa),step,maxm,iout,
|
|
$icore(inatrange),dcore(imem),oeintfile,natoms,dft,-chfx,scftype,
|
|
$dtol,.true.,lbeta,'f')
|
|
endif
|
|
else
|
|
write(iout,*) 'Constructing Fock-matrix...'
|
|
call df_disk_fock(focka,fockb,pa,pa,nbasis,dfnbasis,npos,ipos,
|
|
$dcore(imem),dcore(ix),dcore(ix),dcore(icpr),dcore(ii4core),intpos,
|
|
$teintf,nalf,nbef,dcore(imoa),dcore(imob),step,maxm,iout,
|
|
$icore(inatrange),dcore(imem),oeintfile,natoms,dft,chfx,scftype,
|
|
$dtol,.false.,lbeta,'f')
|
|
endif
|
|
call timer
|
|
write(iout,*)
|
|
call dbldealloc(icpr)
|
|
else
|
|
C
|
|
IPOS=0
|
|
MAXM=IFLTLN*MIN(MAXCOR-(IMEM-IMEM1),20*nbasis*(nbasis+1)/2)
|
|
c MAXM=IFLTLN*MIN(MAXCOR-(IMEM-IMEM1),20*INTPOS(3,NPOS))
|
|
DO
|
|
NNINTEG=0
|
|
IPOSLO=IPOS+1
|
|
DO WHILE(IPOS.LT.NPOS.AND.12*NNINTEG.LT.MAXM)
|
|
IPOS=IPOS+1
|
|
NNINTEG=NNINTEG+INTPOS(3,IPOS)
|
|
ENDDO
|
|
IF(12*NNINTEG.GT.MAXM) THEN
|
|
NNINTEG=NNINTEG-INTPOS(3,IPOS)
|
|
IPOS=IPOS-1
|
|
ENDIF
|
|
CALL INTREADSQ(dcore(imem),NNINTEG,TEINTF)
|
|
NNINTEG=0
|
|
DO IP=IPOSLO,IPOS
|
|
ii2 =INTPOS(1,IP)
|
|
kk2 =INTPOS(2,IP)
|
|
NINTEG=INTPOS(3,IP)
|
|
C BUILDING FOCK PART FROM READ BATCH
|
|
SELECT CASE (scftype)
|
|
CASE (_RHF_, _MCSCF_)
|
|
CALL RHFFOCK(
|
|
& FOCKA,
|
|
& PA,
|
|
& NBASIS,
|
|
& dcore(imem),
|
|
& ii2,
|
|
& kk2,
|
|
& NINTEG,
|
|
& NNINTEG,chfx)
|
|
if(lf12) CALL RHFEXCH(
|
|
& excha,
|
|
& PA,
|
|
& NBASIS,
|
|
& dcore(imem),
|
|
& ii2,
|
|
& kk2,
|
|
& NINTEG,
|
|
& NNINTEG,chfx)
|
|
CASE (_UHF_)
|
|
CALL UHFFOCK(
|
|
& FOCKA,
|
|
& FOCKB,
|
|
& PA,
|
|
& PB,
|
|
& NBASIS,
|
|
& dcore(imem),
|
|
& ii2,
|
|
& kk2,
|
|
& NINTEG,
|
|
& NNINTEG,chfx)
|
|
if(lf12) CALL UHFEXCH(
|
|
& excha,
|
|
& exchb,
|
|
& PA,
|
|
& PB,
|
|
& NBASIS,
|
|
& dcore(imem),
|
|
& ii2,
|
|
& kk2,
|
|
& NINTEG,
|
|
& NNINTEG,chfx)
|
|
CASE (_ROHFSTD_,_ROHFSCN_)
|
|
if(qscf_hess) then
|
|
CALL rohf_qmat_hessian(
|
|
& FOCKA,
|
|
& QMAT,
|
|
& PA,
|
|
& PB,
|
|
& NBASIS,
|
|
& dcore(imem),
|
|
& ii2,
|
|
& kk2,
|
|
& NINTEG,
|
|
& NNINTEG,chfx)
|
|
else
|
|
CALL ROHFFOCK(
|
|
& FOCKA,
|
|
& QMAT,
|
|
& PA,
|
|
& PB,
|
|
& NBASIS,
|
|
& dcore(imem),
|
|
& ii2,
|
|
& kk2,
|
|
& NINTEG,
|
|
& NNINTEG,chfx)
|
|
endif
|
|
END SELECT
|
|
NNINTEG=NNINTEG+6*NINTEG
|
|
ENDDO
|
|
IF(IPOS.EQ.NPOS) EXIT
|
|
ENDDO
|
|
C CLOSE(TEINTFILE)
|
|
endif
|
|
CALL INTCLOSE(TEINTF)
|
|
ENDIF
|
|
C Additional exchange in the case of embedding
|
|
if(lsexc.eq.1) then
|
|
lsexc=0
|
|
call getvar('chfx ',temp)
|
|
chfx=temp-chfx
|
|
sclroute=.true.
|
|
if(dabs(chfx).gt.1d-18) goto 1235
|
|
endif
|
|
if((route.ne.'emft'.and.route.ne.'sch ').or.lfdm)
|
|
$call dbldealloc(nmoat_ptr)
|
|
C Scale diagonal Fock matrix elements in the case of DF
|
|
if(lscale) then
|
|
do i=1,nbasis
|
|
focka(i,i)=0.5d0*focka(i,i)
|
|
enddo
|
|
if(lf12) then
|
|
do i=1,nbasis
|
|
excha(i,i)=0.5d0*excha(i,i)
|
|
enddo
|
|
endif
|
|
if(scftype.eq.2) then
|
|
do i=1,nbasis
|
|
fockb(i,i)=0.5d0*fockb(i,i)
|
|
enddo
|
|
if(lf12) then
|
|
do i=1,nbasis
|
|
exchb(i,i)=0.5d0*exchb(i,i)
|
|
enddo
|
|
endif
|
|
else if(scftype.ge.3) then
|
|
do i=1,nbasis
|
|
qmat(i,i)=0.5d0*qmat(i,i)
|
|
enddo
|
|
endif
|
|
endif
|
|
C SYMMETRISING FOCK AFTER BUILD
|
|
SELECT CASE (scftype)
|
|
CASE (_RHF_,_MCSCF_)
|
|
call mxsym(focka,nbasis)
|
|
if(lf12) call mxsym(excha,nbasis)
|
|
CASE (_UHF_)
|
|
call mxsym(focka,nbasis)
|
|
call mxsym(fockb,nbasis)
|
|
if(lf12) then
|
|
call mxsym(excha,nbasis)
|
|
call mxsym(exchb,nbasis)
|
|
endif
|
|
CASE (_ROHFSTD_,_ROHFSCN_)
|
|
call mxsym(focka,nbasis)
|
|
c%%% meg kell keresni a programban, hogy az a kettes hol i
|
|
c veszik el valami mas helyen......
|
|
call mxsym(qmat,nbasis)
|
|
call dscal(nbasis**2,2.d0,qmat,1)
|
|
END SELECT
|
|
if(lf12.and.trim(dfbasis_scf).ne.'none') then
|
|
call daxpy(nbasis**2,1.d0,excha,1,focka,1)
|
|
if(scftype.ne._RHF_) call daxpy(nbasis**2,1.d0,exchb,1,fockb,1)
|
|
endif
|
|
C SCH exchange for subsystem A
|
|
if(route.eq.'sch ') then
|
|
if(sclroute) then
|
|
call daxpy(sqrsize,1.d0,fockb,1,focka,1)
|
|
else
|
|
nc=nfroz
|
|
call dcopy(nbasis**2,focka,1,fockb,1)
|
|
call daxpy(sqrsize,-1.d0,pb,1,pa,1)
|
|
chfx=chfxa-chfx
|
|
clrhfx=clrhfxa-clrhfx
|
|
csrhfx=csrhfxa-csrhfx
|
|
if(dabs(chfx)+dabs(clrhfx)+dabs(csrhfx).gt.1d-14) then
|
|
focka=0.d0
|
|
sclroute=.true.
|
|
goto 1235
|
|
endif
|
|
endif
|
|
endif
|
|
C PS exchange
|
|
if(lpssp) then
|
|
chfx=chfxold
|
|
call cosx(nbasis,focka,fockb,scrfile5,dcore,iout,scftype,
|
|
$imem,icore,verblevel,dcore,pa,pb,1,1,chfx,.true.)
|
|
if(scftype.eq.2) then
|
|
call cosx(nbasis,fockb,focka,scrfile5,dcore,iout,scftype,
|
|
$imem,icore,verblevel,dcore,pb,pa,1,1,chfx,.true.)
|
|
endif
|
|
endif
|
|
C DFT contribution
|
|
exc=0.d0
|
|
if(trim(dft).ne.'off'.or.route.eq.'emft'.or.route.eq.'den2'.or.
|
|
$route.eq.'sch '.or.trim(pcm).ne.'off') then
|
|
trpfa=0.d0
|
|
trpfb=0.d0
|
|
if(trim(dft).ne.'off'.or.route.eq.'emft'.or.route.eq.'sch '.or.
|
|
$trim(pcm).ne.'off') then
|
|
C Calculate Tr(PF)
|
|
trpfa=0.5d0*ddot(nbasis**2,pa,1,focka,1)
|
|
if(scftype.eq.2.or.route.eq.'sch ') then
|
|
trpfb=0.5d0*ddot(nbasis**2,pb,1,fockb,1)
|
|
if(route.eq.'sch ') then
|
|
call dcopy(nbasis**2,focka,1,rs,1)
|
|
call dcopy(nbasis**2,fockb,1,rs(sqrsize+1),1)
|
|
focka=0.d0
|
|
fockb=0.d0
|
|
endif
|
|
else
|
|
trpfb=0.d0
|
|
endif
|
|
endif
|
|
if(trim(dft).ne.'off'.or.route.eq.'emft'.or.route.eq.'den2'.or.
|
|
$route.eq.'sch ') then
|
|
c write(6,"(24f6.3)") focka
|
|
c write(6,*)
|
|
c write(6,"(24f8.4)") pa
|
|
c write(6,*)
|
|
c write(6,"(9f8.4)") (dcore(imoa+i-1),i=1,nalf*nbasis)
|
|
if(embed.eq.'coulomb ') then
|
|
call mx_symm_extr(dcore(imem+nbasis**2),cmat,offset)
|
|
call dgemm('n','n',nbasis,nbasis,nbasis,1.d0,symtra,nbasis,
|
|
$dcore(imem+nbasis**2),nbasis,0.d0,dcore(imem),nbasis)
|
|
call denschol(nbasis,orbperir(1),dcore,dcore,dcore(imoa),
|
|
$dcore,icore,.true.,dcore(imem),scftype,i,' ')
|
|
call dft_core(nbasis,orbperir(1),nbef,focka,fockb,
|
|
$dcore(imoa),dcore(imob),scrfile5,dcore,iout,exc,dft,minpfile,
|
|
$scftype,ifltln,maxcor,imem,imem1,icore,verblevel,0,dcore,route,pa,
|
|
$pb,1,1,chfx,istore)
|
|
call mx_symm_extr(dcore(imem+nbasis**2),cmat,offset)
|
|
call dgemm('n','n',nbasis,nbasis,nbasis,1.d0,symtra,nbasis,
|
|
$dcore(imem+nbasis**2),nbasis,0.d0,dcore(imem),nbasis)
|
|
call denschol(nbasis,orbperir(2),dcore,dcore,dcore(imoa),
|
|
$dcore,icore,.true.,dcore(imem+nfunc(1)*nbasis),scftype,i,' ')
|
|
call dft_core(nbasis,orbperir(2),nbef,focka,fockb,
|
|
$dcore(imoa),dcore(imob),scrfile5,dcore,iout,exc,dft,minpfile,
|
|
$scftype,ifltln,maxcor,imem,imem1,icore,verblevel,0,dcore,'coul',
|
|
$pa,pb,1,1,chfx,istore)
|
|
c write(6,*)
|
|
c write(6,"(9f8.4)") (dcore(imoa+i-1),i=1,nalf*nbasis)
|
|
C Calculate exchange-correlation energy and matrix
|
|
c write(6,*) 'dft1',nalf,nbef
|
|
else
|
|
if(scftype.ge.3) then
|
|
ii=0
|
|
do j=1,nbasis
|
|
do i=1,nbe
|
|
dcore(imoa+(j-1)*nal+i-1)=
|
|
$ dcore(imoa+(j-1)*nal+i-1)/dsqrt(2.d0)
|
|
dcore(imob+ii)=dcore(imoa+(j-1)*nal+i-1)
|
|
ii=ii+1
|
|
enddo
|
|
enddo
|
|
rs(1:2*nbasis**2)=0.d0
|
|
call dft_core(nbasis,nal,nbe,rs,rs(nbasis**2+1),
|
|
$dcore(imoa),dcore(imob),scrfile5,dcore,iout,exc,dft,minpfile,
|
|
$scftype,ifltln,maxcor,imem,imem1,icore,verblevel,0,dcore,route,pa,
|
|
$pb,1,1,chfx,istore)
|
|
c write(6,*) 'focka'
|
|
c write(6,"(7f9.5)") focka
|
|
c write(6,*) 'rsa'
|
|
c write(6,"(7f9.5)") rs(1:nbasis**2)
|
|
c write(6,*) 'rsb'
|
|
c write(6,"(7f9.5)") rs(nbasis**2+1:2*nbasis**2)
|
|
call daxpy(nbasis**2,0.5d0,rs ,1,focka,1)
|
|
call daxpy(nbasis**2,0.5d0,rs(nbasis**2+1),1,focka,1)
|
|
else
|
|
if(route.eq.'em2 ') then
|
|
ifocka_tmp=dblalloc(nbasis**2)
|
|
call dcopy(nbasis**2,focka,1,dcore(ifocka_tmp),1)
|
|
call dfillzero(focka,nbasis**2)
|
|
endif
|
|
call dft_core(nbasis,nalf,nbef,focka,fockb,dcore(imoa),
|
|
$dcore(imob),scrfile5,dcore,iout,exc,dft,minpfile,scftype,ifltln,
|
|
$maxcor,imem,imem1,icore,verblevel,0,dcore,route,pa,pb,1,1,chfx,
|
|
$istore)
|
|
if(route.eq.'em2 ') then
|
|
open(scrfile1,file='F2_XC_A',form='unformatted')
|
|
call woeint(dcore(imem),dcore(imem),focka,scrfile1,
|
|
$ 1d-10,nbasis)
|
|
close(scrfile1)
|
|
call daxpy(nbasis**2,1.0d0,dcore(ifocka_tmp),1,focka,1)
|
|
call dbldealloc(ifocka_tmp)
|
|
endif
|
|
endif
|
|
endif
|
|
if((route.eq.'emft'.or.route.eq.'sch ').and.nc.lt.nalf) then
|
|
if(route.eq.'sch ') call dcopy(nbasis**2,focka,1,fockb,1)
|
|
ii=0
|
|
do j=1,nbasis
|
|
do i=1,nalf-nc
|
|
dcore(imoa+ii)=dcore(icaa+(i-1)*nbasis+j-1)
|
|
ii=ii+1
|
|
enddo
|
|
enddo
|
|
call dft_core(nbasis,nalf-nc,nbef-nc,focka,fockb,
|
|
$dcore(imoa),dcore(imob),scrfile5,dcore,iout,exc,dft,minpfile,
|
|
$scftype,ifltln,maxcor,imem,imem1,icore,verblevel,0,dcore,'scl1',
|
|
$pa,pb,1,1,chfx,istore)
|
|
endif
|
|
endif
|
|
C Add Tr(PF) to energy
|
|
#if defined (MPI)
|
|
dcore(imem )=trpfa
|
|
dcore(imem+1)=trpfb
|
|
call mpi_allreduce(dcore(imem),dcore(imem+2),2,
|
|
$MPI_DOUBLE_PRECISION,MPI_SUM,MPI_COMM_WORLD,MPIERR)
|
|
trpfa=dcore(imem+2)
|
|
trpfb=dcore(imem+3)
|
|
#endif
|
|
if(verblevel.ge.3) write(iout,
|
|
$"(' Coulomb energy + HF exchange [au]:',f20.12)") trpfa+trpfb
|
|
exc=exc+trpfa+trpfb
|
|
endif
|
|
if(route.eq.'sch ') then
|
|
call daxpy(sqrsize,1.d0,pb,1,pa,1)
|
|
call daxpy(sqrsize,1.d0,rs,1,focka,1)
|
|
call daxpy(sqrsize,1.d0,rs(sqrsize+1),1,fockb,1)
|
|
endif
|
|
#if defined (MPI)
|
|
call symreduce(focka,dcore(imem),nbasis)
|
|
if(scftype.eq.2) call symreduce(fockb,dcore(imem),nbasis)
|
|
if(scftype.ge.3) then
|
|
call symreduce(qmat,dcore(imem),nbasis)
|
|
if(trim(dft).ne.'off') then
|
|
call symreduce(rs ,dcore(imem),nbasis)
|
|
call symreduce(rs(nbasis**2+1),dcore(imem),nbasis)
|
|
endif
|
|
endif
|
|
#endif
|
|
C Calculate solvent contribution
|
|
#if defined (PCM)
|
|
if(trim(pcm).ne.'off') then
|
|
call pcm_core(pcm,epol,verblevel,iout,dcore,icore,imem,nbasis,
|
|
$focka,fockb,pa,pb,scftype,0,dcore)
|
|
exc=exc+epol
|
|
endif
|
|
#endif
|
|
C Release memory
|
|
call dbldealloc(imemold)
|
|
if(lmcl) then
|
|
if(verblevel.ge.3) write(iout,*) 'Restoring memory...'
|
|
open(unit=scrfile6,file='SCFSCR',form='unformatted')
|
|
read(scrfile6) dcore(c_ptr:imem-1)
|
|
close(scrfile6,status='delete')
|
|
endif
|
|
c write(6,*) 'focka scf'
|
|
c write(6,"(850f12.8)") focka
|
|
C
|
|
RETURN
|
|
END
|
|
************************************************************************
|
|
subroutine df_disk_fock(focka,fockb,p,p2,nbasis,dfnbasis,npos,
|
|
$ipos,hai,x,x2,cpr,i4core,intpos,teintf,nal,nbe,moa,mob,step,
|
|
$maxmem,iout,natrange,work,oeintfile,natoms,dft,chfx,scftype,dtol,
|
|
$lqmat,lbeta,job)
|
|
************************************************************************
|
|
* DF-HF Fock-matrix construction, integrals on disk
|
|
************************************************************************
|
|
implicit none
|
|
integer nbasis,dfnbasis,intpos(3,*),npos,ipos,iout,natrange,ihai2
|
|
integer i,j,k,l,n,kk,teintf(10),nn,ii,jpvt(nbasis),nal,nbe,step
|
|
integer maxmem,nblock,iblock,nbl,nbll,oeintfile,natoms,scftype
|
|
real*8 focka(nbasis,nbasis),fockb(nbasis,nbasis),p(nbasis,nbasis)
|
|
real*8 hai(*),cpr(nbasis),moa(nal,nbasis)
|
|
real*8 ddot,pp,pr,work(*),chfx,temp,ss,dtol,x(dfnbasis)
|
|
real*8 mob(nbe,nbasis),p2(nbasis,nbasis),x2(dfnbasis),pp2
|
|
integer*4 i4core(*),ssi(2)
|
|
character*16 dft
|
|
character*1 job
|
|
logical lqmat,lbeta, lq
|
|
equivalence(ss,ssi)
|
|
lbeta=.true.
|
|
C Prescreening values
|
|
do i=1,nbasis
|
|
ss=0.d0
|
|
do ii=1,nal
|
|
ss=max(ss,dabs(moa(ii,i)))
|
|
enddo
|
|
cpr(i)=ss
|
|
enddo
|
|
C Memory
|
|
if(dabs(chfx).gt.dtol) then
|
|
if(dfnbasis*nbasis.gt.maxmem) then
|
|
write(iout,*)
|
|
$'Insufficient memory for Fock-matrix construction!'
|
|
call mrccend(1)
|
|
endif
|
|
i=mod(maxmem,dfnbasis*nbasis)
|
|
nbl=min(nal,(maxmem-i)/(dfnbasis*nbasis))
|
|
nbll=mod(nal,nbl)
|
|
nblock=(nal-nbll)/nbl
|
|
if(nbll.ne.0) then
|
|
nblock=nblock+1
|
|
else
|
|
nbll=nbl
|
|
endif
|
|
if(job .ne. 'm') then
|
|
write(iout,"(' Number of integral batches:',i5)") nblock
|
|
write(iout,"(' Occupied indices per batch:',i5)") nbl
|
|
endif
|
|
else
|
|
nblock=1
|
|
nbl=nal
|
|
nbll=nal
|
|
endif
|
|
C UHF beta Fock matrix or ROHF Q matrix
|
|
if(lqmat) then
|
|
if(job .eq. 'm') then
|
|
i=(nal/2)/nbl+1
|
|
do iblock=1,i-1
|
|
call dfmid(focka,nbasis,dfnbasis,npos,ipos,hai,hai,cpr,
|
|
$ i4core,intpos,teintf,nal,moa((iblock-1)*nbl+1,1),
|
|
$ dtol,nbl,chfx,job,nbl,1,0)
|
|
enddo
|
|
j = nal/2-(i-1)*nbl
|
|
if(j. ne. 0) then
|
|
ihai2 = dfnbasis*nbasis*j+1
|
|
call dfmid(focka,nbasis,dfnbasis,npos,ipos,hai,hai(ihai2),
|
|
$ cpr,i4core,intpos,teintf,nal,moa((i-1)*nbl+1,1),
|
|
$ dtol,nbl,chfx,job,j,nbl-j,nbl-j)
|
|
else
|
|
c we do not process the i-th batch in this step, therefore the next loop
|
|
c should start at i not i+1
|
|
i = i - 1
|
|
endif
|
|
do iblock=i+1,nblock-1
|
|
call dfmid(focka,nbasis,dfnbasis,npos,ipos,hai,hai,cpr,
|
|
$ i4core,intpos,teintf,nal,moa((iblock-1)*nbl+1,1),dtol,
|
|
$ nbl,-chfx,job,nbl,1,0)
|
|
enddo
|
|
if(nblock .ge. 2) then
|
|
call dfmid(focka,nbasis,dfnbasis,npos,ipos,hai,hai,cpr,
|
|
$ i4core,intpos,teintf,nal,moa((nblock-1)*nbl+1,1),dtol,
|
|
$ nbll,-chfx,job,nbll,1,0)
|
|
endif
|
|
elseif(job .eq. 'f') then
|
|
do iblock=1,nblock-1
|
|
call dfmid(focka,nbasis,dfnbasis,npos,ipos,hai,hai,cpr,
|
|
$ i4core,intpos,teintf,nal,moa((iblock-1)*nbl+1,1),dtol,
|
|
$ nbl,chfx,job,nbl,1,0)
|
|
enddo
|
|
call dfmid(focka,nbasis,dfnbasis,npos,ipos,hai,hai,cpr,i4core,
|
|
$ intpos,teintf,nal,moa((nblock-1)*nbl+1,1),dtol,nbll,chfx,
|
|
$ job,nbll,1,0)
|
|
endif
|
|
else
|
|
C Fock-matrices
|
|
C First step of the Coulomb + exchange part
|
|
if(job .eq. 'm' .and. nbl .gt. nal/2) then
|
|
ihai2 = dfnbasis*nbasis*nal/2+1
|
|
call dffirst(focka,p,p2,nbasis,dfnbasis,npos,ipos,hai,
|
|
$hai(ihai2),x,x2,cpr,i4core,intpos,teintf,nal,moa,dtol,nbl,chfx,
|
|
$scftype,job,nal/2,nbl-nal/2,nbl-nal/2)
|
|
else
|
|
call dffirst(focka,p,p2,nbasis,dfnbasis,npos,ipos,hai,hai,x,
|
|
$x2,cpr,i4core,intpos,teintf,nal,moa,dtol,nbl,chfx,scftype,job,
|
|
$nbl,1,0)
|
|
endif
|
|
C Further steps of the exchange part
|
|
if(job .eq. 'm') then
|
|
i=(nal/2)/nbl+1
|
|
do iblock=2,i-1
|
|
call dfmid(focka,nbasis,dfnbasis,npos,ipos,hai,hai,cpr,
|
|
$ i4core,intpos,teintf,nal,moa((iblock-1)*nbl+1,1),
|
|
$ dtol,nbl,chfx,job,nbl,1,0)
|
|
enddo
|
|
if(i .gt. 1) then
|
|
j = nal/2-(i-1)*nbl
|
|
if(j .ne. 0) then
|
|
ihai2 = dfnbasis*nbasis*j+1
|
|
call dfmid(focka,nbasis,dfnbasis,npos,ipos,hai,hai(ihai2),
|
|
$ cpr,i4core,intpos,teintf,nal,moa((i-1)*nbl+1,1),
|
|
$ dtol,nbl,chfx,job,j,nbl-j,nbl-j)
|
|
else
|
|
c we do not process the i-th batch in this step, therefore the next loop
|
|
c should start at i not i+1
|
|
i = i - 1
|
|
endif
|
|
endif
|
|
do iblock=i+1,nblock-1
|
|
call dfmid(focka,nbasis,dfnbasis,npos,ipos,hai,hai,cpr,
|
|
$ i4core,intpos,teintf,nal,moa((iblock-1)*nbl+1,1),dtol,
|
|
$ nbl,-chfx,job,nbl,1,0)
|
|
enddo
|
|
elseif(job .eq. 'f') then
|
|
do iblock=2,nblock-1
|
|
call dfmid(focka,nbasis,dfnbasis,npos,ipos,hai,hai,cpr,
|
|
$ i4core,intpos,teintf,nal,moa((iblock-1)*nbl+1,1),dtol,
|
|
$ nbl,chfx,job,nbl,1,0)
|
|
enddo
|
|
endif
|
|
call intclose(teintf)
|
|
call intopenrsq(teintf)
|
|
if(nblock.gt.1) then
|
|
C Second step of the Coulomb part and last step of the exchange part
|
|
if(job .eq. 'm') then
|
|
lq = scftype.eq.2 .or. scftype .eq. 0 .or. scftype .ge. 3
|
|
call dflast(focka,fockb,p,p2,nbasis,dfnbasis,npos,ipos,hai,
|
|
$ hai,x,x2,cpr,i4core,intpos,teintf,nal,
|
|
$ moa((nblock-1)*nbl+1,1),dtol,nbll,-chfx,scftype,
|
|
$ .true.,lq,job,nbll,1,0)
|
|
elseif(job .eq. 'f') then
|
|
call dflast(focka,fockb,p,p2,nbasis,dfnbasis,npos,ipos,hai,
|
|
$ hai,x,x2,cpr,i4core,intpos,teintf,nal,
|
|
$ moa((nblock-1)*nbl+1,1),dtol,nbll,chfx,scftype,
|
|
$ .true.,scftype.eq.2,job,nbll,1,0)
|
|
endif
|
|
else if(nblock.eq.1.and.
|
|
& (scftype.ge.2.or.(scftype.eq.0.and.job.eq.'m'))) then
|
|
C Second step of the Coulomb part and beta exchange part if nblock=1
|
|
do i=1,nbasis
|
|
ss=0.d0
|
|
do ii=1,nbe
|
|
ss=max(ss,dabs(mob(ii,i)))
|
|
enddo
|
|
cpr(i)=ss
|
|
enddo
|
|
if(job .eq. 'm') then
|
|
ihai2 = dfnbasis*nbasis*nbe/2+1
|
|
lq = scftype .eq. 2 .or. scftype .eq. 0 .or. scftype .ge. 3
|
|
call dflast(fockb,focka,p2,p,nbasis,dfnbasis,npos,ipos,hai,
|
|
$ hai(ihai2),x2,x,cpr,i4core,intpos,teintf,nbe,mob(1,1),
|
|
$ dtol,nbe,chfx,scftype,lq,.true.,job,nbe/2,nbe/2,nbe/2)
|
|
elseif(job.eq.'f') then
|
|
call dflast(fockb,focka,p2,p,nbasis,dfnbasis,npos,ipos,hai,
|
|
$ hai,x2,x,cpr,i4core,intpos,teintf,nbe,mob(1,1),dtol,
|
|
$ nbe,chfx,scftype,scftype.eq.2,.true.,job,nbe,1,0)
|
|
endif
|
|
lbeta=.false.
|
|
else
|
|
C Second step of the Coulomb part if entire hai is kept in memory
|
|
do ipos=1,npos
|
|
i=intpos(1,ipos)
|
|
j=intpos(2,ipos)
|
|
n=intpos(3,ipos)
|
|
call intreadsq(i4core,n,teintf)
|
|
pp=0.d0
|
|
pp2 = 0.0d0
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
pp=pp+ss*x(k)
|
|
if(job .eq. 'm' .and. (scftype.eq.0.or.scftype.ge.3)) then
|
|
pp2 = pp2 + ss * x2(k)
|
|
endif
|
|
enddo
|
|
focka(i,j)=focka(i,j)+pp
|
|
if(scftype.eq.2) fockb(i,j)=fockb(i,j)+pp
|
|
if((scftype.eq.0.or.scftype.ge.3).and.job.eq.'m')
|
|
& fockb(i,j)=fockb(i,j)+pp2
|
|
enddo
|
|
endif
|
|
endif
|
|
C
|
|
if(scftype.ge.2 .or. scftype.eq.0) then
|
|
call intclose(teintf)
|
|
call intopenrsq(teintf)
|
|
endif
|
|
C
|
|
return
|
|
end
|
|
C
|
|
************************************************************************
|
|
subroutine dffirst(fock,p,p2,nbasis,dfnbasis,npos,ipos,hai,hai2,x,
|
|
$x2,cpr,i4core,intpos,teintf,nocc,mo,dtol,nbl,chfx,scftype,job,
|
|
$ldhai,ldhai2,n_neg)
|
|
************************************************************************
|
|
* DF-HF Fock-matrix construction, step 1
|
|
************************************************************************
|
|
implicit none
|
|
integer nbasis,dfnbasis,intpos(3,*),npos,ipos,nbl,n_neg,ldhai
|
|
integer i,j,k,l,n,kk,teintf(10),nn,ii,nocc,scftype,ldhai2
|
|
real*8 fock(nbasis,nbasis),p(nbasis,nbasis),ss,dtol,chfx
|
|
real*8 hai(ldhai,dfnbasis,nbasis),cpr(nbasis),mo(nocc,nbasis)
|
|
real*8 pp,pr,x(dfnbasis), hai2(ldhai2,dfnbasis,nbasis)
|
|
real*8 p2(nbasis,nbasis), x2(dfnbasis), pp2
|
|
integer*4 i4core(*),ssi(2)
|
|
character*1 job
|
|
equivalence(ss,ssi)
|
|
C Coulomb + exchange part
|
|
pp2 = 0.0d0
|
|
call dfillzero(x,dfnbasis)
|
|
if(job .eq. 'm' .and. (scftype .eq. 0 .or. scftype .ge. 3))
|
|
& call dfillzero(x2,dfnbasis)
|
|
if(dabs(chfx).gt.dtol) then
|
|
C We have exchange
|
|
if(job.eq.'f' .or.
|
|
$ (job.eq.'m' .and. (n_neg.eq.0.or.n_neg.eq.nbl))) then
|
|
call dfillzero(hai,nbl*nbasis*dfnbasis)
|
|
do ipos=1,npos
|
|
i=intpos(1,ipos)
|
|
j=intpos(2,ipos)
|
|
n=intpos(3,ipos)
|
|
call intreadsq(i4core,n,teintf)
|
|
pp=p(i,j)
|
|
if(job .eq.'m'.and.(scftype.eq.0.or.scftype.ge.3))
|
|
& pp2 = p2(i, j)
|
|
if(max(dabs(pp),dabs(pp2),cpr(i),cpr(j)).gt.dtol) then
|
|
if(i.ne.j) then
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
x(k)=x(k)+ss*pp
|
|
if(job .eq.'m'.and.(scftype.eq.0.or.scftype.ge.3))then
|
|
x2(k) = x2(k) + ss*pp2
|
|
endif
|
|
pr=dabs(ss)
|
|
if(pr*cpr(i).gt.dtol) then
|
|
do ii=1,nbl
|
|
hai(ii,k,j)=hai(ii,k,j)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
if(pr*cpr(j).gt.dtol) then
|
|
do ii=1,nbl
|
|
hai(ii,k,i)=hai(ii,k,i)+ss*mo(ii,j)
|
|
enddo
|
|
endif
|
|
enddo
|
|
else
|
|
pp=0.5d0*pp
|
|
pp2 = 0.5d0*pp2
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
x(k)=x(k)+ss*pp
|
|
if(job .eq.'m'.and.(scftype.eq.0.or.scftype.ge.3))then
|
|
x2(k) = x2(k) + ss*pp2
|
|
endif
|
|
if(dabs(ss)*cpr(i).gt.dtol) then
|
|
do ii=1,nbl
|
|
hai(ii,k,i)=hai(ii,k,i)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
enddo
|
|
endif
|
|
endif
|
|
enddo
|
|
C Second step of the exchange part
|
|
if(n_neg .eq. nbl) then
|
|
call dsyrk('u','t',nbasis,nbl*dfnbasis,-chfx,hai,
|
|
$ nbl*dfnbasis,1.d0,fock,nbasis)
|
|
else
|
|
call dsyrk('u','t',nbasis,nbl*dfnbasis,chfx,hai,
|
|
$ nbl*dfnbasis,1.d0,fock,nbasis)
|
|
endif
|
|
|
|
elseif(job.eq.'m' .and. n_neg.ne.0 .and. n_neg.ne.nbl) then
|
|
call dfillzero(hai,ldhai*nbasis*dfnbasis)
|
|
call dfillzero(hai2,ldhai2*nbasis*dfnbasis)
|
|
do ipos=1,npos
|
|
i=intpos(1,ipos)
|
|
j=intpos(2,ipos)
|
|
n=intpos(3,ipos)
|
|
call intreadsq(i4core,n,teintf)
|
|
pp=p(i,j)
|
|
if(scftype .eq. 0 .or. scftype .ge. 3) pp2 = p2(i, j)
|
|
if(max(dabs(pp),dabs(pp2),cpr(i),cpr(j)).gt.dtol) then
|
|
if(i.ne.j) then
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
x(k)=x(k)+ss*pp
|
|
if(scftype .eq. 0 .or. scftype .ge. 3)
|
|
& x2(k) = x2(k) + ss*pp2
|
|
pr=dabs(ss)
|
|
if(pr*cpr(i).gt.dtol) then
|
|
do ii=1,ldhai
|
|
hai(ii,k,j)=hai(ii,k,j)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
if(pr*cpr(j).gt.dtol) then
|
|
do ii=1,ldhai
|
|
hai(ii,k,i)=hai(ii,k,i)+ss*mo(ii,j)
|
|
enddo
|
|
endif
|
|
if(pr*cpr(i).gt.dtol) then
|
|
do ii=ldhai+1, nbl
|
|
hai2(ii-ldhai,k,j)=hai2(ii-ldhai,k,j)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
if(pr*cpr(j).gt.dtol) then
|
|
do ii=ldhai+1,nbl
|
|
hai2(ii-ldhai,k,i)=hai2(ii-ldhai,k,i)+ss*mo(ii,j)
|
|
enddo
|
|
endif
|
|
enddo
|
|
else
|
|
pp=0.5d0*pp
|
|
pp2=0.5d0*pp2
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
x(k)=x(k)+ss*pp
|
|
if(scftype.eq.0.or.scftype.ge.3) x2(k)=x2(k)+ss*pp2
|
|
if(dabs(ss)*cpr(i).gt.dtol) then
|
|
do ii=1,ldhai
|
|
hai(ii,k,i)=hai(ii,k,i)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
if(dabs(ss)*cpr(i).gt.dtol) then
|
|
do ii=ldhai+1,nbl
|
|
hai2(ii-ldhai,k,i)=hai2(ii-ldhai,k,i)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
enddo
|
|
endif
|
|
endif
|
|
enddo
|
|
C Second step of the exchange part
|
|
call dsyrk('u','t',nbasis,ldhai*dfnbasis,chfx,hai,
|
|
$ldhai*dfnbasis,1.d0,fock,nbasis)
|
|
call dsyrk('u','t',nbasis,ldhai2*dfnbasis,-chfx,hai2,
|
|
$ldhai2*dfnbasis,1.d0,fock,nbasis)
|
|
endif
|
|
else
|
|
C No exchange
|
|
do ipos=1,npos
|
|
i=intpos(1,ipos)
|
|
j=intpos(2,ipos)
|
|
n=intpos(3,ipos)
|
|
call intreadsq(i4core,n,teintf)
|
|
pp=p(i,j)
|
|
if(job.eq.'m'.and.(scftype.eq.0.or.scftype.ge.3)) pp2=p2(i, j)
|
|
if(max(dabs(pp),dabs(pp2)).gt.dtol) then
|
|
if(i.eq.j) then
|
|
pp=0.5d0*pp
|
|
pp2=0.5d0*pp2
|
|
endif
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
x(k)=x(k)+ss*pp
|
|
if(job.eq.'m'.and.(scftype.eq.0.or.scftype.ge.3)) then
|
|
x2(k) = x2(k) + ss*pp2
|
|
endif
|
|
enddo
|
|
endif
|
|
enddo
|
|
endif
|
|
if(job .eq. 'f') then
|
|
call dscal(dfnbasis,4.d0,x,1)
|
|
elseif(job .eq. 'm') then
|
|
call dscal(dfnbasis,8.d0,x,1)
|
|
endif
|
|
C
|
|
return
|
|
end
|
|
C
|
|
************************************************************************
|
|
subroutine dfmid(fock,nbasis,dfnbasis,npos,ipos,hai,hai2,cpr,
|
|
$i4core,intpos,teintf,nocc,mo,dtol,nbl,chfx,job,ldhai,ldhai2,n_neg)
|
|
************************************************************************
|
|
* DF-HF Fock-matrix construction, middle steps
|
|
************************************************************************
|
|
implicit none
|
|
integer nbasis,dfnbasis,intpos(3,*),npos,ipos,nbl,ldhai,ldhai2
|
|
integer i,j,k,l,n,kk,teintf(10),nn,ii,nocc,n_neg
|
|
real*8 fock(nbasis,nbasis),ss,dtol,chfx
|
|
real*8 hai(ldhai,dfnbasis,nbasis),cpr(nbasis),mo(nocc,nbasis)
|
|
real*8 pp,pr,hai2(ldhai2,dfnbasis,nbasis)
|
|
character*1 job
|
|
integer*4 i4core(*),ssi(2)
|
|
equivalence(ss,ssi)
|
|
C Exchange part only
|
|
call intclose(teintf)
|
|
call intopenrsq(teintf)
|
|
if(job.eq.'f' .or.
|
|
$ (job.eq.'m' .and. (n_neg.eq.0.or.n_neg.eq.nbl))) then
|
|
call dfillzero(hai,nbl*nbasis*dfnbasis)
|
|
do ipos=1,npos
|
|
i=intpos(1,ipos)
|
|
j=intpos(2,ipos)
|
|
n=intpos(3,ipos)
|
|
call intreadsq(i4core,n,teintf)
|
|
if(max(cpr(i),cpr(j)).gt.dtol) then
|
|
if(i.ne.j) then
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
pr=dabs(ss)
|
|
if(pr*cpr(i).gt.dtol) then
|
|
do ii=1,nbl
|
|
hai(ii,k,j)=hai(ii,k,j)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
if(pr*cpr(j).gt.dtol) then
|
|
do ii=1,nbl
|
|
hai(ii,k,i)=hai(ii,k,i)+ss*mo(ii,j)
|
|
enddo
|
|
endif
|
|
enddo
|
|
else
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
if(dabs(ss)*cpr(i).gt.dtol) then
|
|
do ii=1,nbl
|
|
hai(ii,k,i)=hai(ii,k,i)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
enddo
|
|
endif
|
|
endif
|
|
enddo
|
|
C Second step of the exchange part
|
|
call dsyrk('u','t',nbasis,nbl*dfnbasis,chfx,hai,nbl*dfnbasis,
|
|
$1.d0,fock,nbasis)
|
|
elseif(job.eq.'m' .and. n_neg.ne.0 .and. n_neg.ne.nbl) then
|
|
call dfillzero(hai,ldhai*nbasis*dfnbasis)
|
|
call dfillzero(hai2,ldhai2*nbasis*dfnbasis)
|
|
do ipos=1,npos
|
|
i=intpos(1,ipos)
|
|
j=intpos(2,ipos)
|
|
n=intpos(3,ipos)
|
|
call intreadsq(i4core,n,teintf)
|
|
if(max(cpr(i),cpr(j)).gt.dtol) then
|
|
if(i.ne.j) then
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
pr=dabs(ss)
|
|
if(pr*cpr(i).gt.dtol) then
|
|
do ii=1,ldhai
|
|
hai(ii,k,j)=hai(ii,k,j)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
if(pr*cpr(j).gt.dtol) then
|
|
do ii=1,ldhai
|
|
hai(ii,k,i)=hai(ii,k,i)+ss*mo(ii,j)
|
|
enddo
|
|
endif
|
|
if(pr*cpr(i).gt.dtol) then
|
|
do ii=ldhai+1, nbl
|
|
hai2(ii-ldhai,k,j)=hai2(ii-ldhai,k,j)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
if(pr*cpr(j).gt.dtol) then
|
|
do ii=ldhai+1,nbl
|
|
hai2(ii-ldhai,k,i)=hai2(ii-ldhai,k,i)+ss*mo(ii,j)
|
|
enddo
|
|
endif
|
|
enddo
|
|
else
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
if(dabs(ss)*cpr(i).gt.dtol) then
|
|
do ii=1,ldhai
|
|
hai(ii,k,i)=hai(ii,k,i)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
if(dabs(ss)*cpr(i).gt.dtol) then
|
|
do ii=ldhai+1,nbl
|
|
hai2(ii-ldhai,k,i)=hai2(ii-ldhai,k,i)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
enddo
|
|
endif
|
|
endif
|
|
enddo
|
|
C Second step of the exchange part
|
|
call dsyrk('u','t',nbasis,ldhai*dfnbasis,chfx,hai,
|
|
$ ldhai*dfnbasis,1.d0,fock,nbasis)
|
|
call dsyrk('u','t',nbasis,ldhai2*dfnbasis,-chfx,hai2,
|
|
$ ldhai2*dfnbasis,1.d0,fock,nbasis)
|
|
|
|
endif
|
|
|
|
return
|
|
end
|
|
C
|
|
************************************************************************
|
|
subroutine dflast(focka,fockb,p,p2,nbasis,dfnbasis,npos,ipos,hai,
|
|
$hai2,x,x2,cpr,i4core,intpos,teintf,nocc,mo,dtol,nbl,chfx,scftype,
|
|
$lq,lb,job,ldhai,ldhai2,n_neg)
|
|
************************************************************************
|
|
* DF-HF Fock-matrix construction, last step
|
|
************************************************************************
|
|
implicit none
|
|
integer nbasis,dfnbasis,intpos(3,*),npos,ipos,nbl,scftype,ldhai
|
|
integer i,j,k,l,n,kk,teintf(10),nn,ii,nocc,ldhai2,n_neg
|
|
real*8 focka(nbasis,nbasis),fockb(nbasis,nbasis),p(nbasis,nbasis)
|
|
real*8 hai(ldhai,dfnbasis,nbasis),cpr(nbasis),mo(nocc,nbasis)
|
|
real*8 pp,pr,ss,x(*),dtol,chfx,hai2(ldhai2,dfnbasis,nbasis)
|
|
real*8 x2(dfnbasis), p2(nbasis,nbasis), pp2
|
|
logical lq,lb
|
|
character*1 job
|
|
integer*4 i4core(*),ssi(2)
|
|
equivalence(ss,ssi)
|
|
C Coulomb + exchange part
|
|
if(job.eq.'f' .or.
|
|
$ (job.eq.'m' .and. (n_neg.eq.0.or.n_neg.eq.nbl))) then
|
|
call dfillzero(hai,nbl*nbasis*dfnbasis)
|
|
do ipos=1,npos
|
|
i=intpos(1,ipos)
|
|
j=intpos(2,ipos)
|
|
n=intpos(3,ipos)
|
|
call intreadsq(i4core,n,teintf)
|
|
pp=0.d0
|
|
pp2 = 0.0d0
|
|
if(i.ne.j) then
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
pp=pp+ss*x(k)
|
|
if(job.eq.'m'.and.(scftype.eq.0.or.scftype.ge.3)) then
|
|
pp2 = pp2 + ss * x2(k)
|
|
endif
|
|
pr=dabs(ss)
|
|
if(pr*cpr(i).gt.dtol) then
|
|
do ii=1,nbl
|
|
hai(ii,k,j)=hai(ii,k,j)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
if(pr*cpr(j).gt.dtol) then
|
|
do ii=1,nbl
|
|
hai(ii,k,i)=hai(ii,k,i)+ss*mo(ii,j)
|
|
enddo
|
|
endif
|
|
enddo
|
|
else
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
pp=pp+ss*x(k)
|
|
if(job.eq.'m'.and.(scftype.eq.0.or.scftype.ge.3)) then
|
|
pp2 = pp2 + ss * x2(k)
|
|
endif
|
|
if(dabs(ss)*cpr(i).gt.dtol) then
|
|
do ii=1,nbl
|
|
hai(ii,k,i)=hai(ii,k,i)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
enddo
|
|
endif
|
|
if(job.eq.'m'.and.(scftype.eq.0.or.scftype.ge.3)) then
|
|
focka(i, j) = focka(i, j) + pp
|
|
fockb(i, j) = fockb(i, j) + pp2
|
|
else
|
|
if(lq) focka(i,j)=focka(i,j)+pp
|
|
if(lb) fockb(i,j)=fockb(i,j)+pp
|
|
endif
|
|
enddo
|
|
C Second step of the exchange part
|
|
if(lq) then
|
|
if(nbl.gt.0) call dsyrk('u','t',nbasis,nbl*dfnbasis,chfx,hai,
|
|
$nbl*dfnbasis,1.d0,focka,nbasis)
|
|
else
|
|
if(nbl.gt.0) call dsyrk('u','t',nbasis,nbl*dfnbasis,-chfx,hai,
|
|
$nbl*dfnbasis,1.d0,focka,nbasis)
|
|
endif
|
|
elseif(job.eq.'m' .and. n_neg.ne.0 .and. n_neg.ne.nbl) then
|
|
call dfillzero(hai,ldhai*nbasis*dfnbasis)
|
|
call dfillzero(hai2,ldhai2*nbasis*dfnbasis)
|
|
do ipos=1,npos
|
|
i=intpos(1,ipos)
|
|
j=intpos(2,ipos)
|
|
n=intpos(3,ipos)
|
|
call intreadsq(i4core,n,teintf)
|
|
pp=0.d0
|
|
pp2 = 0.0d0
|
|
if(i.ne.j) then
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
pp=pp+ss*x(k)
|
|
if(scftype .eq. 0 .or. scftype .ge. 3) then
|
|
pp2 = pp2 + ss * x2(k)
|
|
endif
|
|
pr=dabs(ss)
|
|
if(pr*cpr(i).gt.dtol) then
|
|
do ii=1,ldhai
|
|
hai(ii,k,j)=hai(ii,k,j)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
if(pr*cpr(j).gt.dtol) then
|
|
do ii=1,ldhai
|
|
hai(ii,k,i)=hai(ii,k,i)+ss*mo(ii,j)
|
|
enddo
|
|
endif
|
|
if(pr*cpr(i).gt.dtol) then
|
|
do ii=ldhai+1, nbl
|
|
hai2(ii-ldhai,k,j)=hai2(ii-ldhai,k,j)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
if(pr*cpr(j).gt.dtol) then
|
|
do ii=ldhai+1,nbl
|
|
hai2(ii-ldhai,k,i)=hai2(ii-ldhai,k,i)+ss*mo(ii,j)
|
|
enddo
|
|
endif
|
|
enddo
|
|
else
|
|
do kk=0,n-1
|
|
ssi(1)=i4core(3*kk+1)
|
|
ssi(2)=i4core(3*kk+2)
|
|
k =i4core(3*kk+3)
|
|
pp=pp+ss*x(k)
|
|
if(job.eq.'m'.and.(scftype.eq.0.or.scftype.ge.3)) then
|
|
pp2 = pp2 + ss * x2(k)
|
|
endif
|
|
if(dabs(ss)*cpr(i).gt.dtol) then
|
|
do ii=1,ldhai
|
|
hai(ii,k,i)=hai(ii,k,i)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
if(dabs(ss)*cpr(i).gt.dtol) then
|
|
do ii=ldhai+1,nbl
|
|
hai2(ii-ldhai,k,i)=hai2(ii-ldhai,k,i)+ss*mo(ii,i)
|
|
enddo
|
|
endif
|
|
enddo
|
|
endif
|
|
if(job.eq.'m'.and.(scftype.eq.0.or.scftype.ge.3)) then
|
|
focka(i, j) = focka(i, j) + pp
|
|
fockb(i, j) = fockb(i, j) + pp2
|
|
else
|
|
if(lq) focka(i,j)=focka(i,j)+pp
|
|
if(lb) fockb(i,j)=fockb(i,j)+pp
|
|
endif
|
|
enddo
|
|
C Second step of the exchange part
|
|
if(lq) then
|
|
if(nbl.gt.0) then
|
|
call dsyrk('u','t',nbasis,ldhai*dfnbasis,chfx,hai,
|
|
$ ldhai*dfnbasis,1.d0,focka,nbasis)
|
|
call dsyrk('u','t',nbasis,ldhai2*dfnbasis,-chfx,hai2,
|
|
$ ldhai2*dfnbasis,1.d0,focka,nbasis)
|
|
endif
|
|
else
|
|
if(nbl.gt.0) call dsyrk('u','t',nbasis,nbl*dfnbasis,-chfx,hai,
|
|
$nbl*dfnbasis,1.d0,focka,nbasis)
|
|
endif
|
|
endif
|
|
C
|
|
return
|
|
end
|
|
************************************************************************
|
|
subroutine df_direct_fock(focka,fockb,p,nbasis,dfnbasis,scftol,
|
|
$nocc,mo,step,iout,natrange,oeintfile,natoms,dcore,icore,imem,
|
|
$nmoat,moat,dfnmobasis,moadd,atmo,natmo,ifile,iimem,scrfile4,lfin,
|
|
$moa,x,ialpha,chfx,varsfile,nbset,scrfile3,maxcor,tedatfile,lwdfn,
|
|
$minpfile,irecln,sclroute,route,hailen,linv,nc,lsexc,ncorenew,caa,
|
|
$devparr,excrad,excrad_fin,llc,scftype,scfiguess,locfit,nmobasis,
|
|
$natdom,atdom,naoat,aoat,atind,clrhfx,csrhfx,omega,qscf_hess,lf12,
|
|
$excha,exchb,lscrohfldf,istore,intpos,loccri)
|
|
************************************************************************
|
|
* Integral-direct Fock-matrix construction for DF-HF
|
|
************************************************************************
|
|
implicit none
|
|
integer nbasis,dfnbasis,iout,imem,ifile,iimem,katoms,lfin
|
|
integer i,j,k,l,n,kk,nn,ii,nocc,step,ierr,scrfile4,ialpha,idfatdom
|
|
integer oeintfile,natoms,is,iv,dfnmobasis(nocc),moadd,hailen,ist
|
|
integer dblalloc,intalloc,icore(*),iipra,natmo(*),idfatind,locfit
|
|
integer isa,ivi,iai,iind,atmo,nmoat(natoms),moat(natoms,nocc)
|
|
integer iover,iiold,icmo,idfnmobasis_old,minpfile,nmobasis(nocc)
|
|
integer naoat(natoms,2),aoat(natoms,nocc),atind,llocfit
|
|
integer varsfile,nbset,scrfile3,maxcor,tedatfile,irecln,idfnatdom
|
|
integer nc,ncore,ncorenew,incorb,inco,ncc1,ncc2,iatdom,lsexc
|
|
integer natdom(nocc),atdom(natoms,nocc),idist,iatoms,istore,intpos
|
|
integer natrange(2,natoms,*),nbatdom,ialpha_ovlp,iuboys
|
|
real*8 focka(nbasis,nbasis),p(nbasis,nbasis),temp,ss,ctol,chfx
|
|
real*8 mo(nbasis,nocc),dcore(*),devparr(2),bpcompo,itol
|
|
real*8 scftol,excrad,ddot,pr,moa(nocc,nbasis),clrhfx,csrhfx,omega
|
|
real*8 fockb(nbasis,nbasis),x(dfnbasis),caa(nbasis,nocc-nc)
|
|
real*8 excrad_fin,bpc(5),chargetol
|
|
real*8 excha(nbasis,nbasis),exchb(nbasis,nbasis)
|
|
character*4 cscr4,route
|
|
character*5 scftype,scfloc5(2)
|
|
character*7 scfiguess,scfmodom
|
|
character*16 orbloco,scfloc,c16
|
|
character*8 c8
|
|
logical linv,lwdfn,sclroute,llc,qscf_hess,lf12,lscrohfldf,loccri
|
|
equivalence(scfloc5,scfloc)
|
|
#if defined (MPI)
|
|
include 'mpif.h'
|
|
#endif
|
|
C Read thresholds
|
|
c write(6,*) 'fock1',chfx
|
|
c write(6,"(13f10.6)") focka
|
|
llocfit=locfit
|
|
if(excrad.eq.0.0d0) llocfit=0
|
|
call getkey('itol',4,cscr4,4)
|
|
read(cscr4,*) i
|
|
itol=10.d0**(-i)
|
|
ctol=min(itol,scftol/dfloat(dfnbasis*nocc))
|
|
if(sclroute) then
|
|
ncc1=0
|
|
ncc2=nc
|
|
if(route.eq.'emft'.or.route.eq.'sch ')
|
|
$call dcopy(nbasis*(nocc-nc),caa,1,mo,1)
|
|
goto 1236
|
|
endif
|
|
ncc1=0
|
|
ncc2=0
|
|
C Initialize MO coefficient matrix
|
|
if(route.eq.'emft'.and.lsexc.eq.0) then
|
|
ncc1=0
|
|
ncc2=nc
|
|
if(route.eq.'emft') call dcopy(nbasis*(nocc-nc),caa,1,mo,1)
|
|
elseif(.not. qscf_hess) then
|
|
open(scrfile3,file='MOA',form='unformatted')
|
|
write(scrfile3) moa
|
|
close(scrfile3)
|
|
call dcopy(nbasis*nocc,moa,1,dcore(imem),1)
|
|
ii=imem
|
|
do j=1,nbasis
|
|
mo(j,1:nocc)=dcore(ii:ii+nocc-1)
|
|
ii=ii+nocc
|
|
enddo
|
|
endif
|
|
C No local fitting
|
|
linv=.false.
|
|
do i=1,max(nocc,nocc-nc)
|
|
nmobasis(i)=nbasis
|
|
dfnmobasis(i)=dfnbasis
|
|
enddo
|
|
C Local fitting domains
|
|
if(nocc.gt.0.and.excrad.gt.0.d0.and.(chfx.ne.0.d0.or.lfin.eq.2))
|
|
$then
|
|
call getvar('ncore ',ncore)
|
|
if(.not.llc) ncore=0
|
|
icmo=dblalloc(nbasis**2)
|
|
c Lowdin charge criterion for initial fitting domains
|
|
chargetol=0.1d0
|
|
if (scftype.ne.'rhf ') chargetol=chargetol/2.d0
|
|
C Read S matrix
|
|
is=dblalloc(nbasis**2)
|
|
open(unit=oeintfile,file='OEINT',status='old',
|
|
$form='unformatted')
|
|
call roeint(dcore(imem),dcore(imem),dcore(is),oeintfile,nbasis)
|
|
C Initial guess for localization
|
|
ierr=1
|
|
if((lwdfn.and.step.ge.2).or.
|
|
& scfiguess.eq.'mo '.or.scfiguess.eq.'restart') then
|
|
iover=dblalloc(nbasis*nocc)
|
|
iiold=intalloc(nocc)
|
|
call loc_guess(imem,dcore,icmo,is,iover,iiold,ialpha,
|
|
&nbasis,nocc,scrfile3,mo,iout,lscrohfldf)
|
|
endif
|
|
C Pipek-Mezey localization
|
|
iv=dblalloc(nbasis*nocc)
|
|
write(iout,*)
|
|
call getkey('scfloc',6,scfloc,16)
|
|
if(scfloc.eq.'pm ') then
|
|
write(iout,*) 'Pipek-Mezey localization...'
|
|
C For Boys localization, orbloco=boys molden=off
|
|
call pmll(nocc,nbasis,natoms,natrange,dcore(is),mo,dcore(iv),
|
|
$dcore(imem),ierr.ne.0,ifile,step,devparr(1)+devparr(2),iout)
|
|
else if(trim(scfloc).eq.'boys') then
|
|
C For Boys localization, orbloco=boys molden=off
|
|
write(iout,*) 'Boys localization...'
|
|
iuboys=dblalloc(nocc*nocc)
|
|
open(scrfile3,file='PRINT',form='UNFORMATTED')
|
|
call localize('x',nocc,'boys',
|
|
&1.0d0,itol,itol,itol,natoms,dcore(imem),nbasis,
|
|
&scrfile3,'restart ',0,mo,nocc,.false.,dcore(iuboys))
|
|
close(scrfile3)
|
|
call dbldealloc(iuboys)
|
|
else if(trim(scfloc).eq.'pmm') then
|
|
write(iout,*) 'PM localization with Mulliken charges...'
|
|
open(scrfile3,file='PRINT',form='UNFORMATTED')
|
|
call localize('x',nocc,'pm ',1.0d0,itol,itol,itol,natoms,
|
|
&dcore(imem),nbasis,scrfile3,'restart ',0,mo,nocc,.false.,dcore)
|
|
close(scrfile3)
|
|
elseif(scfloc5(1).eq.'gboys') then
|
|
read(scfloc5(2),*) ss
|
|
write(*,"(' Generalized Boys localization ',
|
|
& '(m = ',f5.1,')')") ss
|
|
open(scrfile3,file='PRINT',form='UNFORMATTED')
|
|
call localize('x',nocc,'boys',ss,itol,itol,itol,natoms,
|
|
&dcore(imem),nbasis,scrfile3,'restart ',0,mo,nocc,.false.,dcore)
|
|
close(scrfile3)
|
|
endif
|
|
#if defined (MPI)
|
|
call MPI_Bcast(mo,nocc*nbasis,MPI_DOUBLE_PRECISION,0,
|
|
$MPI_COMM_WORLD,i)
|
|
#endif
|
|
call timer
|
|
C Check overlap with old MOs
|
|
if(ierr.eq.0) then
|
|
call dgemm('t','n',nocc,nocc,nbasis,1.d0,mo,nbasis,
|
|
$dcore(iover),nbasis,0.d0,dcore(imem),nocc)
|
|
call chkover(dcore(imem),mo,dcore(icmo),nbasis,nocc,
|
|
$icore(iiold))
|
|
endif
|
|
close(oeintfile)
|
|
C Lowdin charges or Boughton-Pulay algorithm
|
|
isa=dblalloc(nbasis**2)
|
|
ivi=dblalloc(nbasis)
|
|
iai=dblalloc(nbasis)
|
|
iind=intalloc(natoms)
|
|
if(ialpha.le.1.or.(lscrohfldf.and.ialpha.gt.1)) then
|
|
open(scrfile3,file='OLDMO',form='unformatted')
|
|
else
|
|
open(scrfile3,file='OLDMOb',form='unformatted')
|
|
endif
|
|
call wrtmo(dcore(imem),dcore(imem),mo,scrfile3,ctol,nbasis,nocc)
|
|
close(scrfile3)
|
|
ist=6
|
|
if(scfiguess.eq.'mo '.or.scfiguess.eq.'restart')
|
|
$ ist=idnint(dble(natoms)/5.d0)
|
|
if(excrad.gt.0.d0.and.(chfx.ne.0.d0.or.lfin.eq.2)) then
|
|
if(locfit.ge.2) then
|
|
cnp open(minpfile,file='MINP')
|
|
cnp call getkeym('scfmodom',8,scfmodom,7)
|
|
cnp if (scfmodom.eq.' ') scfmodom='bpcompl'
|
|
cnp close(minpfile)
|
|
scfmodom='werner '
|
|
cnp open(unit=oeintfile,file='OEINT',status='old',
|
|
cnp $form='unformatted')
|
|
cnp call roeint(dcore(imem),dcore(imem),dcore(is),oeintfile,
|
|
cnp $nbasis)
|
|
cnp close(oeintfile)
|
|
cnp call dsymm('l','l',nbasis,nocc,1.d0,dcore(is),nbasis,mo,
|
|
cnp $nbasis,0.d0,dcore(iv),nbasis)
|
|
if(scfmodom.eq.'werner '.or.scfmodom.eq.'both ') then ! Werner-like MO domain construction
|
|
c write(iout,*)
|
|
c write(iout,*)'MO domain criterion: ',min(1.d-6,scftol)
|
|
c if(.false.) then
|
|
naoat=0
|
|
natdom=0
|
|
bpc(3)=2.d0
|
|
bpc(4)=0.d0
|
|
bpc(5)=0.d0
|
|
do i=1,nocc
|
|
do iatoms=1,natoms
|
|
if(0.5d0*sum(mo(natrange(1,iatoms,1)+1:
|
|
$natrange(2,iatoms,1),i)**2).gt.min(1d-7,0.1d0*scftol)) then! scftol=1.d-6 by default
|
|
naoat(iatoms,1)=naoat(iatoms,1)+1
|
|
aoat(iatoms,naoat(iatoms,1))=i
|
|
natdom(i)=natdom(i)+1
|
|
atdom(natdom(i),i)=iatoms
|
|
endif
|
|
enddo
|
|
cnp call bpcompleteness(natdom(i),atdom(1,i),dcore(is),
|
|
cnp $dcore(iv),natrange,dcore(isa),dcore(ivi),dcore(iai),bpc(1),
|
|
cnp $dcore(imem),0,0.d0,nbasis,i,.false.,mo,nbatdom)
|
|
cnp call bpcompleteness(natdom(i),atdom(1,i),dcore(is),
|
|
cnp $dcore(iv),natrange,dcore(isa),dcore(ivi),dcore(iai),bpc(2),
|
|
cnp $dcore(imem),0,0.d0,nbasis,i,.true.,mo,nbatdom)
|
|
cnp write(6,"(2i5,4x,2es16.7,4x,1000i5)")
|
|
cnp $i,natdom(i),bpc(1)/2.d0,bpc(2)/2.d0,atdom(1:natdom(i),i)
|
|
cnp bpc(3)=min(bpc(3),bpc(2))
|
|
cnp bpc(4)=max(bpc(4),bpc(2))
|
|
cnp bpc(5)=bpc(5)+bpc(2)
|
|
enddo
|
|
cnp write(6,*)
|
|
cnp write(6,"(a23,i6,f10.1,i6,3es16.7)")
|
|
cnp $'Werner min/avg/max atom',
|
|
cnp $minval(natdom(1:nocc)),dble(sum(natdom(1:nocc),nocc))/dble(nocc),
|
|
cnp $maxval(natdom(1:nocc))!,bpc(3)/2.d0,bpc(4)/2.d0,bpc(5)/dble(2*nocc)
|
|
endif
|
|
if(scfmodom.eq.'bpcompl'.or.scfmodom.eq.'both ') then ! BP MO domain construction
|
|
call timer
|
|
call getkey('bpcompo',7,c16,16)
|
|
read(c16,*) bpcompo
|
|
write(iout,*)
|
|
write(iout,*)'MO domain criterion ',scfmodom,bpcompo
|
|
bpcompo=2.d0*bpcompo
|
|
open(unit=oeintfile,file='OEINT',status='old',
|
|
$form='unformatted')
|
|
call roeint(dcore(imem),dcore(imem),dcore(is),oeintfile,
|
|
$nbasis)
|
|
close(oeintfile)
|
|
call dsymm('l','l',nbasis,nocc,1.d0,dcore(is),nbasis,mo,
|
|
$nbasis,0.d0,dcore(iv),nbasis)
|
|
idist=dblalloc(natoms**2)
|
|
call bopu(nbasis,nocc,natoms,natrange,mo,dcore(iv),
|
|
$icore(iind),dcore(imem),dcore(is),dcore(isa),dcore(ivi),
|
|
$dcore(iai),atdom,naoat,aoat,natdom,bpcompo,bpcompo,nocc,
|
|
$max(30*step,5*ist),'nbp ',icore(iimem),natrange,nbasis,mo,
|
|
$dcore(idist),0,0.d0,0.0d0,.false.,iout,0.05d0)
|
|
call timer
|
|
call dbldealloc(idist)
|
|
endif
|
|
c project MOs onto their AO domain
|
|
cnp if (scfmodom.eq.'bpcompl'.or.scfmodom.eq.'werner '.or.
|
|
cnp $ scfmodom.eq.'both ') then
|
|
cnp bpc(1)=2.d0
|
|
cnp bpc(2)=0.d0
|
|
cnp bpc(5)=0.d0
|
|
cnp call dfillzero(dcore(icmo),nbasis*nocc)
|
|
cnp do i=1,nocc
|
|
cnp c call bpcompleteness(natdom(i),atdom(1,i),dcore(is),
|
|
cnp c $dcore(iv),natrange,dcore(isa),dcore(ivi),dcore(iai),bpc(3),
|
|
cnp c $dcore(imem),0,0.d0,nbasis,i,.false.,mo,nbatdom)
|
|
cnp call bpcompleteness(natdom(i),atdom(1,i),dcore(is),
|
|
cnp $dcore(iv),natrange,dcore(isa),dcore(ivi),dcore(iai),bpc(4),
|
|
cnp $dcore(imem),0,0.d0,nbasis,i,.true.,mo,nbatdom)
|
|
cnp write(*,'("truncated/projected completeness",i7,2es16.7)'),
|
|
cnp $i,bpc(3)/2.d0,bpc(4)/2.d0
|
|
cnp bpc(1)=min(bpc(4),bpc(1))
|
|
cnp bpc(2)=max(bpc(4),bpc(2))
|
|
cnp bpc(5)=bpc(5)+bpc(4)
|
|
cnp call normalize(nbatdom,1,dcore(iai),dcore(ivi),dcore(is),
|
|
cnp $.true.,2.d0,.true.)
|
|
cnp c map back the projected, normalized MO coeffs to the full basis mo
|
|
cnp ii=0
|
|
cnp do katoms=1,natdom(i)
|
|
cnp iatoms=atdom(katoms,i)
|
|
cnp do nn=natrange(1,iatoms,1)+1,natrange(2,iatoms,1)
|
|
cnp ii=ii+1
|
|
cnp dcore(icmo+(i-1)*nbasis+nn-1)=dcore(iai+ii-1)
|
|
cnp enddo !nn
|
|
cnp enddo! iiatoms
|
|
cnp enddo
|
|
cnp write(6,*)
|
|
cnp write(6,"(a22,i6,f10.1,i6,3es16.7)")
|
|
cnp $'final min/avg/max atom',
|
|
cnp $minval(natdom(1:nocc)),dble(sum(natdom(1:nocc),nocc))/dble(nocc),
|
|
cnp $maxval(natdom(1:nocc)),bpc(1)/2.d0,bpc(2)/2.d0,bpc(5)/dble(2*nocc)
|
|
cnp endif
|
|
c
|
|
endif
|
|
open(ifile,file='SROOT',form='UNFORMATTED')
|
|
call roeint(dcore(imem),dcore(imem),dcore(isa),ifile,nbasis)
|
|
close(ifile)
|
|
call dsymm('l','l',nbasis,nocc,1.d0,dcore(isa),nbasis,mo,
|
|
$nbasis,0.d0,dcore(iv),nbasis)
|
|
c call bopu(nbasis,nocc,natoms,natrange,dcore(iv),dcore(iv),
|
|
c $icore(iind),dcore(imem),dcore(isa),dcore(isa),dcore(ivi),
|
|
c $dcore(iai),atdom,naoat,aoat,natdom,0.0000001d0,0.1d0,nocc,natoms,
|
|
c $'lowd',icore(iimem),natrange,nbasis,dcore(iv),dcore(imem),0,0.d0,
|
|
c $0.0d0,.false.,iout,0.05d0)
|
|
call bopu(nbasis,nocc,natoms,natrange,dcore(iv),dcore(iv),
|
|
$icore(iind),dcore(imem),dcore(isa),dcore(isa),dcore(ivi),
|
|
$dcore(iai),atmo,nmoat,moat,natmo,chargetol,chargetol,nocc,
|
|
$max(2*step,ist),'lowd',icore(iimem),natrange,nbasis,dcore(iv),
|
|
$dcore(imem),0,0.d0,0.0d0,.false.,iout,0.05d0)
|
|
C Construct domains
|
|
iipra=dblalloc(natoms**2)
|
|
idfnmobasis_old=intalloc(nocc)
|
|
iatdom=intalloc(natoms)
|
|
idfatdom=intalloc(natoms*nocc)
|
|
idfatind=intalloc(natoms*nocc)
|
|
idfnatdom=intalloc(nocc)
|
|
call locdom(nbasis,nocc,natoms,natrange,atmo,nmoat,moat,natmo,
|
|
$excrad,icore(iatdom),dcore(iipra),dfnmobasis,moadd,hailen,
|
|
$dfnbasis,icore(idfnmobasis_old),linv,scrfile4,step,
|
|
$icore(iimem+natoms),iout,scftype,lwdfn,mo,icore(idfatdom),
|
|
$icore(idfnatdom),icore(iimem),icore(idfatind),2,
|
|
$ialpha,llocfit,nmobasis,natdom,atdom,naoat,aoat,atind,scftol,
|
|
$lscrohfldf)
|
|
cnp if (scfmodom.eq.'bpcompl'.or.scfmodom.eq.'werner '.or.
|
|
cnp $ scfmodom.eq.'both ') then
|
|
cnp c write(*,*) 'project on MO domain + normalize'
|
|
cnp c call dcopy(nbasis*nocc,dcore(icmo),1,mo,1)
|
|
cnp endif
|
|
endif
|
|
call dbldealloc(icmo)
|
|
endif ! Local fitting domains
|
|
1236 continue
|
|
if(lfin.ne.2.and.dabs(excrad-excrad_fin).gt.1d-2*itol) then
|
|
do i=1,nocc
|
|
if(dfnmobasis(i).lt.dfnbasis) lfin=1
|
|
enddo
|
|
lfin=1
|
|
endif
|
|
C Fock-matrix construction
|
|
call getkey('fitting',7,c8,8)
|
|
if(c8.eq.'overlap ') then
|
|
call getvar('ncore ',ncore)
|
|
if(.not.llc) ncore=0
|
|
icmo=dblalloc(nbasis**2)
|
|
C Read S matrix
|
|
is=dblalloc(nbasis**2)
|
|
open(unit=oeintfile,file='OEINT',status='old',
|
|
$form='unformatted')
|
|
call roeint(dcore(imem),dcore(imem),dcore(is),oeintfile,nbasis)
|
|
C Initial guess for localization
|
|
ierr=1
|
|
if(lwdfn.and.step.ge.2) then
|
|
iover=dblalloc(nbasis*nocc)
|
|
iiold=intalloc(nocc)
|
|
call loc_guess(imem,dcore,icmo,is,iover,iiold,ialpha,
|
|
&nbasis,nocc,scrfile3,mo,iout)
|
|
endif
|
|
C Pipek-Mezey localization
|
|
iv=dblalloc(nbasis*nocc)
|
|
write(iout,*)
|
|
write(iout,*) 'Pipek-Mezey localization...'
|
|
call pmll(nocc,nbasis,natoms,natrange,dcore(is),mo,dcore(iv),
|
|
$dcore(imem),ierr.ne.0,ifile,step,devparr(1)+devparr(2),iout)
|
|
#if defined (MPI)
|
|
call MPI_Bcast(mo,nocc*nbasis,MPI_DOUBLE_PRECISION,0,
|
|
$MPI_COMM_WORLD,i)
|
|
#endif
|
|
call timer
|
|
C Check overlap with old MOs
|
|
if(ierr.eq.0) then
|
|
call dgemm('t','n',nocc,nocc,nbasis,1.d0,mo,nbasis,
|
|
$dcore(iover),nbasis,0.d0,dcore(imem),nocc)
|
|
call chkover(dcore(imem),mo,dcore(icmo),nbasis,nocc,
|
|
$icore(iiold))
|
|
endif
|
|
close(oeintfile)
|
|
call dbldealloc(icmo)
|
|
endif
|
|
if(c8.eq.'coulomb ') then
|
|
if(.not.lf12) then
|
|
call direct_fock_build(p,p,focka,fockb,fockb,step,scftype,2,0,
|
|
$1,dcore,dcore,mo(1,ncc1+1),.true.,dcore,dcore,dcore,dcore,hailen,
|
|
$nmoat,moat,moadd,dfnmobasis,ctol,linv,x,ialpha,chfx,
|
|
$iout,varsfile,icore,dcore,nbset,oeintfile,max(1,nocc-ncc2),
|
|
$scrfile3,scrfile4,maxcor,imem,tedatfile,dfnbasis,nbasis,0,
|
|
$dcore,minpfile,.false.,1,dcore,irecln,1,sclroute,0,0,0,
|
|
$devparr(1)+devparr(2),p,1,dcore,0,llocfit,nmobasis,natdom,
|
|
$atdom,naoat,aoat,atind,i,i,clrhfx,csrhfx,omega,.false.,dcore,
|
|
$dcore,dcore,i,qscf_hess,.false.,dcore,.false.,.false.,istore,
|
|
$intpos,.false.,excha,exchb,lf12,loccri,nocc)
|
|
else
|
|
if(ialpha.le.1)
|
|
$ call direct_fock_build(p,p,focka,fockb,fockb,step,scftype,2,0,1,
|
|
$dcore,dcore,mo(1,ncc1+1),.true.,dcore,dcore,dcore,dcore,hailen,
|
|
$nmoat,moat,moadd,dfnmobasis,ctol,linv,x,ialpha,0.d0,
|
|
$iout,varsfile,icore,dcore,nbset,oeintfile,max(1,nocc-ncc2),
|
|
$scrfile3,scrfile4,maxcor,imem,tedatfile,dfnbasis,nbasis,0,
|
|
$dcore,minpfile,.false.,1,dcore,irecln,1,sclroute,0,0,0,
|
|
$devparr(1)+devparr(2),p,1,dcore,0,llocfit,nmobasis,natdom,
|
|
$atdom,naoat,aoat,atind,i,i,clrhfx,csrhfx,omega,.false.,dcore,
|
|
$dcore,dcore,i,qscf_hess,.false.,dcore,.false.,.false.,istore,
|
|
$intpos,.false.,excha,exchb,lf12,loccri,nocc)
|
|
if(dabs(chfx).gt.0.d0)
|
|
$ call direct_fock_build(p,p,excha,exchb,exchb,step,scftype,2,0,1,
|
|
$dcore,dcore,mo(1,ncc1+1),.true.,dcore,dcore,dcore,dcore,hailen,
|
|
$nmoat,moat,moadd,dfnmobasis,ctol,linv,x,ialpha,chfx,
|
|
$iout,varsfile,icore,dcore,nbset,oeintfile,max(1,nocc-ncc2),
|
|
$scrfile3,scrfile4,maxcor,imem,tedatfile,dfnbasis,nbasis,-1,
|
|
$dcore,minpfile,.false.,1,dcore,irecln,1,sclroute,0,0,0,
|
|
$devparr(1)+devparr(2),p,1,dcore,0,llocfit,nmobasis,natdom,
|
|
$atdom,naoat,aoat,atind,i,i,clrhfx,csrhfx,omega,.false.,dcore,
|
|
$dcore,dcore,i,qscf_hess,.false.,dcore,.false.,.false.,istore,
|
|
$intpos,.false.,excha,exchb,lf12,loccri,nocc)
|
|
endif
|
|
elseif(c8.eq.'overlap ') then
|
|
! Exchange part
|
|
if(ialpha.eq.2) then
|
|
ialpha_ovlp=0
|
|
else
|
|
ialpha_ovlp=ialpha
|
|
endif
|
|
call direct_fock_build(p,p,focka,fockb,fockb,step,scftype,2,0,1,
|
|
$dcore,dcore,mo(1,ncc1+1),.true.,dcore,dcore,dcore,dcore,hailen,
|
|
$nmoat,moat,moadd,dfnmobasis,ctol,linv,x,ialpha_ovlp,chfx,
|
|
$iout,varsfile,icore,dcore,nbset,oeintfile,max(1,nocc-ncc2),
|
|
$scrfile3,scrfile4,maxcor,imem,tedatfile,dfnbasis,nbasis,0,
|
|
$dcore,minpfile,.false.,1,dcore,irecln,1,sclroute,0,0,0,
|
|
$devparr(1)+devparr(2),p,1,dcore,0,llocfit,nmobasis,natdom,
|
|
$atdom,naoat,aoat,atind,i,i,clrhfx,csrhfx,omega,.false.,dcore,
|
|
$dcore,dcore,i,qscf_hess,.false.,dcore,.false.,.true.,istore,
|
|
$intpos,.false.,excha,exchb,lf12,loccri,nocc)
|
|
! Coulomb part
|
|
if(ialpha.lt.2) then
|
|
call direct_fock_build(p,p,focka,fockb,fockb,step,scftype,2,0,
|
|
$1,dcore,dcore,mo(1,ncc1+1),.true.,dcore,dcore,dcore,dcore,hailen,
|
|
$nmoat,moat,moadd,dfnmobasis,ctol,linv,x,ialpha,0.0d0,
|
|
$iout,varsfile,icore,dcore,nbset,oeintfile,max(1,nocc-ncc2),
|
|
$scrfile3,scrfile4,maxcor,imem,tedatfile,dfnbasis,nbasis,0,
|
|
$dcore,minpfile,.false.,1,dcore,irecln,1,sclroute,0,0,0,
|
|
$devparr(1)+devparr(2),p,1,dcore,0,llocfit,nmobasis,natdom,
|
|
$atdom,naoat,aoat,atind,i,i,clrhfx,csrhfx,omega,.false.,dcore,
|
|
$dcore,dcore,i,qscf_hess,.false.,dcore,.false.,.false.,istore,
|
|
$intpos,.false.,excha,exchb,lf12,loccri,nocc)
|
|
endif
|
|
endif
|
|
C Restore moa
|
|
if(((route.ne.'emft'.and.route.ne.'sch ').or.lsexc.gt.0).and.
|
|
$ .not.qscf_hess) then
|
|
open(scrfile3,file='MOA',form='unformatted')
|
|
read(scrfile3) moa
|
|
close(scrfile3,status='delete')
|
|
endif
|
|
C
|
|
return
|
|
end
|
|
C
|
|
C***********************************************************************
|
|
subroutine chkover(over,mo,cmo,nbasis,nocc,iold)
|
|
C***********************************************************************
|
|
C Check the overlap with old MOs and reorder new MOs accordingly
|
|
C***********************************************************************
|
|
implicit none
|
|
integer nbasis,nocc,i,j,jj,iold(nocc)
|
|
real*8 over(nocc,nocc),cmo(nbasis,nocc),mo(nbasis,nocc),maxd
|
|
c write(6,"(23f7.3)") over
|
|
C
|
|
call ifillzero(iold,nocc)
|
|
call dcopy(nbasis*nocc,mo,1,cmo,1)
|
|
maxd=0.d0
|
|
do i=1,nocc
|
|
jj=1
|
|
do while(iold(jj).ne.0)
|
|
jj=jj+1
|
|
enddo
|
|
do j=jj+1,nocc
|
|
if(dabs(over(i,j)).gt.dabs(over(i,jj)).and.iold(j).eq.0)then
|
|
jj=j
|
|
endif
|
|
enddo
|
|
iold(jj)=i
|
|
if(i.ne.jj) call dcopy(nbasis,cmo(1,i),1,mo(1,jj),1)
|
|
maxd=max(maxd,2.d0-dabs(over(i,jj)))
|
|
enddo
|
|
C
|
|
return
|
|
end
|
|
C
|
|
************************************************************************
|
|
subroutine moatransp(nocc,nbasis,mo1,mo2,nc)
|
|
************************************************************************
|
|
* Transpose MO coefficient matrix
|
|
************************************************************************
|
|
implicit none
|
|
integer nocc,nbasis,nc,i
|
|
real*8 mo1(nocc,nbasis),mo2(nocc,nbasis)
|
|
C
|
|
call dcopy(nocc*nbasis,mo1,1,mo2,1)
|
|
do i=1,nocc-nc
|
|
mo1(i,1:nbasis)=mo2(nc+i,1:nbasis)
|
|
enddo
|
|
do i=1,nc
|
|
mo1(nocc-nc+i,1:nbasis)=mo2(i,1:nbasis)
|
|
enddo
|
|
C
|
|
return
|
|
end
|
|
C
|
|
************************************************************************
|
|
subroutine r_build(rmat,s,pt,qmat,sqroffset,scr,rs,dft)
|
|
************************************************************************
|
|
* Build R matrix for ROHF: S*D*Q + Q*D*S
|
|
************************************************************************
|
|
#include "MRCCCOMMON"
|
|
#include "SCFCOMMON"
|
|
integer sqroffset(*),i,j
|
|
real*8 rmat(*),s(*),pt(*),qmat(*),scr(*),rs(*)
|
|
character(len=32) dft
|
|
C
|
|
do i=1,nir
|
|
if(nfunc(i).gt.0) then
|
|
call dsymm('l','l',nfunc(i),nfunc(i),1.d0,s(sqroffset(i)),
|
|
$nfunc(i),pt(sqroffset(i)),nfunc(i),0.d0,scr,nfunc(i))
|
|
call dsyr2k('u','n',nfunc(i),nfunc(i),1.d0,scr,nfunc(i),
|
|
$qmat(sqroffset(i)),nfunc(i),0.d0,rmat(sqroffset(i)),nfunc(i))
|
|
if(trim(dft).ne.'off') then
|
|
call dsymm('l','l',nfunc(i),nfunc(i),1.d0,s(sqroffset(i)),
|
|
$nfunc(i),pt(sqrsize+sqroffset(i)),nfunc(i),0.d0,rs(sqrsize+1),
|
|
$nfunc(i))
|
|
call daxpy(nfunc(i)**2,-0.5d0,rs(sqrsize+1),1,scr,1)
|
|
do j=1,nfunc(i)
|
|
scr((j-1)*nfunc(i)+j)=scr((j-1)*nfunc(i)+j)-1.d0
|
|
enddo
|
|
call dsymm('r','l',nfunc(i),nfunc(i),1.d0,rs(sqroffset(i)),
|
|
$nfunc(i),rs(sqrsize+1),nfunc(i),0.d0,scr(nfunc(i)**2+1),nfunc(i))
|
|
call dsyr2k('u','n',nfunc(i),nfunc(i),1.d0,scr,nfunc(i),
|
|
$scr(nfunc(i)**2+1),nfunc(i),1.d0,rmat(sqroffset(i)),nfunc(i))
|
|
endif
|
|
call filllo(rmat(sqroffset(i)),nfunc(i))
|
|
endif
|
|
enddo
|
|
C
|
|
return
|
|
end
|
|
C
|
|
************************************************************************
|
|
subroutine pseig(r8heap,r8heap1n,lshift,step,c,fock,eigenvalue,
|
|
$r8heapsize,offset,sqroffset,s,p,ifile,route)
|
|
************************************************************************
|
|
* Solve pseudo-eigenvalue equation
|
|
************************************************************************
|
|
#include "MRCCCOMMON"
|
|
#include "SCFCOMMON"
|
|
integer i,j,step,q,error,r8heapsize,offset(nir),ifile
|
|
integer sqroffset(nir),nq
|
|
integer*4 error4
|
|
real*8 r8heap(*),r8heap1n(*),lshift,c(*),fock(*),eigenvalue(*)
|
|
real*8 s(*),p(*),fac
|
|
equivalence(error,error4)
|
|
character*4 route
|
|
C
|
|
nq=0
|
|
if(scftype.eq._UHF_.or.route.eq.'sch ') nq=1
|
|
call dcopy((nq+1)*sqrsize,fock,1,c,1)
|
|
fac=-0.5d0*dble(nq+1)
|
|
if(route.eq.'sch ') fac=-0.5d0
|
|
C Level-shifting
|
|
if(lshift.gt.0.d0.and.step.gt.1) then
|
|
if(lnos) then
|
|
open(oeintfile,file='OEINT',form='unformatted')
|
|
call roeint(r8heap,r8heap,s,oeintfile,nfunc(1)) ! r8heap2n is overwritten by S !!!
|
|
close(oeintfile)
|
|
endif
|
|
do q=0,nq
|
|
do i=1,nir
|
|
if(nfunc(i).gt.0) then
|
|
call dsymm('l','l',nfunc(i),nfunc(i),fac,
|
|
$p(q*sqrsize+sqroffset(i)),nfunc(i),s(sqroffset(i)),nfunc(i),0.d0,
|
|
$r8heap1n,nfunc(i))
|
|
do j=1,nfunc(i)
|
|
r8heap1n((j-1)*nfunc(i)+j)=1.d0+
|
|
$ r8heap1n((j-1)*nfunc(i)+j)
|
|
enddo
|
|
call dsymm('l','l',nfunc(i),nfunc(i),lshift,
|
|
$s(sqroffset(i)),nfunc(i),r8heap1n,nfunc(i),1.d0,
|
|
$c(q*sqrsize+sqroffset(i)),nfunc(i))
|
|
endif
|
|
enddo
|
|
enddo
|
|
endif
|
|
error=0
|
|
C Solve generalized eigenvalue problem
|
|
open(ifile,file='SCHOL',form='unformatted')
|
|
if(ndao.eq.0) then
|
|
do i=1,nir
|
|
if(nfunc(i).gt.0) then
|
|
call rspmx(r8heap,nfunc(i),ifile)
|
|
do q=0,nq
|
|
call dsygst(1,'L',nfunc(i),c(q*sqrsize+sqroffset(i)),
|
|
$nfunc(i),r8heap,nfunc(i),error)
|
|
call dsyev('V','L',nfunc(i),c(q*sqrsize+sqroffset(i)),
|
|
$nfunc(i),eigenvalue(q*nbasis+offset(i)),r8heap1n,r8heapsize,error)
|
|
call dtrsm('L','L','T','N',nfunc(i),nfunc(i),1.d0,
|
|
$r8heap,nfunc(i),c(q*sqrsize+sqroffset(i)),nfunc(i))
|
|
if(error4.ne.0) then
|
|
write(iout,*) 'Fatal error at diagonalization!'
|
|
call mrccend(1)
|
|
endif
|
|
enddo
|
|
endif
|
|
enddo
|
|
else
|
|
do i=1,nir
|
|
if(nfunc(i).gt.0) then
|
|
read(ifile) r8heap(1:nfunc(i)*nfuns(i))
|
|
do q=0,nq
|
|
if(nfuns(i).gt.0) then
|
|
call dsymm('l','l',nfunc(i),nfuns(i),1.d0,
|
|
$c(q*sqrsize+sqroffset(i)),nfunc(i),r8heap,nfunc(i),0.d0,
|
|
$r8heap1n,nfunc(i))
|
|
call dgemm('t','n',nfuns(i),nfuns(i),nfunc(i),1.d0,
|
|
$r8heap,nfunc(i),r8heap1n,nfunc(i),0.d0,
|
|
$c(q*sqrsize+sqroffset(i)),nfuns(i))
|
|
call dsyev('V','L',nfuns(i),c(q*sqrsize+sqroffset(i)),
|
|
$nfuns(i),eigenvalue(q*nbasis+offset(i)),r8heap1n,r8heapsize,error)
|
|
if(error4.ne.0) then
|
|
write(iout,*) 'Fatal error at diagonalization!'
|
|
call mrccend(1)
|
|
endif
|
|
call dgemm('n','n',nfunc(i),nfuns(i),nfuns(i),1.d0,
|
|
$r8heap,nfunc(i),c(q*sqrsize+sqroffset(i)),nfuns(i),0.d0,
|
|
$r8heap1n,nfunc(i))
|
|
call dcopy(nfunc(i)*nfuns(i),r8heap1n,1,
|
|
$c(q*sqrsize+sqroffset(i)),1)
|
|
endif
|
|
eigenvalue(q*nbasis+offset(i)+nfuns(i):
|
|
$ q*nbasis+offset(i)+nfunc(i)-1)=1d30
|
|
c(q*sqrsize+sqroffset(i)+nfunc(i)*nfuns(i):
|
|
$ q*sqrsize+sqroffset(i)+nfunc(i)*nfunc(i)-1)=0.d0
|
|
enddo
|
|
endif
|
|
enddo
|
|
endif
|
|
close(ifile)
|
|
C Restore orbital energies in the case of level-shifting
|
|
if(lshift.gt.0.d0.and.step.gt.1) then
|
|
do q=0,nq
|
|
do i=1,nir
|
|
do j=orbperir(i+q*nir),nfunc(i)-1
|
|
eigenvalue(offset(i)+q*nbasis+j)=
|
|
$ eigenvalue(offset(i)+q*nbasis+j)-lshift
|
|
enddo
|
|
enddo
|
|
enddo
|
|
if(scftype.eq._ROHFSTD_.or.scftype.eq._ROHFSCN_) then
|
|
do i=1,nir
|
|
do j=orbperir(i),orbperir(i)+orbperir(i+nir)-1
|
|
eigenvalue(offset(i)+j)=
|
|
$ eigenvalue(offset(i)+j)+0.5d0*lshift
|
|
enddo
|
|
enddo
|
|
endif
|
|
endif
|
|
#if defined (MPI)
|
|
call MPI_Bcast(c,(nq+1)*sqrsize,MPI_DOUBLE_PRECISION,0,
|
|
$MPI_COMM_WORLD,i)
|
|
#endif
|
|
C
|
|
return
|
|
end
|
|
C
|
|
************************************************************************
|
|
subroutine moto(mat1,symtra,r8heap,nbasis,mat2,offset,lsa)
|
|
************************************************************************
|
|
* Transform one-electron quantities to symmetry basis
|
|
************************************************************************
|
|
implicit none
|
|
integer nbasis,offset
|
|
real*8 mat1(nbasis,nbasis),mat2(nbasis,nbasis)
|
|
real*8 symtra(nbasis,nbasis),r8heap(*)
|
|
logical lsa
|
|
C
|
|
if(lsa) then
|
|
call mx_symm_extr(r8heap,mat2,offset)
|
|
call dgemm('n','n',nbasis,nbasis,nbasis,1.d0,symtra,nbasis,
|
|
$r8heap,nbasis,0.d0,mat1,nbasis)
|
|
else
|
|
call dcopy(nbasis*nbasis,mat2,1,mat1,1) !Do not touch
|
|
endif
|
|
C
|
|
return
|
|
end
|
|
C
|