Statistiques
| Révision :

root / src / Hupdate_Bofill.f90 @ 2

Historique | Voir | Annoter | Télécharger (3,08 ko)

1 1 equemene
! This program reads an old hessian, old forces, new forces
2 1 equemene
! and print the updated hessian and old coordinates.
3 1 equemene
! Instead of the Murtagh-Sargent update, we use the Bofill update
4 1 equemene
! which is an average of Murtagh-Sargent and Powell-symmetryc-Broyden
5 1 equemene
! cf JCP 1999, vol 111 (19), p 8773
6 1 equemene
7 1 equemene
! This subroutine slightly differs from previous ones as
8 1 equemene
! it is written with the Gradient as input and not the forces
9 1 equemene
! Using the relation F=-Grad, one can easily go from older
10 1 equemene
! versions to this one (which more closely mimics the JCP article)
11 1 equemene
12 1 equemene
SUBROUTINE Hupdate_Bofill(Nfree,ds,dgrad,Hess)
13 1 equemene
14 1 equemene
  IMPLICIT NONE
15 1 equemene
16 1 equemene
  INTEGER, PARAMETER :: KINT=KIND(1)
17 1 equemene
  INTEGER, PARAMETER :: KREAL=KIND(1.D0)
18 1 equemene
19 1 equemene
  INTEGER(KINT), INTENT(IN) :: NFREE
20 1 equemene
  REAL(KREAL), INTENT(INOUT) :: Hess(Nfree,Nfree)
21 1 equemene
  REAL(KREAL), INTENT(IN) :: ds(Nfree)
22 1 equemene
  REAL(KREAL), INTENT(IN) :: dGrad(Nfree)
23 1 equemene
24 1 equemene
25 1 equemene
  REAL(KREAL), ALLOCATABLE  :: HessOld(:,:) , HupMS(:,:)
26 1 equemene
  REAL(KREAL), ALLOCATABLE  :: HupPSB(:,:), Hup(:,:)
27 1 equemene
  REAL(KREAL), ALLOCATABLE  :: HupInt(:)
28 1 equemene
  REAL(KREAL), ALLOCATABLE  :: HS(:), Num(:,:), Num2(:,:)
29 1 equemene
  REAL(KREAL) :: Phi, Num3, Den, Den2,NormDS
30 1 equemene
  CHARACTER(120) :: fmt,fmt2,Line
31 1 equemene
  INTEGER(KINT) :: i,j, idx
32 1 equemene
33 1 equemene
  LOGICAL debug,valid
34 1 equemene
  EXTERNAL valid
35 1 equemene
36 1 equemene
  debug=valid("Hupdate").OR.Valid("Hupdate_bofill")
37 1 equemene
38 1 equemene
  if (debug) WRITE(*,*) "=========================== Entering Hupdate_Bofill ===================="
39 1 equemene
40 1 equemene
  ALLOCATE(HessOld(nfree,nfree), HupMS(nfree,nfree),  &
41 1 equemene
       HupPSB(nfree,nfree), Hup(nfree,nfree), &
42 1 equemene
       HupInt(nfree), HS(nfree),  &
43 1 equemene
       Num(nfree,nfree), Num2(nfree,nfree) )
44 1 equemene
45 1 equemene
  HessOld=Hess
46 1 equemene
47 1 equemene
  if (debug) THEN
48 1 equemene
     WRITE(*,*) 'DBG Hupdate HessOld'
49 1 equemene
     Idx=min(12,Nfree)
50 1 equemene
     DO I=1,NFree
51 1 equemene
        WRITE(*,'(12(1X,F8.4))') HessOld(I,1:Idx)
52 1 equemene
     END DO
53 1 equemene
     WRITE(*,*) 'DBG Hupdate ds'
54 1 equemene
     WRITE(*,'(12(1X,F8.4))') ds(1:Idx)
55 1 equemene
     WRITE(*,*) 'DBG Hupdate dGrad'
56 1 equemene
     WRITE(*,'(12(1X,F8.4))') dGrad(1:Idx)
57 1 equemene
  END IF
58 1 equemene
59 1 equemene
  NormDS=sqrt(DOT_PRODUCT(DS,DS))
60 1 equemene
  if (NormDS>=1e-6) THEN
61 1 equemene
62 1 equemene
     HS=0
63 1 equemene
     DO I=1,nfree
64 1 equemene
        DO J=1,nfree
65 1 equemene
           HS(I)=HS(I)+HessOld(i,j)*Ds(j)
66 1 equemene
        END DO
67 1 equemene
     END DO
68 1 equemene
     HupInt=DGrad-HS
69 1 equemene
70 1 equemene
     ! WE calculate the MS update
71 1 equemene
     Num=0.
72 1 equemene
     Den=0.
73 1 equemene
     DO I=1,nfree
74 1 equemene
        DO J=1,nfree
75 1 equemene
           Num(I,J)=HUpInt(i)*HupInt(j)
76 1 equemene
        END DO
77 1 equemene
        Den=Den+Hupint(i)*Ds(i)
78 1 equemene
     END DO
79 1 equemene
80 1 equemene
     HupMS=Num/Den
81 1 equemene
82 1 equemene
     ! Now we calculate the PSB update
83 1 equemene
     Num=0
84 1 equemene
     Num2=0
85 1 equemene
     Num3=0
86 1 equemene
     Den=0
87 1 equemene
     DO I=1,nfree
88 1 equemene
        DO J=1,nfree
89 1 equemene
           Num(I,J)=HUpInt(i)*Ds(j)+Ds(i)*HupInt(j)
90 1 equemene
           Num2(I,J)=DS(i)*DS(j)
91 1 equemene
        END DO
92 1 equemene
        Den=Den+Ds(i)*Ds(i)
93 1 equemene
        Num3=Num3+DS(i)*HupInt(i)
94 1 equemene
     END DO
95 1 equemene
     HupPSB=Num/Den-Num3*Num2/(Den)**2
96 1 equemene
97 1 equemene
     ! We calculate Phi
98 1 equemene
     Den2=0.
99 1 equemene
     Do I=1,nfree
100 1 equemene
        Den2=Den2+HupInt(i)*HupInt(i)
101 1 equemene
     END DO
102 1 equemene
     Phi=Num3**2/(Den*Den2)
103 1 equemene
104 1 equemene
     Hup=Phi*HupMS+(1-Phi)*HupPSB
105 1 equemene
106 1 equemene
     Hess=HessOld+Hup
107 1 equemene
  ELSE
108 1 equemene
     Hess=HessOld
109 1 equemene
  END IF
110 1 equemene
  !     WRITE(*,*) 'New hess'
111 1 equemene
  !     DO I=1,nfree
112 1 equemene
  !        WRITE(*,fmt) Hess(i,:)
113 1 equemene
  !     END DO
114 1 equemene
115 1 equemene
  DEALLOCATE(HessOld, HupMS, HupPSB, Hup, &
116 1 equemene
       HupInt, HS, Num, Num2 )
117 1 equemene
118 1 equemene
  if (debug) WRITE(*,*) "=========================== Hupdate Over ===================="
119 1 equemene
120 1 equemene
END SUBROUTINE Hupdate_Bofill