652
723
value = value.and.MA_push_get(mt_dbl, (3*nion), 'r1',r1(2),r1(1))
653
724
value = value.and.MA_push_get(mt_dbl, (3*nion), 'r2',r2(2),r2(1))
654
725
value = value.and.MA_push_get(mt_dbl, (3*nion), 'r3',r3(2),r3(1))
726
value = value.and.MA_push_get(mt_dbl, (3*nion),
727
> 'rmid',rmid(2),rmid(1))
655
728
if (.not.value) call errquit('neb_initial_path failed',1,0)
657
730
value = value.and.geom_create(geom,'neb_tmp')
658
value = value.and.geom_rtdb_load(rtdb,geom,'neb_end')
732
!*** try neb_end, then endgeom ****
733
if (.not.geom_rtdb_load(rtdb,geom,'neb_end')) then
734
value = value.and.geom_rtdb_load(rtdb,geom,'endgeom')
659
736
value = value.and.geom_cart_coords_get(geom,dbl_mb(r2(1)))
660
value = value.and.geom_rtdb_load(rtdb,geom,'neb_start')
738
!*** try neb_start, then geometry****
739
if (.not.geom_rtdb_load(rtdb,geom,'neb_start')) then
740
value = value.and.geom_rtdb_load(rtdb,geom,'geometry')
661
742
value = value.and.geom_cart_coords_get(geom,dbl_mb(r1(1)))
662
743
if (.not.value) call errquit('neb_initial_path failed',2,0)
665
t = (i-1)/dble(nbeads-1)
667
call dcopy(3*nion,dbl_mb(r1(1)),1,dbl_mb(r3(1)),1)
668
call dscal(3*nion,(1.0d0-t),dbl_mb(r3(1)),1)
669
call daxpy(3*nion,t,dbl_mb(r2(1)),1,dbl_mb(r3(1)),1)
671
geom_name = 'neb_bead'//bead_index_name(i)//':geom'
672
movecs_name = 'neb_bead'//bead_index_name(i)//'.movecs'
673
geomlen = inp_strlen(geom_name)
674
movecslen = inp_strlen(movecs_name)
675
value = value.and.geom_cart_coords_set(geom,dbl_mb(r3(1)))
676
value = value.and.geom_rtdb_store(rtdb,geom,
677
> geom_name(1:geomlen))
679
call add_bead_list(bead_list,
680
> movecs_name(1:movecslen),
681
> geom_name(1:geomlen))
745
if (.not.rtdb_get(rtdb,'neb:hasmiddle',mt_log,1,hasmiddle))
746
> hasmiddle = .false.
749
if (.not.geom_rtdb_load(rtdb,geom,'neb_middle')) then
750
if (.not.geom_rtdb_load(rtdb,geom,'midgeom')) then
754
if (.not.geom_cart_coords_get(geom,dbl_mb(rmid(1))))
755
> call errquit('neb_initial_path failed',2,0)
761
> " - Generating initial path by linear interpolation"
762
write(luout,'(A,I4)') " + number images = ",nbeads
765
> " + neb_start (geometry) geometry -->",
766
> " neb_middle (midgeom) geometry -->",
767
> " neb_end (endgeom) geometry"
770
> " + neb_start (geometry) geometry -->",
771
> " neb_end (endgeom) geometry"
777
if (.not.rtdb_get(rtdb,'neb:impose',mt_log,1,impose))
781
value = MA_push_get(mt_int,(2*nion),'ifit',ifit(2),ifit(1))
783
> MA_push_get(mt_dbl,(nion),'wfit',wfit(2),wfit(1))
784
if(.not.value) call errquit('neb_initial_path failed',3,MA_ERR)
787
call neb_impose(nion,dbl_mb(r1(1)),dbl_mb(rmid(1)),
788
> nfit,int_mb(ifit(1)),dbl_mb(wfit(1)),rms1,rms2)
791
> " - Imposing neb_mid (midgeom) geometry onto",
792
> " neb_start (geometry) geometry"
793
write(luout,'(A,F10.6)') " + initial rmsq = ",rms1
794
write(luout,'(A,F10.6)') " + imposed rmsq = ",rms2
797
call neb_impose(nion,dbl_mb(rmid(1)),dbl_mb(r2(1)),
798
> nfit,int_mb(ifit(1)),dbl_mb(wfit(1)),rms1,rms2)
801
> " - Imposing neb_end geometry onto neb_mid geometry"
802
write(luout,'(A,F10.6)') " + initial rmsq = ",rms1
803
write(luout,'(A,F10.6)') " + imposed rmsq = ",rms2
806
call neb_impose(nion,dbl_mb(r1(1)),dbl_mb(r2(1)),
807
> nfit,int_mb(ifit(1)),dbl_mb(wfit(1)),rms1,rms2)
810
> " - Imposing neb_end (endgeom) geometry",
811
> " onto neb_start (geometry) geometry"
812
write(luout,'(A,F10.6)') " + initial rmsq = ",rms1
813
write(luout,'(A,F10.6)') " + imposed rmsq = ",rms2
817
value = MA_pop_stack(wfit(2))
818
value = value.and.MA_pop_stack(ifit(2))
819
if(.not.value) call errquit('neb_initial_path failed',4,MA_ERR)
824
if(.not.ma_push_get(mt_dbl,3*nion*nbeads,'rcoords',
825
> rcoords(2), rcoords(1)))
826
> call errquit('neb_initialize: memory',3*nion*nbeads,MA_ERR)
833
call dcopy(3*nion,dbl_mb(r1(1)),1,dbl_mb(rcoords(1)),1)
834
call dcopy(3*nion,dbl_mb(rmid(1)),1,
835
> dbl_mb(rcoords(1)+3*nion*(i2-1)),1)
836
call dcopy(3*nion,dbl_mb(r2(1)),1,
837
> dbl_mb(rcoords(1)+3*nion*(nbeads-1)),1)
839
call zts_guess(nion,nbeads,i2,dbl_mb(rcoords(1)),pathguess)
842
call dcopy(3*nion,dbl_mb(rcoords(1)+3*nion*(i-1)),1,
845
geom_name = 'bead'//bead_index_name(i)//':geom'
846
movecs_name = 'bead'//bead_index_name(i)//'.movecs'
847
geomlen = inp_strlen(geom_name)
848
movecslen = inp_strlen(movecs_name)
849
value = value.and.geom_cart_coords_set(geom,dbl_mb(r3(1)))
850
value = value.and.geom_rtdb_store(rtdb,geom,
851
> geom_name(1:geomlen))
852
call add_bead_list(bead_list,
853
> movecs_name(1:movecslen),
854
> geom_name(1:geomlen))
859
c t = (i-1)/dble(i2-1)
860
c call dcopy(3*nion,dbl_mb(r1(1)),1,dbl_mb(r3(1)),1)
861
c call dscal(3*nion,(1.0d0-t),dbl_mb(r3(1)),1)
862
c call daxpy(3*nion,t,dbl_mb(rmid(1)),1,dbl_mb(r3(1)),1)
864
c geom_name = 'bead'//bead_index_name(i)//':geom'
865
c movecs_name = 'bead'//bead_index_name(i)//'.movecs'
866
c geomlen = inp_strlen(geom_name)
867
c movecslen = inp_strlen(movecs_name)
868
c value = value.and.geom_cart_coords_set(geom,dbl_mb(r3(1)))
869
c value = value.and.geom_rtdb_store(rtdb,geom,
870
c > geom_name(1:geomlen))
871
c call add_bead_list(bead_list,
872
c > movecs_name(1:movecslen),
873
c > geom_name(1:geomlen))
879
c call dcopy(3*nion,dbl_mb(rmid(1)),1,dbl_mb(r3(1)),1)
880
c call dscal(3*nion,(1.0d0-t),dbl_mb(r3(1)),1)
881
c call daxpy(3*nion,t,dbl_mb(r2(1)),1,dbl_mb(r3(1)),1)
883
c geom_name = 'bead'//bead_index_name(i+i2)//':geom'
884
c movecs_name = 'bead'//bead_index_name(i+i2)//'.movecs'
885
c geomlen = inp_strlen(geom_name)
886
c movecslen = inp_strlen(movecs_name)
887
c value = value.and.geom_cart_coords_set(geom,dbl_mb(r3(1)))
888
c value = value.and.geom_rtdb_store(rtdb,geom,
889
c > geom_name(1:geomlen))
890
c call add_bead_list(bead_list,
891
c > movecs_name(1:movecslen),
892
c > geom_name(1:geomlen))
895
* **** linear interpolation with Robinson Checking ****
898
call dcopy(3*nion,dbl_mb(r1(1)),1,dbl_mb(rcoords(1)),1)
899
call dcopy(3*nion,dbl_mb(r2(1)),1,
900
> dbl_mb(rcoords(1)+3*nion*(nbeads-1)),1)
902
call zts_guessall(nion,nbeads,dbl_mb(rcoords(1)),geom)
905
c t = (i-1)/dble(nbeads-1)
907
c call dcopy(3*nion,dbl_mb(r1(1)),1,dbl_mb(r3(1)),1)
908
c call dscal(3*nion,(1.0d0-t),dbl_mb(r3(1)),1)
909
c call daxpy(3*nion,t,dbl_mb(r2(1)),1,dbl_mb(r3(1)),1)
911
call dcopy(3*nion,dbl_mb(rcoords(1)+3*nion*(i-1)),1,
914
geom_name = 'bead'//bead_index_name(i)//':geom'
915
movecs_name = 'bead'//bead_index_name(i)//'.movecs'
916
geomlen = inp_strlen(geom_name)
917
movecslen = inp_strlen(movecs_name)
918
value = value.and.geom_cart_coords_set(geom,dbl_mb(r3(1)))
919
value = value.and.geom_rtdb_store(rtdb,geom,
920
> geom_name(1:geomlen))
922
call add_bead_list(bead_list,
923
> movecs_name(1:movecslen),
924
> geom_name(1:geomlen))
928
value = value.and.MA_pop_stack(rcoords(2))
684
929
value = value.and.geom_destroy(geom)
930
value = value.and.MA_pop_stack(rmid(2))
685
931
value = value.and.MA_pop_stack(r3(2))
686
932
value = value.and.MA_pop_stack(r2(2))
687
933
value = value.and.MA_pop_stack(r1(2))
1109
* *****************************************
1113
* *****************************************
1114
subroutine neb_lmbfgs(n,m,x,g,hg)
1121
* **** local variables ****
1123
real*8 rho(25),alpha(25),beta(25)
1126
* **** external functions ****
1130
* **** compute rho(k) = 1/y(:,k)' * s(:,k) ****
1132
tmp = ddot(n,x(1,k+1),1,g(1,k+1),1)
1133
tmp = tmp - ddot(n,x(1,k+1),1,g(1,k), 1)
1134
tmp = tmp - ddot(n,x(1,k), 1,g(1,k+1),1)
1135
tmp = tmp + ddot(n,x(1,k), 1,g(1,k), 1)
1136
if (dabs(tmp).gt.1.0d-9) then
1143
call dcopy(n,g(1,m),1,hg,1)
1147
> *(ddot(n,x(1,k+1),1,hg,1) - ddot(n,x(1,k),1,hg,1))
1149
call daxpy(n,(-alpha(k)),g(1,k+1),1,hg,1)
1150
call daxpy(n,( alpha(k)),g(1,k), 1,hg,1)
1155
> *(ddot(n,g(1,k+1),1,hg,1) - ddot(n,g(1,k),1,hg,1))
1157
call daxpy(n,(alpha(k)-beta(k)),x(1,k+1),1,hg,1)
1158
call daxpy(n,(beta(k)-alpha(k)),x(1,k), 1,hg,1)
1165
* ***********************************************
1167
* * neb_resize_path *
1169
* ***********************************************
1170
subroutine neb_resize_path(rtdb,bead_list,nbeads1,nbeads2)
1173
character*(*) bead_list
1177
#include "mafdecls.fh"
1180
* **** local variables ****
1182
integer i,geom,geomlen,movecslen,nion
1184
integer r1(2),r2(2),r3(2),c(2)
1186
character*255 geom_name,movecs_name
1188
* **** external functions ****
1190
character*7 bead_index_name
1192
external bead_index_name
1194
value = geom_create(geom,'neb_tmp')
1195
if (.not.geom_rtdb_load(rtdb,geom,'neb_start')) then
1196
value = value.and.geom_rtdb_load(rtdb,geom,'geometry')
1198
value = value.and.geom_ncent(geom,nion)
1199
value = value.and.geom_destroy(geom)
1200
if (.not.value) call errquit('neb_resize_path failed',0,0)
1203
value = value.and.MA_push_get(mt_dbl,(3*nion*nbeads1),
1205
value = value.and.MA_push_get(mt_dbl,(3*nion),'r1',r1(2),r1(1))
1206
value = value.and.MA_push_get(mt_dbl,(3*nion),'r2',r2(2),r2(1))
1207
value = value.and.MA_push_get(mt_dbl,(3*nion),'r3',r3(2),r3(1))
1208
if (.not.value) call errquit('neb_resize_path failed',1,0)
1210
value = value.and.geom_create(geom,'neb_tmp')
1211
if (.not.geom_rtdb_load(rtdb,geom,'neb_start')) then
1212
value = value.and.geom_rtdb_load(rtdb,geom,'geometry')
1214
value = value.and.geom_cart_coords_get(geom,dbl_mb(r3(1)))
1215
if (.not.value) call errquit('neb_resize_path failed',2,0)
1218
shift = (i-1)*3*nion
1219
call coords_get_bead_list(bead_list,i,dbl_mb(c(1)+shift))
1221
call reset_bead_list(bead_list)
1224
t = (i-1)/dble(nbeads2-1)
1226
j1 = t*(nbeads1-1) + 1
1228
t1 = (j1-1)/dble(nbeads1-1)
1229
t2 = (j2-1)/dble(nbeads1-1)
1232
if (j2.gt.nbeads1) then
1237
shift = (j1-1)*3*nion
1238
call dcopy(3*nion,dbl_mb(c(1)+shift),1,dbl_mb(r1(1)),1)
1240
shift = (j2-1)*3*nion
1241
call dcopy(3*nion,dbl_mb(c(1)+shift),1,dbl_mb(r2(1)),1)
1243
call dcopy(3*nion,dbl_mb(r1(1)),1,dbl_mb(r3(1)),1)
1244
call dscal(3*nion,(1.0d0-t3),dbl_mb(r3(1)),1)
1245
call daxpy(3*nion,t3,dbl_mb(r2(1)),1,dbl_mb(r3(1)),1)
1247
geom_name = 'bead'//bead_index_name(i)//':geom'
1248
movecs_name = 'bead'//bead_index_name(i)//'.movecs'
1249
geomlen = inp_strlen(geom_name)
1250
movecslen = inp_strlen(movecs_name)
1251
value = value.and.geom_cart_coords_set(geom,dbl_mb(r3(1)))
1252
value = value.and.geom_rtdb_store(rtdb,geom,
1253
> geom_name(1:geomlen))
1255
call add_bead_list(bead_list,
1256
> movecs_name(1:movecslen),
1257
> geom_name(1:geomlen))
1260
value = value.and.geom_destroy(geom)
1261
value = value.and.MA_pop_stack(r3(2))
1262
value = value.and.MA_pop_stack(r2(2))
1263
value = value.and.MA_pop_stack(r1(2))
1264
value = value.and.MA_pop_stack(c(2))
1265
if (.not.value) call errquit('neb_new_path failed',3,0)
1270
* ***********************************************
1274
* ***********************************************
1275
c subroutine neb_impose -- superimpose two coordinate sets
1277
c This routine performs the least squares best superposition
1278
c of two atomic coordinate sets via a quaternion method;
1279
c upon return, the first coordinate set is unchanged while
1280
c the second set is translated and rotated to give best fit;
1281
c the final root mean square fit is returned in "rmsvalue"
1283
subroutine neb_impose(nion,rion1,rion2,nfit,ifit,wfit,rms1,rms2)
1286
real*8 rion1(3,*),rion2(3,*)
1287
integer nfit,ifit(2,*)
1291
* **** local variables ****
1293
real*8 xmid,ymid,zmid
1295
* **** external functions ****
1305
rms1 = neb_rmsfit(nfit,ifit,wfit,rion1,rion2)
1307
c superimpose the centroids of active atom pairs
1309
call neb_center(nion,rion1,rion2,
1314
c use a quaternion method to achieve the superposition
1316
call neb_quatfit(nion,rion1,rion2,nfit,ifit,wfit)
1318
c translate both coordinate sets so as to return
1319
c the first set to its original position
1322
rion1(1,i) = rion1(1,i) + xmid
1323
rion1(2,i) = rion1(2,i) + ymid
1324
rion1(3,i) = rion1(3,i) + zmid
1327
rion2(1,i) = rion2(1,i) + xmid
1328
rion2(2,i) = rion2(2,i) + ymid
1329
rion2(3,i) = rion2(3,i) + zmid
1331
rms2 = neb_rmsfit(nfit,ifit,wfit,rion1,rion2)
1336
* ***********************************************
1340
* ***********************************************
1341
c function neb_rmsfit -- rms deviation for paired atoms
1343
c This routine computes the rms fit of two coordinate sets
1345
real*8 function neb_rmsfit(nfit,ifit,wfit,rion1,rion2)
1347
integer nfit,ifit(2,*)
1349
real*8 rion1(3,*),rion2(3,*)
1352
real*8 rmsterm,rmsfit
1353
real*8 xr,yr,zr,dist2
1356
c compute the rms fit over superimposed atom pairs
1364
xr = rion1(1,i1) - rion2(1,i2)
1365
yr = rion1(2,i1) - rion2(2,i2)
1366
zr = rion1(3,i1) - rion2(3,i2)
1367
dist2 = xr**2 + yr**2 + zr**2
1368
norm = norm + weight
1369
rmsterm = dist2 * weight
1370
rmsfit = rmsfit + rmsterm
1372
neb_rmsfit = sqrt(rmsfit/norm)
1377
* ***********************************************
1381
* ***********************************************
1382
c subroutine neb_center -- superimpose structure centroids
1384
c This routine moves the weighted centroid of each coordinate
1385
c set to the origin during least squares superposition
1387
subroutine neb_center(nion,rion1,rion2,
1392
real*8 rion1(3,*),rion2(3,*)
1393
integer nfit,ifit(2,*)
1395
real*8 xmid,ymid,zmid
1397
* **** local variables ****
1402
c find the weighted centroid of the second
1403
c structure and translate it to the origin
1412
xmid = xmid + rion2(1,k)*weight
1413
ymid = ymid + rion2(2,k)*weight
1414
zmid = zmid + rion2(3,k)*weight
1415
norm = norm + weight
1422
rion2(1,i) = rion2(1,i) - xmid
1423
rion2(2,i) = rion2(2,i) - ymid
1424
rion2(3,i) = rion2(3,i) - zmid
1427
c now repeat for the first structure, note
1428
c that this centroid position gets returned
1437
xmid = xmid + rion1(1,k)*weight
1438
ymid = ymid + rion1(2,k)*weight
1439
zmid = zmid + rion1(3,k)*weight
1440
norm = norm + weight
1447
rion1(1,i) = rion1(1,i) - xmid
1448
rion1(2,i) = rion1(2,i) - ymid
1449
rion1(3,i) = rion1(3,i) - zmid
1456
* ***********************************************
1460
* ***********************************************
1461
c subroutine quatfit -- quaternion superposition of coords
1463
c This routine uses a quaternion-based method to achieve the best
1464
c fit superposition of two sets of coordinates
1466
c literature reference:
1468
c S. J. Kearsley, "An Algorithm for the Simultaneous Superposition
1469
c of a Structural Series", Journal of Computational Chemistry,
1470
c 11, 1187-1192 (1990)
1472
c adapted from an original program written by David J. Heisterberg,
1473
c Ohio Supercomputer Center, Columbus, OH
1475
subroutine neb_quatfit(nion,rion1,rion2,nfit,ifit,wfit)
1478
real*8 rion1(3,*),rion2(3,*)
1484
integer i,i1,i2,n1,n2
1485
real*8 weight,xrot,drot,zrot
1486
real*8 xxyx,xxyy,xxyz,xyyx,xyyy
1487
real*8 xyyz,xzyx,xzyy,xzyz
1488
real*8 rot(3,3),temp1(4),temp2(4)
1489
real*8 q(4),d(4),c(4,4),v(4,4)
1491
c build the upper triangle of the quadratic form matrix
1506
xxyx = xxyx + weight*rion1(1,i1)*rion2(1,i2)
1507
xxyy = xxyy + weight*rion1(2,i1)*rion2(1,i2)
1508
xxyz = xxyz + weight*rion1(3,i1)*rion2(1,i2)
1509
xyyx = xyyx + weight*rion1(1,i1)*rion2(2,i2)
1510
xyyy = xyyy + weight*rion1(2,i1)*rion2(2,i2)
1511
xyyz = xyyz + weight*rion1(3,i1)*rion2(2,i2)
1512
xzyx = xzyx + weight*rion1(1,i1)*rion2(3,i2)
1513
xzyy = xzyy + weight*rion1(2,i1)*rion2(3,i2)
1514
xzyz = xzyz + weight*rion1(3,i1)*rion2(3,i2)
1516
c(1,1) = xxyx + xyyy + xzyz
1517
c(1,2) = xzyy - xyyz
1518
c(2,2) = xxyx - xyyy - xzyz
1519
c(1,3) = xxyz - xzyx
1520
c(2,3) = xxyy + xyyx
1521
c(3,3) = xyyy - xzyz - xxyx
1522
c(1,4) = xyyx - xxyy
1523
c(2,4) = xzyx + xxyz
1524
c(3,4) = xyyz + xzyy
1525
c(4,4) = xzyz - xxyx - xyyy
1527
c diagonalize the quadratic form matrix
1529
call neb_jacobi4(4,4,c,d,v,temp1,temp2)
1531
c extract the desired quaternion
1538
c assemble rotation matrix that superimposes the molecules
1540
rot(1,1) = q(1)**2 + q(2)**2 - q(3)**2 - q(4)**2
1541
rot(2,1) = 2.0d0 * (q(2) * q(3) - q(1) * q(4))
1542
rot(3,1) = 2.0d0 * (q(2) * q(4) + q(1) * q(3))
1543
rot(1,2) = 2.0d0 * (q(3) * q(2) + q(1) * q(4))
1544
rot(2,2) = q(1)**2 - q(2)**2 + q(3)**2 - q(4)**2
1545
rot(3,2) = 2.0d0 * (q(3) * q(4) - q(1) * q(2))
1546
rot(1,3) = 2.0d0 * (q(4) * q(2) - q(1) * q(3))
1547
rot(2,3) = 2.0d0 * (q(4) * q(3) + q(1) * q(2))
1548
rot(3,3) = q(1)**2 - q(2)**2 - q(3)**2 + q(4)**2
1550
c rotate second molecule to best fit with first molecule
1553
xrot=rion2(1,i)*rot(1,1)+rion2(2,i)*rot(1,2)+rion2(3,i)*rot(1,3)
1554
drot=rion2(1,i)*rot(2,1)+rion2(2,i)*rot(2,2)+rion2(3,i)*rot(2,3)
1555
zrot=rion2(1,i)*rot(3,1)+rion2(2,i)*rot(3,2)+rion2(3,i)*rot(3,3)
1565
* ***********************************************
1569
* ***********************************************
1570
c subroutine neb_jacobi4 -- jacobi matrix diagonalization
1573
c This routine performs a matrix diagonalization of a real
1574
c symmetric matrix by the method of Jacobi rotations
1576
c n logical dimension of the matrix to be diagonalized
1577
c np physical dimension of the matrix storage area
1578
c a input with the matrix to be diagonalized; only
1579
c the upper triangle and diagonal are required
1580
c d returned with the eigenvalues in ascending order
1581
c v returned with the eigenvectors of the matrix
1582
c b temporary work vector
1583
c z temporary work vector
1585
subroutine neb_jacobi4(n,np,a,d,v,b,z)
1587
integer i,j,k,ip,iq,n,np,nrot,maxrot
1588
real*8 sm,tresh,s,c,t,theta,tau,h,g,p
1589
real*8 a(np,np),d(np),v(np,np),b(np),z(np)
1592
c setup and initialization
1608
c perform the jacobi rotations
1614
sm = sm + abs(a(ip,iq))
1617
if (sm .eq. 0.0d0) goto 10
1619
tresh = 0.2d0*sm / n**2
1625
g = 100.0d0 * abs(a(ip,iq))
1626
if (i.gt.4 .and. abs(d(ip))+g.eq.abs(d(ip))
1627
& .and. abs(d(iq))+g.eq.abs(d(iq))) then
1629
else if (abs(a(ip,iq)) .gt. tresh) then
1631
if (abs(h)+g .eq. abs(h)) then
1634
theta = 0.5d0*h / a(ip,iq)
1635
t = 1.0d0 / (abs(theta)+sqrt(1.0d0+theta**2))
1636
if (theta .lt. 0.0d0) t = -t
1638
c = 1.0d0 / sqrt(1.0d0+t**2)
1650
a(j,ip) = g - s*(h+g*tau)
1651
a(j,iq) = h + s*(g-h*tau)
1656
a(ip,j) = g - s*(h+g*tau)
1657
a(j,iq) = h + s*(g-h*tau)
1662
a(ip,j) = g - s*(h+g*tau)
1663
a(iq,j) = h + s*(g-h*tau)
1668
v(j,ip) = g - s*(h+g*tau)
1669
v(j,iq) = h + s*(g-h*tau)
1676
b(ip) = b(ip) + z(ip)
1682
c print warning if not converged
1685
if (nrot.eq.maxrot) then
1687
20 format (/,' JACOBI4 -- Matrix Diagonalization not Converged')
1690
c sort the eigenvalues and vectors
1696
if (d(j) .lt. p) then
1717
* ********************************
1719
* * neb_linesearch_init *
1721
* ********************************
1722
subroutine neb_linesearch_init()
1725
* **** neblinesearch_counter common block ****
1727
common / neblinesearch_counter / counter
1734
* ********************************
1736
* * neb_linesearch_count *
1738
* ********************************
1739
integer function neb_linesearch_count()
1742
* **** neblinesearch_counter common block ****
1744
common / neblinesearch_counter / counter
1746
neb_linesearch_count = counter
1750
* ********************************
1752
* * neb_linesearch *
1754
* ********************************
1756
real*8 function neb_linesearch(bead_list,kbeads,t0,f0,deltat,
1757
> tolerance,tmin,deltaE,
1760
character*(*) bead_list
1770
* **** local variables ****
1771
integer maxiter,iteration
1772
parameter (maxiter=8)
1773
logical secant,notfinished
1777
real*8 t_last, f_last
1778
real*8 t_first,f_first
1779
real*8 up,down,fmin,deltaf
1781
* **** neblinesearch_counter common block ****
1783
common / neblinesearch_counter / counter
1785
* **** external functions ****
1786
real*8 neb_line_energy
1787
external neb_line_energy
1789
counter = counter + 1
1800
f(2) = neb_line_energy(bead_list,kbeads,t(1)+deltat,0)
1803
* **** make sure that f2 < f1 ******
1804
do while ((f(2).gt.f(1)).and.(iteration.le.maxiter))
1805
deltat = 0.5d0*deltat
1806
f(2) = neb_line_energy(bead_list,kbeads,t(1)+deltat,0)
1807
iteration = iteration + 1
1809
t(2) = t(1) + deltat
1814
* **** use secant method to generate f(3) *****
1815
deltat = -f(1)*(t(2)-t(1))/(f(2)-f(1))
1816
t(3) = t(1) + deltat
1817
f(3) = neb_line_energy(bead_list,kbeads,t(3),0)
1818
iteration = iteration + 1
1822
* **** sort the function values ****
1823
call neb_Order_Values(3,f,indx)
1825
deltaf = f(indx(2)) - f(indx(1))
1828
if (stoptype.eq.1) then
1829
notfinished = (dabs(deltaf).gt.tolerance)
1830
> .and.(iteration.le.maxiter)
1832
notfinished = (dabs(f(indx(1))/f_first).gt.tolerance)
1833
> .and.(iteration.le.maxiter)
1837
do while (notfinished)
1840
* **** use secant interpolation to generate tmin ***
1843
deltat = -f(indx(1))
1844
> *(t(indx(2))-t(indx(1)))
1845
> /(f(indx(2))-f(indx(1)))
1846
tmin = t(indx(1)) + deltat
1847
fmin = neb_line_energy(bead_list,kbeads,tmin,0)
1848
iteration = iteration + 1
1852
* **** finish using secant method ****
1853
if (fmin.ge.f(indx(1))) then
1855
if (fmin.lt.f(indx(3))) then
1858
call neb_Order_Values(3,f,indx)
1865
* **** use quadradic interpolation to generate tmin ***
1866
if (.not.secant) then
1867
up = (t(2)*t(2) - t(3)*t(3))*f(1)
1868
> + (t(3)*t(3) - t(1)*t(1))*f(2)
1869
> + (t(1)*t(1) - t(2)*t(2))*f(3)
1870
down = (t(2) - t(3))*f(1)
1871
> + (t(3) - t(1))*f(2)
1872
> + (t(1) - t(2))*f(3)
1874
* **** check added by E.Apra ****
1875
if(abs(down).gt.tolerance**2) then
1876
tmin = 0.5d0*up/down
1877
fmin = neb_line_energy(bead_list,kbeads,tmin,0)
1878
iteration = iteration + 1
1882
* **** parabola fit failed - exit loop ****
1885
fmin=f(indx(3))+tolerance
1886
iteration = maxiter+1
1892
* **** tolerance check and replacement ****
1893
if (fmin.lt.f(indx(3))) then
1896
call neb_Order_Values(3,f,indx)
1897
deltaf = f(indx(2)) - f(indx(1))
1902
if (stoptype.eq.1) then
1903
notfinished = (dabs(deltaf).gt.tolerance)
1904
> .and.(iteration.le.maxiter)
1906
notfinished = (dabs(f(indx(1))/f_first).gt.tolerance)
1907
> .and.(iteration.le.maxiter)
1912
* **** make sure that tmin is last functions call *****
1916
> f_last = neb_line_energy(bead_list,kbeads,tmin,0)
1918
deltaE = (fmin-f_first)
1920
neb_linesearch = fmin
1924
* *****************************
1926
* * neb_Order_Values *
1928
* *****************************
1930
* this subroutine makes f(indx(1)) < f(indx(2)) < f(indx(3)) < ....
1934
* Exit - returns indx
1937
subroutine neb_Order_Values(n,f,indx)
1943
* ****** local variables *****
1951
if (f(indx(j)).lt.f(indx(i))) then
1963
* *****************************
1965
* * neb_linesearch_start *
1967
* *****************************
1968
subroutine neb_linesearch_start(ng_in,c0_in,s_in,
1979
#include "mafdecls.fh"
1981
* *** neb_linesearch ***
1982
integer cs(2),gs(2),c1(2),c0(2),s(2),g1(2),t1(2),e1(2),m,ng
1983
common / neblinesearch / cs,gs,c1,c0,s,g1,t1,e1,m,ng
1985
* **** local variables ****
1991
value = MA_push_get(mt_dbl,m*ng,'lcs',cs(2),cs(1))
1992
value = value.and.MA_push_get(mt_dbl,m*ng,'lgs',gs(2),gs(1))
1993
value = value.and.MA_push_get(mt_dbl,ng,'lc1',c1(2),c1(1))
1994
value = value.and.MA_push_get(mt_dbl,ng,'lc0',c0(2),c0(1))
1995
value = value.and.MA_push_get(mt_dbl,ng,'ls',s(2),s(1))
1996
value = value.and.MA_push_get(mt_dbl,ng,'lg1',g1(2),g1(1))
1997
value = value.and.MA_push_get(mt_dbl,ng,'lt1',t1(2),t1(1))
1998
value = value.and.MA_push_get(mt_dbl,nbeads,'le1',e1(2),e1(1))
2000
> call errquit('neb_linesearch_start:increase stack memory',1,0)
2002
call dcopy(m_in*ng,cs_in,1,dbl_mb(cs(1)),1)
2003
call dcopy(m_in*ng,gs_in,1,dbl_mb(gs(1)),1)
2004
call dcopy(ng,c0_in,1,dbl_mb(c0(1)),1)
2005
call dcopy(ng,s_in,1,dbl_mb(s(1)),1)
2010
* *****************************
2012
* * neb_linesearch_end *
2014
* *****************************
2015
subroutine neb_linesearch_end()
2018
#include "mafdecls.fh"
2020
* *** neb_linesearch ***
2021
integer cs(2),gs(2),c1(2),c0(2),s(2),g1(2),t1(2),e1(2),m,ng
2022
common / neblinesearch / cs,gs,c1,c0,s,g1,t1,e1,m,ng
2024
* **** local variables ****
2027
value = MA_pop_stack(e1(2))
2028
value = value.and.MA_pop_stack(t1(2))
2029
value = value.and.MA_pop_stack(g1(2))
2030
value = value.and.MA_pop_stack(s(2))
2031
value = value.and.MA_pop_stack(c0(2))
2032
value = value.and.MA_pop_stack(c1(2))
2033
value = value.and.MA_pop_stack(gs(2))
2034
value = value.and.MA_pop_stack(cs(2))
2036
> call errquit('neb_linesearch_end: popping stack',1,0)
2041
* *****************************
2043
* * neb_line_energy *
2045
* *****************************
2046
real*8 function neb_line_energy(bead_list,kbeads,alpha,opt)
2048
character*(*) bead_list
2052
#include "mafdecls.fh"
2054
* *** neb_linesearch ***
2055
integer cs(2),gs(2),c1(2),c0(2),s(2),g1(2),t1(2),e1(2),m,ng
2056
common / neblinesearch / cs,gs,c1,c0,s,g1,t1,e1,m,ng
2058
* **** local variables ****
2062
* **** external functions ****
2063
logical task_gradient
2064
external task_gradient
2076
call neb_coords_set(bead_list,dbl_mb(c1(1)))
2077
call runmid_bead_list(bead_list,task_gradient)
2078
call neb_energies_get(bead_list,dbl_mb(e1(1)))
2079
call neb_gradient_get(bead_list,kbeads,
2085
call dcopy(ng,dbl_mb(c1(1)),1,dbl_mb(cs(1)+shift),1)
2086
call dcopy(ng,dbl_mb(g1(1)),1,dbl_mb(gs(1)+shift),1)
2087
call neb_lmbfgs(ng,m,
2091
ee = ddot(ng,dbl_mb(g1(1)),1,dbl_mb(s(1)),1)
2095
neb_line_energy = ee