From 965ffeb5dc42980646a10607c4ffd655db107c40 Mon Sep 17 00:00:00 2001
From: Marc de Wergifosse <56387143+mdewergi@users.noreply.github.com>
Date: Thu, 9 Jan 2025 11:28:38 +0100
Subject: [PATCH] std2 major update
08.01.2024: Version 2.0.0:
- interfaced by default to libcint (magnetic moment one-electron integrals still computed with the old integral deck)
- XsTDA (restricted and unrestricted[only excited states]) for global hybrids and range-separated hybrids
- XsTD-DFT (restricted and unrestricted[only excited states]) for global hybrids and range-separated hybrids
- SF-XsTD-DFT for global hybrids
- CAM-B3LYP, wB97X-D2, wB97X-D3, wB97MV, SRC2R1, and SRC2R2 RSH functionals natively implemented with XsTD
---
2PA.f90 | 773 +++++++
INFO | 42 +-
Makefile | 52 +-
README.md | 194 +-
apbtrafo.f | 225 +-
block.f | 41 +-
full.f | 1373 ++++++++++++
g2molden/Makefile | 0
g2molden/main.f | 0
g2molden/stringmod.f90 | 0
g_spec/Makefile | 0
g_spec/g_spec.f | 0
header.f | 16 +-
intpack.f90 | 52 +-
intslvm.f | 229 +-
io.f | 12 +-
libcint.f | 904 ++++++++
linal.f | 12 +-
linear_response.f | 120 +-
main.f | 438 +++-
meson.build | 223 +-
meson_options.txt | 63 +-
molden.f | 43 +-
normalize.f | 40 +-
onetri.f | 17 +-
pckao.f | 31 +-
print_nto.f | 98 +-
printvec.f | 93 +-
prmat.f | 11 +-
readbasa.f | 83 +-
readbasmold.f | 185 +-
readl.f | 13 +-
readxtb.f | 51 +-
sfstda.f | 22 +-
sosor.f | 28 +-
srpapack.f | 63 +-
stda_manual.pdf => std2_manual.pdf | Bin 378611 -> 386594 bytes
stda-rw.f | 231 ++-
stda-rw_dual.f | 189 +-
stda.f | 198 +-
stdacommon.f90 | 19 +-
stringmod.f90 | 81 +-
subprojects/libcint.wrap | 9 +
sutda.f | 357 ++--
tests/compare.py | 135 ++
tests/expected_results/2PA_TEST1.txt | 3 +
tests/expected_results/2PA_TEST2.txt | 3 +
tests/expected_results/2PA_TEST3.txt | 3 +
tests/expected_results/BETA_TEST1.txt | 3 +
tests/expected_results/BETA_TEST2.txt | 3 +
tests/expected_results/BETA_TEST3.txt | 3 +
tests/expected_results/EXCI_TEST1.dat | 17 +
tests/expected_results/EXCI_TEST2.dat | 18 +
tests/expected_results/EXCI_TEST3.dat | 19 +
tests/run_tests.sh | 86 +
tests/water_sto3g.molden | 106 +
tests/wavelength | 2 +
velo.f | 37 +-
xstd.f90 | 2769 +++++++++++++++++++++++++
59 files changed, 8673 insertions(+), 1165 deletions(-)
create mode 100755 2PA.f90
create mode 100644 full.f
mode change 100644 => 100755 g2molden/Makefile
mode change 100644 => 100755 g2molden/main.f
mode change 100644 => 100755 g2molden/stringmod.f90
mode change 100644 => 100755 g_spec/Makefile
mode change 100644 => 100755 g_spec/g_spec.f
create mode 100755 libcint.f
rename stda_manual.pdf => std2_manual.pdf (50%)
mode change 100755 => 100644
create mode 100644 subprojects/libcint.wrap
create mode 100644 tests/compare.py
create mode 100644 tests/expected_results/2PA_TEST1.txt
create mode 100644 tests/expected_results/2PA_TEST2.txt
create mode 100644 tests/expected_results/2PA_TEST3.txt
create mode 100644 tests/expected_results/BETA_TEST1.txt
create mode 100644 tests/expected_results/BETA_TEST2.txt
create mode 100644 tests/expected_results/BETA_TEST3.txt
create mode 100644 tests/expected_results/EXCI_TEST1.dat
create mode 100644 tests/expected_results/EXCI_TEST2.dat
create mode 100644 tests/expected_results/EXCI_TEST3.dat
create mode 100755 tests/run_tests.sh
create mode 100644 tests/water_sto3g.molden
create mode 100644 tests/wavelength
create mode 100644 xstd.f90
diff --git a/2PA.f90 b/2PA.f90
new file mode 100755
index 0000000..91868d8
--- /dev/null
+++ b/2PA.f90
@@ -0,0 +1,773 @@
+! This file is part of std2.
+!
+! Copyright (C) 2025 Marc de Wergifosse
+!
+! std2 is free software: you can redistribute it and/or modify it under
+! the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! std2 is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU Lesser General Public License for more details.
+!
+! You should have received a copy of the GNU Lesser General Public License
+! along with std2. If not, see .
+!
+!! ------------------------------------------------------------------------
+SUBROUTINE lresp_2PA_full(nci,apb,amb,iconf,maxconf,xl,yl,zl,moci,no,nv,eci,Xci,Yci,nroot,&
+&ncent,dax,nao,clow)
+use commonresp
+use omp_lib
+IMPLICIT NONE
+
+integer ::i,j,k,ii,jj,kk,ij,jk,ab,io,iv,idum1,idum2,nci
+integer ::io1,io2,iv1,iv2,iwrk,jwrk,nroot,ncent,nao
+integer ::maxconf,moci,no,nv,ino,nno,inv,nnv
+integer ::iconf(maxconf,2)
+integer, allocatable :: A_list(:,:)
+integer ::counter_A
+integer, allocatable :: B_list(:,:)
+integer ::counter_B
+integer*8 ::lin8
+real*8 :: dax,clow(nao*moci)
+
+real*8 ::xl(moci*(moci+1)/2)
+real*8 ::yl(moci*(moci+1)/2)
+real*8 ::zl(moci*(moci+1)/2)
+
+real*4 ::mu_x(nci)
+real*4 ::mu_y(nci)
+real*4 ::mu_z(nci)
+real*4 ::XpY_int(nci,3)
+real*4 ::XpYci(nci)
+
+real*8 ::mu(moci*(moci+1)/2,3)
+real*4 ::omega
+real*4 ::Xci(nci,nroot), Yci(nci,nroot),eci(nci)
+real*4 ::apb(nci*(nci+1)/2)
+real*4 ::amb(nci*(nci+1)/2)
+real*4, allocatable ::inv_amb(:)
+real*4, allocatable ::inv_resp(:)
+real*8, allocatable ::XpY(:,:)
+real*8, allocatable ::XmY(:,:)
+real*8, allocatable ::X(:,:)
+real*8, allocatable ::Y(:,:)
+character*1 ::uplo
+integer ::info
+integer, allocatable ::ipiv(:)
+real*4, allocatable ::work (:)
+
+integer ::ix,iy,iz
+real*8 ::sigma(3,3),A,B,sigma_f,sigma_g,sigma_h
+
+real*8 ::alpha_xx,alpha_xy,alpha_xz
+real*8 ::alpha_yy,alpha_yz
+real*8 ::alpha_zz
+
+
+real*4 ::start_time,end_time,sdot
+
+real*4,allocatable :: f_ijka(:,:),f_abic(:,:),F_ij(:,:),F_ab(:,:)
+
+open(unit=60,file='2PA-abs',status='replace')
+
+mu=0.0
+mu(:,1)=xl(:)
+mu(:,2)=yl(:)
+mu(:,3)=zl(:)
+
+write(*,*)
+write(*,*)'======================================================================'
+write(*,*)' Welcome in nonlinear response sTD-DFT program'
+write(*,*)'======================================================================'
+write(*,*)
+
+allocate(inv_amb(nci*(nci+1)/2))
+inv_amb=amb
+uplo='U'
+allocate(ipiv(1:nci),work(1:nci))
+call ssptrf(uplo,nci,inv_amb,ipiv,info)
+call ssptri(uplo,nci,inv_amb,ipiv,work,info)
+deallocate(ipiv,work)
+
+allocate( XpY(nci,3))
+allocate( XmY(nci,3))
+allocate( X(nci,3),Y(nci,3))
+
+! the dipole moment matrix mu_ai
+mu_x=0.0
+mu_y=0.0
+mu_z=0.0
+!$omp parallel private(j,io,iv,idum1,idum2,ij)
+!$omp do
+ Do j=1, nci
+ io=iconf(j,1)
+ iv=iconf(j,2)
+ idum1=max(io,iv)
+ idum2=min(io,iv)
+ ij=idum2+idum1*(idum1-1)/2
+ mu_x(j)=-xl(ij)
+ mu_y(j)=-yl(ij)
+ mu_z(j)=-zl(ij)
+ enddo
+!$omp end do
+!$omp end parallel
+
+! Generating Hartree XC kernel
+
+ino=minval(iconf(1:nci,1))
+nno=maxval(iconf(1:nci,1))
+inv=minval(iconf(1:nci,2)) ! start with no+1
+nnv=maxval(iconf(1:nci,2))
+allocate(f_ijka(ino*(ino+1)/2:nno*(nno+1)/2,nci),f_abic(inv*(inv+1)/2:nnv*(nnv+1)/2,nci))
+call HXC(nci,ncent,no,nv,maxconf,iconf,dax,nao,moci,clow,f_ijka,f_abic,ino,nno,inv,nnv)
+
+allocate(F_ij(ino*(ino+1)/2:nno*(nno+1)/2,4),F_ab(inv*(inv+1)/2:nnv*(nnv+1)/2,4))
+
+Do ii=1, num_trans
+
+XpY(:,:)=0.0
+XmY(:,:)=0.0
+X(:,:)=0.0
+Y(:,:)=0.0
+omega=-eci(ii)/2.0
+call cpu_time(start_time)
+allocate(inv_resp(nci*(nci+1)/2))
+inv_resp=apb-omega**2.0*inv_amb
+
+
+uplo='U'
+XpY_int(:,1)=mu_x(:)
+XpY_int(:,2)=mu_y(:)
+XpY_int(:,3)=mu_z(:)
+allocate(ipiv(1:nci))
+call ssptrf(uplo,nci,inv_resp,ipiv,info)
+call ssptrs(uplo,nci,3,inv_resp,ipiv,XpY_int,nci,info)
+deallocate(ipiv)
+
+XpY(:,1)=dble(XpY_int(:,1))
+XpY(:,2)=dble(XpY_int(:,2))
+XpY(:,3)=dble(XpY_int(:,3))
+
+ write(*,*)
+ write(*,*)ii
+ write(*,*)
+
+! extract X and Y from XpY
+! (X-Y)=omega*(A-B)^-1 (X+Y)
+! X=((X+Y)+(X-Y))/2
+! Y=(X+Y)-X
+!$omp parallel private(i,j,ij,ix) reduction (+:XmY)
+!$omp do
+ Do i=1,nci
+ Do j=1,nci
+ ij=lin8(i,j)
+ Do ix=1,3
+ XmY(i,ix)=XmY(i,ix)+ dble(omega)*dble(inv_amb(ij))*XpY(j,ix)
+ enddo
+ enddo
+ enddo
+!$omp end do
+!$omp end parallel
+!$omp parallel private(ix,j) reduction(+:X,Y)
+!$omp do
+ Do ix=1,3
+ Do j=1,nci
+ X(j,ix)=(XpY(j,ix)+XmY(j,ix))/2.0
+ Y(j,ix)=XpY(j,ix)-X(j,ix)
+ enddo
+ enddo
+!$omp end do
+!$omp end parallel
+
+deallocate(inv_resp)
+
+call cpu_time(end_time)
+print '("alpha Time = ",f12.2," minutes.")',(end_time-start_time)/60.0
+
+XpYci(:)=Xci(:,ii)+Yci(:,ii)
+!$omp parallel private(i,j,ix)
+!$omp do
+Do i=ino,nno
+Do j=ino,i
+Do ix=1,3
+F_ij(lin8(i,j),ix)=sdot(nci,f_ijka(lin8(i,j),:),1,XpY_int(:,ix),1)
+enddo
+F_ij(lin8(i,j),4)=sdot(nci,f_ijka(lin8(i,j),:),1,XpYci(:),1)
+enddo
+enddo
+!$omp end do
+!$omp end parallel
+!$omp parallel private(i,j,ix)
+!$omp do
+Do i=inv,nnv
+Do j=inv,i
+Do ix=1,3
+F_ab(lin8(i,j),ix)=sdot(nci,f_abic(lin8(i,j),:),1,XpY_int(:,ix),1)
+enddo
+F_ab(lin8(i,j),4)=sdot(nci,f_abic(lin8(i,j),:),1,XpYci(:),1)
+enddo
+enddo
+!$omp end do
+!$omp end parallel
+write(*,*)'F_ij and F_ab computed'
+
+if(ii==1)then
+!
+! Genarating a list of indexes used in A and B formula to save a great bunch of time
+!
+call cpu_time(start_time)
+counter_A=0
+!$omp parallel private(j,i,kk) reduction(+:counter_A)
+!$omp do
+ Do i=1,nci
+ Do j=1,no
+ Do kk=1,nci
+ if(iconf(kk,1)==j .and. iconf(kk,2)==iconf(i,2))then
+ counter_A=counter_A+1
+ endif
+ enddo
+ enddo
+ enddo
+!$omp end do
+!$omp end parallel
+ allocate(A_list(1:counter_A,1:3))
+ A_list=-9999
+ call List_A(maxconf,no,nci,iconf,A_list,counter_A)
+ !Do i=1,counter_A
+ !write(*,*)i,A_list(i,1:3)
+ !enddo
+
+ counter_B=0
+!$omp parallel private(j,i,kk) reduction(+:counter_B)
+!$omp do
+ Do i=1,nci
+ Do j=1,nv
+ Do kk=1,nci
+ if(iconf(kk,1)==iconf(i,1) .and. iconf(kk,2)==j+no)then
+ counter_B=counter_B+1
+ endif
+ enddo
+ enddo
+ enddo
+!$omp end do
+!$omp end parallel
+allocate(B_list(1:counter_B,1:3))
+B_list=-9999
+call List_B(maxconf,no,nv,nci,iconf,B_list,counter_B)
+!Do i=1,counter_B
+!write(*,*)i,B_list(i,1:3)
+!enddo
+call cpu_time(end_time)
+print '("A & B indexes list Time = ",f12.2," minutes.")',(end_time-start_time)/60.0
+endif
+
+! sigma sigma = -A + B
+call cpu_time(start_time)
+!
+! Fast version
+!
+sigma(:,:)=0.0
+Do ix=1,3
+Do iy=1,ix
+call TPA_resp_fast_full(ix,iy,X,Y,Xci,Yci,nroot,A_list,B_list,counter_A,counter_B,mu,&
+&maxconf,no,nv,nci,moci,ii,iconf,A,B,ino,nno,inv,nnv,F_ij,F_ab)
+sigma(ix,iy)=(-A+B)/2.0d0
+if(ix/=iy)then
+sigma(iy,ix)=sigma(ix,iy)
+endif
+enddo
+enddo
+
+sigma_f=0.0
+sigma_g=0.0
+sigma_h=0.0
+Do ix=1,3
+Do iy=1,3
+sigma_f=sigma_f+sigma(ix,ix)*sigma(iy,iy)
+sigma_g=sigma_g+sigma(ix,iy)*sigma(ix,iy)
+sigma_h=sigma_h+sigma(ix,iy)*sigma(iy,ix)
+enddo
+enddo
+sigma_f=sigma_f/30.0
+sigma_g=sigma_g/30.0
+sigma_h=sigma_h/30.0
+
+
+
+call cpu_time(end_time)
+print '("2PA Time = ",f12.2," minutes.")',(end_time-start_time)/60.0
+write(*,*)
+write(*,3333)'Delta (',eci(ii)*27.21139,')'
+write(*,*)
+write(*,1111)'x','y','z'
+write(*,2222)'x',sigma(1,1),sigma(1,2),sigma(1,3)
+write(*,2222)'y',sigma(2,1),sigma(2,2),sigma(2,3)
+write(*,2222)'z',sigma(3,1),sigma(3,2),sigma(3,3)
+write(*,*)
+write(*,5555)'F =',sigma_f,' G =',sigma_G,' H =',sigma_H
+write(*,4444)'Delta_2PA_// =',2.0*sigma_f+2.0*sigma_g+2.0*sigma_h
+write(*,4444)'Delta_2PA__|_ =',-1.0*sigma_f+4.0*sigma_g-1.0*sigma_h
+write(*,4444)'Delta_2PA_circ =',-2.0*sigma_f+3.0*sigma_g+3.0*sigma_h
+write(*,4444)'rho = //*(_|_)**-1 =',(2.0*sigma_f+2.0*sigma_g+2.0*sigma_h)/&
+&(-1.0*sigma_f+4.0*sigma_g-1.0*sigma_h)
+write(60,6666)ii,eci(ii)*27.21139,2.0*sigma_f+2.0*sigma_g+2.0*sigma_h,&
+&-1.0*sigma_f+4.0*sigma_g-1.0*sigma_h,-2.0*sigma_f&
+&+3.0*sigma_g+3.0*sigma_h,(2.0*sigma_f+2.0*sigma_g&
+&+2.0*sigma_h)/(-1.0*sigma_f+4.0*sigma_g-1.0*sigma_h)
+enddo
+close(60)
+deallocate(XpY)
+deallocate(XmY)
+deallocate(X,Y)
+deallocate(inv_amb)
+write(*,*)
+write(*,*)'======================================================================'
+write(*,*)' end of nonlinear response sTD-DFT program'
+write(*,*)'======================================================================'
+write(*,*)
+111 format(A15,F20.6)
+1111 format(A22,2A20)
+2222 format(A2,3F20.6)
+3334 format(A16,F7.3,A1,F7.3,A1)
+3333 format(A16,F7.3,A1)
+4444 format(A20,F20.3)
+5555 format(A3,F20.3,A4,F20.3,A4,F20.3)
+6666 format(I3,F7.3,4F20.3)
+end subroutine lresp_2PA_full
+
+
+
+
+
+subroutine HXC(nci,ncent,no,nv,mxcnf,iconf,dax,nao,moci,clow,f_ijka,f_abic,ino,nno,inv,nnv) ! (AA|BB) only
+use commonlogicals
+use stdacommon
+use commonlibcint
+use omp_lib
+implicit none
+integer, intent(in) :: nci,ncent,no,nv,mxcnf,iconf(mxcnf,2)
+real*8, intent(in) :: dax
+real*4, intent(out) :: f_ijka(ino*(ino+1)/2:nno*(nno+1)/2,nci),f_abic(inv*(inv+1)/2:nnv*(nnv+1)/2,nci)
+integer i,j,ij,io,iv,ko,kv,ierr,lin,iiv,jjv,iwrk,jwrk,iwrk2,k,l,a,b,m,n,o,p,aa,bb,ia,jb
+real*4 ek,ej,sdot,ax
+
+real*8 :: wtime
+real*4 :: start_time,end_time,start
+integer :: ino,nno,inv,nnv
+
+integer :: nao,moci
+real*8 :: clow(nao*moci)
+
+real*4,allocatable :: Q_ia(:,:,:),P_ia(:,:,:),Q_ij(:,:),Q_ab(:,:),AABB_integral(:,:)
+
+real*4 :: value1,value2,value3,rabx
+Write(*,*)'Compute f_HXC once'
+write(*,*)'using on_site AO integrals'
+
+! Read AO integrals data
+
+allocate(AABB_integral(nao,nao))
+call two_elec_int(ncent,nao,nao,AABB_integral,1,nbas,1,nbas)
+
+
+write(*,*)'AO integrals computed'
+
+call cpu_time(start_time)
+
+! reduce the mo range to match the configuration space
+write(*,*)'Q transition charges computed for occ.',ino,'to',nno
+write(*,*)'and for unocc.',inv,'to',nnv
+
+
+allocate(Q_ia(ino:nno,inv:nnv,nao))
+
+!$omp parallel private(i,j)
+!$omp do
+Do i=ino, nno
+Do j=inv,nnv
+Do k=1,nao
+ Q_ia(i,j,k)=clow(k+(i-1)*nao)*clow(k+(j-1)*nao)
+enddo
+enddo
+enddo
+!$omp end do
+!$omp end parallel
+
+allocate(P_ia(ino:nno,inv:nnv,nao))
+
+!$omp parallel private(i,j)
+!$omp do
+Do i=ino, nno
+ Do j=inv,nnv
+
+ call sgemv('T',nao,nao,1.0,AABB_integral,nao,Q_ia(i,j,:),1,0.0,P_ia(i,j,:),1)
+
+ enddo
+enddo
+!$omp end do
+!$omp end parallel
+
+allocate(Q_ij(ino*(ino+1)/2:nno*(nno+1)/2,nao),Q_ab(inv*(inv+1)/2:nnv*(nnv+1)/2,nao))
+
+!$omp parallel private(i,k)
+!$omp do
+Do i=ino, nno
+Do k=ino, i
+Do j=1, nao
+ Q_ij(lin(i,k),j)=clow(j+(i-1)*nao)*clow(j+(k-1)*nao)
+enddo
+enddo
+enddo
+!$omp end do
+!$omp end parallel
+
+!$omp parallel private(j,l)
+!$omp do
+Do j=inv,nnv
+Do l=inv, j
+Do i=1,nao
+ Q_ab(lin(j,l),i)=clow(i+(j-1)*nao)*clow(i+(l-1)*nao)
+enddo
+enddo
+enddo
+!$omp end do
+!$omp end parallel
+
+
+deallocate(AABB_integral)
+
+
+write(*,*)"Intemediates computed"
+call cpu_time(end_time)
+print '("time = ",f12.2," minutes.")',(end_time-start_time)/60.0
+
+
+ax=real(dax)
+! calculate f_ijka and f_abic
+f_ijka=0.0e0
+f_abic=0.0e0
+!$omp parallel private(i,j,k,ko,kv,ek,ej)
+!$omp do
+Do i=ino,nno
+Do j=ino,i
+Do k=1,nci
+ko=iconf(k,1)
+kv=iconf(k,2)
+ej=sdot(nao,Q_ij(lin(i,j),:),1,P_ia(ko,kv,:),1)
+ek=-ax*sdot(nao,Q_ij(lin(i,ko),:),1,P_ia(j,kv,:),1)
+f_ijka(lin(i,j),k)=ej+ek
+enddo
+enddo
+enddo
+!$omp end do
+!$omp end parallel
+
+!$omp parallel private(i,j,k,ko,kv,ek,ej)
+!$omp do
+Do i=inv,nnv
+Do j=inv,i
+Do k=1,nci
+ko=iconf(k,1)
+kv=iconf(k,2)
+ej=sdot(nao,Q_ab(lin(i,j),:),1,P_ia(ko,kv,:),1)
+ek=-ax*sdot(nao,Q_ab(lin(j,kv),:),1,P_ia(ko,i,:),1)
+f_abic(lin(i,j),k)=ej+ek
+enddo
+enddo
+enddo
+!$omp end do
+!$omp end parallel
+
+deallocate(P_ia,Q_ia,Q_ij,Q_ab)
+write(*,*)'f_HXC computed'
+
+return
+
+end subroutine HXC
+
+SUBROUTINE TPA_resp_fast_full(ix,iy,X,Y,Xci,Yci,nroot,A_list,B_list,counter_A,counter_B,mu,maxconf,no,nv,nci,moci,ii,&
+&iconf,A,B,ino,nno,inv,nnv,F_ij,F_ab)
+use commonresp
+use omp_lib
+implicit none
+
+integer ::xx,yy,nroot
+integer ::ix,iy,no,nv,nci,ii,maxconf,moci
+integer ::iconf(maxconf,2)
+real*8 ::mu(moci*(moci+1)/2,3)
+real*8 ::X(nci,3)
+real*8 ::Y(nci,3)
+real*4 ::Xci(nci,nroot), Yci(nci,nroot)
+real*8 ::A,B
+real*8 ::A1,A2,A3,A4,A5,A6
+real*8 ::B1,B2,B3,B4,B5,B6
+integer ::counter_A,counter_B
+integer :: A_list(1:counter_A,1:3)
+integer :: B_list(1:counter_B,1:3)
+
+integer :: ino,nno,inv,nnv
+real*4 :: F_ij(ino*(ino+1)/2:nno*(nno+1)/2,4),F_ab(inv*(inv+1)/2:nnv*(nnv+1)/2,4)
+
+A=0.0d0
+B=0.0d0
+A1=0.0d0
+A2=0.0d0
+A3=0.0d0
+A4=0.0d0
+A5=0.0d0
+A6=0.0d0
+B1=0.0d0
+B2=0.0d0
+B3=0.0d0
+B4=0.0d0
+B5=0.0d0
+B6=0.0d0
+
+! A1 ix iy n
+ xx=ix
+ yy=iy
+call A_2PA_1_fast_full(xx,yy,X,Y,Xci,Yci,nroot,A_list,counter_A,mu,nci,moci,ii,A1,F_ij,ino,nno,iconf,maxconf)
+! A2 iy ix n
+ xx=iy
+ yy=ix
+call A_2PA_1_fast_full(xx,yy,X,Y,Xci,Yci,nroot,A_list,counter_A,mu,nci,moci,ii,A2,F_ij,ino,nno,iconf,maxconf)
+! A3 n ix iy
+ xx=ix
+ yy=iy
+call A_2PA_2_fast_full(xx,yy,X,Y,Xci,Yci,nroot,A_list,counter_A,mu,nci,moci,ii,A3,F_ij,ino,nno,iconf,maxconf)
+! A4 n iy ix
+ xx=iy
+ yy=ix
+call A_2PA_2_fast_full(xx,yy,X,Y,Xci,Yci,nroot,A_list,counter_A,mu,nci,moci,ii,A4,F_ij,ino,nno,iconf,maxconf)
+! A5 ix n iy
+ xx=ix
+ yy=iy
+call A_2PA_3_fast_full(xx,yy,X,Y,Xci,Yci,nroot,A_list,counter_A,mu,nci,moci,ii,A5,F_ij,ino,nno,iconf,maxconf)
+! A6 iy n ix
+ xx=iy
+ yy=ix
+call A_2PA_3_fast_full(xx,yy,X,Y,Xci,Yci,nroot,A_list,counter_A,mu,nci,moci,ii,A6,F_ij,ino,nno,iconf,maxconf)
+ A=A1+A2+A3+A4+A5+A6
+
+! B1 ix iy n
+ xx=ix
+ yy=iy
+call B_2PA_1_fast_full(xx,yy,X,Y,Xci,Yci,nroot,B_list,counter_B,mu,nci,moci,ii,B1,F_ab,inv,nnv,iconf,maxconf)
+! B2 iy ix n
+ xx=iy
+ yy=ix
+call B_2PA_1_fast_full(xx,yy,X,Y,Xci,Yci,nroot,B_list,counter_B,mu,nci,moci,ii,B2,F_ab,inv,nnv,iconf,maxconf)
+! B3 n ix iy
+ xx=ix
+ yy=iy
+call B_2PA_2_fast_full(xx,yy,X,Y,Xci,Yci,nroot,B_list,counter_B,mu,nci,moci,ii,B3,F_ab,inv,nnv,iconf,maxconf)
+! B4 n iy ix
+ xx=iy
+ yy=ix
+call B_2PA_2_fast_full(xx,yy,X,Y,Xci,Yci,nroot,B_list,counter_B,mu,nci,moci,ii,B4,F_ab,inv,nnv,iconf,maxconf)
+! B5 ix n iy
+ xx=ix
+ yy=iy
+call B_2PA_3_fast_full(xx,yy,X,Y,Xci,Yci,nroot,B_list,counter_B,mu,nci,moci,ii,B5,F_ab,inv,nnv,iconf,maxconf)
+! B6 iy n ix
+ xx=iy
+ yy=ix
+call B_2PA_3_fast_full(xx,yy,X,Y,Xci,Yci,nroot,B_list,counter_B,mu,nci,moci,ii,B6,F_ab,inv,nnv,iconf,maxconf)
+ B=B1+B2+B3+B4+B5+B6
+
+end subroutine TPA_resp_fast_full
+
+Subroutine A_2PA_1_fast_full(ix,iy,X,Y,Xci,Yci,nroot,A_list,counter_A,mu,nci,moci,ifreq,A,F_ij,ino,nno,iconf,maxconf)
+use commonresp
+use omp_lib
+implicit none
+
+integer ::ix,iy,nci,ifreq,moci,ino,nno,maxconf
+integer ::nroot
+real*8 ::A
+real*8 ::mu(moci*(moci+1)/2,3)
+real*8 ::X(nci,3)
+real*8 ::Y(nci,3)
+real*4 ::Xci(nci,nroot), Yci(nci,nroot)
+real*4 :: F_ij(ino*(ino+1)/2:nno*(nno+1)/2,4)
+integer ::i,ii
+integer*8 :: lin8
+integer ::iconf(maxconf,2)
+integer ::counter_A
+integer ::A_list(1:counter_A,1:3)
+
+ii=ifreq
+A=0.0
+!$omp parallel private(i) reduction(+:A)
+!$omp do
+ Do i=1,counter_A
+ A=A+X(A_list(i,1),ix)*(-mu(A_list(i,2),iy)&
+ &+dble(F_ij(lin8(iconf(A_list(i,1),1),iconf(A_list(i,3),1)),iy))&
+ &)*dble(Yci(A_list(i,3),ii))
+ enddo
+!$omp end do
+!$omp end parallel
+end subroutine A_2PA_1_fast_full
+
+Subroutine A_2PA_2_fast_full(ix,iy,X,Y,Xci,Yci,nroot,A_list,counter_A,mu,nci,moci,ifreq,A,F_ij,ino,nno,iconf,maxconf)
+use commonresp
+use omp_lib
+implicit none
+
+integer ::ix,iy,nci,ifreq,moci,ino,nno,maxconf
+integer ::nroot
+real*8 ::A
+real*8 ::mu(moci*(moci+1)/2,3)
+real*8 ::X(nci,3)
+real*8 ::Y(nci,3)
+real*4 ::Xci(nci,nroot), Yci(nci,nroot)
+real*4 :: F_ij(ino*(ino+1)/2:nno*(nno+1)/2,4)
+integer ::i,ii
+integer*8 :: lin8
+integer ::iconf(maxconf,2)
+integer ::counter_A
+integer ::A_list(1:counter_A,1:3)
+
+ii=ifreq
+A=0.0
+!$omp parallel private(i) reduction(+:A)
+!$omp do
+ Do i=1,counter_A
+ A=A+dble(Xci(A_list(i,1),ii))*(-mu(A_list(i,2),ix)&
+ &+dble(F_ij(lin8(iconf(A_list(i,1),1),iconf(A_list(i,3),1)),ix))&
+ &)*Y(A_list(i,3),iy)
+ enddo
+!$omp end do
+!$omp end parallel
+end subroutine A_2PA_2_fast_full
+
+Subroutine A_2PA_3_fast_full(ix,iy,X,Y,Xci,Yci,nroot,A_list,counter_A,mu,nci,moci,ifreq,A,F_ij,ino,nno,iconf,maxconf)
+use commonresp
+use omp_lib
+implicit none
+
+integer ::ix,iy,nci,ifreq,moci,ino,nno,maxconf
+integer ::nroot
+real*8 ::A
+real*8 ::mu(moci*(moci+1)/2,3)
+real*8 ::X(nci,3)
+real*8 ::Y(nci,3)
+real*4 ::Xci(nci,nroot), Yci(nci,nroot)
+real*4 :: F_ij(ino*(ino+1)/2:nno*(nno+1)/2,4)
+integer ::i,ii
+integer*8 :: lin8
+integer ::iconf(maxconf,2)
+integer ::counter_A
+integer ::A_list(1:counter_A,1:3)
+
+ii=ifreq
+A=0.0
+!$omp parallel private(i) reduction(+:A)
+!$omp do
+ Do i=1,counter_A
+ A=A+X(A_list(i,1),ix)*(&
+ &dble(F_ij(lin8(iconf(A_list(i,1),1),iconf(A_list(i,3),1)),4))&
+ &)*dble(Y(A_list(i,3),iy))
+ enddo
+!$omp end do
+!$omp end parallel
+end subroutine A_2PA_3_fast_full
+
+Subroutine B_2PA_1_fast_full(ix,iy,X,Y,Xci,Yci,nroot,B_list,counter_B,mu,nci,moci,ifreq,B,F_ab,inv,nnv,iconf,maxconf)
+use commonresp
+use omp_lib
+implicit none
+
+integer ::ix,iy,nci,ifreq,moci,inv,nnv,maxconf
+integer ::nroot
+real*8 ::B
+real*8 ::mu(moci*(moci+1)/2,3)
+real*8 ::X(nci,3)
+real*8 ::Y(nci,3)
+real*4 ::Xci(nci,nroot), Yci(nci,nroot)
+real*4 :: F_ab(inv*(inv+1)/2:nnv*(nnv+1)/2,4)
+integer ::i,ii
+integer*8 :: lin8
+integer ::iconf(maxconf,2)
+integer ::counter_B
+integer ::B_list(1:counter_B,1:3)
+
+ii=ifreq
+B=0.0
+!$omp parallel private(i) reduction(+:B)
+!$omp do
+ Do i=1,counter_B
+ B=B+X(B_list(i,1),ix)*(-mu(B_list(i,2),iy)&
+ &+dble(F_ab(lin8(iconf(B_list(i,1),2),iconf(B_list(i,3),2)),iy))&
+ &)*dble(Yci(B_list(i,3),ii))
+ enddo
+!$omp end do
+!$omp end parallel
+end subroutine B_2PA_1_fast_full
+
+Subroutine B_2PA_2_fast_full(ix,iy,X,Y,Xci,Yci,nroot,B_list,counter_B,mu,nci,moci,ifreq,B,F_ab,inv,nnv,iconf,maxconf)
+use commonresp
+use omp_lib
+implicit none
+
+integer ::ix,iy,nci,ifreq,moci,inv,nnv,maxconf
+integer ::nroot
+real*8 ::B
+real*8 ::mu(moci*(moci+1)/2,3)
+real*8 ::X(nci,3)
+real*8 ::Y(nci,3)
+real*4 ::Xci(nci,nroot), Yci(nci,nroot)
+real*4 :: F_ab(inv*(inv+1)/2:nnv*(nnv+1)/2,4)
+integer ::i,ii
+integer*8 :: lin8
+integer ::iconf(maxconf,2)
+integer ::counter_B
+integer ::B_list(1:counter_B,1:3)
+
+ii=ifreq
+B=0.0
+!$omp parallel private(i) reduction(+:B)
+!$omp do
+ Do i=1,counter_B
+ B=B+dble(Xci(B_list(i,1),ii))*(-mu(B_list(i,2),ix)&
+ &+dble(F_ab(lin8(iconf(B_list(i,1),2),iconf(B_list(i,3),2)),ix))&
+ &)*Y(B_list(i,3),iy)
+ enddo
+!$omp end do
+!$omp end parallel
+end subroutine B_2PA_2_fast_full
+
+Subroutine B_2PA_3_fast_full(ix,iy,X,Y,Xci,Yci,nroot,B_list,counter_B,mu,nci,moci,ifreq,B,F_ab,inv,nnv,iconf,maxconf)
+use commonresp
+use omp_lib
+implicit none
+
+integer ::ix,iy,nci,ifreq,moci,inv,nnv,maxconf
+integer ::nroot
+real*8 ::B
+real*8 ::mu(moci*(moci+1)/2,3)
+real*8 ::X(nci,3)
+real*8 ::Y(nci,3)
+real*4 ::Xci(nci,nroot), Yci(nci,nroot)
+real*4 :: F_ab(inv*(inv+1)/2:nnv*(nnv+1)/2,4)
+integer ::i,ii
+integer*8 :: lin8
+integer ::iconf(maxconf,2)
+integer ::counter_B
+integer ::B_list(1:counter_B,1:3)
+
+ii=ifreq
+B=0.0
+!$omp parallel private(i) reduction(+:B)
+!$omp do
+ Do i=1,counter_B
+ B=B+X(B_list(i,1),ix)*(&
+ &+dble(F_ab(lin8(iconf(B_list(i,1),2),iconf(B_list(i,3),2)),4))&
+ &)*dble(Y(B_list(i,3),iy))
+ enddo
+!$omp end do
+!$omp end parallel
+end subroutine B_2PA_3_fast_full
diff --git a/INFO b/INFO
index 6ebf6c1..6cdf21d 100755
--- a/INFO
+++ b/INFO
@@ -5,27 +5,53 @@
26.08.2014: Version 1.3:
- -Interfacing with Gaussian 09 possible (via g2molden)
+ -Interfacing with Gaussian 09 possible (via g2molden)
29.10.2014: Version 1.4:
-sTDA program is now interfaced to TeraChem
-Eigenvectors may be printed (Turbomole format)
- -small bugfixes
+ -small bugfixes
-01.03.2016: Version 1.5:
+01.03.2016: Version 1.5:
- -xTB
- -velocity correction
+ -xTB
+ -velocity correction
-make UKS available to public
-
+
13.02.2018: Version 1.6:
- linear and nonlinear response function (SHG)
- two-photon absorption
-
+
26.11.2019: Version 1.6.1:
-
+
- state to state transitions
- SF-sTD-DFT
- NTOs
+
+10.09.2020: Version 1.6.2:
+
+ - evaluation of the molecular optical rotation
+ - for spin-flip states
+ - speed-up for the response function deck
+
+10.10.2022: Version 1.6.3:
+
+ - evaluation of the two-photon cross-sections (now fully working)
+ - RespA approach for the interpretation of molecular response properties
+ - dual-threshold method for the efficient treatment of large systems
+ - polarizability bug fixed
+
+12.09.2023: Version 1.6.3.3:
+
+ - Sources corrected for NTOs with dual threshold
+ - Sign error in the response part of the calculation of 2PA strengths is corrected
+
+08.01.2024: Version 2.0.0:
+
+ - interfaced by default to libcint (magnetic moment one-electron integrals still computed with the old integral deck)
+ - XsTDA (restricted and unrestricted[only excited states]) for global hybrids and range-separated hybrids
+ - XsTD-DFT (restricted and unrestricted[only excited states]) for global hybrids and range-separated hybrids
+ - SF-XsTD-DFT for global hybrids
+ - CAM-B3LYP, wB97X-D2, wB97X-D3, wB97MV, SRC2R1, and SRC2R2 RSH functionals natively implemented with XsTD
diff --git a/Makefile b/Makefile
index 075305f..b91ce42 100755
--- a/Makefile
+++ b/Makefile
@@ -1,47 +1,45 @@
-
-PROG = stda
-
+PROG = std2
OSTYPE=LINUXI
-#--------------------------------------------------------------------------
-#-------------------------------------------------------------------------
+#--------------------------------------------------------------------------
+# see https://www.intel.com/content/www/us/en/developer/tools/oneapi/onemkl-link-line-advisor.html details on these options
ifeq ($(OSTYPE),LINUXI)
- FC = ifort
- # FC = lfc
- CC = gcc
-
- ### multithread ###
- LINKER = ifort -static -qopenmp -I$(MKLROOT)/include/intel64/lp64 -I$(MKLROOT)/include
- LIBS = $(MKLROOT)/lib/intel64/libmkl_blas95_lp64.a $(MKLROOT)/lib/intel64/libmkl_lapack95_lp64.a -Wl,--start-group $(MKLROOT)/lib/intel64/libmkl_intel_lp64.a $(MKLROOT)/lib/intel64/libmkl_core.a $(MKLROOT)/lib/intel64/libmkl_intel_thread.a -Wl,--end-group -lpthread -lm
-
- ### sequential ###
- # LINKER = ifort -static
- # LIBS = ${MKLROOT}/lib/intel64/libmkl_blas95_lp64.a ${MKLROOT}/lib/intel64/libmkl_lapack95_lp64.a -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_lp64.a ${MKLROOT}/lib/intel64/libmkl_core.a $(MKLROOT)/lib/intel64/libmkl_sequential.a -Wl,--end-group -lpthread -lm
-
+ FC = ifx
+ CC = icx
+
+ ifdef USEILP64
+ LINKER = ifx -Bdynamic $(CURDIR)/libcint/build/libcint.so -Bstatic
+ LIBS = -Wl,--start-group ${MKLROOT}/lib/libmkl_intel_ilp64.a ${MKLROOT}/lib/libmkl_intel_thread.a ${MKLROOT}/lib/libmkl_core.a -Wl,--end-group -liomp5
+ FFLAGS = -O3 -qopenmp -I$(MKLROOT)/include/intel64/ilp64 -I$(MKLROOT)/include -i8
+ else
+ LINKER = ifx -Bdynamic $(CURDIR)/libcint/build/libcint.so -Bstatic
+ LIBS = -Wl,--start-group ${MKLROOT}/lib/libmkl_intel_lp64.a ${MKLROOT}/lib/libmkl_intel_thread.a ${MKLROOT}/lib/libmkl_core.a -Wl,--end-group -liomp5
+ FFLAGS = -O3 -qopenmp -I$(MKLROOT)/include/intel64/lp64 -I$(MKLROOT)/include
+ endif
+
CFLAGS = -O -DLINUX
- FFLAGS = -O3 -qopenmp -I$(MKLROOT)/include/intel64/lp64 -I$(MKLROOT)/include
endif
ifeq ($(OSTYPE),MACOS)
- FC = ifort
- CC = gcc
- LINKER = ifort -qopenmp -I$(MKLROOT)/include/intel64/lp64 -I$(MKLROOT)/include
- LIBS = ${MKLROOT}/lib/libmkl_blas95_lp64.a ${MKLROOT}/lib/libmkl_intel_lp64.a ${MKLROOT}/lib/libmkl_intel_thread.a ${MKLROOT}/lib/libmkl_core.a -liomp5 -lpthread -lm -ldl
+ FC = ifx
+ CC = gcc
+ LINKER = ifx -qopenmp -I$(MKLROOT)/include/intel64/lp64 -I$(MKLROOT)/include
+ LIBS = ${MKLROOT}/lib/libmkl_blas95_lp64.a ${MKLROOT}/lib/libmkl_intel_lp64.a ${MKLROOT}/lib/libmkl_intel_thread.a ${MKLROOT}/lib/libmkl_core.a -liomp5 -lpthread -ldl -lm
PREFLAG = -E -P
FFLAGS = -O3 -qopenmp -I$(MKLROOT)/include/intel64/lp64 -I$(MKLROOT)/include #-check all
- FFLAGS = -O3 -I${MKLROOT}/include/intel64/lp64 -I${MKLROOT}/include
+ FFLAGS = -O3 -I${MKLROOT}/include/intel64/lp64 -I${MKLROOT}/include
CCFLAGS = -O3 -DLINUX
endif
#################################################
OBJS=\
stdacommon.o stringmod.o main.o pckao.o \
- header.o intpack.o velo.o \
+ header.o intpack.o velo.o libcint.o \
onetri.o prmat.o readl.o block.o\
stda.o stda-rw.o stda-rw_dual.o sutda.o sfstda.o srpapack.o intslvm.o io.o\
- linal.o readbasa.o readbasmold.o printvec.o normalize.o\
- apbtrafo.o sosor.o readxtb.o linear_response.o molden.o print_nto.o
+ linal.o readbasa.o readbasmold.o printvec.o normalize.o 2PA.o\
+ apbtrafo.o sosor.o readxtb.o linear_response.o molden.o print_nto.o xstd.o full.o
#################################################
%.o: %.f90
@@ -51,7 +49,7 @@ OBJS=\
@echo "making $@ from $<"
$(FC) $(FFLAGS) -c $< -o $@
-$(PROG): $(OBJS)
+$(PROG): $(OBJS)
@echo "Loading $(PROG) ... "
@$(LINKER) $(OBJS) $(LIBS) -o $(PROG)
diff --git a/README.md b/README.md
index 9e244e5..d4173f6 100755
--- a/README.md
+++ b/README.md
@@ -1,72 +1,165 @@
-# *stda* program for computing excited states and response functions via simplified TD-DFT methods (sTDA, sTD-DFT, and SF-sTD-DFT)[![DOI](https://zenodo.org/badge/221426808.svg)](https://doi.org/10.5281/zenodo.4022460)
+# *std2* program for computing excited states and response functions via simplified TD-DFT methods (sTDA, sTD-DFT, SF-sTD-DFT, XsTDA, XsTD-DFT, and SF-Xs-TD-DFT)
-This project provides the `stda` program.
+This project provides the `std2` program.
+
+The `std2` program is the rebranded and updated version of the `stda` program. Originally, `stda` was implemented only for the simplified time-dependent density functional theory using the Tamm-Dancoff approximation (sTDA) method. With the implementation of more simplified quantum chemistry (sQC) methods in `stda`, the name was not fitting the application of the program anymore.
## Installation
-Statically linked binaries can be found at the projects
-[release page](https://github.com/grimme-lab/stda/releases/latest).
-To build from source this project uses a `make` based build system and requires
-a version of Intel Parallel Studio 17 or newer to be compiled.
-To trigger the build run in the root directory
+Two options exist: `make` or `meson`.
+
+### Using `make` (and the intel compiler)
+
+For that option, you need:
+
++ [`cmake`](https://cmake.org/),
++ the latest intel oneAPI Fortran compiler, `ifx` (**not** `ifort`), with `MKL`.
+
+Then, you need to download the library to compute one- and two-electron integrals : `libcint`:
+
+```bash
+# create a `libcint` directory, then download sources in it
+mkdir libcint
+cd libcint
+wget https://github.com/pierre-24/libcint-meson/releases/download/v0.3.0/libcint_v6.1.2.tar.gz -O libcint.tar.gz
+tar -xzf libcint.tar.gz
+```
+
+The next step depends on your target.
+The default (32 bits integers, `LP64`) use a bit less memory but limits the size of the system you can treat.
+If you target large system, use the 64 bit integers (`ILP64`) instead.
+
+#### 32 bit integers (default, `LP64`)
+
+First, build `libcint`:
```bash
+# use intel
+export CC=icx
+
+# In the libcint directory, create a build directory and build `libcint` in it (using cmake)
+mkdir build
+cd build
+cmake ..
+cmake --build .
+```
+
+Then, compile `std2` itself:
+
+```bash
+# go back
+cd ../..
+
+# make std2
make
```
-You will find a statically linked executable named `stda`.
-To make `stda` accessible export
+#### 64 bit integers (`ILP64`) for larger calculations
+
+First, build `libcint` with the option for 64 bits integers:
+
+```bash
+export CC=icx
+
+# In the libcint directory, create a build directory and build `libcint` in it (using cmake)
+mkdir build
+cd build
+cmake .. -DI8=true
+cmake --build .
+```
+
+Then, compile `std2` itself:
+
+```bash
+# go back
+cd ../..
+
+# make std2 (using ILP64)
+make USEILP64=1
+```
+Troubleshootings:
+
+In some cases, the path to libraries is a bit different and the Makefile should be adapted as
+
+```
+LIBS = -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_ilp64.a ${MKLROOT}/lib/intel64/libmkl_intel_thread.a ${MKLROOT}/lib/intel64/libmkl_core.a -Wl,--end-group -liomp5
+```
+
+#### Run
+
+You will find a executable named `std2` in this folder.
+To make `std2` accessible, do:
```bash
-export STDAHOME=$PWD
-export PATH=$PATH:$STDAHOME
+export STD2HOME=/path/to/std2/folder
+export LD_LIBRARY_PATH=$STD2HOME/libcint/build:$LD_LIBRARY_PATH
+export PATH=$PATH:$STD2HOME
```
-### Alternatives
+in your `.bashrc` or submission scripts.
+
+### Using `meson` (and any compiler)
+
+**Note that for the moment, it is not possible to use Meson to compile the 64 bit version with `ifx` (see [there](https://github.com/mesonbuild/meson/issues/13052))**
-If you are not a fan of `make`, you can use [`meson`](https://mesonbuild.com/)
-as alternative, but it requires a fairly new version like 0.49 or newer for a
-decent Fortran support.
-For the default backend [`ninja`](https://ninja-build.org/) version 1.5 or newer
-has to be provided.
+If you are not found of `make`, you can use [`meson`](https://mesonbuild.com/) and [`ninja`](https://ninja-build.org/) instead.
+Other advantages include: automatic `libcint` import, more flexibility on the linear algebra backend and `gfortran` instead of intel.
-To perform a build run:
+First of all, if you want to use other compilers than `gfortran`, use:
```bash
-export FC=ifort
-meson setup build_intel
-ninja -C build_intel
+# for latest version of intel compilers
+export FC=ifx CC=icx
+
+# for older versions of intel compilers
+export FC=ifort CC=icc
```
-You may also consider to add the following option to `meson`:
+Then, pick one of the `meson setup` line below:
+
+```bash
+# netlib BLAS and LAPACK, 32 bits integers
+meson setup _build -Dla_backend=netlib
+
+# openblas and netlib LAPACK, 32 bits integers
+meson setup _build -Dla_backend=openblas
+
+# MKL, 32 bits integers
+meson setup _build -Dla_backend=mkl
+
+# MKL, 64 bits integers (ILP64)
+meson setup _build -Dla_backend=mkl -Dinterface=64
+```
-+ `-Dinterface=64` to use 64 bit integers,
-+ `-Dstatic=false` to use dynamic libraries (usefull if you get error such as `ld: cannot find -lpthread` at the linking stage of `ninja`),
-+ `-Dfortran_link_args=-qopenmp`(useful if you use OneAPI 2021 or latter, and meson ends with `Fortran shared or static library 'mkl_intel_thread' not found`).
+You can also:
++ generate a statically linked executable by adding `-Dstatic=true` (only with MKL), or
++ disable OpenMP (not recommended) by adding `-Dopenmp=false`.
-To install the `stda` binaries to `/usr/local` use (might require `sudo`)
+And finally, compile everything with
```bash
-ninja -C build_intel install
+meson compile -C _build
```
-For a local installation (or if you want to pack a release), modify the
-configuration by using
+#### Run
+
+You will an executable named `std2` in the `_build` directory.
+To make `std2` accessible, export
```bash
-meson configure build_intel --prefix=/
-DESTDIR=$HOME/.local ninja -C build_intel install
+export STD2HOME=/path/to/std2/folder
+export PATH=$PATH:$STD2HOME/_build/
```
-The build system will generate binary files in `$DESTDIR/bin` (don't forget to add that to `PATH` if it is not the case).
+in your `.bashrc` or submission scripts.
## Usage
For parallel usage set the threads for OMP and the MKL linear algebra backend by
```bash
-export OMP_NUM_THREADS= MKL_NUM_THREADS=
+export OMP_NUM_THREADS=
```
For larger systems please adjust the stack size accordingly, otherwise
@@ -90,32 +183,50 @@ See the manual on the [release page](https://github.com/grimme-lab/stda/releases
- S. Grimme and C. Bannwarth, Ultra-fast computation of electronic spectra for large systems by tight-binding based simplified Tamm-Dancoff approximation (sTDA-xTB) *J. Chem. Phys.*, **2016**, 145, 054103.
DOI: [10.1063/1.4959605](https://dx.doi.org/10.1063/1.4959605)
-- M. de Wergifosse, C. Bannwarth, S. Grimme, A simplified spin-flip time-dependent density functional theory (SF-sTD-DFT) approach for the electronic excitation spectra of very large diradicals, *J. Phys. Chem. A*, **2019**, 123 (27), 815–5825.
- DOI: [10.1021/acs.jpca.9b03176](https://doi.org/10.1021/acs.jpca.9b03176)
-
- M. de Wergifosse, S. Grimme, Nonlinear-response properties in a simplified time-dependent density functional theory (sTD-DFT) framework: Evaluation of the first hyperpolarizability, *J. Chem. Phys.*, **2018**, 149 (2), 024108.
DOI: [10.1063/1.5037665](https://doi.org/10.1063/1.5037665)
- M. de Wergifosse, S. Grimme, Nonlinear-response properties in a simplified time-dependent density functional theory (sTD-DFT) framework: Evaluation of excited-state absorption spectra, *J. Chem. Phys.*, **2019**, 150, 094112.
DOI: [10.1063/1.5080199](https://doi.org/10.1063/1.5080199)
+- M. de Wergifosse, C. Bannwarth, S. Grimme, A simplified spin-flip time-dependent density functional theory (SF-sTD-DFT) approach for the electronic excitation spectra of very large diradicals, *J. Phys. Chem. A*, **2019**, 123 (27), 815–5825.
+ DOI: [10.1021/acs.jpca.9b03176](https://doi.org/10.1021/acs.jpca.9b03176)
+
+- M. de Wergifosse, J. Seibert, B. Champagne, and S. Grimme, Are fully conjugated expanded indenofluorenes analogues and diindeno[n]thiophene derivatives diradicals? A simplified (spin-flip) time-dependent density functional theory [(SF-)sTD-DFT] study, *J. Phys. Chem. A*, **2019**, 123 (45), 9828-9839.
+ DOI: [DOI: 10.1021/acs.jpca.9b08474](https://doi.org/10.1021/acs.jpca.9b08474)
+
- M. de Wergifosse, J. Seibert, S. Grimme, Simplified time-dependent density functional theory (sTD-DFT) for molecular optical rotation, *J. Chem. Phys.*, **2020**, 153, 084116.
DOI: [10.1063/5.0020543](https://doi.org/10.1063/5.0020543)
- M. de Wergifosse, S. Grimme, A unified strategy for the chemically intuitive interpretation of molecular optical response properties, *J. Chem. Theory Comput.*, **2020**, 16 (12), 7709–7720.
DOI: [10.1021/acs.jctc.0c00990](https://doi.org/10.1021/acs.jctc.0c00990)
-- M. de Wergifosse, P. Beaujean, S. Grimme, Ultrafast evaluation of two-photon absorption with simplified time-dependent density functional theory, *J. Phys. Chem. A*, **2022**, XX, XXXX.
+- M. de Wergifosse, S. Grimme, Perspective on simplified quantum chemistry methods for excited states and response properties, *J. Phys. Chem. A*, **2021**, *J. Phys. Chem. A*, **2021**, 125 (18) 3841–3851.
+ DOI: [10.1021/acs.jpca.1c02362](https://doi.org/10.1021/acs.jpca.1c02362)
+
+- P. Beaujean, B. Champagne, S. Grimme, and M. de Wergifosse, All-atom quantum mechanical calculation of the second-harmonic generation of fluorescent proteins, *J. Phys. Chem. Lett.*, **2021**, 12 (39), 9684-9690.
+ DOI: [10.1021/acs.jpclett.1c02911](https://doi.org/10.1021/acs.jpclett.1c02911)
+
+- M. de Wergifosse, P. Beaujean, S. Grimme, Ultrafast evaluation of two-photon absorption with simplified time-dependent density functional theory, *J. Phys. Chem. A*, **2022**, 126 (41) 7534–7547.
DOI: [10.1021/acs.jpca.2c02395](https://doi.org/10.1021/acs.jpca.2c02395)
+- S. Löffelsender, P. Beaujean, M. de Wergifosse. Simplified quantum chemistry methods to evaluate non-linear optical properties of large systems, *WIREs Comput Mol Sci.* **2024**, 14 (1) e1695.
+ DOI: [10.1002/wcms.1695](https://doi.org/10.1002/wcms.1695)
+
+- M. de Wergifosse, S. Grimme, The eXact integral simplified time-dependent density functional theory (XsTD-DFT), *J. Chem. Phys.*, **2024**, 160, 204110.
+ DOI: [10.1063/5.0206380](https://doi.org/10.1063/5.0206380)
+
+- M. de Wergifosse, Computing excited states of very large systems with range-separated hybrid functionals and the eXact integral simplified time-dependent density functional theory (XsTD-DFT), *J. Phys. Chem. Lett.*, **2024**, 15, (51) 12628–12635.
+ DOI: [10.1021/acs.jpclett.4c03193](https://doi.org/10.1021/acs.jpclett.4c03193)
+
## License
-`stda` is free software: you can redistribute it and/or modify it under
+`std2` is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
-`stda` is distributed in the hope that it will be useful,
+`std2` is distributed in the hope that it will be useful,
but without any warranty; without even the implied warranty of
merchantability or fitness for a particular purpose. See the
GNU Lesser General Public License for more details.
@@ -129,15 +240,16 @@ Before opening a bug report:
1. Check if the issue has already been reported.
2. Check if it still is an issue or has already been fixed?
- Try to reproduce it with the latest version from the `master` branch.
+ Try to reproduce it with the latest version from the `main` branch.
3. Isolate the problem and create a reduced test case.
A good bug report should not leave others needing to chase you up for more
information. So please try to be as detailed as possible in your report,
answer at least these questions:
-1. Which version of `stda` are you using? The current version is always
+1. Which version of `std2` are you using? The current version is always
a subject to change, so be more specific.
+ If possible, also provide the *commit*.
2. What is your environment (your laptop, the cluster of the university)?
3. What steps will reproduce the issue?
We have to reproduce the issue, so we need all the input files.
diff --git a/apbtrafo.f b/apbtrafo.f
index 129d4e6..2e66f0a 100755
--- a/apbtrafo.f
+++ b/apbtrafo.f
@@ -1,20 +1,21 @@
-! This file is part of stda.
+! This file is part of std2.
!
-! Copyright (C) 2013-2019 Stefan Grimme
+! Copyright (C) 2013-2025 Stefan Grimme and Marc de Wergifosse
!
-! stda is free software: you can redistribute it and/or modify it under
+! std2 is free software: you can redistribute it and/or modify it under
! the terms of the GNU Lesser General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
-! stda is distributed in the hope that it will be useful,
+! std2 is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
-! along with stda. If not, see .
+! along with std2. If not, see .
!
+!! ------------------------------------------------------------------------
ccccccccccccccccccccccccccccccccccc
! Correct TDA eigenvector for Rv c
! (A+0.5*B)/omega * X c
@@ -45,7 +46,7 @@ subroutine apbtrafo(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
************** read B matrix (packed) **************************
open(unit=52,file='bmat',form='unformatted',status='old')
- read(52)bmat
+ read(52)bmat
close(52,status='delete')
******************************************************************
@@ -54,12 +55,12 @@ subroutine apbtrafo(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
call spack2tri(n,bmat,upper) ! blow up matrix, but we only need upper triangle
deallocate(bmat)
allocate(xnew(n,nroot))
- call ssymm('l','u',n,nroot,1.0e0,upper,n,x,n,0.e0,xnew,n)
+ call ssymm('l','u',n,nroot,1.0e0,upper,n,x,n,0.e0,xnew,n)
deallocate(upper)
******************************************************************
!
!******************** scale with omega_TDA ************************
-! compute divide by omega_TDA to yield X_new
+! compute divide by omega_TDA to yield X_new
do i=1,nroot
ef=1.0d0/(dble(e(i))+1.0d-8)
do j=1,n
@@ -68,7 +69,7 @@ subroutine apbtrafo(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
enddo
!******************************************************************
!
-!!! OLD ORTHOGONALIZATION PART - NOT USED ANYMORE
+!!! OLD ORTHOGONALIZATION PART - NOT USED ANYMORE
!
************** compute overlap: S = (X_new)**T * (X_new) *********
! allocate(upper(nroot,nroot))
@@ -89,7 +90,7 @@ subroutine apbtrafo(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
!******************************************************************
!!
!************** orthogonalize vector: X' = X_new * U**-1 **********
-! call strsm('R','U','N','N',n, nroot,1.0,upper,nroot,xnew,n)
+! call strsm('R','U','N','N',n, nroot,1.0,upper,nroot,xnew,n)
!*****************************************************************
!
!*********** check orthogonality *****************
@@ -97,7 +98,7 @@ subroutine apbtrafo(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
! upper=0.0
! call sgemm('T','n',nroot,nroot,n,1.0,xnew,n,xnew,n,0.0,
! . upper,nroot)
-!
+!
!
! do i=1,min(12,nroot)
! write(*,'(12f10.6)') (upper(j,i),j=1,min(12,nroot))
@@ -170,7 +171,7 @@ subroutine apbtrafo(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
write(27,*)'SHIFT'
write(27,*)' 0.00'
write(27,*)'DATXY'
- endif
+ endif
p23=ak* 2.0d0/3.0d0
do i=1,nroot
@@ -179,7 +180,7 @@ subroutine apbtrafo(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
ef=1.0d0/(de+1.0d-8)
! damp exponent from -1 to 0 for small energies
hilf=1.0d0-exp(-150.0d0*de*de)
- efmod=1.0d0/((de**hilf)+1.0d-8)
+ efmod=1.0d0/((de**hilf)+1.0d-8)
xlp=0.0d0
ylp=0.0d0
zlp=0.0d0
@@ -217,18 +218,18 @@ subroutine apbtrafo(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
unew=dble(xnew(j,i))
uold=dble(x(j,i))
ij=lin8(io,iv)
-! A+B transformed stuff
+! A+B transformed stuff
xlp=xlp+xl(ij)*uold
ylp=ylp+yl(ij)*uold
zlp=zlp+zl(ij)*uold
- xvp=xvp+xv(ij)*uold
+ xvp=xvp+xv(ij)*uold
yvp=yvp+yv(ij)*uold
zvp=zvp+zv(ij)*uold
xmp=xmp+xm(ij)*uold
ymp=ymp+ym(ij)*uold
- zmp=zmp+zm(ij)*uold
- xvp2=xvp2+xv(ij)*unew
- yvp2=yvp2+yv(ij)*unew
+ zmp=zmp+zm(ij)*uold
+ xvp2=xvp2+xv(ij)*unew
+ yvp2=yvp2+yv(ij)*unew
zvp2=zvp2+zv(ij)*unew
xmp2=xmp2+xm(ij)*unew
ymp2=ymp2+ym(ij)*unew
@@ -284,7 +285,7 @@ subroutine apbtrafo(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
write(26,'(i4,F10.4,4f13.6)')i,de*27.21139,fly,fvy,rly,rvy
write(27,'(i4,F10.4,4f13.6)')i,de*27.21139,flz,fvz,rlz,rvz
endif
- enddo
+ enddo
close(28)
if(aniso)then
close(25)
@@ -292,7 +293,7 @@ subroutine apbtrafo(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
close(27)
write(*,*)'data given such that f = (f_x + f_y + f_z)/3'
write(*,*)' and R = R_x + R_y + R_z'
- endif
+ endif
deallocate(xnew)
end subroutine apbtrafo
@@ -346,7 +347,7 @@ subroutine apbtrafo_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva,zva,
************** read 0.5*B matrix (packed) ***********************
open(unit=52,file='bmat',form='unformatted',status='old')
- read(52)bmat
+ read(52)bmat
close(52,status='delete')
******************************************************************
@@ -355,12 +356,12 @@ subroutine apbtrafo_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva,zva,
call spack2tri(n,bmat,upper) ! blow up matrix, but we only need upper triangle
deallocate(bmat)
allocate(xnew(n,nroot))
- call ssymm('l','u',n,nroot,1.e0,upper,n,x,n,0.e0,xnew,n)
+ call ssymm('l','u',n,nroot,1.e0,upper,n,x,n,0.e0,xnew,n)
deallocate(upper)
******************************************************************
!
******************** scale with omega_TDA ************************
-! divide by omega_TDA to yield X_new
+! divide by omega_TDA to yield X_new
do i=1,nroot
ef=1.0d0/(dble(e(i))+1.0d-8)
do j=1,n
@@ -386,7 +387,7 @@ subroutine apbtrafo_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva,zva,
!******************************************************************
!!
!************** orthogonalize vector: X' = X_new * U**-1 **********
-! call strsm('R','U','N','N',n, nroot,1.0,upper,nroot,xnew,n)
+! call strsm('R','U','N','N',n, nroot,1.0,upper,nroot,xnew,n)
!******************************************************************
!!
!*********** check orthogonality *****************
@@ -394,7 +395,7 @@ subroutine apbtrafo_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva,zva,
!! upper=0.0
!! call sgemm('T','n',nroot,nroot,n,1.0,xnew,n,xnew,n,0.0,
!! . upper,nroot)
-!!
+!!
!!
!! do i=1,min(12,nroot)
!! write(*,'(12f10.6)') (upper(j,i),j=1,min(12,nroot))
@@ -422,7 +423,7 @@ subroutine apbtrafo_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva,zva,
write(28,*)'SHIFT'
write(28,*)' 0.00'
write(28,*)'DATXY'
-
+
p23=2.0d0/3.0d0
do i=1,nroot
! A+B transformed stuff
@@ -469,12 +470,12 @@ subroutine apbtrafo_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva,zva,
unew=dble(xnew(j,i))
uold=dble(x(j,i))
ij=lin8(io,iv)
-! A+B transformed stuff
+! A+B transformed stuff
xlp=xlp+xla(ij)*uold
ylp=ylp+yla(ij)*uold
- zlp=zlp+zla(ij)*uold
- xvp=xvp+xva(ij)*uold
- yvp=yvp+yva(ij)*uold
+ zlp=zlp+zla(ij)*uold
+ xvp=xvp+xva(ij)*uold
+ yvp=yvp+yva(ij)*uold
zvp=zvp+zva(ij)*uold
xmp=xmp+xma(ij)*uold
ymp=ymp+yma(ij)*uold
@@ -494,11 +495,11 @@ subroutine apbtrafo_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva,zva,
unew=dble(xnew(k,i))
uold=dble(x(k,i))
ij=lin8(io,iv)
-! A+B transformed stuff
+! A+B transformed stuff
xlp=xlp+xlb(ij)*uold
ylp=ylp+ylb(ij)*uold
zlp=zlp+zlb(ij)*uold
- xvp=xvp+xvb(ij)*uold
+ xvp=xvp+xvb(ij)*uold
yvp=yvp+yvb(ij)*uold
zvp=zvp+zvb(ij)*uold
xmp=xmp+xmb(ij)*uold
@@ -560,7 +561,7 @@ subroutine apbtrafo_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva,zva,
write(26,'(i4,F10.4,4f13.6)')i,de*27.21139,fly,fvy,rly,rvy
write(29,'(i4,F10.4,4f13.6)')i,de*27.21139,flz,fvz,rlz,rvz
endif
- enddo
+ enddo
close(28)
if(aniso)then
close(25)
@@ -568,7 +569,7 @@ subroutine apbtrafo_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva,zva,
close(29)
write(*,*)'data given such that f = (f_x + f_y + f_z)/3'
write(*,*)' and R = R_x + R_y + R_z'
- endif
+ endif
deallocate(xnew)
end subroutine apbtrafo_uks
@@ -595,9 +596,9 @@ subroutine rtdacorr(nci,ncent,no,nv,mxcnf,iconf,dak,dax
if(ierr.ne.0)stop 'allocation for qkj/bmat crashed'
ak=real(dak)
ax=real(dax)
-! calculate 0.5*B
+! calculate 0.5*B
bmat=0.0e0
- fact=0.50d0 ! this is the scaling of the B-contribution
+ fact=0.50d0 ! this is the scaling of the B-contribution
open(unit=52,file='bmat',form='unformatted',status='replace')
ij=0
!$omp parallel private(ij,i,j,io,iv,jo,jv,iiv,iwrk,jjv,jwrk,qk,qj,ek,ej)
@@ -623,11 +624,11 @@ subroutine rtdacorr(nci,ncent,no,nv,mxcnf,iconf,dak,dax
bmat(ij)=bmat(ij)-fact*ax*ek ! scaled by ax
enddo
ij=lin8(i,i)
- ek=sdot(ncent,qk,1,qia(1,iwrk),1)
+ ek=sdot(ncent,qk,1,qia(1,iwrk),1)
bmat(ij)=fact*(ak*ek-ax*ek) ! diagonal element of 0.5*B
enddo
!$omp end do
-!$omp end parallel
+!$omp end parallel
write(52)bmat
close(52)
deallocate(bmat,qk,qj)
@@ -639,7 +640,7 @@ end subroutine rtdacorr
***********************************************************************
-* set up 0.5*B (packed form) in UKS case !
+* set up 0.5*B (packed form) in UKS case !
***********************************************************************
subroutine utdacorr(nexa,nexb,ncent,noa,nva,nob,nvb,mxcnfa,
. mxcnfb,iconfa,iconfb,dax,piaa,qiaa,
@@ -665,8 +666,8 @@ subroutine utdacorr(nexa,nexb,ncent,noa,nva,nob,nvb,mxcnfa,
allocate(qj(ncent),qk(ncent),bmat(ij), stat=ierr)
if(ierr.ne.0)stop 'allocation for qkj/bmat crashed'
ax=real(dax)
-! calculate 0.5*B
- fact=0.50e0 ! this is the scaling of the B-contribution
+! calculate 0.5*B
+ fact=0.50e0 ! this is the scaling of the B-contribution
bmat=0.0e0
open(unit=52,file='bmat',form='unformatted',status='replace')
ij=0
@@ -691,7 +692,7 @@ subroutine utdacorr(nexa,nexb,ncent,noa,nva,nob,nvb,mxcnfa,
qj(1:ncent)=piaa(1:ncent,jwrk)
jwrk=(jo-1)*nva+iiv
ek=sdot(ncent,qj,1,qiaa(1,jwrk),1) ! now ek = (ib|aj), results from Fock-exchange, thus we scale by ax
- bmat(ij)=bmat(ij)-fact*ax*ek
+ bmat(ij)=bmat(ij)-fact*ax*ek
enddo
ij=lin8(i,i)
ek=sdot(ncent,qk,1,qiaa(1,iwrk),1)
@@ -726,7 +727,7 @@ subroutine utdacorr(nexa,nexb,ncent,noa,nva,nob,nvb,mxcnfa,
jv=iconfb(j-nexa,2)
jjv=jv-nob
jwrk=(jo-1)*nvb + jjv
- ek=sdot(ncent,qk,1,qiab(1,jwrk),1)
+ ek=sdot(ncent,qk,1,qiab(1,jwrk),1)
bmat(ij)=(fact)*ek
jwrk=(io-1)*nvb+jjv
qj(1:ncent)=piab(1:ncent,jwrk)
@@ -740,7 +741,7 @@ subroutine utdacorr(nexa,nexb,ncent,noa,nva,nob,nvb,mxcnfa,
enddo
!$omp end do
!$omp end parallel
-! call prmat4(6,bmat,nexa+nexb,0,'A+ 0.5 * B')
+! call prmat4(6,bmat,nexa+nexb,0,'A+ 0.5 * B')
write(52)bmat
close(52)
deallocate(bmat,qj,qk)
@@ -778,7 +779,7 @@ subroutine apbtrafoexc(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
************** read B matrix (packed) **************************
open(unit=52,file='bmat',form='unformatted',status='old')
- read(52)bmat
+ read(52)bmat
close(52,status='delete')
******************************************************************
@@ -787,12 +788,12 @@ subroutine apbtrafoexc(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
call spack2tri(n,bmat,upper) ! blow up matrix, but we only need upper triangle
deallocate(bmat)
allocate(xnew(n,nroot))
- call ssymm('l','u',n,nroot,1.0e0,upper,n,x,n,0.e0,xnew,n)
+ call ssymm('l','u',n,nroot,1.0e0,upper,n,x,n,0.e0,xnew,n)
deallocate(upper)
******************************************************************
!
!******************** scale with omega_TDA ************************
-! compute divide by omega_TDA to yield X_new
+! compute divide by omega_TDA to yield X_new
do i=1,nroot
ef=1.0d0/(dble(e(i))+1.0d-8)
do j=1,n
@@ -800,7 +801,7 @@ subroutine apbtrafoexc(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
enddo
enddo
!******************************************************************
-
+
write(*,*)' writing trafoed spectral data to tda.dat ...'
open(unit=28,file='tda.dat',status='replace')
write(28,*)'NM'
@@ -862,7 +863,7 @@ subroutine apbtrafoexc(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
write(29,*)'SHIFT'
write(29,*)' 0.00'
write(29,*)'DATXY'
- endif
+ endif
allocate(q1(ncent))
q1=0.0e0
@@ -875,7 +876,7 @@ subroutine apbtrafoexc(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
ef=1.0d0/(de+1.0d-8)
! damp exponent from -1 to 0 for small energies
hilf=1.0d0-exp(-150.0d0*de*de)
- efmod=1.0d0/((de**hilf)+1.0d-8)
+ efmod=1.0d0/((de**hilf)+1.0d-8)
xlp=0.0d0
ylp=0.0d0
zlp=0.0d0
@@ -894,9 +895,9 @@ subroutine apbtrafoexc(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
zmp2=0.0d0
xvp2=0.0d0
yvp2=0.0d0
- zvp2=0.0d0
+ zvp2=0.0d0
xms=0.0d0
- yms=0.0d0
+ yms=0.0d0
zms=0.0d0
xmu=0.0d0
ymu=0.0d0
@@ -923,18 +924,18 @@ subroutine apbtrafoexc(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
unew=dble(xnew(j,i))
uold=dble(x(j,i))
ij=lin(io,iv)
-! A+B transformed stuff
+! A+B transformed stuff
xlp=xlp+xl(ij)*uold
ylp=ylp+yl(ij)*uold
zlp=zlp+zl(ij)*uold
- xvp=xvp+xv(ij)*uold
+ xvp=xvp+xv(ij)*uold
yvp=yvp+yv(ij)*uold
zvp=zvp+zv(ij)*uold
xmp=xmp+xm(ij)*uold
ymp=ymp+ym(ij)*uold
- zmp=zmp+zm(ij)*uold
- xvp2=xvp2+xv(ij)*unew
- yvp2=yvp2+yv(ij)*unew
+ zmp=zmp+zm(ij)*uold
+ xvp2=xvp2+xv(ij)*unew
+ yvp2=yvp2+yv(ij)*unew
zvp2=zvp2+zv(ij)*unew
xmp2=xmp2+xm(ij)*unew
ymp2=ymp2+ym(ij)*unew
@@ -1030,7 +1031,7 @@ subroutine apbtrafoexc(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
write(26,'(i4,F10.4,4f13.6)')i,de*27.21139,fly,fvy,rly,rvy
write(29,'(i4,F10.4,4f13.6)')i,de*27.21139,flz,fvz,rlz,rvz
endif
- enddo
+ enddo
close(28)
if(aniso)then
close(25)
@@ -1038,7 +1039,7 @@ subroutine apbtrafoexc(n,nroot,x,e,xl,yl,zl,xv,yv,zv,xm,ym,zm,xmss
close(29)
write(*,*)'data given such that f = (f_x + f_y + f_z)/3'
write(*,*)' and R = R_x + R_y + R_z'
- endif
+ endif
deallocate(xnew,q1)
end subroutine apbtrafoexc
@@ -1047,53 +1048,53 @@ subroutine apbtrafoexc_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva
. ,zva,xma,yma,zma,xlb,ylb,zlb,xvb,yvb,zvb,xmb,ymb,zmb,xmss
. ,noa,nva,nob,nvb,coc,ncent,qiaa,qiab,maxconfa,maxconfb,iconfa
. ,iconfb,rvpout)
- use commonlogicals
- implicit none
- integer, intent ( in ) :: maxconfa,maxconfb,n,na,nb,nroot
+ use commonlogicals
+ implicit none
+ integer, intent ( in ) :: maxconfa,maxconfb,n,na,nb,nroot
integer, intent ( in ) :: ncent,noa,nva,nob,nvb
- integer, intent ( in ) :: iconfa(maxconfa,2),iconfb(maxconfb,2)
- real*8, intent(in) :: xla(*),yla(*),zla(*)
- real*8, intent(in) :: xva(*),yva(*),zva(*)
- real*8, intent(in) :: xma(*),yma(*),zma(*)
- real*8, intent(in) :: xlb(*),ylb(*),zlb(*)
- real*8, intent(in) :: xvb(*),yvb(*),zvb(*)
- real*8, intent(in) :: xmb(*),ymb(*),zmb(*)
- real*4, intent(in) :: x(n,n),e(n),qiaa(ncent,na),qiab(ncent,nb)
- real*8, intent(in) :: xmss,coc(3)
- real*8, intent( out ) :: rvpout(nroot)
-
- integer i,j,k,l,ij,io,iv,lin
- real*8 de,ef,xp,xlp,ylp,zlp,xvp,yvp,zvp,xmp,ymp,zmp
+ integer, intent ( in ) :: iconfa(maxconfa,2),iconfb(maxconfb,2)
+ real*8, intent(in) :: xla(*),yla(*),zla(*)
+ real*8, intent(in) :: xva(*),yva(*),zva(*)
+ real*8, intent(in) :: xma(*),yma(*),zma(*)
+ real*8, intent(in) :: xlb(*),ylb(*),zlb(*)
+ real*8, intent(in) :: xvb(*),yvb(*),zvb(*)
+ real*8, intent(in) :: xmb(*),ymb(*),zmb(*)
+ real*4, intent(in) :: x(n,n),e(n),qiaa(ncent,na),qiab(ncent,nb)
+ real*8, intent(in) :: xmss,coc(3)
+ real*8, intent( out ) :: rvpout(nroot)
+
+ integer i,j,k,l,ij,io,iv,lin
+ real*8 de,ef,xp,xlp,ylp,zlp,xvp,yvp,zvp,xmp,ymp,zmp
real*8 xmu,ymu,zmu,xvu,yvu,zvu,xms,yms,zms
- real*8 xvp2,yvp2,zvp2,xmp2,ymp2,zmp2,hilf,efmod
- real*8 flp,fvp,rlp,rvp,p23,fact,unew,uold !,enew(nroot)
+ real*8 xvp2,yvp2,zvp2,xmp2,ymp2,zmp2,hilf,efmod
+ real*8 flp,fvp,rlp,rvp,p23,fact,unew,uold !,enew(nroot)
real*8 flx,fly,flz,fvx,fvy,fvz,rlx,rly,rlz,rvx,rvy,rvz ! resolved along the three orientations
- real*4, allocatable :: bmat(:),upper(:,:), xnew(:,:),q1(:)
+ real*4, allocatable :: bmat(:),upper(:,:), xnew(:,:),q1(:)
write(*,'(A)',advance='yes') ' perform velo correction for X...'
- rvpout=0.0d0
-
- allocate(bmat(n*(n+1)/2))
-
-************** read 0.5*B matrix (packed) ***********************
- open(unit=52,file='bmat',form='unformatted',status='old')
- read(52)bmat
- close(52,status='delete')
-******************************************************************
-
-************** blow up 0.5*B and compute (0.5*B)*X ***************
- allocate(upper(n,n))
- call spack2tri(n,bmat,upper) ! blow up matrix, but we only need upper triangle
- deallocate(bmat)
- allocate(xnew(n,nroot))
- call ssymm('l','u',n,nroot,1.e0,upper,n,x,n,0.e0,xnew,n)
- deallocate(upper)
-******************************************************************
-!
-******************** scale with omega_TDA ************************
-! divide by omega_TDA to yield X_new
- do i=1,nroot
- ef=1.0d0/(dble(e(i))+1.0d-8)
- do j=1,n
+ rvpout=0.0d0
+
+ allocate(bmat(n*(n+1)/2))
+
+************** read 0.5*B matrix (packed) ***********************
+ open(unit=52,file='bmat',form='unformatted',status='old')
+ read(52)bmat
+ close(52,status='delete')
+******************************************************************
+
+************** blow up 0.5*B and compute (0.5*B)*X ***************
+ allocate(upper(n,n))
+ call spack2tri(n,bmat,upper) ! blow up matrix, but we only need upper triangle
+ deallocate(bmat)
+ allocate(xnew(n,nroot))
+ call ssymm('l','u',n,nroot,1.e0,upper,n,x,n,0.e0,xnew,n)
+ deallocate(upper)
+******************************************************************
+!
+******************** scale with omega_TDA ************************
+! divide by omega_TDA to yield X_new
+ do i=1,nroot
+ ef=1.0d0/(dble(e(i))+1.0d-8)
+ do j=1,n
xnew(j,i)=ef*xnew(j,i)
enddo
enddo
@@ -1117,7 +1118,7 @@ subroutine apbtrafoexc_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva
allocate(q1(ncent))
q1=0.0e0
-
+
p23=2.0d0/3.0d0
do i=1,nroot
! A+B transformed stuff
@@ -1165,12 +1166,12 @@ subroutine apbtrafoexc_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva
unew=dble(xnew(j,i))
uold=dble(x(j,i))
ij=lin(io,iv)
-! A+B transformed stuff
+! A+B transformed stuff
xlp=xlp+xla(ij)*uold
ylp=ylp+yla(ij)*uold
- zlp=zlp+zla(ij)*uold
- xvp=xvp+xva(ij)*uold
- yvp=yvp+yva(ij)*uold
+ zlp=zlp+zla(ij)*uold
+ xvp=xvp+xva(ij)*uold
+ yvp=yvp+yva(ij)*uold
zvp=zvp+zva(ij)*uold
xmp=xmp+xma(ij)*uold
ymp=ymp+yma(ij)*uold
@@ -1192,11 +1193,11 @@ subroutine apbtrafoexc_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva
unew=dble(xnew(k,i))
uold=dble(x(k,i))
ij=lin(io,iv)
-! A+B transformed stuff
+! A+B transformed stuff
xlp=xlp+xlb(ij)*uold
ylp=ylp+ylb(ij)*uold
zlp=zlp+zlb(ij)*uold
- xvp=xvp+xvb(ij)*uold
+ xvp=xvp+xvb(ij)*uold
yvp=yvp+yvb(ij)*uold
zvp=zvp+zvb(ij)*uold
xmp=xmp+xmb(ij)*uold
@@ -1281,7 +1282,7 @@ subroutine apbtrafoexc_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva
write(26,'(i4,F10.4,4f13.6)')i,de*27.21139,fly,fvy,rly,rvy
write(29,'(i4,F10.4,4f13.6)')i,de*27.21139,flz,fvz,rlz,rvz
endif
- enddo
+ enddo
close(28)
if(aniso)then
close(25)
@@ -1289,8 +1290,6 @@ subroutine apbtrafoexc_uks(n,na,nb,nroot,x,e,xla,yla,zla,xva,yva
close(29)
write(*,*)'data given such that f = (f_x + f_y + f_z)/3'
write(*,*)' and R = R_x + R_y + R_z'
- endif
+ endif
deallocate(xnew,q1)
end subroutine apbtrafoexc_uks
-
-
diff --git a/block.f b/block.f
index 989a433..8adaa19 100755
--- a/block.f
+++ b/block.f
@@ -1,39 +1,40 @@
-! This file is part of stda.
+! This file is part of std2.
!
-! Copyright (C) 2013-2019 Stefan Grimme
+! Copyright (C) 2013-2025 Stefan Grimme and Marc de Wergifosse
!
-! stda is free software: you can redistribute it and/or modify it under
+! std2 is free software: you can redistribute it and/or modify it under
! the terms of the GNU Lesser General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
-! stda is distributed in the hope that it will be useful,
+! std2 is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
-! along with stda. If not, see .
+! along with std2. If not, see .
!
+!! ------------------------------------------------------------------------
BLOCK DATA
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
common /amass / ams(107)
- data ams / 1.00790d0, 4.00260d0, 6.94000d0, 9.01218d0,
- 110.81000d0, 12.01100d0, 14.00670d0, 15.99940d0, 18.99840d0,
- 220.17900d0, 22.98977d0, 24.30500d0, 26.98154d0, 28.08550d0,
- 330.97376d0, 32.06000d0, 35.45300d0, 39.94800d0, 39.09830d0,
- 440.08000d0, 44.95590d0, 47.90000d0, 50.94150d0, 51.99600d0,
- 554.93800d0, 55.84700d0, 58.93320d0, 58.71000d0, 63.54600d0,
- 665.38000d0, 69.73500d0, 72.59000d0, 74.92160d0, 78.96000d0,
- 779.90400d0, 83.80000d0, 85.46780d0, 87.62000d0, 88.90590d0,
- 891.22000d0, 92.90640d0, 95.94000d0, 98.90620d0, 101.0700d0,
- 9102.9055d0, 106.4000d0, 107.8680d0, 112.4100d0, 114.8200d0,
- 1118.6900d0, 121.7500d0, 127.6000d0, 126.9045d0, 131.3000d0,
- 2132.9054d0, 137.3300d0, 15*0.000d0, 178.4900d0, 180.9479d0,
- 3183.8500d0, 186.2070d0, 190.2000d0, 192.2200d0, 195.0900d0,
- 4196.9665d0, 200.5900d0, 204.3700d0, 207.2000d0, 208.9804d0,
- 518*0.000d0, 1.0079d0, 5*0.000d0/
+ data ams / 1.00790d0, 4.00260d0, 6.94000d0, 9.01218d0,
+ 110.81000d0, 12.01100d0, 14.00670d0, 15.99940d0, 18.99840d0,
+ 220.17900d0, 22.98977d0, 24.30500d0, 26.98154d0, 28.08550d0,
+ 330.97376d0, 32.06000d0, 35.45300d0, 39.94800d0, 39.09830d0,
+ 440.08000d0, 44.95590d0, 47.90000d0, 50.94150d0, 51.99600d0,
+ 554.93800d0, 55.84700d0, 58.93320d0, 58.71000d0, 63.54600d0,
+ 665.38000d0, 69.73500d0, 72.59000d0, 74.92160d0, 78.96000d0,
+ 779.90400d0, 83.80000d0, 85.46780d0, 87.62000d0, 88.90590d0,
+ 891.22000d0, 92.90640d0, 95.94000d0, 98.90620d0, 101.0700d0,
+ 9102.9055d0, 106.4000d0, 107.8680d0, 112.4100d0, 114.8200d0,
+ 1118.6900d0, 121.7500d0, 127.6000d0, 126.9045d0, 131.3000d0,
+ 2132.9054d0, 137.3300d0, 15*0.000d0, 178.4900d0, 180.9479d0,
+ 3183.8500d0, 186.2070d0, 190.2000d0, 192.2200d0, 195.0900d0,
+ 4196.9665d0, 200.5900d0, 204.3700d0, 207.2000d0, 208.9804d0,
+ 518*0.000d0, 1.0079d0, 5*0.000d0/
END
diff --git a/full.f b/full.f
new file mode 100644
index 0000000..2e85d45
--- /dev/null
+++ b/full.f
@@ -0,0 +1,1373 @@
+! This file is part of std2.
+!
+! Copyright (C) 2025 Marc de Wergifosse
+!
+! std2 is free software: you can redistribute it and/or modify it under
+! the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! std2 is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU Lesser General Public License for more details.
+!
+! You should have received a copy of the GNU Lesser General Public License
+! along with std2. If not, see .
+!
+!! ------------------------------------------------------------------------
+!!! (|) integrals are computed exactly, for testing purpose only, not optimized !!!!!!!!
+ subroutine rrpamat_full(nci,ncent,no,nv,mxcnf,iconf,dak,dax,ed,
+ . apb,ambsqr,ca,nao,moci,nprims,epsi)
+ use commonlogicals
+ use omp_lib
+ implicit none
+ integer, intent(in) :: nci,ncent,no,nv,mxcnf,iconf(mxcnf,2)
+ real*8, intent(in) :: dak,dax,ed(mxcnf)
+ real*4, intent(out) :: apb(nci*(nci+1)/2),ambsqr(nci*(nci+1)/2)
+ integer i,j,ij,io,iv,jo,jv,ierr,lin,iiv,jjv,iwrk,jwrk,a,b,k,l,ii
+ real*4 ek,ej,sdot,ak,ax,de
+ real*8 :: ca(nao*moci)
+ real*4, allocatable :: integral2(:,:,:,:)
+ integer :: nao, moci, nprims
+ integer*8 :: lin8
+ real*4 :: start_time,end_time,start,finished
+ integer :: m,n,o,p
+ real*4, allocatable :: iatemp1(:,:),itemp(:,:,:)
+ real*4, allocatable :: iatemp2(:,:)
+ real*4, allocatable :: iajtemp1(:),iajtemp2(:)
+ real*4, allocatable :: K_iajb(:,:,:,:)
+ real*4, allocatable :: J_ijab(:,:,:,:)
+ real*8 :: ddot
+ integer :: canon
+ real*8 :: wtime
+ integer :: ino,nno,inv,nnv
+ integer*8 :: counter
+ real*8 :: epsi(moci)
+
+ start_time=wtime()
+! call cpu_time(start)
+! Compute ( | ) integrals with lbcint
+ ! reduce the mo range to match the configuration space
+ ino=minval(iconf(1:nci,1))
+ nno=maxval(iconf(1:nci,1))
+ inv=minval(iconf(1:nci,2))-no
+ nnv=maxval(iconf(1:nci,2))-no
+! write(*,*)'MO integrals computed for occ.',ino,'to',nno
+! write(*,*)'and for unocc.',inv,'to',nnv
+
+ allocate(integral2(nno+1-ino,nao,nao,nao),stat=ierr)
+ if(ierr.ne.0)stop 'allocation failed for 2-e integrals'
+
+ call two_elec_int_i(ncent,nprims,nao,integral2,
+ .ino,nno,ca,moci)
+
+! call cpu_time(finished)
+ end_time=wtime()
+! print '("cpu time = ",f12.2," minutes.")'
+! . ,(finished-start)/60.0
+ print '("time = ",f12.2," minutes.")'
+ . ,(end_time-start_time)/60.0
+ start_time=wtime()
+ call cpu_time(start)
+
+
+ allocate(itemp(nao,nao,nao))
+ allocate(iatemp1(nao,nao))
+ allocate(iatemp2(nao,nao))
+ allocate(iajtemp1(nao))
+ allocate(iajtemp2(nao))
+
+
+
+ if(abs(dax).lt.1.0d-6) then
+ allocate(K_iajb(ino:nno,inv:nnv,ino:nno,inv:nnv))
+!$omp parallel private(ii,p,j,a,b,itemp,
+!$omp& iatemp1)
+!$omp& shared(ca,integral2,nao,no)
+!$omp do
+ Do ii=ino, nno
+ !(i.|..)
+ itemp(:,:,:)=integral2(ii,:,:,:)
+
+ Do a=inv, nnv
+ iatemp1=0.0
+ Do p=1,nao
+ !(ia|..)
+ call sgemv('T',nao,nao,1.0,itemp(:,:,p),nao,
+ .real(ca(1+(a+no-1)*nao:nao+(a+no-1)*nao),4),1,0.0,iatemp1(:,p),1)
+
+ Do j=ino, nno
+ iajtemp1=0.0
+ !(ia|j.)
+ call sgemv('T',nao,nao,1.0,iatemp1,nao,
+ .real(ca(1+(j-1)*nao:nao+(j-1)*nao),4),1,0.0,iajtemp1,1)
+ enddo
+
+ Do b=inv, nnv
+ !(ia|jb)
+ K_iajb(ii,a,j,b)=sdot(nao,iajtemp1,1,
+ . real(ca(1+(b+no-1)*nao:nao+(b+no-1)*nao),4),1)
+
+ enddo
+ enddo
+ enddo
+ enddo
+!$omp end do
+!$omp end parallel
+ else
+
+ allocate(K_iajb(ino:nno,inv:nnv,ino:nno,inv:nnv))
+ allocate(J_ijab(ino:nno,ino:nno,inv:nnv,inv:nnv))
+
+!$omp parallel private(ii,p,j,a,b,itemp,
+!$omp& iatemp1,iatemp2,iajtemp1,iajtemp2)
+!$omp& shared(ca,integral2,nao,no)
+!$omp do
+ Do ii=ino, nno
+ !(i.|..)
+ itemp(:,:,:)=integral2(ii,:,:,:) ! this is increasing the speed drastically :)
+
+ Do a=inv, nnv
+ iatemp1=0.0
+ iatemp2=0.0
+ Do p=1,nao
+ !(ia|..)
+ call sgemv('T',nao,nao,1.0,itemp(:,:,p),nao,
+ .real(ca(1+(a+no-1)*nao:nao+(a+no-1)*nao),4),1,0.0,iatemp1(:,p),1)
+ !(i.|a.)
+ call sgemv('N',nao,nao,1.0,itemp(:,:,p),nao,
+ .real(ca(1+(a+no-1)*nao:nao+(a+no-1)*nao),4),1,0.0,iatemp2(:,p),1)
+ enddo
+
+ Do j=ino, nno
+ iajtemp1=0.0
+ iajtemp2=0.0
+ !(ia|j.)
+ call sgemv('T',nao,nao,1.0,iatemp1,nao,
+ .real(ca(1+(j-1)*nao:nao+(j-1)*nao),4),1,0.0,iajtemp1,1)
+ !(ij|a.)
+ call sgemv('T',nao,nao,1.0,iatemp2,nao,
+ .real(ca(1+(j-1)*nao:nao+(j-1)*nao),4),1,0.0,iajtemp2,1)
+
+ Do b=inv, nnv
+ !(ia|jb) Since (ia|jb)=(jb|ia), I could decrease memory by collapsing the array... but with respect to integral
+ K_iajb(ii,a,j,b)=sdot(nao,iajtemp1,1,
+ . real(ca(1+(b+no-1)*nao:nao+(b+no-1)*nao),4),1)
+ !(ij|ab)
+ J_ijab(ii,j,a,b)=sdot(nao,iajtemp2,1,
+ . real(ca(1+(b+no-1)*nao:nao+(b+no-1)*nao),4),1)
+ enddo
+ enddo
+ enddo
+ enddo
+!$omp end do
+!$omp end parallel
+ endif
+
+ deallocate(itemp)
+ deallocate(iatemp1)
+ deallocate(iatemp2)
+ deallocate(iajtemp1)
+ deallocate(iajtemp2)
+ deallocate(integral2)
+
+ write(*,*)'MO ( | ) computed'
+! call cpu_time(finished)
+ end_time=wtime()
+! print '("cpu time = ",f12.2," minutes.")'
+! . ,(finished-start)/60.0
+ print '("time = ",f12.2," minutes.")'
+ . ,(end_time-start_time)/60.0
+
+
+ ak=real(dak)
+ ax=real(dax)
+! calculate A+B and A-B
+ apb=0.0e0
+ ambsqr=0.0e0
+
+! if ax=0, A-B is diagonal and its off-diagonal elements do not need to be calculated
+ if(abs(dax).lt.1.0d-6) then
+ ij=0
+!$omp parallel private(ij,i,j,ek,de)
+!$omp do
+ do i=1,nci
+ do j=1,i-1
+ ij=lin(i,j)
+ ek=k_iajb(iconf(i,1),iconf(i,2)-no,iconf(j,1),iconf(j,2)-no) ! ek = (ia|jb)
+ apb(ij)=2.0*ak*ek
+ ambsqr(ij)=0.0
+ enddo ! j
+ de=real(epsi(iconf(i,2))-epsi(iconf(i,1)),4)
+ ij=lin(i,i)
+ ek=k_iajb(iconf(i,1),iconf(i,2)-no,iconf(i,1),iconf(i,2)-no)
+ if(aresp.or.resp.or.optrota) then
+ ambsqr(ij)=de ! diagonal element of (A-B)
+ else
+ ambsqr(ij)=sqrt(de) ! diagonal element of (A-B)^0.5
+ endif
+ apb(ij)=de+ak*ek*2.0 ! diagonal element of A+B
+ enddo ! i
+!$omp end do
+!$omp end parallel
+
+ deallocate(K_iajb)
+ open(unit=53,file='amb',form='unformatted',status='replace')
+ write(53) ambsqr
+ close(53)
+
+ else
+
+ ij=0
+ ! for now ambsqr=A+B and apb=A-B, since we need to take the sqrt of A-B (but want to save memory)
+!$omp parallel private(ij,i,j,ek,ej)
+!$omp do
+ do i=1,nci
+ do j=1,i-1
+ ij=lin(i,j)
+ ek=k_iajb(iconf(i,1),iconf(i,2)-no,iconf(j,1),iconf(j,2)-no) ! ek = (ia|jb)
+ ej=J_ijab(iconf(i,1),iconf(j,1),iconf(i,2)-no,iconf(j,2)-no)*ax ! ej = (ij|ab)
+ ambsqr(ij)=2.0*ak*ek
+ ek=K_iajb(iconf(i,1),iconf(j,2)-no,iconf(j,1),iconf(i,2)-no) ! now ek = (ib|aj), results from Fock-exchange, thus we scale by ax
+ ambsqr(ij)=ambsqr(ij)-ax*ek-ej
+ apb(ij)=ax*ek-ej
+ enddo ! j
+ ij=lin(i,i)
+ ek=k_iajb(iconf(i,1),iconf(i,2)-no,iconf(i,1),iconf(i,2)-no)
+ ej=J_ijab(iconf(i,1),iconf(i,1),iconf(i,2)-no,iconf(i,2)-no)*ax
+ de=real(epsi(iconf(i,2))-epsi(iconf(i,1)),4)
+ apb(ij)=de+ax*ek -ej ! diagonal element of A-B
+ ambsqr(ij)=de-ax*ek+2.0*ak*ek -ej! diagonal element of A+B
+ enddo ! i
+!$omp end do
+!$omp end parallel
+
+ deallocate(K_iajb)
+ deallocate(J_ijab)
+
+
+! call prmat4(6,apb,nci,0,'A-B')
+! call prmat4(6,ambsqr,nci,0,'A+B')
+
+
+ if(aresp.or.resp.or.optrota) then
+ write(*,*) ' calculating (A-B)^0.5 not necessary...'
+ open(unit=53,file='amb',form='unformatted',status='replace')
+ write(53) apb
+ close(53)
+ apb=ambsqr
+ else
+ open(unit=52,file='apbmat',form='unformatted',status='replace')
+ write(52) ambsqr
+ open(unit=53,file='amb',form='unformatted',status='replace')
+ write(53) apb
+ write(*,*) ' calculating (A-B)^0.5 ...'
+ write(*,'('' estimated time (min) '',f8.2)')
+ . float(nci)**2*float(nci)/4.d+8/60.
+ call smatpow(nci,apb) ! calculate sqrt(a-b), termed ambsqr
+
+ ambsqr=apb
+
+ rewind(52)
+ read(52) apb
+ close(52,status='delete')
+ close(53)
+ endif
+ endif ! GGA/hybrid case
+
+
+ return
+
+ end subroutine rrpamat_full
+
+ function wtime ( )
+ implicit none
+
+ integer ( kind = 4 ) clock_max
+ integer ( kind = 4 ) clock_rate
+ integer ( kind = 4 ) clock_reading
+ real ( kind = 8 ) wtime
+
+ call system_clock ( clock_reading, clock_rate, clock_max )
+
+ wtime = real ( clock_reading, kind = 8 )
+ . / real ( clock_rate, kind = 8 )
+
+ return
+ end
+
+
+ subroutine two_elec_int_i(ncent,nprims,nbf,integral,
+ .ino,nno,ca,moci)
+ use stdacommon
+ use commonlibcint
+ use omp_lib
+ implicit none
+ integer :: i,j,k,l
+ integer,target :: n,m,o,p,mm,nn
+ integer,pointer :: ddj,ddk,ddl,dddl
+ logical :: extra_step
+ integer :: ncent,nprims,nbf,canon
+ integer :: ino,nno,moci
+ real*8 :: ca(nbf*moci)
+ integer :: shls(4)
+ integer, target :: di,dj,dk,dl
+ integer :: orb_cart(1:10,1:10)
+ double precision, allocatable :: buf(:,:,:,:)
+ real*4 :: integral(nno+1-ino,nbf,nbf,nbf)
+ double precision :: norm_cart(1:10,1:10),thresh
+
+ integer,external :: CINTcgto_cart
+
+ integer*8 :: opt
+ ! enforce not RSH integrals, putting mu to zero
+ env(9)=0.0d0
+
+ ! see Theoret. Chim. Acta 33 1-6 (1974) Diercksen
+ ! and Methods in computational chemistry Vol 1, 1987, page 257
+ ! It uses integral symmetries
+ ! number of integrals nbf*(nbf+1)/2*(nbf*(nbf+1)/2+1)/2
+ ! including vanishing ones
+ ! integral canonical index for (ij|kl):
+ ! i>=j k>=l
+ ! ij=i(i-1)/2+j kl=k(k-1)/2+l
+ ! ij>=kl
+ ! canonical_index=ij(ij-1)/2+kl
+
+ ! To get the same order as in libcint
+ orb_cart(1,1)=1
+ orb_cart(3,1)=1
+ orb_cart(3,2)=2
+ orb_cart(3,3)=3
+ orb_cart(6,1)=1
+ orb_cart(6,2)=4
+ orb_cart(6,3)=5
+ orb_cart(6,4)=2
+ orb_cart(6,5)=6
+ orb_cart(6,6)=3
+ orb_cart(10,1)=1
+ orb_cart(10,2)=4
+ orb_cart(10,3)=5
+ orb_cart(10,4)=6
+ orb_cart(10,5)=10
+ orb_cart(10,6)=8
+ orb_cart(10,7)=2
+ orb_cart(10,8)=7
+ orb_cart(10,9)=9
+ orb_cart(10,10)=3
+ ! For cartesian basis libcint uses d and f not normalized
+ if(spherical)then
+ norm_cart=1.0
+ else
+ norm_cart=1.0
+ norm_cart(6,1)=1.0
+ norm_cart(6,2)=dsqrt(3.0d0)
+ norm_cart(6,3)=dsqrt(3.0d0)
+ norm_cart(6,4)=1.0
+ norm_cart(6,5)=dsqrt(3.0d0)
+ norm_cart(6,6)=1.0
+ norm_cart(10,1)=1.0
+ norm_cart(10,2)=dsqrt(5.0d0)
+ norm_cart(10,3)=dsqrt(5.0d0)
+ norm_cart(10,4)=dsqrt(5.0d0)
+ norm_cart(10,5)=dsqrt(15.0d0)
+ norm_cart(10,6)=dsqrt(5.0d0)
+ norm_cart(10,7)=1.0
+ norm_cart(10,8)=dsqrt(5.0d0)
+ norm_cart(10,9)=dsqrt(5.0d0)
+ norm_cart(10,10)=1.0
+ endif
+ integral=0.0d0
+ thresh=1.0d-7
+
+ write(*,*)'number of unique AO integrals',
+ .int(nbf,8)*(int(nbf,8)+1)/2*
+ . (int(nbf,8)*(int(nbf,8)+1)/2+1)/2
+ write(*,*)'number of (i.|..) that will be stored temporarily',
+ .int((nno+1-ino),8)*int(nbf,8)*int(nbf,8)*int(nbf,8)
+ !compute (ij|kl)
+ call cint2e_cart_optimizer(opt,atm,ncent,bas,nbas,env)
+!$omp parallel private(i,j,k,l,m,n,o,p,shls,di,dj,dk,dl,buf,
+!$omp& ddj,ddk,ddl,mm,extra_step)
+!$omp& reduction(+:integral)
+!$omp do
+ Do i=1,nbas
+ shls(1)=i-1 ; di=di_all(i)
+ Do j=1,i
+ shls(2)=j-1 ; dj=di_all(j)
+
+ Do k=1,i-1
+ shls(3)=k-1 ; dk=di_all(k)
+
+ Do l=1,k
+ shls(4)=l-1 ; dl=di_all(l)
+ allocate(buf(di,dj,dk,dl))
+ call cint2e_cart(buf,shls,atm,ncent,bas,nbas,env,opt)
+ ! select case for writing into integral
+ nullify(ddj,ddk,ddl)
+
+ if(i==j)then
+ ddj=>m
+ else
+ ddj=>dj
+ endif
+
+ ddk=>dk
+
+ if(k==l)then
+ ddl=>o
+ else
+ ddl=>dl
+ endif
+
+ Do m=1,di
+ Do n=1,ddj
+ Do o=1,ddk
+ Do p=1,ddl
+ if(dabs(buf(m,n,o,p)
+ .*norm_cart(di,m)
+ .*norm_cart(dj,n)
+ .*norm_cart(dk,o)
+ .*norm_cart(dl,p))>thresh)then
+ call select_ijkl(sum_di(i)+orb_cart(di,m)
+ .,sum_di(j)+orb_cart(dj,n)
+ .,sum_di(k)+orb_cart(dk,o)
+ .,sum_di(l)+orb_cart(dl,p),ca,nbf,moci,integral,real(buf(m,n,o,p)
+ .*norm_cart(di,m)
+ .*norm_cart(dj,n)
+ .*norm_cart(dk,o)
+ .*norm_cart(dl,p),4),ino,nno)
+ endif
+ enddo
+ enddo
+ enddo
+ enddo
+
+ deallocate(buf)
+
+ enddo!l
+
+ enddo!k
+
+ k=i!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ shls(3)=k-1 ; dk=di_all(k)
+ Do l=1,j
+ shls(4)=l-1 ; dl=di_all(l)
+
+ allocate(buf(di,dj,dk,dl))
+ call cint2e_cart(buf,shls,atm,ncent,bas,nbas,env,opt)
+ ! select case for writing into integral
+ extra_step=.false.
+ nullify(ddj,ddk,ddl)
+
+ if(i==j)then
+ ddj=>m
+ else
+ ddj=>dj
+ endif
+
+ if(k==l)then
+ ddk=>mm
+ ddl=>o
+ extra_step=.true.
+ else
+
+ if(j==l)then
+ ddk=>mm
+ ddl=>dl
+ extra_step=.true.
+ else
+ ddk=>dk
+ ddl=>dl
+ endif
+ endif
+
+
+ Do m=1,di
+ mm=m-1
+ Do n=1,ddj
+ Do o=1,ddk
+ Do p=1,ddl
+ if(dabs(buf(m,n,o,p)
+ .*norm_cart(di,m)
+ .*norm_cart(dj,n)
+ .*norm_cart(dk,o)
+ .*norm_cart(dl,p))>thresh)then
+ call select_ijkl(sum_di(i)+orb_cart(di,m)
+ .,sum_di(j)+orb_cart(dj,n)
+ .,sum_di(k)+orb_cart(dk,o)
+ .,sum_di(l)+orb_cart(dl,p),ca,nbf,moci,integral,real(buf(m,n,o,p)
+ .*norm_cart(di,m)
+ .*norm_cart(dj,n)
+ .*norm_cart(dk,o)
+ .*norm_cart(dl,p),4),ino,nno)
+ endif
+ enddo
+ enddo
+ if(extra_step)then
+ o=m
+ Do p=1,n
+ if(dabs(buf(m,n,o,p)
+ .*norm_cart(di,m)
+ .*norm_cart(dj,n)
+ .*norm_cart(dk,o)
+ .*norm_cart(dl,p))>thresh)then
+ call select_ijkl(sum_di(i)+orb_cart(di,m)
+ .,sum_di(j)+orb_cart(dj,n)
+ .,sum_di(k)+orb_cart(dk,o)
+ .,sum_di(l)+orb_cart(dl,p),ca,nbf,moci,integral,real(buf(m,n,o,p)
+ .*norm_cart(di,m)
+ .*norm_cart(dj,n)
+ .*norm_cart(dk,o)
+ .*norm_cart(dl,p),4),ino,nno)
+ endif
+ enddo
+ endif
+ enddo
+ enddo
+
+ deallocate(buf)
+ enddo
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ enddo
+ enddo
+!$omp end do
+!$omp end parallel
+
+ call CINTdel_optimizer(opt)
+
+ write(*,*)'(i.|..) integrals done'
+ end subroutine two_elec_int_i
+
+ subroutine select_ijkl(i,j,k,l,ca,nao,moci,itemp,value,ino,nno)
+ implicit none
+ integer :: i,j,k,l,p
+ integer :: ino,nno,moci,nao
+ real*4 :: itemp((nno+1-ino),nao,nao,nao)
+ real*4 :: value
+ real*8 :: ca(nao*moci)
+
+
+ if(i==j.and.i==k.and.i==l)then!iiii
+ Do p=ino,nno
+ itemp(p,i,i,i)=itemp(p,i,i,i)+value*ca(i+(p-1)*nao)
+ enddo
+ elseif(i==j.and.i==k.and.k/=l)then!iiil
+ Do p=ino,nno
+ itemp(p,i,i,l)=itemp(p,i,i,l)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,i,l,i)=itemp(p,i,l,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,l,i,i)=itemp(p,l,i,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,i,i,i)=itemp(p,i,i,i)+value*real(ca(l+(p-1)*nao),4)
+ enddo
+ elseif(i==j.and.i/=k.and.i==l)then!iiki
+ Do p=ino,nno
+ itemp(p,i,i,k)=itemp(p,i,i,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,i,k,i)=itemp(p,i,k,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,k,i,i)=itemp(p,k,i,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,i,i,i)=itemp(p,i,i,i)+value*real(ca(k+(p-1)*nao),4)
+ enddo
+ elseif(i/=j.and.i==k.and.i==l)then!ijii
+ Do p=ino,nno
+ itemp(p,i,i,j)=itemp(p,i,i,j)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,i,j,i)=itemp(p,i,j,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,j,i,i)=itemp(p,j,i,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,i,i,i)=itemp(p,i,i,i)+value*real(ca(j+(p-1)*nao),4)
+ enddo
+ elseif(i/=j.and.j==k.and.j==l)then!ijjj
+ Do p=ino,nno
+ itemp(p,j,j,i)=itemp(p,j,j,i)+value*real(ca(j+(p-1)*nao),4)
+ itemp(p,j,i,j)=itemp(p,j,i,j)+value*real(ca(j+(p-1)*nao),4)
+ itemp(p,i,j,j)=itemp(p,i,j,j)+value*real(ca(j+(p-1)*nao),4)
+ itemp(p,j,j,j)=itemp(p,j,j,j)+value*real(ca(i+(p-1)*nao),4)
+ enddo
+ elseif(i==j.and.i/=k.and.k==l)then!iikk
+ Do p=ino,nno
+ itemp(p,i,k,k)=itemp(p,i,k,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,k,i,i)=itemp(p,k,i,i)+value*real(ca(k+(p-1)*nao),4)
+ enddo
+ elseif(i==j.and.i/=k.and.k/=l)then!iikl
+ Do p=ino,nno
+ itemp(p,i,k,l)=itemp(p,i,k,l)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,i,l,k)=itemp(p,i,l,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,l,i,i)=itemp(p,l,i,i)+value*real(ca(k+(p-1)*nao),4)
+ itemp(p,k,i,i)=itemp(p,k,i,i)+value*real(ca(l+(p-1)*nao),4)
+ enddo
+ elseif(i/=j.and.i/=k.and.k==l)then!ijkk
+ Do p=ino,nno
+ itemp(p,j,k,k)=itemp(p,j,k,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,i,k,k)=itemp(p,i,k,k)+value*real(ca(j+(p-1)*nao),4)
+ itemp(p,k,i,j)=itemp(p,k,i,j)+value*real(ca(k+(p-1)*nao),4)
+ itemp(p,k,j,i)=itemp(p,k,j,i)+value*real(ca(k+(p-1)*nao),4)
+ enddo
+ elseif(i/=j.and.i==k.and.j==l)then!ijij or jiji
+ Do p=ino,nno
+ itemp(p,j,i,j)=itemp(p,j,i,j)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,i,i,j)=itemp(p,i,i,j)+value*real(ca(j+(p-1)*nao),4)
+ itemp(p,j,j,i)=itemp(p,j,j,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,i,j,i)=itemp(p,i,j,i)+value*real(ca(j+(p-1)*nao),4)
+ enddo
+ elseif(i/=j.and.i==l.and.j==k)then!ijji or jiij
+ Do p=ino,nno
+ itemp(p,j,i,j)=itemp(p,j,i,j)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,i,i,j)=itemp(p,i,i,j)+value*real(ca(j+(p-1)*nao),4)
+ itemp(p,j,j,i)=itemp(p,j,j,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,i,j,i)=itemp(p,i,j,i)+value*real(ca(j+(p-1)*nao),4)
+ enddo
+ else!ijkl ijil
+ Do p=ino,nno
+ itemp(p,j,k,l)=itemp(p,j,k,l)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,j,l,k)=itemp(p,j,l,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(p,i,k,l)=itemp(p,i,k,l)+value*real(ca(j+(p-1)*nao),4)
+ itemp(p,i,l,k)=itemp(p,i,l,k)+value*real(ca(j+(p-1)*nao),4)
+ itemp(p,l,i,j)=itemp(p,l,i,j)+value*real(ca(k+(p-1)*nao),4)
+ itemp(p,l,j,i)=itemp(p,l,j,i)+value*real(ca(k+(p-1)*nao),4)
+ itemp(p,k,i,j)=itemp(p,k,i,j)+value*real(ca(l+(p-1)*nao),4)
+ itemp(p,k,j,i)=itemp(p,k,j,i)+value*real(ca(l+(p-1)*nao),4)
+ enddo
+ endif
+
+
+ end subroutine select_ijkl
+
+ subroutine rrpamat_full_direct(nci,ncent,no,nv,mxcnf,iconf,
+ . dak,dax,ed,apb,ambsqr,ca,nao,moci,nprims,epsi)
+ use commonlogicals
+ use omp_lib
+ implicit none
+ integer, intent(in) :: nci,ncent,no,nv,mxcnf,iconf(mxcnf,2)
+ real*8, intent(in) :: dak,dax,ed(mxcnf)
+ real*4, intent(out) :: apb(nci*(nci+1)/2),ambsqr(nci*(nci+1)/2)
+ integer i,j,ij,io,iv,jo,jv,ierr,lin,iiv,jjv,iwrk,jwrk,a,b,k,l,ii
+ real*4 ek,ej,sdot,ak,ax,de
+ real*8 :: ca(nao*moci)
+ integer :: nao, moci, nprims
+ integer*8 :: lin8
+ real*4 :: start_time,end_time,start,finished
+ integer :: m,n,o,p
+ real*4, allocatable :: iatemp1(:,:),itemp(:,:,:)
+ real*4, allocatable :: iajtemp1(:)
+ real*4, allocatable :: K_iajb(:,:,:,:)
+ real*4, allocatable :: J_ijab(:,:,:,:)
+ real*8 :: ddot
+ integer :: canon
+ real*8 :: wtime
+ integer :: ino,nno,inv,nnv,step
+ integer*8 :: counter
+ real*8 :: epsi(moci)
+
+ start_time=wtime()
+! call cpu_time(start)
+! Compute ( | ) integrals with lbcint
+ ! reduce the mo range to match the configuration space
+ ino=minval(iconf(1:nci,1))
+ nno=maxval(iconf(1:nci,1))
+ inv=minval(iconf(1:nci,2))-no
+ nnv=maxval(iconf(1:nci,2))-no
+ write(*,*)'MO integrals computed from occ.',ino,'to',nno
+ write(*,*)'and from unocc.',inv,'to',nnv
+
+
+ allocate(itemp(nao,nao,nao), stat=ierr )
+ if(ierr.ne.0)stop 'allocation failed for itemp'
+ allocate(iatemp1(nao,nao), stat=ierr )
+ if(ierr.ne.0)stop 'allocation failed for iatemp1'
+ allocate(iajtemp1(nao), stat=ierr )
+ if(ierr.ne.0)stop 'allocation failed for iajtemp1'
+
+
+ if(abs(dax).lt.1.0d-6) then
+ allocate(K_iajb(ino:nno,inv:nnv,ino:nno,inv:nnv), stat=ierr )
+ if(ierr.ne.0)stop 'allocation failed for K_iajb'
+!$omp parallel private(i,p,j,a,b,itemp,
+!$omp& iatemp1)
+!$omp& shared(ca,nao,no)
+!$omp do
+ Do i=ino, nno
+ !(i.|..)
+ call two_elec_int_i_direct(ncent,nprims,nao,itemp,
+ .ca,moci,i)
+
+ Do a=inv, nnv
+ iatemp1=0.0
+ Do p=1,nao
+ !(ia|..)
+ call sgemv('T',nao,nao,1.0,itemp(:,:,p),nao,
+ .real(ca(1+(a+no-1)*nao:nao+(a+no-1)*nao),4),1,0.0,iatemp1(:,p),1)
+ enddo
+
+ Do j=ino, i-1
+ iajtemp1=0.0
+ !(ia|j.)
+ call sgemv('T',nao,nao,1.0,iatemp1,nao,
+ .real(ca(1+(j-1)*nao:nao+(j-1)*nao),4),1,0.0,iajtemp1,1)
+
+ Do b=inv, nnv
+ !(ia|jb)
+ K_iajb(i,a,j,b)=sdot(nao,iajtemp1,1,
+ . real(ca(1+(b+no-1)*nao:nao+(b+no-1)*nao),4),1)
+ K_iajb(j,b,i,a)=K_iajb(i,a,j,b)
+ enddo
+ enddo
+
+ iajtemp1=0.0
+ !(ia|i.)
+ call sgemv('T',nao,nao,1.0,iatemp1,nao,
+ .real(ca(1+(i-1)*nao:nao+(i-1)*nao),4),1,0.0,iajtemp1,1)
+ Do b=inv, a-1
+ !(ia|ib)
+ K_iajb(i,a,i,b)=sdot(nao,iajtemp1,1,
+ . real(ca(1+(b+no-1)*nao:nao+(b+no-1)*nao),4),1)
+ K_iajb(i,b,i,a)=K_iajb(i,a,i,b)
+ enddo
+ !(ia|ia)
+ K_iajb(i,a,i,a)=sdot(nao,iajtemp1,1,
+ . real(ca(1+(a+no-1)*nao:nao+(a+no-1)*nao),4),1)
+ enddo
+ enddo
+!$omp end do
+!$omp end parallel
+ else
+
+ allocate(K_iajb(ino:nno,inv:nnv,ino:nno,inv:nnv), stat=ierr )
+ if(ierr.ne.0)stop 'allocation failed for K_iajb'
+ allocate(J_ijab(ino:nno,ino:nno,inv:nnv,inv:nnv), stat=ierr )
+ if(ierr.ne.0)stop 'allocation failed for J_ijab'
+
+!$omp parallel private(i,p,j,a,b,itemp,
+!$omp& iatemp1,iajtemp1)
+!$omp& shared(ca,nao,no)
+!$omp do
+ Do i=ino, nno
+ !(i.|..)
+ call two_elec_int_i_direct(ncent,nprims,nao,itemp,
+ .ca,moci,i)
+
+ Do a=inv, nnv
+
+ iatemp1=0.0
+ Do p=1,nao
+ !(ia|..)
+ call sgemv('T',nao,nao,1.0,itemp(:,:,p),nao,
+ .real(ca(1+(a+no-1)*nao:nao+(a+no-1)*nao),4),1,0.0,iatemp1(:,p),1)
+ enddo
+
+ Do j=ino, i-1
+ iajtemp1=0.0
+ !(ia|j.)
+ call sgemv('T',nao,nao,1.0,iatemp1,nao,
+ .real(ca(1+(j-1)*nao:nao+(j-1)*nao),4),1,0.0,iajtemp1,1)
+
+ Do b=inv, nnv
+ !(ia|jb)
+ K_iajb(i,a,j,b)=sdot(nao,iajtemp1,1,
+ . real(ca(1+(b+no-1)*nao:nao+(b+no-1)*nao),4),1)
+ K_iajb(j,b,i,a)=K_iajb(i,a,j,b)
+ enddo
+ enddo
+
+ iajtemp1=0.0
+ !(ia|i.)
+ call sgemv('T',nao,nao,1.0,iatemp1,nao,
+ .real(ca(1+(i-1)*nao:nao+(i-1)*nao),4),1,0.0,iajtemp1,1)
+ Do b=inv, a-1
+ !(ia|ib)
+ K_iajb(i,a,i,b)=sdot(nao,iajtemp1,1,
+ . real(ca(1+(b+no-1)*nao:nao+(b+no-1)*nao),4),1)
+ K_iajb(i,b,i,a)=K_iajb(i,a,i,b)
+ enddo
+ !(ia|ia)
+ K_iajb(i,a,i,a)=sdot(nao,iajtemp1,1,
+ . real(ca(1+(a+no-1)*nao:nao+(a+no-1)*nao),4),1)
+
+
+
+ iatemp1=0.0
+ Do p=1,nao
+ !(i.|a.)
+ call sgemv('N',nao,nao,1.0,itemp(:,:,p),nao,
+ .real(ca(1+(a+no-1)*nao:nao+(a+no-1)*nao),4),1,0.0,iatemp1(:,p),1)
+ enddo
+
+ Do j=ino, i-1
+ iajtemp1=0.0
+ !(ij|a.)
+ call sgemv('T',nao,nao,1.0,iatemp1,nao,
+ .real(ca(1+(j-1)*nao:nao+(j-1)*nao),4),1,0.0,iajtemp1,1)
+
+ Do b=inv, nnv
+ !(ij|ab)
+ J_ijab(i,j,a,b)=sdot(nao,iajtemp1,1,
+ . real(ca(1+(b+no-1)*nao:nao+(b+no-1)*nao),4),1)
+ J_ijab(j,i,b,a)=J_ijab(i,j,a,b)
+ enddo
+ enddo
+
+ iajtemp1=0.0
+ !(ii|a.)
+ call sgemv('T',nao,nao,1.0,iatemp1,nao,
+ .real(ca(1+(i-1)*nao:nao+(i-1)*nao),4),1,0.0,iajtemp1,1)
+
+ Do b=inv, a-1
+ !(ii|ab)
+ J_ijab(i,i,a,b)=sdot(nao,iajtemp1,1,
+ . real(ca(1+(b+no-1)*nao:nao+(b+no-1)*nao),4),1)
+ J_ijab(i,i,b,a)=J_ijab(i,i,a,b)
+ enddo
+ !(ii|aa)
+ J_ijab(i,i,a,a)=sdot(nao,iajtemp1,1,
+ . real(ca(1+(a+no-1)*nao:nao+(a+no-1)*nao),4),1)
+
+ enddo
+ enddo
+!$omp end do
+!$omp end parallel
+ endif
+
+ deallocate(itemp)
+ deallocate(iatemp1)
+ deallocate(iajtemp1)
+
+ write(*,*)'MO ( | ) computed'
+! call cpu_time(finished)
+ end_time=wtime()
+! print '("cpu time = ",f12.2," minutes.")'
+! . ,(finished-start)/60.0
+ print '("time = ",f12.2," minutes.")'
+ . ,(end_time-start_time)/60.0
+
+
+ ak=real(dak)
+ ax=real(dax)
+! calculate A+B and A-B
+ apb=0.0e0
+ ambsqr=0.0e0
+
+! if ax=0, A-B is diagonal and its off-diagonal elements do not need to be calculated
+ if(abs(dax).lt.1.0d-6) then
+ ij=0
+!$omp parallel private(ij,i,j,ek,de)
+!$omp do
+ do i=1,nci
+ do j=1,i-1
+ ij=lin(i,j)
+ ek=k_iajb(iconf(i,1),iconf(i,2)-no,iconf(j,1),iconf(j,2)-no) ! ek = (ia|jb)
+ apb(ij)=2.0*ak*ek
+ ambsqr(ij)=0.0
+ enddo ! j
+ de=real(epsi(iconf(i,2))-epsi(iconf(i,1)),4)
+ ij=lin(i,i)
+ ek=k_iajb(iconf(i,1),iconf(i,2)-no,iconf(i,1),iconf(i,2)-no)
+ if(aresp.or.resp.or.optrota) then
+ ambsqr(ij)=de ! diagonal element of (A-B)
+ else
+ ambsqr(ij)=sqrt(de) ! diagonal element of (A-B)^0.5
+ endif
+ apb(ij)=de+ak*ek*2.0 ! diagonal element of A+B
+ enddo ! i
+!$omp end do
+!$omp end parallel
+
+ deallocate(K_iajb)
+ open(unit=53,file='amb',form='unformatted',status='replace')
+ write(53) ambsqr
+ close(53)
+
+ else
+
+ ij=0
+ ! for now ambsqr=A+B and apb=A-B, since we need to take the sqrt of A-B (but want to save memory)
+!$omp parallel private(ij,i,j,ek,ej)
+!$omp do
+ do i=1,nci
+ do j=1,i-1
+ ij=lin(i,j)
+ ek=k_iajb(iconf(i,1),iconf(i,2)-no,iconf(j,1),iconf(j,2)-no) ! ek = (ia|jb)
+ ej=J_ijab(iconf(i,1),iconf(j,1),iconf(i,2)-no,iconf(j,2)-no)*ax ! ej = (ij|ab)
+ ambsqr(ij)=2.0*ak*ek
+ ek=K_iajb(iconf(i,1),iconf(j,2)-no,iconf(j,1),iconf(i,2)-no) ! now ek = (ib|aj), results from Fock-exchange, thus we scale by ax
+ ambsqr(ij)=ambsqr(ij)-ax*ek-ej
+ apb(ij)=ax*ek-ej
+ enddo ! j
+ ij=lin(i,i)
+ ek=k_iajb(iconf(i,1),iconf(i,2)-no,iconf(i,1),iconf(i,2)-no)
+ ej=J_ijab(iconf(i,1),iconf(i,1),iconf(i,2)-no,iconf(i,2)-no)*ax
+ de=real(epsi(iconf(i,2))-epsi(iconf(i,1)),4)
+ apb(ij)=de+ax*ek-ej ! diagonal element of A-B
+ ambsqr(ij)=de-ax*ek+2.0*ak*ek-ej ! diagonal element of A+B
+ enddo ! i
+!$omp end do
+!$omp end parallel
+
+ deallocate(K_iajb)
+ deallocate(J_ijab)
+
+
+! call prmat4(6,apb,nci,0,'A-B')
+! call prmat4(6,ambsqr,nci,0,'A+B')
+
+
+ if(aresp.or.resp.or.optrota) then
+ write(*,*) ' calculating (A-B)^0.5 not necessary...'
+ open(unit=53,file='amb',form='unformatted',status='replace')
+ write(53) apb
+ close(53)
+ apb=ambsqr
+ else
+ open(unit=52,file='apbmat',form='unformatted',status='replace')
+ write(52) ambsqr
+ open(unit=53,file='amb',form='unformatted',status='replace')
+ write(53) apb
+ write(*,*) ' calculating (A-B)^0.5 ...'
+ write(*,'('' estimated time (min) '',f8.2)')
+ . float(nci)**2*float(nci)/4.d+8/60.
+ call smatpow(nci,apb) ! calculate sqrt(a-b), termed ambsqr
+
+ ambsqr=apb
+
+ rewind(52)
+ read(52) apb
+ close(52,status='delete')
+ close(53)
+ endif
+ endif ! GGA/hybrid case
+
+
+ return
+
+ end subroutine rrpamat_full_direct
+
+ subroutine two_elec_int_i_direct(ncent,nprims,nbf,integral,
+ .ca,moci,ii)
+ use stdacommon
+ use commonlibcint
+ use omp_lib
+ implicit none
+ integer :: i,j,k,l,ii
+ integer,target :: n,m,o,p,mm,nn
+ integer,pointer :: ddj,ddk,ddl,dddl
+ logical :: extra_step
+ integer :: ncent,nprims,nbf,canon
+ integer :: moci
+ real*8 :: ca(nbf*moci)
+ integer :: shls(4)
+ integer, target :: di,dj,dk,dl
+ integer :: orb_cart(1:10,1:10)
+ double precision, allocatable :: buf(:,:,:,:)
+ real*4 :: integral(nbf,nbf,nbf)
+ double precision :: norm_cart(1:10,1:10),thresh
+
+ integer,external :: CINTcgto_cart
+
+ integer*8 :: opt
+
+
+
+ ! see Theoret. Chim. Acta 33 1-6 (1974) Diercksen
+ ! and Methods in computational chemistry Vol 1, 1987, page 257
+ ! It uses integral symmetries
+ ! number of integrals nbf*(nbf+1)/2*(nbf*(nbf+1)/2+1)/2
+ ! including vanishing ones
+ ! integral canonical index for (ij|kl):
+ ! i>=j k>=l
+ ! ij=i(i-1)/2+j kl=k(k-1)/2+l
+ ! ij>=kl
+ ! canonical_index=ij(ij-1)/2+kl
+
+ ! To get the same order as in libcint
+ orb_cart(1,1)=1
+ orb_cart(3,1)=1
+ orb_cart(3,2)=2
+ orb_cart(3,3)=3
+ orb_cart(6,1)=1
+ orb_cart(6,2)=4
+ orb_cart(6,3)=5
+ orb_cart(6,4)=2
+ orb_cart(6,5)=6
+ orb_cart(6,6)=3
+ orb_cart(10,1)=1
+ orb_cart(10,2)=4
+ orb_cart(10,3)=5
+ orb_cart(10,4)=6
+ orb_cart(10,5)=10
+ orb_cart(10,6)=8
+ orb_cart(10,7)=2
+ orb_cart(10,8)=7
+ orb_cart(10,9)=9
+ orb_cart(10,10)=3
+ ! For cartesian basis libcint uses d and f not normalized
+ if(spherical)then
+ norm_cart=1.0
+ else
+ norm_cart=1.0
+ norm_cart(6,1)=1.0
+ norm_cart(6,2)=dsqrt(3.0d0)
+ norm_cart(6,3)=dsqrt(3.0d0)
+ norm_cart(6,4)=1.0
+ norm_cart(6,5)=dsqrt(3.0d0)
+ norm_cart(6,6)=1.0
+ norm_cart(10,1)=1.0
+ norm_cart(10,2)=dsqrt(5.0d0)
+ norm_cart(10,3)=dsqrt(5.0d0)
+ norm_cart(10,4)=dsqrt(5.0d0)
+ norm_cart(10,5)=dsqrt(15.0d0)
+ norm_cart(10,6)=dsqrt(5.0d0)
+ norm_cart(10,7)=1.0
+ norm_cart(10,8)=dsqrt(5.0d0)
+ norm_cart(10,9)=dsqrt(5.0d0)
+ norm_cart(10,10)=1.0
+ endif
+ integral=0.0d0
+ thresh=1.0d-7
+
+ !compute (ij|kl)
+ call cint2e_cart_optimizer(opt,atm,ncent,bas,nbas,env)
+!$omp parallel private(i,j,k,l,m,n,o,p,shls,di,dj,dk,dl,buf,
+!$omp& ddj,ddk,ddl,mm,extra_step)
+!$omp& reduction(+:integral)
+!$omp do
+ Do i=1,nbas
+ shls(1)=i-1 ; di=di_all(i)
+ Do j=1,i
+ shls(2)=j-1 ; dj=di_all(j)
+
+ Do k=1,i-1
+ shls(3)=k-1 ; dk=di_all(k)
+
+ Do l=1,k
+ shls(4)=l-1 ; dl=di_all(l)
+ allocate(buf(di,dj,dk,dl))
+ !!!! this is the step that cost too much
+ call cint2e_cart(buf,shls,atm,ncent,bas,nbas,env,opt)
+ ! select case for writing into integral
+ nullify(ddj,ddk,ddl)
+
+ if(i==j)then
+ ddj=>m
+ else
+ ddj=>dj
+ endif
+
+ ddk=>dk
+
+ if(k==l)then
+ ddl=>o
+ else
+ ddl=>dl
+ endif
+
+ Do m=1,di
+ Do n=1,ddj
+ Do o=1,ddk
+ Do p=1,ddl
+ if(dabs(buf(m,n,o,p)
+ .*norm_cart(di,m)
+ .*norm_cart(dj,n)
+ .*norm_cart(dk,o)
+ .*norm_cart(dl,p))>thresh)then
+ call select_ijkl_directA(sum_di(i)+orb_cart(di,m)
+ .,sum_di(j)+orb_cart(dj,n)
+ .,sum_di(k)+orb_cart(dk,o)
+ .,sum_di(l)+orb_cart(dl,p),ca,nbf,moci,integral,real(buf(m,n,o,p)
+ .*norm_cart(di,m)
+ .*norm_cart(dj,n)
+ .*norm_cart(dk,o)
+ .*norm_cart(dl,p),4),ii)
+ endif
+ enddo
+ enddo
+ enddo
+ enddo
+
+ deallocate(buf)
+
+ enddo!l
+
+ enddo!k
+
+ k=i!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ shls(3)=k-1 ; dk=di_all(k)
+ Do l=1,j
+ shls(4)=l-1 ; dl=di_all(l)
+
+ allocate(buf(di,dj,dk,dl))
+ call cint2e_cart(buf,shls,atm,ncent,bas,nbas,env,opt)
+ ! select case for writing into integral
+ extra_step=.false.
+ nullify(ddj,ddk,ddl)
+
+ if(i==j)then
+ ddj=>m
+ else
+ ddj=>dj
+ endif
+
+ if(k==l)then
+ ddk=>mm
+ ddl=>o
+ extra_step=.true.
+ else
+
+ if(j==l)then
+ ddk=>mm
+ ddl=>dl
+ extra_step=.true.
+ else
+ ddk=>dk
+ ddl=>dl
+ endif
+ endif
+
+
+ Do m=1,di
+ mm=m-1
+ Do n=1,ddj
+ Do o=1,ddk
+ Do p=1,ddl
+ if(dabs(buf(m,n,o,p)
+ .*norm_cart(di,m)
+ .*norm_cart(dj,n)
+ .*norm_cart(dk,o)
+ .*norm_cart(dl,p))>thresh)then
+ call select_ijkl_direct(sum_di(i)+orb_cart(di,m)
+ .,sum_di(j)+orb_cart(dj,n)
+ .,sum_di(k)+orb_cart(dk,o)
+ .,sum_di(l)+orb_cart(dl,p),ca,nbf,moci,integral,real(buf(m,n,o,p)
+ .*norm_cart(di,m)
+ .*norm_cart(dj,n)
+ .*norm_cart(dk,o)
+ .*norm_cart(dl,p),4),ii)
+ endif
+ enddo
+ enddo
+ if(extra_step)then
+ o=m
+ Do p=1,n
+ if(dabs(buf(m,n,o,p)
+ .*norm_cart(di,m)
+ .*norm_cart(dj,n)
+ .*norm_cart(dk,o)
+ .*norm_cart(dl,p))>thresh)then
+ call select_ijkl_directB(sum_di(i)+orb_cart(di,m)
+ .,sum_di(j)+orb_cart(dj,n)
+ .,sum_di(k)+orb_cart(dk,o)
+ .,sum_di(l)+orb_cart(dl,p),ca,nbf,moci,integral,real(buf(m,n,o,p)
+ .*norm_cart(di,m)
+ .*norm_cart(dj,n)
+ .*norm_cart(dk,o)
+ .*norm_cart(dl,p),4),ii)
+ endif
+ enddo
+ endif
+ enddo
+ enddo
+
+ deallocate(buf)
+ enddo
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ enddo
+ enddo
+!$omp end do
+!$omp end parallel
+
+ call CINTdel_optimizer(opt)
+
+
+ end subroutine two_elec_int_i_direct
+
+ subroutine select_ijkl_direct(i,j,k,l,ca,nao,moci,itemp,value,p)
+ implicit none
+ integer :: i,j,k,l,p
+ integer :: moci,nao
+ real*4 :: itemp(nao,nao,nao)
+ real*4 :: value
+ real*8 :: ca(nao*moci)
+
+
+ if(i==j.and.i==k.and.i==l)then!iiii
+
+ itemp(i,i,i)=itemp(i,i,i)+value*real(ca(i+(p-1)*nao),4)
+
+ elseif(i==j.and.i==k.and.k/=l)then!iiil
+
+ itemp(i,i,l)=itemp(i,i,l)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,l,i)=itemp(i,l,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(l,i,i)=itemp(l,i,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,i,i)=itemp(i,i,i)+value*real(ca(l+(p-1)*nao),4)
+
+ elseif(i==j.and.i/=k.and.i==l)then!iiki
+
+ itemp(i,i,k)=itemp(i,i,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,k,i)=itemp(i,k,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(k,i,i)=itemp(k,i,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,i,i)=itemp(i,i,i)+value*real(ca(k+(p-1)*nao),4)
+
+ elseif(i/=j.and.i==k.and.i==l)then!ijii
+
+ itemp(i,i,j)=itemp(i,i,j)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,j,i)=itemp(i,j,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(j,i,i)=itemp(j,i,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,i,i)=itemp(i,i,i)+value*real(ca(j+(p-1)*nao),4)
+
+ elseif(i/=j.and.j==k.and.j==l)then!ijjj
+
+ itemp(j,j,i)=itemp(j,j,i)+value*real(ca(j+(p-1)*nao),4)
+ itemp(j,i,j)=itemp(j,i,j)+value*real(ca(j+(p-1)*nao),4)
+ itemp(i,j,j)=itemp(i,j,j)+value*real(ca(j+(p-1)*nao),4)
+ itemp(j,j,j)=itemp(j,j,j)+value*real(ca(i+(p-1)*nao),4)
+
+ elseif(i==j.and.i/=k.and.k==l)then!iikk
+
+ itemp(i,k,k)=itemp(i,k,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(k,i,i)=itemp(k,i,i)+value*real(ca(k+(p-1)*nao),4)
+
+ elseif(i==j.and.i/=k.and.k/=l)then!iikl
+
+ itemp(i,k,l)=itemp(i,k,l)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,l,k)=itemp(i,l,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(l,i,i)=itemp(l,i,i)+value*real(ca(k+(p-1)*nao),4)
+ itemp(k,i,i)=itemp(k,i,i)+value*real(ca(l+(p-1)*nao),4)
+
+ elseif(i/=j.and.i/=k.and.k==l)then!ijkk
+
+ itemp(j,k,k)=itemp(j,k,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,k,k)=itemp(i,k,k)+value*real(ca(j+(p-1)*nao),4)
+ itemp(k,i,j)=itemp(k,i,j)+value*real(ca(k+(p-1)*nao),4)
+ itemp(k,j,i)=itemp(k,j,i)+value*real(ca(k+(p-1)*nao),4)
+
+ elseif(i/=j.and.i==k.and.j==l)then!ijij or jiji
+
+ itemp(j,i,j)=itemp(j,i,j)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,i,j)=itemp(i,i,j)+value*real(ca(j+(p-1)*nao),4)
+ itemp(j,j,i)=itemp(j,j,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,j,i)=itemp(i,j,i)+value*real(ca(j+(p-1)*nao),4)
+
+ elseif(i/=j.and.i==l.and.j==k)then!ijji or jiij
+
+ itemp(j,i,j)=itemp(j,i,j)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,i,j)=itemp(i,i,j)+value*real(ca(j+(p-1)*nao),4)
+ itemp(j,j,i)=itemp(j,j,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,j,i)=itemp(i,j,i)+value*real(ca(j+(p-1)*nao),4)
+
+ else!ijkl ijil
+
+ itemp(j,k,l)=itemp(j,k,l)+value*real(ca(i+(p-1)*nao),4)
+ itemp(j,l,k)=itemp(j,l,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,k,l)=itemp(i,k,l)+value*real(ca(j+(p-1)*nao),4)
+ itemp(i,l,k)=itemp(i,l,k)+value*real(ca(j+(p-1)*nao),4)
+ itemp(l,i,j)=itemp(l,i,j)+value*real(ca(k+(p-1)*nao),4)
+ itemp(l,j,i)=itemp(l,j,i)+value*real(ca(k+(p-1)*nao),4)
+ itemp(k,i,j)=itemp(k,i,j)+value*real(ca(l+(p-1)*nao),4)
+ itemp(k,j,i)=itemp(k,j,i)+value*real(ca(l+(p-1)*nao),4)
+
+ endif
+
+
+ end subroutine select_ijkl_direct
+ subroutine select_ijkl_directA(i,j,k,l,ca,nao,moci,itemp,value,p)
+ implicit none
+ integer :: i,j,k,l,p
+ integer :: moci,nao
+ real*4 :: itemp(nao,nao,nao)
+ real*4 :: value
+ real*8 :: ca(nao*moci)
+
+
+ if(i==j.and.i/=k.and.i==l)then!iiki
+
+ itemp(i,i,k)=itemp(i,i,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,k,i)=itemp(i,k,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(k,i,i)=itemp(k,i,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,i,i)=itemp(i,i,i)+value*real(ca(k+(p-1)*nao),4)
+
+ elseif(i==j.and.i/=k.and.k==l)then!iikk
+
+ itemp(i,k,k)=itemp(i,k,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(k,i,i)=itemp(k,i,i)+value*real(ca(k+(p-1)*nao),4)
+
+ elseif(i==j.and.i/=k.and.k/=l)then!iikl
+
+ itemp(i,k,l)=itemp(i,k,l)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,l,k)=itemp(i,l,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(l,i,i)=itemp(l,i,i)+value*real(ca(k+(p-1)*nao),4)
+ itemp(k,i,i)=itemp(k,i,i)+value*real(ca(l+(p-1)*nao),4)
+
+ elseif(i/=j.and.i/=k.and.k==l)then!ijkk
+
+ itemp(j,k,k)=itemp(j,k,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,k,k)=itemp(i,k,k)+value*real(ca(j+(p-1)*nao),4)
+ itemp(k,i,j)=itemp(k,i,j)+value*real(ca(k+(p-1)*nao),4)
+ itemp(k,j,i)=itemp(k,j,i)+value*real(ca(k+(p-1)*nao),4)
+
+ elseif(i/=j.and.i==l.and.j==k)then!ijji or jiij
+
+ itemp(j,i,j)=itemp(j,i,j)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,i,j)=itemp(i,i,j)+value*real(ca(j+(p-1)*nao),4)
+ itemp(j,j,i)=itemp(j,j,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,j,i)=itemp(i,j,i)+value*real(ca(j+(p-1)*nao),4)
+
+ else!ijkl ijil
+
+ itemp(j,k,l)=itemp(j,k,l)+value*real(ca(i+(p-1)*nao),4)
+ itemp(j,l,k)=itemp(j,l,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,k,l)=itemp(i,k,l)+value*real(ca(j+(p-1)*nao),4)
+ itemp(i,l,k)=itemp(i,l,k)+value*real(ca(j+(p-1)*nao),4)
+ itemp(l,i,j)=itemp(l,i,j)+value*real(ca(k+(p-1)*nao),4)
+ itemp(l,j,i)=itemp(l,j,i)+value*real(ca(k+(p-1)*nao),4)
+ itemp(k,i,j)=itemp(k,i,j)+value*real(ca(l+(p-1)*nao),4)
+ itemp(k,j,i)=itemp(k,j,i)+value*real(ca(l+(p-1)*nao),4)
+
+ endif
+
+
+ end subroutine select_ijkl_directA
+
+ subroutine select_ijkl_directB(i,j,k,l,ca,nao,moci,itemp,value,p)
+ implicit none
+ integer :: i,j,k,l,p
+ integer :: moci,nao
+ real*4 :: itemp(nao,nao,nao)
+ real*4 :: value
+ real*8 :: ca(nao*moci)
+
+
+ if(i==j.and.i==k.and.i==l)then!iiii
+
+ itemp(i,i,i)=itemp(i,i,i)+value*ca(i+(p-1)*nao)
+
+ elseif(i==j.and.i==k.and.k/=l)then!iiil
+
+ itemp(i,i,l)=itemp(i,i,l)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,l,i)=itemp(i,l,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(l,i,i)=itemp(l,i,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,i,i)=itemp(i,i,i)+value*real(ca(l+(p-1)*nao),4)
+
+ elseif(i/=j.and.i==k.and.i==l)then!ijii
+
+ itemp(i,i,j)=itemp(i,i,j)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,j,i)=itemp(i,j,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(j,i,i)=itemp(j,i,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,i,i)=itemp(i,i,i)+value*real(ca(j+(p-1)*nao),4)
+
+ elseif(i/=j.and.i==k.and.j==l)then!ijij or jiji
+
+ itemp(j,i,j)=itemp(j,i,j)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,i,j)=itemp(i,i,j)+value*real(ca(j+(p-1)*nao),4)
+ itemp(j,j,i)=itemp(j,j,i)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,j,i)=itemp(i,j,i)+value*real(ca(j+(p-1)*nao),4)
+
+ else!ijkl ijil
+
+ itemp(j,k,l)=itemp(j,k,l)+value*real(ca(i+(p-1)*nao),4)
+ itemp(j,l,k)=itemp(j,l,k)+value*real(ca(i+(p-1)*nao),4)
+ itemp(i,k,l)=itemp(i,k,l)+value*real(ca(j+(p-1)*nao),4)
+ itemp(i,l,k)=itemp(i,l,k)+value*real(ca(j+(p-1)*nao),4)
+ itemp(l,i,j)=itemp(l,i,j)+value*real(ca(k+(p-1)*nao),4)
+ itemp(l,j,i)=itemp(l,j,i)+value*real(ca(k+(p-1)*nao),4)
+ itemp(k,i,j)=itemp(k,i,j)+value*real(ca(l+(p-1)*nao),4)
+ itemp(k,j,i)=itemp(k,j,i)+value*real(ca(l+(p-1)*nao),4)
+
+ endif
+
+
+ end subroutine select_ijkl_directB
diff --git a/g2molden/Makefile b/g2molden/Makefile
old mode 100644
new mode 100755
diff --git a/g2molden/main.f b/g2molden/main.f
old mode 100644
new mode 100755
diff --git a/g2molden/stringmod.f90 b/g2molden/stringmod.f90
old mode 100644
new mode 100755
diff --git a/g_spec/Makefile b/g_spec/Makefile
old mode 100644
new mode 100755
diff --git a/g_spec/g_spec.f b/g_spec/g_spec.f
old mode 100644
new mode 100755
diff --git a/header.f b/header.f
index 6c1c3e3..653220d 100755
--- a/header.f
+++ b/header.f
@@ -1,20 +1,21 @@
-! This file is part of stda.
+! This file is part of std2.
!
-! Copyright (C) 2013-2019 Stefan Grimme
+! Copyright (C) 2013-2025 Stefan Grimme and Marc de Wergifosse
!
-! stda is free software: you can redistribute it and/or modify it under
+! std2 is free software: you can redistribute it and/or modify it under
! the terms of the GNU Lesser General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
-! stda is distributed in the hope that it will be useful,
+! std2 is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
-! along with stda. If not, see .
-!
+! along with std2. If not, see .
+!
+!! ------------------------------------------------------------------------
subroutine header(aarg,iarg)
IMPLICIT REAL*8(A-H,O-Z)
character*(*) aarg
@@ -30,7 +31,6 @@ subroutine header(aarg,iarg)
130 format(/)
120 format(20x,a,5x,i4)
121 format(20x,a)
-
+
return
end
-
diff --git a/intpack.f90 b/intpack.f90
index 7f892f8..25b2966 100755
--- a/intpack.f90
+++ b/intpack.f90
@@ -1,19 +1,21 @@
-! This file is part of stda.
+! This file is part of std2.
!
-! Copyright (C) 2013-2019 Stefan Grimme
+! Copyright (C) 2013-2025 Stefan Grimme and Marc de Wergifosse
!
-! stda is free software: you can redistribute it and/or modify it under
+! std2 is free software: you can redistribute it and/or modify it under
! the terms of the GNU Lesser General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
-! stda is distributed in the hope that it will be useful,
+! std2 is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
-! along with stda. If not, see .
+! along with std2. If not, see .
+!
+!! ------------------------------------------------------------------------
!
! Adapted from xtb4stda by MdeW
!! ------------------------------------------------------------------------
@@ -21,7 +23,7 @@ module intpack
use iso_fortran_env, only : wp => real64
contains
-! propa split in propa0 and propa1 to avoid computing several time the same things and neglect if efact below thr
+! propa split in propa0 and propa1 to avoid computing several time the same things and neglect if efact below thr
subroutine propa0(aname,c,va,nt,ij,kl,efact)
use stdacommon
implicit real(wp)(a-h,o-z)
@@ -31,10 +33,10 @@ subroutine propa0(aname,c,va,nt,ij,kl,efact)
! local
common /abfunc/ ra(3),rb(3),ga,gb,ia,ib,gama, &
& d(3),dd(84),e(3),aa(20),bb(20),a(3),b(3)
- dimension v(nt),val(nt)
-
+ dimension v(nt),val(nt)
+
a(1:3)=eta(ij,1:3)
- b(1:3)=eta(kl,1:3)
+ b(1:3)=eta(kl,1:3)
etaij4=eta(ij,4)
etakl4=eta(kl,4)
iff1=dint(eta(ij,5))
@@ -80,8 +82,8 @@ subroutine propa1(aname,c,va,nt,ij,kl,efact)
! local
common /abfunc/ ra(3),rb(3),ga,gb,ia,ib,gama, &
& d(3),dd(84),e(3),aa(20),bb(20),a(3),b(3)
- common/ prptyp / mprp
- dimension v(nt),val(nt)
+ common/ prptyp / mprp
+ dimension v(nt),val(nt)
integer,parameter :: lin(84) = &
& (/0,1,0,0,2,0,0,1,1,0,3,0,0,2,2,1,0,1,0,1,4,0,0,3,3,1,0,1,0,2,2,0, &
& 2,1,1,5,0,0,3,3,2,2,0,0,4,4,1,0,0,1,1,3,1,2,2,1,6,0,0,3,3,0,5,5, &
@@ -94,7 +96,7 @@ subroutine propa1(aname,c,va,nt,ij,kl,efact)
& (/0,0,0,1,0,0,2,0,1,1,0,0,3,0,1,0,1,2,2,1,0,0,4,0,1,0,1,3,3,0,2,2, &
& 1,1,2,0,0,5,0,2,0,3,2,3,0,1,0,1,4,4,3,1,1,1,2,2,0,0,6,0,3,3,0,1, &
& 5,5,1,0,0,2,4,4,0,2,1,2,2,3,1,3,1,1,4,2/)
-
+
iff1=ia
iff2=ib
val = 0
@@ -281,9 +283,9 @@ subroutine propa1(aname,c,va,nt,ij,kl,efact)
return
!cha
end subroutine propa1
-
-
-
+
+
+
!=======================================================================
! cartesian gaussian functions (6d,10f...)
! iff :
@@ -306,7 +308,7 @@ subroutine propa(aname,c,va,nt,ij,kl)
real(wp) a(3),b(3),c(3),va(nt)
! local
common /abfunc/ ra(3),rb(3),ga,gb,ia,ib
- common/ prptyp / mprp
+ common/ prptyp / mprp
dimension d(3),dd(84),v(nt),val(nt) !,v(3),val(3)
dimension e(3),aa(20),bb(20)
integer,parameter :: lin(84) = &
@@ -321,9 +323,9 @@ subroutine propa(aname,c,va,nt,ij,kl)
& (/0,0,0,1,0,0,2,0,1,1,0,0,3,0,1,0,1,2,2,1,0,0,4,0,1,0,1,3,3,0,2,2, &
& 1,1,2,0,0,5,0,2,0,3,2,3,0,1,0,1,4,4,3,1,1,1,2,2,0,0,6,0,3,3,0,1, &
& 5,5,1,0,0,2,4,4,0,2,1,2,2,3,1,3,1,1,4,2/)
-
+
a(1:3)=eta(ij,1:3)
- b(1:3)=eta(kl,1:3)
+ b(1:3)=eta(kl,1:3)
etaij4=eta(ij,4)
etakl4=eta(kl,4)
iff1=dint(eta(ij,5))
@@ -579,7 +581,7 @@ pure subroutine rhftce(cfs,a,e,iff)
integer,intent(in) :: iff
real(wp), intent(in) :: a(*),e(*)
real(wp), intent(inout) :: cfs(*)
- real(wp), parameter :: c2 = 2.0d0
+ real(wp), parameter :: c2 = 2.0d0
real(wp), parameter :: c3 = 3.0d0
real(wp) :: aex,aey,aez
! ---- e = center of product function, a = center of single gaussian
@@ -588,7 +590,7 @@ pure subroutine rhftce(cfs,a,e,iff)
aez = e(3)-a(3)
select case(iff)
- case(1)
+ case(1)
continue
case(2)
cfs(1)=aex*cfs(2)
@@ -1252,7 +1254,7 @@ subroutine opam(l,m,n,gama,v,d)
do i=1,l
s3=s3+g(i)*ovl(i)
enddo
- call bip(my(ia),my(ib),pa(2),pb(2))
+ call bip(my(ia),my(ib),pa(2),pb(2))
m=my(ia)+my(ib)
m1=m-1
do i=1,m1
@@ -1262,7 +1264,7 @@ subroutine opam(l,m,n,gama,v,d)
do i=1,m
s6 =s6+g(i)*ovl(i)
enddo
- call bip(nz(ia),nz(ib),pa(3),pb(3))
+ call bip(nz(ia),nz(ib),pa(3),pb(3))
n=nz(ia)+nz(ib)
n1=n-1
do i=1,n1
@@ -1281,7 +1283,7 @@ subroutine opam(l,m,n,gama,v,d)
return
end subroutine opam
-subroutine bip(la,lb,a,b)
+subroutine bip(la,lb,a,b)
implicit real(wp)(a-h,o-z)
common /abfunc/ ra(3),rb(3),ga,gb,ia,ib
common /gf/f(7),g(8)
@@ -1396,7 +1398,7 @@ subroutine bip(la,lb,a,b)
f(3)=c3*a
g(1)=-gb2*(a**3)*b
g(2)=-gb2*a*a*(a+c3*b)
- g(3)=-c6*a*gb*(a+b)
+ g(3)=-c6*a*gb*(a+b)
g(4)=-gb2*(c3*a+b)
return
! f - p
@@ -1425,7 +1427,7 @@ subroutine bip(la,lb,a,b)
return
! f - f
34 f(1)=(a*b)**3
- f(2)=c3*((a*b)**2)*(a+b)
+ f(2)=c3*((a*b)**2)*(a+b)
f(3)=c3*a*b*(a*(a+c3*b)+b*b)
f(4)=a*a*(a+9.d0*b)+b*b*(b+9.d0*a)
f(5)=c3*(a*(a+c3*b)+b*b)
diff --git a/intslvm.f b/intslvm.f
index 7e758ce..8d237b9 100755
--- a/intslvm.f
+++ b/intslvm.f
@@ -1,26 +1,27 @@
-! This file is part of stda.
+! This file is part of std2.
!
-! Copyright (C) 2013-2019 Stefan Grimme
+! Copyright (C) 2013-2025 Stefan Grimme and Marc de Wergifosse
!
-! stda is free software: you can redistribute it and/or modify it under
+! std2 is free software: you can redistribute it and/or modify it under
! the terms of the GNU Lesser General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
-! stda is distributed in the hope that it will be useful,
+! std2 is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
-! along with stda. If not, see .
+! along with std2. If not, see .
!
+!! ------------------------------------------------------------------------
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
- subroutine intslvm(ncent,nmo,nbf,nprims)
+ subroutine intslvm(ncent,nmo,nbf,nprims)
use stdacommon
use intpack
- implicit real*8(a-h,o-z)
+ implicit real*8(a-h,o-z)
real*8, allocatable ::r0(:)
real*8, allocatable ::r1(:)
@@ -33,7 +34,7 @@ subroutine intslvm(ncent,nmo,nbf,nprims)
real*8, allocatable ::r8(:)
real*8, allocatable ::r9(:)
integer*8 memneed,mp,nrecordlen,k,i1,lin8
- common/ prptyp / mprp
+ common/ prptyp / mprp
common /cema / cen(3),xmolw
common /amass / ams(107)
@@ -41,26 +42,26 @@ subroutine intslvm(ncent,nmo,nbf,nprims)
call header('A O I N T E G R A L S',0)
-c overlap based neglect prim prefactor threshold
+c overlap based neglect prim prefactor threshold
thr=1.d-7
c center of nuclear charge and molar mass
- sumwx=0.d0
- sumwy=0.d0
- sumwz=0.d0
+ sumwx=0.d0
+ sumwy=0.d0
+ sumwz=0.d0
sumw=0.0d0
xmolw=0.0d0
- do 10 i=1,ncent
- atmass=co(i,4)
- sumw=sumw+atmass
- sumwx=sumwx+atmass*co(i,1)
- sumwy=sumwy+atmass*co(i,2)
- sumwz=sumwz+atmass*co(i,3)
+ do 10 i=1,ncent
+ atmass=co(i,4)
+ sumw=sumw+atmass
+ sumwx=sumwx+atmass*co(i,1)
+ sumwy=sumwy+atmass*co(i,2)
+ sumwz=sumwz+atmass*co(i,3)
xmolw=xmolw+ams(idint(atmass))
- 10 continue
+ 10 continue
cen(1)=sumwx/sumw
- cen(2)=sumwy/sumw
- cen(3)=sumwz/sumw
+ cen(2)=sumwy/sumw
+ cen(3)=sumwz/sumw
if(nbf.eq.0) then
do i=1,nprims
@@ -73,20 +74,20 @@ subroutine intslvm(ncent,nmo,nbf,nprims)
iaoat(ipao(i))=ii
enddo
nao=nbf
- endif
+ endif
mp=nao
mp=mp*(mp+1)/2
memneed=10*8*mp
call byteout('AO int data',memneed)
- allocate(r1(mp),r2(mp),r3(mp),
- . r4(mp),r5(mp),r6(mp),
+ allocate(r1(mp),r2(mp),r3(mp),
+ . r4(mp),r5(mp),r6(mp),
. r7(mp),r8(mp),r9(mp),r0(mp),
. stat=ierr)
if(ierr.ne.0)stop 'allocation failed in intslvm for AOs'
- open(unit=40,file='sint', form='unformatted',status='replace')
+ open(unit=40,file='sint', form='unformatted',status='replace')
open(unit=31,file='xlint',form='unformatted',status='replace')
open(unit=32,file='ylint',form='unformatted',status='replace')
open(unit=33,file='zlint',form='unformatted',status='replace')
@@ -100,13 +101,13 @@ subroutine intslvm(ncent,nmo,nbf,nprims)
ccccccccccccccccccccccccccccccccccccccccccccccccccc
c
-c overlap and dipole
+c overlap and dipole
c
ccccccccccccccccccccccccccccccccccccccccccccccccccc
-
+
point=0.0d0
- r0=0.0d0
+ r0=0.0d0
r1=0.0d0
r2=0.0d0
r3=0.0d0
@@ -124,53 +125,53 @@ subroutine intslvm(ncent,nmo,nbf,nprims)
iaj=ipao(j)
iaa=max(iaj,iai)
iii=min(iaj,iai)
- ij=iii+iaa*(iaa-1)/2
+ ij=iii+iaa*(iaa-1)/2
cf=c1*cxip(j)*2.0d0
-c prefactor
+c prefactor
call propa0(opad1,point,v,1,i,j,s)
if(s.gt.thr)then
mprp=0
-c S
+c S
call propa1(opad1,point,v,1,i,j,s)
r0(ij)=r0(ij)+v(1)*cf
-c R
+c R
call propa1(opab1,point,v,3,i,j,s)
- r1(ij)=r1(ij)+v(1)*cf
- r2(ij)=r2(ij)+v(2)*cf
- r3(ij)=r3(ij)+v(3)*cf
-C L
+ r1(ij)=r1(ij)+v(1)*cf
+ r2(ij)=r2(ij)+v(2)*cf
+ r3(ij)=r3(ij)+v(3)*cf
+C L
mprp=16
call propa1(opam,point,v,3,i,j,s)
! note that s is changed by propa1 in this very case
- r4(ij)=r4(ij)+v(1)*cf
- r5(ij)=r5(ij)+v(2)*cf
- r6(ij)=r6(ij)+v(3)*cf
-C V
- mprp=0
+ r4(ij)=r4(ij)+v(1)*cf
+ r5(ij)=r5(ij)+v(2)*cf
+ r6(ij)=r6(ij)+v(3)*cf
+C V
+ mprp=0
call velo(i,j,v)
- r7(ij)=r7(ij)-v(1)*cf
- r8(ij)=r8(ij)-v(2)*cf
- r9(ij)=r9(ij)-v(3)*cf
+ r7(ij)=r7(ij)-v(1)*cf
+ r8(ij)=r8(ij)-v(2)*cf
+ r9(ij)=r9(ij)-v(3)*cf
endif
enddo
mprp=0
call propa0(opad1,point,v,1,i,i,s)
call propa1(opad1,point,v,1,i,i,s)
- ij=iai+iai*(iai-1)/2
+ ij=iai+iai*(iai-1)/2
cf=c1*c1
- r0(ij)=r0(ij)+v(1)*cf
+ r0(ij)=r0(ij)+v(1)*cf
call propa1(opab1,point,v,3,i,i,s)
- r1(ij)=r1(ij)+v(1)*cf
- r2(ij)=r2(ij)+v(2)*cf
- r3(ij)=r3(ij)+v(3)*cf
+ r1(ij)=r1(ij)+v(1)*cf
+ r2(ij)=r2(ij)+v(2)*cf
+ r3(ij)=r3(ij)+v(3)*cf
enddo
-
+
ij=0
do i=1,nao
do j=1,i-1
ij=lin8(i,j)
- r0(ij)=r0(ij)*0.50d0
+ r0(ij)=r0(ij)*0.50d0
r1(ij)=r1(ij)*0.50d0
r2(ij)=r2(ij)*0.50d0
r3(ij)=r3(ij)*0.50d0
@@ -180,11 +181,11 @@ subroutine intslvm(ncent,nmo,nbf,nprims)
r7(ij)=r7(ij)*0.50d0
r8(ij)=r8(ij)*0.50d0
r9(ij)=r9(ij)*0.50d0
- enddo
+ enddo
enddo
write(40)r0
- close(40)
+ close(40)
write(31)r1
write(32)r2
write(33)r3
@@ -203,9 +204,129 @@ subroutine intslvm(ncent,nmo,nbf,nprims)
close(37)
close(38)
close(39)
-
+
deallocate(r0,r1,r2,r3,r4,r5,r6,r7,r8,r9)
write(*,*) 'done.'
end
+!*******************************************************************************
+ subroutine intslvm2(ncent,nmo,nbf,nprims)
+ use stdacommon
+ use commonlogicals
+ use intpack
+ implicit real*8(a-h,o-z)
+ real*8, allocatable ::r4(:)
+ real*8, allocatable ::r5(:)
+ real*8, allocatable ::r6(:)
+ integer*8 memneed,mp,nrecordlen,k,i1,lin8
+ common/ prptyp / mprp
+ common /cema / cen(3),xmolw
+ common /amass / ams(107)
+
+ dimension v(6),point(3)
+
+ call header('A O I N T E G R A L S',0)
+
+c overlap based neglect prim prefactor threshold
+ thr=1.d-7
+
+c center of nuclear charge and molar mass
+ sumwx=0.d0
+ sumwy=0.d0
+ sumwz=0.d0
+ sumw=0.0d0
+ xmolw=0.0d0
+ do 10 i=1,ncent
+ atmass=co(i,4)
+ sumw=sumw+atmass
+ sumwx=sumwx+atmass*co(i,1)
+ sumwy=sumwy+atmass*co(i,2)
+ sumwz=sumwz+atmass*co(i,3)
+ xmolw=xmolw+ams(idint(atmass))
+ 10 continue
+ cen(1)=sumwx/sumw
+ cen(2)=sumwy/sumw
+ cen(3)=sumwz/sumw
+
+ if(nbf.eq.0) then
+ do i=1,nprims
+ iaoat(i)=ipat(i)
+ enddo
+ nao=nprims
+ else
+ do i=1,nprims
+ ii=ipat(i)
+ iaoat(ipao(i))=ii
+ enddo
+ nao=nbf
+ endif
+
+ mp=nao
+ mp=mp*(mp+1)/2
+
+ memneed=3*8*mp
+ if(multipole.eqv..true.)then
+ memneed=memneed+6*8*mp
+ endif
+ call byteout('AO int data',memneed)
+
+ allocate(r4(mp),r5(mp),r6(mp),stat=ierr)
+ if(ierr.ne.0)stop 'allocation failed in intslvm for AOs'
+ open(unit=34,file='xmint',form='unformatted',status='replace')
+ open(unit=35,file='ymint',form='unformatted',status='replace')
+ open(unit=36,file='zmint',form='unformatted',status='replace')
+ccccccccccccccccccccccccccccccccccccccccccccccccccc
+c
+c overlap and dipole
+c
+ccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+ point=0.0d0
+ r4=0.0d0
+ r5=0.0d0
+ r6=0.0d0
+
+ do i=1,nprims
+ iai=ipao(i)
+ c1=cxip(i)
+ do j=1,i-1
+ iaj=ipao(j)
+ iaa=max(iaj,iai)
+ iii=min(iaj,iai)
+ ij=iii+iaa*(iaa-1)/2
+ cf=c1*cxip(j)*2.0d0
+c prefactor
+ call propa0(opad1,point,v,1,i,j,s)
+ if(s.gt.thr)then
+C L
+ mprp=16
+ call propa1(opam,point,v,3,i,j,s)
+ ! note that s is changed by propa1 in this very case
+ r4(ij)=r4(ij)+v(1)*cf
+ r5(ij)=r5(ij)+v(2)*cf
+ r6(ij)=r6(ij)+v(3)*cf
+ endif
+ enddo
+ mprp=0
+ enddo
+
+ ij=0
+ do i=1,nao
+ do j=1,i-1
+ ij=lin8(i,j)
+ r4(ij)=r4(ij)*0.50d0
+ r5(ij)=r5(ij)*0.50d0
+ r6(ij)=r6(ij)*0.50d0
+ enddo
+ enddo
+
+ write(34)r4
+ write(35)r5
+ write(36)r6
+ close(34)
+ close(35)
+ close(36)
+ deallocate(r4,r5,r6)
+ write(*,*) 'done.'
+ end
diff --git a/io.f b/io.f
index 42818a1..f86663c 100755
--- a/io.f
+++ b/io.f
@@ -1,20 +1,21 @@
-! This file is part of stda.
+! This file is part of std2.
!
-! Copyright (C) 2013-2019 Stefan Grimme
+! Copyright (C) 2013-2025 Stefan Grimme and Marc de Wergifosse
!
-! stda is free software: you can redistribute it and/or modify it under
+! std2 is free software: you can redistribute it and/or modify it under
! the terms of the GNU Lesser General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
-! stda is distributed in the hope that it will be useful,
+! std2 is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
-! along with stda. If not, see .
+! along with std2. If not, see .
!
+!! ------------------------------------------------------------------------
***********************************************************************
subroutine mwrite(n,iwo,v,irec)
@@ -31,4 +32,3 @@ subroutine mread(n,iwo,v,irec)
read(iwo,rec=irec) v
return
end
-
diff --git a/libcint.f b/libcint.f
new file mode 100755
index 0000000..93caa54
--- /dev/null
+++ b/libcint.f
@@ -0,0 +1,904 @@
+! This file is part of std2.
+!
+! Copyright (C) 2025 Marc de Wergifosse
+!
+! std2 is free software: you can redistribute it and/or modify it under
+! the terms of the GNU Lesser General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! std2 is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU Lesser General Public License for more details.
+!
+! You should have received a copy of the GNU Lesser General Public License
+! along with std2. If not, see .
+!
+!! ------------------------------------------------------------------------
+ subroutine overlap(ncent,nprims,nbf,overlap_AO)
+ use stdacommon
+ use commonlibcint
+ use omp_lib
+ implicit none
+ integer :: i,j,k,l,n,m
+ integer :: ncent,nprims,nbf
+ integer, allocatable :: info(:)
+ double precision, parameter :: PI=4.D0*DATAN(1.D0)
+
+ integer :: shls(2), di,dj,dk,dl, orb_cart(1:10,1:10)
+ double precision, allocatable :: buf(:,:)
+ double precision :: overlap_AO(nbf*(nbf+1)/2)
+ double precision :: norm_cart(1:10,1:10)
+
+ integer,external :: CINTcgto_cart
+
+ integer*8 ::lin8
+
+! real*8 :: sumwx,sumwy,sumwz,sumw,atmass
+! real*8 :: cen,xmolw,ams
+! common /cema / cen(3),xmolw
+! common /amass / ams(107)
+
+ allocate(atm(1:6,1:ncent))
+ j=21 ! variables are defined below 20 note that the array in libcint starts with 0
+ Do i=1, ncent
+ atm(1,i)=int(co(i,4)) ! atom charge
+ atm(2,i)=j ! "zero" for list of atoms in env
+ j=j+3
+ enddo
+ n_env=j
+
+ allocate(info(nprims)) !indicate the number of primitives in each contractions
+ ! Counting the number of primitives without those by symmetry in each contractions
+ nbas=1
+ info=1
+ j=1
+ Do i=2,nprims
+ if(nbas/=i)then
+ if(ipty(i)==1.or.ipty(i)==2.or.ipty(i)==5.or.ipty(i)==11)then ! remove those by symmetry
+ if(ipao(i)==ipao(i-1))then
+ info(nbas)=info(nbas)+1
+ info(i)=0
+ else ! jump to the next AO
+ nbas=i
+ j=j+1
+ endif
+ else ! other than x, xx, xxx are zero, no need to count them
+ info(i)=0
+ endif
+ endif
+ enddo
+
+ nbas=j
+ allocate(bas(1:8,1:nbas))
+
+ j=0
+ n_env=n_env+1
+ Do i=1, nprims
+ if(info(i)/=0)then
+ bas(1,j+1)=ipat(i)-1 ! atom id starts with zero
+ if(ipty(i)==1)bas(2,j+1)=0 ! orbital quantum number l
+ if(ipty(i)==2)bas(2,j+1)=1
+ if(ipty(i)==5)bas(2,j+1)=2
+ if(ipty(i)==11)bas(2,j+1)=3
+ bas(3,j+1)=info(i) ! number of primitives in each contraction
+ bas(4,j+1)=1 ! one contraction, no more
+ bas(6,j+1)=n_env-1 ! "zero" for list of exponents in env
+ bas(7,j+1)=n_env+info(i)-1 ! "zero" for list of contraction coefficients in env
+ n_env=n_env+info(i)*2
+ j=j+1
+ endif
+ enddo
+
+ allocate(env(1:n_env)) ! start with 20 because variables are passed with values <=
+ !env(1) threshold on integrals
+ !env(1)=7.0d0
+c center of nuclear charge and molar mass
+! sumwx=0.d0
+! sumwy=0.d0
+! sumwz=0.d0
+! sumw=0.0d0
+! xmolw=0.0d0
+! do i=1,ncent
+! atmass=co(i,4)
+! sumw=sumw+atmass
+! sumwx=sumwx+atmass*co(i,1)
+! sumwy=sumwy+atmass*co(i,2)
+! sumwz=sumwz+atmass*co(i,3)
+! xmolw=xmolw+ams(idint(atmass))
+! enddo
+! cen(1)=sumwx/sumw
+! cen(2)=sumwy/sumw
+! cen(3)=sumwz/sumw
+ env(2:4)=0.0 ! env(PTR_COMMON_ORIG:PTR_COMMON_ORIG+2)
+
+
+ ! copy all data in env vector
+ j=21
+ Do i=1,ncent
+ env(j+1)=co(i,1)
+ env(j+2)=co(i,2)
+ env(j+3)=co(i,3)
+ j=j+3
+ enddo
+
+ j=j+1
+ n=1
+ Do i=1,nprims
+ if(info(i)/=0)then
+ Do k=0,info(i)-1
+ env(j)=exip(i+k)
+ j=j+1
+ enddo
+ Do k=0,info(i)-1
+ If(ipty(i)==1)then
+ env(j)=cxip(i+k)*dsqrt(PI*4.0d0) ! different normalization in libcint
+ endif
+ If(ipty(i)==2)then
+ env(j)=cxip(i+k)*dsqrt(PI*4.0d0/3.0d0)
+ endif
+ If(ipty(i)==5)then
+ env(j)=cxip(i+k)
+ endif
+ If(ipty(i)==11)then
+ env(j)=cxip(i+k)
+ endif
+ j=j+1
+ enddo
+ n=n+1
+ endif
+ enddo
+
+ allocate(di_all(nbas),sum_di(nbas))
+ sum_di=0
+ Do i=1, nbas
+ di_all(i)=CINTcgto_cart(i-1,bas)
+ if(i.
+! along with std2. If not, see .
!
+!! ------------------------------------------------------------------------
subroutine blow(nbf,F,X)
implicit none
real*8 F(nbf*(nbf+1)/2),X(nbf,nbf)
@@ -31,4 +32,3 @@ subroutine blow(nbf,F,X)
enddo
end
-
diff --git a/linear_response.f b/linear_response.f
index 95b1b86..0975e26 100755
--- a/linear_response.f
+++ b/linear_response.f
@@ -1,20 +1,21 @@
-! This file is part of stda.
+! This file is part of std2.
!
-! Copyright (C) 2013-2020 Stefan Grimme
+! Copyright (C) 2013-2025 Stefan Grimme and Marc de Wergifosse
!
-! stda is free software: you can redistribute it and/or modify it under
+! std2 is free software: you can redistribute it and/or modify it under
! the terms of the GNU Lesser General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
-! stda is distributed in the hope that it will be useful,
+! std2 is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
-! along with stda. If not, see .
+! along with std2. If not, see .
!
+!! ------------------------------------------------------------------------
! written by Marc de Wegifosse 2017-2020
@@ -2871,14 +2872,14 @@ subroutine lresp_ESAbis(nci,iconf,maxconf,xl,yl,zl,moci,
mu(:,2)=yl(:)
mu(:,3)=zl(:)
- write(*,*)
- write(*,*)'====================================================
- .=================='
- write(*,*)' Welcome in nonlinear response sTD-DFT
- . program'
- write(*,*)'====================================================
- .=================='
- write(*,*)
+! write(*,*)
+! write(*,*)'====================================================
+! .=================='
+! write(*,*)' Welcome in nonlinear response sTD-DFT
+! . program'
+! write(*,*)'====================================================
+! .=================='
+! write(*,*)
!
! Genarating a list of indexes used in A and B formula to save a great bunch of time
@@ -2927,10 +2928,10 @@ subroutine lresp_ESAbis(nci,iconf,maxconf,xl,yl,zl,moci,
!Do i=1,counter_B
!write(*,*)i,B_list(i,1:3)
!enddo
- call cpu_time(end_time)
- print '("A & B indexes list Time = ",f12.2," minutes.")'
- . ,(end_time-start_time)/60.0
- write(*,*)
+! call cpu_time(end_time)
+! print '("A & B indexes list Time = ",f12.2," minutes.")'
+! . ,(end_time-start_time)/60.0
+! write(*,*)
mu_s2s=0.0
Do jj=1,nroot
Do ii=1, nroot
@@ -2966,7 +2967,7 @@ subroutine lresp_ESAbis(nci,iconf,maxconf,xl,yl,zl,moci,
enddo
!$omp end do
!$omp end parallel
- mu_s2s(ii,jj,ix)=-(A1+A2-B1-B2)/2.0
+ mu_s2s(ii,jj,ix)=-(A1+A2-B1-B2)/2.0d0
!write(*,*) ix, mu_s2s(ii,jj,ix)
enddo
!else
@@ -2975,24 +2976,24 @@ subroutine lresp_ESAbis(nci,iconf,maxconf,xl,yl,zl,moci,
!mu_s2s(ii,jj,ix)=0.0
!endif
enddo
- write(*,*)
- write(*,*) 'State to state eV fL'
+! write(*,*)
+! write(*,*) 'State to state eV fL'
Do ii=1, nroot
osc_strength=2.0/3.0*(eci(ii)-eci(jj))*
.(mu_s2s(ii,jj,1)**2.0+mu_s2s(ii,jj,2)**2.0+mu_s2s(ii,jj,3)**2.0)
- write(*,11) jj, ii, (eci(ii)-eci(jj))*27.21139,
- .osc_strength
- enddo
- write(*,*)
- write(*,*)
- enddo
- write(*,*)'====================================================
- .=================='
- write(*,*)' end of nonlinear response sTD-DFT
- . program'
- write(*,*)'====================================================
- .=================='
- write(*,*)
+! write(*,11) jj, ii, (eci(ii)-eci(jj))*27.21139,
+! .osc_strength
+ enddo
+! write(*,*)
+! write(*,*)
+ enddo
+! write(*,*)'====================================================
+! .=================='
+! write(*,*)' end of nonlinear response sTD-DFT
+! . program'
+! write(*,*)'====================================================
+! .=================='
+! write(*,*)
11 format(i6,i9,f9.3,f11.4)
12 format(a1,i3,a17,i3,a1)
@@ -3105,7 +3106,7 @@ subroutine hyperpol_sos(nroot,nci,eci,Xci,Yci,xl,yl,zl,moci,
.,-45.56335/(freq(iroot)*2.0),';',45.56335/freq(iroot),','
.,45.56335/freq(iroot),')'
write(*,*)
- call PrintBeta(beta)
+ call PrintBeta(beta,5555)
write(*,*) '_____________________________________________
.________'
enddo
@@ -3138,10 +3139,12 @@ subroutine tpa_sos(nroot,nci,eci,Xci,Yci,xl,yl,zl,moci,
real*4 ::freq(num_freq+1)
real*4 ::Xci(nci,nroot), Yci(nci,nroot),eci(nci)
- real*8 ::sigma(3,3)
+ real*8 ::sigma(3,3),sigma_f,sigma_g,sigma_h
real*8 ::mu_s(nroot,3)
real*8 ::mu_s2s(nroot,nroot,3)
+ if(nroot.
+! along with std2. If not, see .
!
+!! ------------------------------------------------------------------------
program acis_prog
use stdacommon ! mostly input and primitive data
use kshiftcommon ! kshiftvariables
@@ -33,6 +34,10 @@ program acis_prog
integer imethod,inpchk,mform,nvec
logical molden,da,chkinp,xtbinp
integer, dimension(8) :: datetimevals
+ !!! libcint
+ double precision, allocatable :: overlap_AO(:),mu(:,:),mag(:,:)
+ double precision, allocatable :: velo(:,:),quadrupole(:,:)
+ real*8,allocatable :: help(:),help1(:),help2(:),help3(:)
call date_and_time(VALUES=datetimevals)
print '(I0,"-",I0,"-",I0,1X,I0,":",I0,":",I0,".",I3)',
@@ -41,22 +46,37 @@ program acis_prog
write(*,'(//
. 17x,''*********************************************'')')
write(*,'(17x,''* *'')')
- write(*,'(17x,''* s T D A *'')')
+ write(*,'(17x,''* s t d 2 *'')')
write(*,'(17x,''* *'')')
write(*,'(17x,''* S. Grimme *'')')
write(*,'(17x,''* Mulliken Center for Theoretical Chemistry *'')')
write(*,'(17x,''* Universitaet Bonn *'')')
- write(*,'(17x,''* Version 1.6.3 *'')')
- write(*,'(17x,''* Fri Aug 26 14:28:49 CEST 2022 *'')')
+ write(*,'(17x,''* *'')')
+ write(*,'(17x,''* M. de Wergifosse *'')')
+ write(*,'(17x,''* MOST/IMCN *'')')
+ write(*,'(17x,''* Universite Catholique de Louvain *'')')
+ write(*,'(17x,''* *'')')
+ write(*,'(17x,''* Version 2.0 *'')')
+ write(*,'(17x,''* Tue 07 Jan 2025 09:09:41 AM CET *'')')
write(*,'(17x,''*********************************************'')')
write(*,*)
- write(*,'('' Please cite as:'')')
+ write(*,'('' Please cite:'')')
+ write(*,*)
+ write(*,'('' For sTDA and sTD-DFT,'')')
write(*,'('' S. Grimme, J. Chem. Phys. 138 (2013) 244104'')')
- write(*,'('' M. de Wergifosse, S. Grimme, J. Phys. Chem A'')')
- write(*,'('' 125 (2021) 18 3841-3851'')')
+ write(*,'('' C. Bannwarth, S. Grimme Comput. Theor. Chem.
+ . 1040–1041 (2014) 45-53'')')
+ write(*,'('' M. de Wergifosse, S. Grimme, J. Phys. Chem A
+ . 125 (2021) 18 3841-3851'')')
+ write(*,*)
+ write(*,'('' For XsTDA and XsTD-DFT,'')')
+ write(*,'('' M. de Wergifosse, S. Grimme, J. Chem. Phys.
+ . 160 (2024) 204110'')')
+ write(*,'('' M. de Wergifosse, J. Phys. Chem. Lett. 15
+ . (2024) 51 12628–12635'')')
write(*,*)
write(*,'('' With contributions from:'')')
- write(*,'('' C. Bannwarth, P. Shushkov, M. de Wergifosse'')')
+ write(*,'('' C. Bannwarth, P. Shushkov, P. Beaujean'')')
write(*,*)
write(*,'(a,a)')'===============================================',
. '======================='
@@ -109,7 +129,14 @@ program acis_prog
rw=.false.
rw_dual=.false.
pt_off=.false.
- optrot=.false.
+ optrota=.false.
+ XsTD=.false.
+ cint=.true.
+ RSH_flag=.false.
+ SOS_2PA=.false.
+ Xcore=.false.
+ FULL2PA=.false.
+ multipole=.false.
! check for input file
inquire(file='.STDA',exist=da)
@@ -218,6 +245,25 @@ program acis_prog
num_trans=int(xx(1))
endif
+ if(index(dummy,'-SOS2PA').ne.0)then ! Do response function
+ SOS_2PA=.true.
+ rpachk=.true.
+ call getarg(i+1,dummy)
+ call readl(79,dummy,xx,nn)
+ num_trans=int(xx(1))
+ endif
+
+ if(index(dummy,'-hxc2PA').ne.0)then ! Do response function
+ FULL2PA=.true.
+ rpachk=.true.
+ call getarg(i+1,dummy)
+ call readl(79,dummy,xx,nn)
+ num_trans=int(xx(1))
+ XsTD=.true.
+ write(*,*) 'hxc2PA, only with XsTD-DFT'
+ cint=.true.
+ endif
+
if(index(dummy,'-s2s').ne.0)then ! Do response function
ESA=.true.
!rpachk=.true.
@@ -275,6 +321,310 @@ program acis_prog
Nnto=int(xx(1))
endif
+ if(index(dummy,'-XsTD').ne.0)then
+ XsTD=.true.
+ if(xtbinp.eqv..true.)stop 'xTB with XsTD is not implemented'
+ cint=.true.
+ write(*,*)'**********************'
+ write(*,*)'You choose to use XsTD'
+ write(*,*)'**********************'
+ !dokshift=.false.
+ if(rpachk.eqv..false.)then
+ write(*,*)'Velocity correction deactivated with XsTDA by default'
+ velcorr=.false.
+ endif
+ endif
+
+ if(index(dummy,'-libcintOFF').ne.0)then
+ cint=.false.
+ endif
+
+ if(index(dummy,'-CORE').ne.0)then
+ Xcore=.true.
+ call getarg(i+1,dummy)
+ call readl(79,dummy,xx,nn)
+ Ecore=int(xx(1))
+ call getarg(i+2,dummy)
+ call readl(79,dummy,xx,nn)
+ Ecore2=int(xx(1))
+ write(*,*)'Doing core to valence excitations'
+ write(*,*)'using an occupied space from'
+ write(*,*)Ecore, ' to ',Ecore2
+ endif
+! if(index(dummy,'-RSH').ne.0)then ! Do range-separated hybrid only with XsTD
+! RSH_flag=.true.
+! XsTD=.true.
+! cint=.true.
+! dokshift=.false.
+! call getarg(i+1,dummy)
+! call readl(79,dummy,xx,nn)
+! if(nn.gt.0) RSH=xx(1)
+! call getarg(i+2,dummy)
+! call readl(79,dummy,xx,nn)
+! if(nn.gt.0) RSH_ax=xx(1)
+! call getarg(i+3,dummy)
+! call readl(79,dummy,xx,nn)
+! if(nn.gt.0) RSH_beta=xx(1)
+! call getarg(i+4,dummy)
+! call readl(79,dummy,xx,nn)
+! if(nn.gt.0) RSH_sub=xx(1)
+! write(*,*)RSH_sub
+! RSH_sub=.true.
+! write(*,*)'Using a long-range corrected functional with XsTD'
+! write(*,*)'Range-separated hybrid parameter is ', RSH,RSH_ax,
+! . RSH_beta,RSH_sub
+! endif
+ 12 format(a,3f9.4,L)
+ if(index(dummy,'-CAMB3LYP').ne.0)then ! Do range-separated hybrid only with XsTD
+ RSH_flag=.true.
+ XsTD=.true.
+ cint=.true.
+ dokshift=.false.
+ RSH=0.33d0
+ RSH2=RSH
+ RSH_ax=0.19d0
+ RSH_beta=0.46d0
+ RSH_sub=.true.
+ ax=0.38d0
+ alpha=0.9d0
+ beta=1.86d0
+ write(*,*)'**********************'
+ write(*,*)'You choose to use XsTD'
+ write(*,*)'**********************'
+ write(*,*)'Using CAM-B3LYP with XsTD'
+ write(*,12)'Range-separated hybrid parameters are ', RSH,
+ . RSH_ax,RSH_beta,RSH_sub
+ if(rpachk.eqv..false.)then
+ write(*,*)'Velocity correction deactivated with XsTDA by default'
+ velcorr=.false.
+ endif
+ endif
+
+ if(index(dummy,'-wB97XD2').ne.0)then ! Do range-separated hybrid only with XsTD
+ RSH_flag=.true.
+ XsTD=.true.
+ cint=.true.
+ dokshift=.false.
+ RSH=0.2d0
+ RSH2=RSH
+ RSH_ax=0.222d0
+ RSH_beta=0.888d0
+ RSH_sub=.true.
+ ax=0.51d0
+ alpha=4.51d0
+ beta=8.0d0
+ write(*,*)'**********************'
+ write(*,*)'You choose to use XsTD'
+ write(*,*)'**********************'
+ write(*,*)'Using wB97X-D with XsTD'
+ write(*,12)'Range-separated hybrid parameters are ', RSH,
+ . RSH_ax,RSH_beta,RSH_sub
+ if(rpachk.eqv..false.)then
+ write(*,*)'Velocity correction deactivated with XsTDA by default'
+ velcorr=.false.
+ endif
+ endif
+
+ if(index(dummy,'-wB97XD3').ne.0)then ! Do range-separated hybrid only with XsTD
+ RSH_flag=.true.
+ XsTD=.true.
+ cint=.true.
+ dokshift=.false.
+ RSH=0.25d0
+ RSH2=RSH
+ RSH_ax=0.1957d0
+ RSH_beta=0.8043d0
+ RSH_sub=.true.
+ ax=0.51d0
+ alpha=4.51d0
+ beta=8.0d0
+ write(*,*)'**********************'
+ write(*,*)'You choose to use XsTD'
+ write(*,*)'**********************'
+ write(*,*)'Using wB97X-D3 with XsTD'
+ write(*,12)'Range-separated hybrid parameters are ', RSH,
+ . RSH_ax,RSH_beta,RSH_sub
+ if(rpachk.eqv..false.)then
+ write(*,*)'Velocity correction deactivated with XsTDA by default'
+ velcorr=.false.
+ endif
+ endif
+
+ if(index(dummy,'-wB97MV').ne.0)then ! Do range-separated hybrid only with XsTD
+ RSH_flag=.true.
+ XsTD=.true.
+ cint=.true.
+ dokshift=.false.
+ RSH=0.3d0
+ RSH2=RSH
+ RSH_ax=0.15d0
+ RSH_beta=0.85d0
+ RSH_sub=.true.
+ ax=0.51d0
+ alpha=4.51d0
+ beta=8.0d0
+ write(*,*)'**********************'
+ write(*,*)'You choose to use XsTD'
+ write(*,*)'**********************'
+ write(*,*)'Using wB97MV with XsTD'
+ write(*,12)'Range-separated hybrid parameters are ', RSH,
+ . RSH_ax,RSH_beta,RSH_sub
+ if(rpachk.eqv..false.)then
+ write(*,*)'Velocity correction deactivated with XsTDA by default'
+ velcorr=.false.
+ endif
+ endif
+
+ if(index(dummy,'-Bvel').ne.0)then
+ velcorr=.true.
+ write(*,*)'Velocity correction asked for XsTDA'
+ endif
+
+ if(index(dummy,'-oldwB97XD3').ne.0)then ! Do range-separated hybrid only with XsTD
+ RSH_flag=.true.
+ XsTD=.true.
+ cint=.true.
+ dokshift=.false.
+ RSH=0.25d0
+ RSH2=RSH
+ RSH_ax=0.1957d0
+ RSH_beta=1.0d0
+ RSH_sub=.false.
+ ax=0.51d0
+ alpha=4.51d0
+ beta=8.0d0
+ write(*,*)'**********************'
+ write(*,*)'You choose to use XsTD'
+ write(*,*)'**********************'
+ write(*,*)'Using oldwB97X-D3 with XsTD'
+ write(*,12)'Range-separated hybrid parameters are ', RSH,
+ . RSH_ax,RSH_beta,RSH_sub
+ if(rpachk.eqv..false.)then
+ write(*,*)'No velocity correction with XsTDA/RSH for the moment'
+ velcorr=.false.
+ endif
+ endif
+
+ if(index(dummy,'-oldwB97MV').ne.0)then ! Do range-separated hybrid only with XsTD
+ RSH_flag=.true.
+ XsTD=.true.
+ cint=.true.
+ dokshift=.false.
+ RSH=0.3d0
+ RSH2=RSH
+ RSH_ax=0.15d0
+ RSH_beta=1.0d0
+ RSH_sub=.false.
+ ax=0.51d0
+ alpha=4.51d0
+ beta=8.0d0
+ write(*,*)'**********************'
+ write(*,*)'You choose to use XsTD'
+ write(*,*)'**********************'
+ write(*,*)'Using oldwB97MV with XsTD'
+ write(*,12)'Range-separated hybrid parameters are ', RSH,
+ . RSH_ax,RSH_beta,RSH_sub
+ if(rpachk.eqv..false.)then
+ write(*,*)'No velocity correction with XsTDA/RSH for the moment'
+ velcorr=.false.
+ endif
+ endif
+
+ if(index(dummy,'-oldwB97XD2').ne.0)then ! Do range-separated hybrid only with XsTD
+ RSH_flag=.true.
+ XsTD=.true.
+ cint=.true.
+ dokshift=.false.
+ RSH=0.2d0
+ RSH2=RSH
+ RSH_ax=0.222d0
+ RSH_beta=1.0d0
+ RSH_sub=.false.
+ ax=0.51d0
+ alpha=4.51d0
+ beta=8.0d0
+ write(*,*)'**********************'
+ write(*,*)'You choose to use XsTD'
+ write(*,*)'**********************'
+ write(*,*)'Using oldwB97X-D with XsTD'
+ write(*,12)'Range-separated hybrid parameters are ', RSH,
+ . RSH_ax,RSH_beta,RSH_sub
+ if(rpachk.eqv..false.)then
+ write(*,*)'No velocity correction with XsTDA/RSH for the moment'
+ velcorr=.false.
+ endif
+ endif
+
+ if(index(dummy,'-SRC2R1').ne.0)then ! Do range-separated hybrid only with XsTD
+ RSH_flag=.true.
+ XsTD=.true.
+ cint=.true.
+ dokshift=.false.
+ RSH2=0.69d0 !short range mu
+ RSH=1.02d0 !long range mu
+ RSH_ax=0.55d0
+ RSH_beta=0.08d0
+ RSH_sub=.false.
+ !B3LYP parameters for the CSF screening
+ ax=0.2d0
+ alpha=1.516d0
+ beta=0.566d0
+ write(*,*)'**********************'
+ write(*,*)'You choose to use XsTD'
+ write(*,*)'**********************'
+ write(*,*)'Using SRC2-R1 with XsTD'
+ write(*,12)'Range-separated hybrid parameters are ', RSH,
+ . RSH_ax,RSH_beta,RSH_sub
+ if(rpachk.eqv..false.)then
+ write(*,*)'No velocity correction with XsTDA/RSH for the moment'
+ velcorr=.false.
+ endif
+ endif
+
+ if(index(dummy,'-SRC2R2').ne.0)then ! Do range-separated hybrid only with XsTD
+ RSH_flag=.true.
+ XsTD=.true.
+ cint=.true.
+ dokshift=.false.
+ RSH2=2.20d0 !short range mu
+ RSH=1.80d0 !long range mu
+ RSH_ax=0.91d0
+ RSH_beta=0.28d0
+ RSH_sub=.false.
+ !B3LYP parameters for the CSF screening
+ ax=0.2d0
+ alpha=1.516d0
+ beta=0.566d0
+ write(*,*)'**********************'
+ write(*,*)'You choose to use XsTD'
+ write(*,*)'**********************'
+ write(*,*)'Using SRC2-R2 with XsTD'
+ write(*,12)'Range-separated hybrid parameters are ', RSH,
+ . RSH_ax,RSH_beta,RSH_sub
+ if(rpachk.eqv..false.)then
+ write(*,*)'No velocity correction with XsTDA/RSH for the moment'
+ velcorr=.false.
+ endif
+ endif
+
+ if(index(dummy,'-intfull').ne.0)then
+ if(XsTD.eqv..true.)stop 'you cannot ask for full
+ .integrals and XsTD at the same time'
+ full=.true.
+ cint=.true.
+ rpachk=.true.
+ dokshift=.false.
+ endif
+
+ if(index(dummy,'-directintfull').ne.0)then
+ if(XsTD.eqv..true.)stop 'you cannot ask for full
+ .integrals and XsTD at the same time'
+ direct_full=.true.
+ cint=.true.
+ rpachk=.true.
+ dokshift=.false.
+ endif
+
if(index(dummy,'-chk').ne.0) chkinp=.true. ! do input check
if(index(dummy,'-vectm').ne.0)then
eigvec=.true. ! print eigenvectors
@@ -397,9 +747,60 @@ program acis_prog
ccccccccccccccccccccccccccccccccc
c precalculate primitive data
ccccccccccccccccccccccccccccccccc
+ if(cint)then
+ write(*,*)'*****************************'
+ write(*,*)'*using libcint integral deck*'
+ write(*,*)'*****************************'
+ write(*,*) 'SIZEOF(int)', SIZEOF(nbf)
+ allocate(overlap_AO(nbf*(nbf+1)/2))
+ call overlap(ncent,nprims,nbf,overlap_AO)
+ allocate(mu(nbf*(nbf+1)/2,1:3))
+ call dipole_moment(ncent,nprims,nbf,mu)
+! unfortunately libcint does not give the same result for the magnetic moment.
+! thus, we still use the old integral deck for the magnetic moment
+! allocate(mag(nbf*(nbf+1)/2,1:3))
+! call magnetic_moment(ncent,nprims,nbf,mag)
+ call intslvm2(ncent,nmo,nbf,nprims)
+ nao=nbf
+ if(nao.eq.0)nao=nprims
+ allocate(velo(nbf*(nbf+1)/2,1:3))
+ call velo_moment(ncent,nprims,nbf,velo)
+ open(unit=40,file='sint', form='unformatted',status='replace')
+ open(unit=31,file='xlint',form='unformatted',status='replace')
+ open(unit=32,file='ylint',form='unformatted',status='replace')
+ open(unit=33,file='zlint',form='unformatted',status='replace')
+! open(unit=34,file='xmint',form='unformatted',status='replace')
+! open(unit=35,file='ymint',form='unformatted',status='replace')
+! open(unit=36,file='zmint',form='unformatted',status='replace')
+ open(unit=37,file='xvint',form='unformatted',status='replace')
+ open(unit=38,file='yvint',form='unformatted',status='replace')
+ open(unit=39,file='zvint',form='unformatted',status='replace')
+ write(40)overlap_AO
+ close(40)
+ write(31)mu(:,1)
+ write(32)mu(:,2)
+ write(33)mu(:,3)
+ close(31)
+ close(32)
+ close(33)
+! write(34)mag(:,1)
+! write(35)mag(:,2)
+! write(36)mag(:,3)
+! close(34)
+! close(35)
+! close(36)
+ write(37)velo(:,1)
+ write(38)velo(:,2)
+ write(39)velo(:,3)
+ close(37)
+ close(38)
+ close(39)
+ deallocate(overlap_AO,mu,velo)
+ else
call intslvm(ncent,nmo,nbf,nprims)
nao=nbf
if(nao.eq.0)nao=nprims
+ endif
@@ -443,11 +844,8 @@ program acis_prog
21 format(3i10,3x,2f24.9)
11 format(3i5,2f9.4)
- if(rw_dual)then
+
deallocate(ipty,exip,cxip,atnam,eta)
- else
- deallocate(ipat,ipty,ipao,exip,cxip,atnam,eta)
- endif
cccccccccccccccccccccccccccccccccccccc
@@ -521,21 +919,21 @@ program acis_prog
if (imethod.eq.1) then
if(rw)then
call stda_rw(ncent,nmo,nao,xyz,cc,eps,occ,iaoat,thre,
- . thrp,ax,alpha,beta,ptlim,nvec)
+ . thrp,ax,alpha,beta,ptlim,nvec,nprims)
else
if(rw_dual)then
call stda_rw_dual(ncent,nmo,nao,xyz,cc,eps,occ,iaoat,thre,
. thrp,ax,alpha,beta,ptlim,nvec,ipat,ipao,nprims)
- deallocate(ipat,ipao)
else
call stda(ncent,nmo,nao,xyz,cc,eps,occ,iaoat,thre,
- . thrp,ax,alpha,beta,ptlim,nvec)
+ . thrp,ax,alpha,beta,ptlim,nvec,nprims)
endif
endif
else
call sutda(ncent,nmo,nao,xyz,cc,eps,occ,ccspin,iaoat,thre,
. thrp,ax,alpha,beta,ptlim,nvec)
endif
+ deallocate(ipat,ipao)
call date_and_time(VALUES=datetimevals)
print '(I0,"-",I0,"-",I0,1X,I0,":",I0,":",I0,".",I3)',
diff --git a/meson.build b/meson.build
index 42a6d92..a484c6a 100755
--- a/meson.build
+++ b/meson.build
@@ -1,125 +1,138 @@
-# This file is part of stda.
+# This file is part of std2.
#
# Copyright (C) 2019 Sebastian Ehlert
-#
-# stda is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# stda is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with xtb4stda. If not, see .
+# Copyright (C) 2024 Marc de Wergifosse
-# modified to include options for Windows with Intel Fortran only (Shoubhik Maiti, April 2022)
+# Modified by P. Beaujean
-project('stda', 'fortran',
- version: '1.6.1',
- license: 'LGPL3',
- meson_version: '>=0.51')
+project('std2', 'fortran',
+ version: '1.6.1',
+ meson_version: '>=0.51',
+ default_options : ['warning_level=0', 'fortran_std=legacy'],
+)
-if get_option('interface') == '64' and get_option('la_backend') != 'mkl'
- error('64 bit integer interface only supported for MKL backend')
+if get_option('interface') == '64' and (get_option('la_backend') == 'netlib' or get_option('la_backend') == 'openblas')
+ error('64 bit integer interface not supported by OpenBLAS/netlib backends, use -Dinterface=32')
endif
+# set compiler options
fc = meson.get_compiler('fortran')
-if fc.get_id() == 'gcc'
- add_project_arguments('-ffree-line-length-none', language: 'fortran')
- add_project_arguments('-fbacktrace', language: 'fortran')
- if get_option('interface') == '64'
- add_project_arguments('-fdefault-integer-8', language: 'fortran')
- endif
-elif fc.get_id() == 'intel'
- add_project_arguments('-axAVX2', language: 'fortran')
- if get_option('buildtype') == 'debug'
- add_project_arguments('-traceback', language: 'fortran')
- endif
- if get_option('interface') == '64'
- add_project_arguments('-i8', language: 'fortran')
- endif
- if get_option('static')
- add_project_link_arguments('-static', language: 'fortran')
- endif
-elif fc.get_id() == 'intel-cl' # for Windows with Intel Fortran
- add_project_arguments('-QaxCORE-AVX2', language: 'fortran')
- if get_option('buildtype') == 'debug'
- add_project_arguments('-traceback', language: 'fortran')
- endif
- if get_option('interface') == '64'
- add_project_arguments('-integer-size:64', language: 'fortran')
- endif
- if get_option('static')
- add_project_arguments('-MT', language: 'fortran') # linker does not need MT
- endif
+build_args = [
+ '-DPROJECT_NAME="' + meson.project_name() + '"',
+ '-DPROJECT_VERSION="' + meson.project_version() + '"',
+]
+
+if fc.has_argument('-march=native')
+ build_args += ['-march=native', '-fno-math-errno']
+ if fc.get_id() == 'intel'
+ build_args += ['-unroll-aggressive', '-ipo']
+ else
+ build_args += ['-funroll-loops', '-ftree-vectorize']
+ endif
+ message('added -march=native and loop unroling flags')
endif
-dependencies = []
+# configure project_dep
+project_dep = []
+libcint_options = ['with_fortran=true', 'with_cint2_interface=true']
la_backend = get_option('la_backend')
if la_backend == 'mkl'
- if host_machine.system() == 'windows'
- libmkl = [fc.find_library('libiomp5md')]
+ # build a pkg-config compatible string, list all possibilities with `pkg-config --list-all | grep "mkl"`
+ mkl_kind = 'mkl'
+ if get_option('static')
+ mkl_kind += '-static'
+ build_args += '-static'
else
- libmkl = [fc.find_library('pthread')]
- libmkl += fc.find_library('m')
- libmkl += fc.find_library('dl')
+ mkl_kind += '-dynamic'
endif
- if (fc.get_id() == 'intel') or (fc.get_id() == 'intel-cl')
- if get_option('interface') == '64'
- libmkl += fc.find_library('mkl_intel_ilp64')
+
+ if get_option('interface') == '64'
+ mkl_kind += '-ilp64'
+ # specific requirements for ilp64 libraries, see https://www.intel.com/content/www/us/en/docs/onemkl/developer-guide-windows/2023-0/using-the-ilp64-interface-vs-lp64-interface.html
+ build_args += '-DMKL_ILP64'
+ libcint_options += 'i8=true'
+ if fc.get_id() == 'intel' or fc.get_id() == 'intel-llvm'
+ build_args += '-i8'
else
- libmkl += fc.find_library('mkl_intel_lp64')
+ build_args += '-fdefault-integer-8'
endif
- libmkl += fc.find_library('mkl_intel_thread')
else
- if get_option('interface') == '64'
- libmkl += fc.find_library('mkl_gf_ilp64')
- else
- libmkl += fc.find_library('mkl_gf_lp64')
- endif
- libmkl += fc.find_library('mkl_gnu_thread')
+ mkl_kind += '-lp64'
endif
- libmkl += fc.find_library('mkl_core')
- if host_machine.system() != 'windows'
- libmkl += fc.find_library('iomp5')
+
+ if get_option('openmp')
+ mkl_kind += '-iomp'
+ else
+ mkl_kind += '-seq'
+ endif
+
+ message('MKL kind: ' + mkl_kind)
+
+ # backups for system that do not provide pkg-config
+ mkl_libraries = {
+ 'mkl-dynamic-ilp64-iomp': ['mkl_core', 'mkl_intel_ilp64', 'mkl_gnu_thread', 'iomp5', 'pthread', 'm', 'dl'],
+ 'mkl-dynamic-ilp64-seq': ['mkl_core', 'mkl_intel_ilp64', 'mkl_sequential', 'm', 'dl'],
+ 'mkl-dynamic-lp64-iomp': ['mkl_core', 'mkl_intel_lp64', 'mkl_gnu_thread', 'iomp5', 'pthread', 'm', 'dl'],
+ 'mkl-dynamic-lp64-seq': ['mkl_core', 'mkl_intel_lp64', 'mkl_sequential', 'm', 'dl']
+ # ... some of them are missing at the moment
+ }
+
+ mkl_dep = dependency(mkl_kind, required: false)
+ if mkl_dep.found() # pkg-config
+ project_dep += mkl_dep
+ else # back up to finding libraries one per one
+ foreach lib: mkl_libraries[mkl_kind]
+ project_dep += fc.find_library(lib)
+ endforeach
endif
- dependencies += libmkl
elif la_backend == 'openblas'
- dependencies += fc.find_library('openblas', required : true)
- dependencies += fc.find_library('lapack', required : true)
+ project_dep += fc.find_library('openblas', required : true)
+ project_dep += fc.find_library('lapack', required : true)
+elif la_backend == 'netlib'
+ project_dep += fc.find_library('blas', required : true)
+ project_dep += fc.find_library('lapack', required : true)
elif la_backend == 'custom'
foreach lib: get_option('custom_libraries')
- dependencies += fc.find_library(lib)
+ project_dep += fc.find_library(lib)
endforeach
-else
- dependencies += fc.find_library('blas', required : true)
- dependencies += fc.find_library('lapack', required : true)
endif
-if get_option('openmp')
- if fc.get_id() == 'intel'
- add_project_arguments('-qopenmp', language : 'fortran')
- add_project_link_arguments('-qopenmp', language : 'fortran')
- elif fc.get_id() == 'intel-cl'
- add_project_arguments('-Qopenmp', language : 'fortran')
+# add openMP if requested but MKL (and thus intel-openMP) was not used
+if la_backend != 'mkl' and get_option('openmp')
+ dep_openmp = dependency('openmp', required: false)
+ if dep_openmp.found()
+ project_dep += dep_openmp
else
- add_project_arguments('-fopenmp', language : 'fortran')
- add_project_link_arguments('-fopenmp', language : 'fortran')
+ if fc.get_id() == 'intel' or fc.get_id() == 'intel-llvm'
+ build_args += '-qopenmp'
+ else
+ build_args += '-fopenmp'
+ endif
endif
endif
-stda_srcs = [
+libcint_dep = fc.find_library('libcint', required: false)
+if not libcint_dep.found()
+ libcint_proj = subproject('libcint', default_options: libcint_options)
+ libcint_dep = libcint_proj.get_variable('libcint_dep')
+endif
+project_dep += libcint_dep
+
+message('Build args are: ' + ', '.join(build_args))
+
+# Sources
+std2_srcs = [
+ '2PA.f90',
'apbtrafo.f',
'block.f',
+ 'full.f',
'header.f',
'intpack.f90',
'intslvm.f',
'io.f',
+ 'libcint.f',
'linal.f',
'linear_response.f',
'main.f',
@@ -137,13 +150,14 @@ stda_srcs = [
'sfstda.f',
'sosor.f',
'srpapack.f',
- 'stdacommon.f90',
'stda.f',
+ 'stdacommon.f90',
'stda-rw.f',
'stda-rw_dual.f',
'stringmod.f90',
'sutda.f',
- 'velo.f'
+ 'velo.f',
+ 'xstd.f90',
]
g_spec_srcs = [
@@ -155,15 +169,32 @@ g2molden_srcs = [
'g2molden/stringmod.f90'
]
-stda_exe = executable(meson.project_name(), stda_srcs,
- dependencies: dependencies,
- install: true)
+# Executables
+std2_exe = executable(
+ meson.project_name(),
+ std2_srcs,
+ dependencies: project_dep,
+ fortran_args : build_args,
+ link_language : 'fortran',
+ install: true
+)
-g2molden_exe = executable('g2molden', g2molden_srcs,
- dependencies: dependencies,
- install: true)
+g2molden_exe = executable(
+ 'g2molden',
+ g2molden_srcs,
+ dependencies: project_dep,
+ fortran_args : build_args,
+ link_language : 'fortran',
+ install: true
+)
+g_spec_exe = executable(
+ 'g_spec', g_spec_srcs,
+ dependencies: project_dep,
+ fortran_args : build_args,
+ link_language : 'fortran',
+ install: true
+)
-g_spec_exe = executable('g_spec', g_spec_srcs,
- dependencies: dependencies,
- install: true)
+# add test
+test('valid input', std2_exe, args: ['-f', '../tests/water_sto3g.molden', '-sty', '3', '-ax', '1', '-e', '20'], suite: 'app')
diff --git a/meson_options.txt b/meson_options.txt
index 3987f1a..2e0cc85 100755
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,28 +1,43 @@
# This file is part of stda.
#
# Copyright (C) 2019 Sebastian Ehlert
-#
-# stda is free software: you can redistribute it and/or modify it under
-# the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# stda is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with xtb4stda. If not, see .
+# Copyright (C) 2024 Marc de Wergifosse
+
+# Modified by P. Beaujean
+
+option(
+ 'openmp',
+ type: 'boolean',
+ value: true,
+ description: 'use OpenMP parallelisation'
+)
+
+option(
+ 'la_backend',
+ type: 'combo',
+ value: 'mkl',
+ choices: ['mkl', 'openblas', 'netlib', 'custom'],
+ description : 'linear algebra backend'
+)
+
+option(
+ 'custom_libraries',
+ type: 'array',
+ value: [],
+ description: 'libraries to load for custom linear algebra backend'
+)
+
+option(
+ 'static',
+ type: 'boolean',
+ value: false,
+ description: 'Produce statically linked executables'
+)
-option('la_backend', type: 'combo', value: 'mkl',
- choices: ['mkl', 'openblas', 'netlib', 'custom'],
- description : 'linear algebra backend')
-option('custom_libraries', type: 'array', value: [],
- description: 'libraries to load for custom linear algebra backend')
-option('openmp', type: 'boolean', value: true,
- description: 'use OpenMP parallelisation')
-option('static', type: 'boolean', value: true,
- description: 'Produce statically linked executables')
-option('interface', type: 'combo', value: '32', choices: ['32', '64'],
- description: 'integer precision range in bits.')
+option(
+ 'interface',
+ type: 'combo',
+ value: '32',
+ choices: ['32', '64'],
+ description: 'integer precision range in bits.'
+)
diff --git a/molden.f b/molden.f
index 75fa111..b4aade1 100755
--- a/molden.f
+++ b/molden.f
@@ -1,20 +1,21 @@
-! This file is part of stda.
+! This file is part of std2.
!
-! Copyright (C) 2013-2019 Stefan Grimme
+! Copyright (C) 2013-2025 Stefan Grimme and Marc de Wergifosse
!
-! stda is free software: you can redistribute it and/or modify it under
+! std2 is free software: you can redistribute it and/or modify it under
! the terms of the GNU Lesser General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
-! stda is distributed in the hope that it will be useful,
+! std2 is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
-! along with stda. If not, see .
+! along with std2. If not, see .
!
+!! ------------------------------------------------------------------------
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
!
@@ -29,7 +30,7 @@ subroutine molden_file(ncent,nprims,nmo,icdim,nbf,imethod,cc,
integer:: nmo,nbf,imethod,icdim,ccspin(nmo),counter_BF
integer:: f_info(nbf),flag,flag2
real*8:: cc(icdim),norm(nprims)
-
+
open(unit=11,file='molden.molden')
open(unit=12,file='fnorm')
! read normalization
@@ -44,7 +45,7 @@ subroutine molden_file(ncent,nprims,nmo,icdim,nbf,imethod,cc,
write(11,21) atnam(i),i,int(co(i,4)),co(i,1:3)*0.52917721092
enddo
!Basis set (sp are seperated)
-
+
! Counting the number of prim in each contraction
prim=1
info=1
@@ -58,7 +59,7 @@ subroutine molden_file(ncent,nprims,nmo,icdim,nbf,imethod,cc,
endif
endif
enddo
-
+
write(11,*) '[GTO]'
at=0
counter_BF=0
@@ -85,14 +86,14 @@ subroutine molden_file(ncent,nprims,nmo,icdim,nbf,imethod,cc,
if(ipty(i)==2.and.flag==0) write(11,23)'p',info(i),'1.000000'
if(ipty(i)==5) write(11,23)'d',info(i),'1.000000'
if(ipty(i)==11) write(11,23)'f',info(i),'1.000000'
-
+
if(ipty(i)==14.or.ipty(i)==15.or.ipty(i)==16.or.
. ipty(i)==17.or.ipty(i)==18.or.ipty(i)==19) then
f_info(counter_BF)=ipty(i)
endif
-
-
+
+
endif
!
! Contractactions are normalized
@@ -116,7 +117,7 @@ subroutine molden_file(ncent,nprims,nmo,icdim,nbf,imethod,cc,
. /((2.0*exip(i))**3.0*dsqrt(2.0*exip(i))))/norm(i)
if(ipty(i)==11) write(11,24)exip(i),
. cxip(i)*dsqrt(5.5683279968317*1.875
- . /((2.0*exip(i))**4.0*dsqrt(2.0*exip(i))))/norm(i)
+ . /((2.0*exip(i))**4.0*dsqrt(2.0*exip(i))))/norm(i)
at=ipat(i)
if(at/=ipat(i+1)) write(11,*)
if(flag==1.and.ipty(i)==4)then
@@ -124,10 +125,10 @@ subroutine molden_file(ncent,nprims,nmo,icdim,nbf,imethod,cc,
flag2=0
endif
enddo
-
+
! MOs
-
- write(11,*) '[MO]'
+
+ write(11,*) '[MO]'
Do i=1,nmo
write(11,*) 'Sym= X'
write(11,*) 'Ene=',eps(i)
@@ -139,18 +140,18 @@ subroutine molden_file(ncent,nprims,nmo,icdim,nbf,imethod,cc,
endif
write(11,*) 'Occup=',int(occ(i))
Do j=1,nbf
-
+
! f molden order
if(f_info(j)==14.or.f_info(j)==15.or.f_info(j)==16.or.
. f_info(j)==17.or.f_info(j)==18.or.f_info(j)==19) then
-
+
if(f_info(j)==14)write(11,*) j, cc((i-1)*nbf+j+2) ! 16
if(f_info(j)==15)write(11,*) j, cc((i-1)*nbf+j-1) ! 14
if(f_info(j)==16)write(11,*) j, cc((i-1)*nbf+j-1) ! 15
if(f_info(j)==17)write(11,*) j, cc((i-1)*nbf+j+1) ! 18
if(f_info(j)==18)write(11,*) j, cc((i-1)*nbf+j+1) ! 19
if(f_info(j)==19)write(11,*) j, cc((i-1)*nbf+j-2) ! 17
-
+
else
write(11,*) j, cc((i-1)*nbf+j)
endif
@@ -159,10 +160,10 @@ subroutine molden_file(ncent,nprims,nmo,icdim,nbf,imethod,cc,
write(11,*)
close(11)
-
+
21 format(a,2i7,3f16.8)
- 22 format(i,3x,a)
- 23 format(a,3x,i,3x,a)
+ 22 format(i7,3x,a)
+ 23 format(a,3x,i7,3x,a)
24 format(2f16.8)
25 format(3f16.8)
diff --git a/normalize.f b/normalize.f
index b88e6de..58dbaa3 100755
--- a/normalize.f
+++ b/normalize.f
@@ -1,20 +1,21 @@
-! This file is part of stda.
+! This file is part of std2.
!
-! Copyright (C) 2013-2019 Stefan Grimme
+! Copyright (C) 2013-2025 Stefan Grimme and Marc de Wergifosse
!
-! stda is free software: you can redistribute it and/or modify it under
+! std2 is free software: you can redistribute it and/or modify it under
! the terms of the GNU Lesser General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
-! stda is distributed in the hope that it will be useful,
+! std2 is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
-! along with stda. If not, see .
+! along with std2. If not, see .
!
+!! ------------------------------------------------------------------------
ccccccccccccccccccccccccccccccccccc
! optional: Normalization of AOs c
ccccccccccccccccccccccccccccccccccc
@@ -22,14 +23,14 @@
subroutine normalize(cartbas,nprims,ipao,ipty,exip,cxip)
implicit none
logical, intent ( in ) :: cartbas
- integer, intent ( in ) :: ipao(nprims),ipty(nprims)
+ integer, intent ( in ) :: ipao(nprims),ipty(nprims)
integer, intent ( in ) :: nprims
- real*8, intent( in ) :: exip(nprims)
+ real*8, intent( in ) :: exip(nprims)
real*8, intent( inout ) :: cxip(nprims)
integer i,j,k,l,iprimao,iprimtyp,jprimao,jprimtyp
integer ifac,lang,lx,my,nz
real*8 fnorm,summe,dzaehl,dnenn,expon,xlinf
-
+
open(unit=11,file='fnorm')
write(*,'(A)',advance='no') 'normalizing...'
j=1
@@ -63,7 +64,7 @@ subroutine normalize(cartbas,nprims,ipao,ipty,exip,cxip)
dnenn=dnenn**expon
summe=summe+dzaehl/dnenn
enddo
- enddo
+ enddo
summe=dsqrt(summe)
fnorm=fnorm*summe
fnorm=xlinf/fnorm
@@ -111,7 +112,7 @@ subroutine normalize(cartbas,nprims,ipao,ipty,exip,cxip)
! enddo
! enddo
! summe=fnorm*summe
-! write(*,*) 'self ovlp:', summe
+! write(*,*) 'self ovlp:', summe
! j=i
! endif
! endif
@@ -131,16 +132,16 @@ subroutine deflmna(iprtyp,lx,my,nz,lang,xlinf)
my=0
nz=0
lang=0
-c=======================================================================
-c cartesian gaussian functions (6d,10f...)
-c s,px, py pz, dx**2 dy**2 dz**2 dxy dxz dyz
-c 1 2 3 4 5 6 7 8 9 10
-c fxxx, fyyy, fzzz, fxxy, fxxz, fyyx, fyyz, fxzz, fyzz, fxyz
-c 11 12 13 14 15 16 17 18 19 20
+c=======================================================================
+c cartesian gaussian functions (6d,10f...)
+c s,px, py pz, dx**2 dy**2 dz**2 dxy dxz dyz
+c 1 2 3 4 5 6 7 8 9 10
+c fxxx, fyyy, fzzz, fxxy, fxxz, fyyx, fyyz, fxzz, fyzz, fxyz
+c 11 12 13 14 15 16 17 18 19 20
c
c assign for each ipty, the angular momentum (L), and the expinents l,m,n of x,y,z
c linf is the factor to multiply normalized functions that are linearly dependent (e.g. dx**2,dy**2,dz**2)
-c=======================================================================
+c=======================================================================
select case(iprtyp)
case(1)
lx=0
@@ -190,14 +191,14 @@ subroutine deflmna(iprtyp,lx,my,nz,lang,xlinf)
nz=0
lang=2
xlinf=dsqrt(3.0d0)
-c xlinf=1.0d0
+c xlinf=1.0d0
case(9)
lx=1
my=0
nz=1
lang=2
xlinf=dsqrt(3.0d0)
-c xlinf=1.0d0
+c xlinf=1.0d0
case(10)
lx=0
my=1
@@ -304,4 +305,3 @@ subroutine dblfac(iin,iout)
iout=jdem/jnum
return
end
-
diff --git a/onetri.f b/onetri.f
index 39b2244..b00e4e6 100755
--- a/onetri.f
+++ b/onetri.f
@@ -1,19 +1,21 @@
-! This file is part of stda.
+! This file is part of std2.
!
-! Copyright (C) 2013-2019 Stefan Grimme
+! Copyright (C) 2013-2025 Stefan Grimme and Marc de Wergifosse
!
-! stda is free software: you can redistribute it and/or modify it under
+! std2 is free software: you can redistribute it and/or modify it under
! the terms of the GNU Lesser General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
-! stda is distributed in the hope that it will be useful,
+! std2 is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
-! along with stda. If not, see .
+! along with std2. If not, see .
+!
+!! ------------------------------------------------------------------------
!
SUBROUTINE ONETRI(ITY,S,S1,S2,ARRAY,N,IVAL)
IMPLICIT REAL*8 (A-H,O-Z)
@@ -29,7 +31,7 @@ SUBROUTINE ONETRI(ITY,S,S1,S2,ARRAY,N,IVAL)
C N LINEAR DIMENSION OF ARRAYS
C BERND HESS, UNIVERSITY OF BONN, JANUARY 1991
DIMENSION S(*),S1(*),S2(*),ARRAY(N,IVAL)
-
+
C
C DETERMINE IF WE HAVE AN ANTISYMMETRIC INTEGRAL
IF (ITY.EQ.-1) GOTO 99
@@ -57,7 +59,7 @@ SUBROUTINE BLOWSY(ITY,A,B,N)
REAL*8 A(*),B(N,N)
C
C DETERMINE IF WE HAVE AN ANTISYMMETRIC INTEGRAL
-
+
IF (ITY.EQ.-1) GOTO 99
IJ=0
DO 1 I=1,N
@@ -80,4 +82,3 @@ SUBROUTINE BLOWSY(ITY,A,B,N)
11 CONTINUE
RETURN
END
-
diff --git a/pckao.f b/pckao.f
index c63efa9..1ce582b 100755
--- a/pckao.f
+++ b/pckao.f
@@ -1,23 +1,24 @@
-! This file is part of stda.
+! This file is part of std2.
!
-! Copyright (C) 2013-2019 Stefan Grimme
+! Copyright (C) 2013-2025 Stefan Grimme and Marc de Wergifosse
!
-! stda is free software: you can redistribute it and/or modify it under
+! std2 is free software: you can redistribute it and/or modify it under
! the terms of the GNU Lesser General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
-! stda is distributed in the hope that it will be useful,
+! std2 is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
-! along with stda. If not, see .
+! along with std2. If not, see .
!
+!! ------------------------------------------------------------------------
SUBROUTINE pckao(NPR,NAO,A,B)
use stdacommon
- IMPLICIT REAL*8(A-H,O-Z)
+ IMPLICIT REAL*8(A-H,O-Z)
integer*8 ij,kl,k,iaa,iii
dimension a(*),b(*)
@@ -27,7 +28,7 @@ SUBROUTINE pckao(NPR,NAO,A,B)
do i=1,npr
do j=1,i
k=k+1
- b(k)=a(k)
+ b(k)=a(k)
enddo
enddo
return
@@ -47,12 +48,12 @@ SUBROUTINE pckao(NPR,NAO,A,B)
iaj=ipao(j)
iaa=max(iaj,iai)
iii=min(iaj,iai)
- ij=iii+iaa*(iaa-1)/2
+ ij=iii+iaa*(iaa-1)/2
b(ij)=b(ij)+a(kl)*c1*c2*2.0d0
enddo
kl=kl+1
ij=iai
- ij=ij+ij*(ij-1)/2
+ ij=ij+ij*(ij-1)/2
b(ij)=b(ij)+a(kl)*c1*c1
enddo
@@ -70,7 +71,7 @@ SUBROUTINE pckao(NPR,NAO,A,B)
SUBROUTINE pckao3(NPR,NAO,A1,A2,A3,B1,B2,B3)
use stdacommon
- IMPLICIT REAL*8(A-H,O-Z)
+ IMPLICIT REAL*8(A-H,O-Z)
integer*8 ij,kl,k
dimension a1(*),b1(*)
@@ -82,9 +83,9 @@ SUBROUTINE pckao3(NPR,NAO,A1,A2,A3,B1,B2,B3)
do i=1,npr
do j=1,i
k=k+1
- b1(k)=a1(k)
- b2(k)=a2(k)
- b3(k)=a3(k)
+ b1(k)=a1(k)
+ b2(k)=a2(k)
+ b3(k)=a3(k)
enddo
enddo
return
@@ -106,14 +107,14 @@ SUBROUTINE pckao3(NPR,NAO,A1,A2,A3,B1,B2,B3)
iaj=ipao(j)
iaa=max(iaj,iai)
iii=min(iaj,iai)
- ij=iii+iaa*(iaa-1)/2
+ ij=iii+iaa*(iaa-1)/2
ccf=c1*c2*2.0d0
b1(ij)=b1(ij)+a1(kl)*ccf
b2(ij)=b2(ij)+a2(kl)*ccf
b3(ij)=b3(ij)+a3(kl)*ccf
enddo
kl=kl+1
- ij=iai
+ ij=iai
ij=ij+ij*(ij-1)/2
b1(ij)=b1(ij)+a1(kl)*c1*c1
b2(ij)=b2(ij)+a2(kl)*c1*c1
diff --git a/print_nto.f b/print_nto.f
index dcdb3a7..d387009 100755
--- a/print_nto.f
+++ b/print_nto.f
@@ -1,20 +1,21 @@
-! This file is part of stda.
+! This file is part of std2.
!
-! Copyright (C) 2013-2019 Stefan Grimme
+! Copyright (C) 2013-2025 Stefan Grimme and Marc de Wergifosse
!
-! stda is free software: you can redistribute it and/or modify it under
+! std2 is free software: you can redistribute it and/or modify it under
! the terms of the GNU Lesser General Public License as published by
! the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
-! stda is distributed in the hope that it will be useful,
+! std2 is distributed in the hope that it will be useful,
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU Lesser General Public License for more details.
!
! You should have received a copy of the GNU Lesser General Public License
-! along with stda. If not, see .
+! along with std2. If not, see .
!
+!! ------------------------------------------------------------------------
! written by Marc de Wegifosse 2019
! need a cleanup ...
@@ -37,7 +38,6 @@ subroutine print_nto(Xci,ca,moci,nci,nroot,nao,iconf,maxconf,
. no,nv)
use stdacommon
use commonresp
- use commonlogicals
implicit none
integer:: moci,nci,nroot,nao,maxconf,no,nv
real*4:: Xci(nci,nroot),X(no,nv),MO(nao)
@@ -73,11 +73,7 @@ subroutine print_nto(Xci,ca,moci,nci,nroot,nao,iconf,maxconf,
enddo
close(12,status='delete')
open(unit=11,file='NTOao')
- if(rw_dual)then
allocate(ipty(nprims),info(nprims))
- else
- allocate(ipat(nprims),ipty(nprims),ipao(nprims),info(nprims))
- endif
allocate(atnam(ncent),exip(nprims),cxip(nprims),co(ncent,4))
allocate(f_info(nbf))
Do i=1, nprims
@@ -143,7 +139,7 @@ subroutine print_nto(Xci,ca,moci,nci,nroot,nao,iconf,maxconf,
write(14,*)'load ',fname
- write(15,'(a,i,a)')'NTO ',k,'
'
+ write(15,'(a,i7,a)')'NTO ',k,'
'
write(15,'(a)')''
open(unit=13,file=fname)
@@ -325,8 +321,8 @@ subroutine print_nto(Xci,ca,moci,nci,nroot,nao,iconf,maxconf,
write(15,'(a)')'