Skip to content

Commit

Permalink
format geometry_optimization
Browse files Browse the repository at this point in the history
Signed-off-by: albert <92109627+Albkat@users.noreply.github.com>
  • Loading branch information
Albkat committed Jan 23, 2024
1 parent 1c1e699 commit 21a4c70
Show file tree
Hide file tree
Showing 11 changed files with 596 additions and 290 deletions.
126 changes: 126 additions & 0 deletions optts.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
subroutine optts(n,at,xyz,q,qsh,nshell,z,cn,nel,nopen,nbf,nao,P,wb, &
& kspd,gscal,kcn,xbrad,xbdamp,alphaj,d3a1,d3a2,d3s8, &
& d3atm,egap,et,maxiter,epot,grd)

use iso_fortran_env, only : wp => real64
use setcommon
use splitcommon
use atmass
implicit none

integer :: n,at(n),nel,nopen,nbf,nao,icall,nshell,maxiter
real(wp) :: xyz(3,n),epot,wb(n,n),q(n),z(n),kspd(6),et,egap
real(wp) :: cn(n),grd(3,n),qsh(nshell),P(nao,nao)
real(wp) :: gscal,kcn(4),xbrad,xbdamp,alphaj,d3a1,d3a2,d3s8,d3atm

real(wp),allocatable:: coord(:,:), freq(:), u(:,:), uu(:,:)
real(wp),allocatable:: xyza (:,:,:), rmass(:), e(:), e2(:), geo(:,:)
real(wp),allocatable:: coord0(:,:), displ(:), xyzmin(:,:), bmat(:,:)
real(wp),allocatable:: x(:),b(:),c(:),d(:),xx(:),yy(:),yy1(:),yy2(:)

real(wp) :: norm,thr
integer :: i,j,k,m,n3,ii,ia,ic,isave,nprj,mode,maxoptiter
character(len=2) :: asym
character(len=30) :: fname
logical :: ex,fail

thr=-10.0_wp ! modes below this value are projected out !
mode=tsroot+6
fname='xtb_normalmodes'

write(*,*)
write(*,'(7x,''======================================='')')
write(*,'(7x,''| T S O P T I M I Z E R |'')')
write(*,'(7x,''======================================='')')
write(*,*)


write(*,*) 'normal mode file : ',trim(fname)
write(*,*) 'root for TS : ',mode

! error section
inquire(file=fname,exist=ex)
if (.not.ex) then
write(*,*) 'run -hess first!'
return
endif

!> DoF
n3=3*n
allocate(freq(n3),u(n3,n3),rmass(n3))

! read normal modes !
! normal case !
open(newunit=112,file=fname,form='unformatted')
read (112)k
if(k.ne.n3) stop 'severe read error on modes'
read (112)freq
read (112)rmass
read (112)u
close(112)

! remove masses from normal modes and re-normalize !
nprj=0
do m=7,n3
norm=0

! loop through the atoms
do ia=1,n
! loop through compnents
do ic=1,3


ii = (ia-1)*3+ic
u(ii,m)=u(ii,m)*sqrt(ams(at(ia))) ! remove atomic masses
norm=norm+u(ii,m)**2 ! renormalize

enddo
enddo

u(1:n3,m)=u(1:n3,m)/(sqrt(norm)+1.d-12)
if(freq(m).lt.thr) nprj=nprj+1
enddo

allocate(uu(n3,nprj))
k=0
do i=7,n3
if(freq(i).lt.thr) then
k=k+1
uu(1:n3,k)=u(1:n3,i)
endif
enddo

maxoptiter=25
isave=micro_opt
micro_opt=1000 ! no coordinate update in ancopt

write(*,'(''frequency /cm-1 :'',F12.2)')freq(mode)
write(*,'(''maxiter (opt) :'',i5 )')maxoptiter
write(*,'(''optlevel :'',i5 )')optlev
write(*,'(''# of projected modes :'',i5 )')nprj

open(unit=112,file='.xtbtmpmode',form='unformatted')
write(112) nprj
write(112) uu
close(112)

tsopt=.false.
call ancopt(n,at,xyz,q,qsh,nshell,z,cn,nel,nopen,nbf,nao,
. P,wb,kspd,gscal,kcn,xbrad,xbdamp,alphaj,d3a1,d3a2,d3s8,
. d3atm,egap,et,maxiter,maxoptiter,epot,grd,optlev,
. .true.,fail)

call system('rm .xtbtmpmode 2>/dev/null') ! normal operation
micro_opt =isave ! back to default
tsopt=.true.

! call system('mv hessian hessian.xtbtmp 2>/dev/null') ! don't use hessian in ancopt

call ancopt(n,at,xyz,q,qsh,nshell,z,cn,nel,nopen,nbf,nao,
. P,wb,kspd,gscal,kcn,xbrad,xbdamp,alphaj,d3a1,d3a2,d3s8,
. d3atm,egap,et,maxiter,maxoptcycle,epot,grd,optlev,
. .true.,fail)

! call system('mv hessian.xtbtmp hessian 2>/dev/null')

end subroutine optts
198 changes: 115 additions & 83 deletions src/axis_trafo.f90
Original file line number Diff line number Diff line change
Expand Up @@ -112,96 +112,128 @@ subroutine axis(numat,nat,xyz,aa,bb,cc)
return
end subroutine axis

subroutine axis2(numat,nat,xyz,aa,bb,cc,avmom,sumw)
use xtb_splitparam
implicit double precision (a-h,o-z)
dimension xyz(3,numat)
integer nat(numat)

PARAMETER (BOHR=0.52917726)
dimension t(6), rot(3), xyzmom(3), eig(3), evec(3,3)
dimension x(numat),y(numat),z(numat),coord(3,numat)
data t /6*0.d0/
!************************************************************************
!* const1 = 10**40/(n*a*a)
!* n = avergadro's number
!* a = cm in an angstrom
!* 10**40 is to allow units to be 10**(-40)gram-cm**2
!*
!************************************************************************
const1 = 1.66053d0
!************************************************************************
!*
!* const2 = conversion factor from angstrom-amu to cm**(-1)
!*
!* = (planck's constant*n*10**16)/(8*pi*pi*c)
!* = 6.62618*10**(-27)[erg-sec]*6.02205*10**23*10**16/
!* (8*(3.1415926535)**2*2.997925*10**10[cm/sec])
!*
!************************************************************************
const2=16.8576522d0

sumw=1.d-20
sumwx=0.d0
sumwy=0.d0
sumwz=0.d0

coord(1:3,1:numat)=xyz(1:3,1:numat)*bohr
subroutine axis2(n,xyz,aa,bb,cc,avmom,sumw)

use xtb_splitparam, only : atmass
use xtb_mctc_convert, only : autoaa

implicit double precision (a-h,o-z)

!> number of atoms
integer, intent(in) :: n

!> cartesian coordinates
real(wp), intent(in) :: xyz(:,:)

!> rotational constants
real(wp), intent(out) :: aa,bb,cc

!> average moment of inertia
real(wp), intent(out) :: avmom

!> sum of atomic masses
real(wp), intent(out) :: sumw

!> const1 = 10**40/(n*a*a)
!> n = avergadro's number
!> a = cm in an angstrom
!> 10**40 is to allow units to be 10**(-40)gram-cm**2
real(wp), parameter :: const1 = 1.66053_wp

!> const2 = conversion factor from angstrom-amu to cm**(-1)
!> = (planck's constant*n*10**16)/(8*pi*pi*c)
!> = 6.62618*10**(-27)[erg-sec]*6.02205*10**23*10**16/
!> (8*(3.1415926535)**2*2.997925*10**10[cm/sec])
real(wp), parameter :: const2 = 16.8576522_wp

!> temporary variables
real(wp) :: xsum,eps,ams

!> weighted sum of coordinates
real(wp) :: sumwx,sumwy,sumwz

!> loop variables
integer :: i

!> temporary arrays
real(wp) :: t(6), rot(3), xyzmom(3), eig(3), evec(3,3)
real(wp) :: x(n),y(n),z(n)

!> Cartesian coordinates in Bohr
real(wp) :: coord(3,n)

t(:) = 0.0_wp
sumw = 0.0_wp
sumwx = 0.0_wp
sumwy = 0.0_wp
sumwz = 0.0_wp

! convert Bohr to Angstrom !
coord(:,:) = xyz(:,:) * autoaa

! cma !
do i=1,n
sumw=sumw+atmass(i)
sumwx=sumwx+atmass(i)*coord(1,i)
sumwy=sumwy+atmass(i)*coord(2,i)
sumwz=sumwz+atmass(i)*coord(3,i)
enddo

sumwx=sumwx/sumw
sumwy=sumwy/sumw
sumwz=sumwz/sumw

do i=1,n
x(i)=coord(1,i)-sumwx
y(i)=coord(2,i)-sumwy
z(i)=coord(3,i)-sumwz
enddo

!************************************************************************
!* matrix for moments of inertia is of form
!*
!* | y**2+z**2 |
!* | -y*x z**2+x**2 | -i =0
!* | -z*x -z*y x**2+y**2 |
!*
!************************************************************************
do i=1,6
t(i)=dble(i)*1.0d-10
enddo

do i=1,n
t(1)=t(1)+atmass(i)*(y(i)**2+z(i)**2)
t(2)=t(2)-atmass(i)*x(i)*y(i)
t(3)=t(3)+atmass(i)*(z(i)**2+x(i)**2)
t(4)=t(4)-atmass(i)*z(i)*x(i)
t(5)=t(5)-atmass(i)*y(i)*z(i)
t(6)=t(6)+atmass(i)*(x(i)**2+y(i)**2)
enddo

call rsp(t,3,3,eig,evec)

do i=1,3

if(eig(i).lt.3.d-4) then
eig(i)=0.d0
rot(i)=0.d0
else
rot(i)=2.9979245d+4*const2/eig(i)
endif

do i=1,numat
sumw=sumw+atmass(i)
sumwx=sumwx+atmass(i)*coord(1,i)
sumwy=sumwy+atmass(i)*coord(2,i)
sumwz=sumwz+atmass(i)*coord(3,i)
enddo
xyzmom(i)=eig(i)*const1

sumwx=sumwx/sumw
sumwy=sumwy/sumw
sumwz=sumwz/sumw
f=1.0d0/bohr
do i=1,numat
x(i)=coord(1,i)-sumwx
y(i)=coord(2,i)-sumwy
z(i)=coord(3,i)-sumwz
enddo
enddo

!************************************************************************
!* matrix for moments of inertia is of form
!*
!* | y**2+z**2 |
!* | -y*x z**2+x**2 | -i =0
!* | -z*x -z*y x**2+y**2 |
!*
!************************************************************************
do i=1,6
t(i)=dble(i)*1.0d-10
enddo
do i=1,numat
t(1)=t(1)+atmass(i)*(y(i)**2+z(i)**2)
t(2)=t(2)-atmass(i)*x(i)*y(i)
t(3)=t(3)+atmass(i)*(z(i)**2+x(i)**2)
t(4)=t(4)-atmass(i)*z(i)*x(i)
t(5)=t(5)-atmass(i)*y(i)*z(i)
t(6)=t(6)+atmass(i)*(x(i)**2+y(i)**2)
enddo
call rsp(t,3,3,eig,evec)
do i=1,3
if(eig(i).lt.3.d-4) then
eig(i)=0.d0
rot(i)=0.d0
else
rot(i)=2.9979245d+4*const2/eig(i)
endif
xyzmom(i)=eig(i)*const1
enddo
aa=rot(3)/2.9979245d+4
bb=rot(2)/2.9979245d+4
cc=rot(1)/2.9979245d+4

aa=rot(3)/2.9979245d+4
bb=rot(2)/2.9979245d+4
cc=rot(1)/2.9979245d+4
avmom=1.d-47*(xyzmom(1)+xyzmom(2)+xyzmom(3))/3.
avmom=1.d-47*(xyzmom(1)+xyzmom(2)+xyzmom(3))/3.

return
end subroutine axis2
end subroutine axis2

subroutine axisvec(numat,nat,xyz,aa,bb,cc,evec)
use xtb_splitparam
Expand Down
Loading

0 comments on commit 21a4c70

Please sign in to comment.