root / src / egrad_test.f90 @ 7
Historique | Voir | Annoter | Télécharger (6,5 ko)
1 | 1 | equemene | SUBROUTINE egrad_test(nat,e,geom,grad) |
---|---|---|---|
2 | 1 | equemene | ! This program reads cartesian coordinates from the file Ext.in |
3 | 1 | equemene | ! and print the energy (in au) and gradient (in au/Ang) in the file Ext.out |
4 | 1 | equemene | ! format D25.15 |
5 | 1 | equemene | |
6 | 1 | equemene | IMPLICIT NONE |
7 | 1 | equemene | integer, parameter :: KINT = kind(1) |
8 | 1 | equemene | integer, parameter :: KREAL = kind(1.0d0) |
9 | 1 | equemene | |
10 | 1 | equemene | INTEGER(KINT), INTENT(IN) :: Nat |
11 | 1 | equemene | REAL(KREAL), INTENT(OUT) :: E,grad(Nat*3) |
12 | 1 | equemene | REAL(KREAL), INTENT(IN) :: Geom(Nat,3) |
13 | 1 | equemene | |
14 | 1 | equemene | ! Bohr --> Angstr |
15 | 1 | equemene | real(KREAL), parameter :: BOHR = 0.52917726D+00 |
16 | 1 | equemene | ! |
17 | 1 | equemene | ! Parameters to define the surface |
18 | 1 | equemene | INTEGER(KINT), DIMENSION(6), PARAMETER :: IECOEF = (/-1,9,-45,45,-9,1/) |
19 | 1 | equemene | INTEGER(KINT), DIMENSION(6), PARAMETER :: ISCOEF = (/-3,-2,-1,1,2,3/) |
20 | 1 | equemene | REAL(KREAL), PARAMETER :: hh=0.001d0 |
21 | 1 | equemene | |
22 | 1 | equemene | ! Variables |
23 | 1 | equemene | INTEGER(KINT) :: i,j,iat,jat |
24 | 1 | equemene | REAL(KREAL), ALLOCATABLE :: Xyztmp(:,:),GradTmp(:,:) |
25 | 1 | equemene | REAL(KREAL) :: xp,yp |
26 | 1 | equemene | |
27 | 1 | equemene | CHARACTER(132) :: Line |
28 | 1 | equemene | LOGICAL :: Debug |
29 | 1 | equemene | |
30 | 1 | equemene | real(KREAL), parameter :: zero = 0.0_KREAL, one = 1.0_KREAL |
31 | 1 | equemene | REAL(KREAL), external :: Exyz |
32 | 1 | equemene | |
33 | 1 | equemene | |
34 | 1 | equemene | INTERFACE |
35 | 1 | equemene | function valid(string) result (isValid) |
36 | 1 | equemene | CHARACTER(*), intent(in) :: string |
37 | 1 | equemene | logical :: isValid |
38 | 1 | equemene | END function VALID |
39 | 1 | equemene | |
40 | 1 | equemene | END INTERFACE |
41 | 1 | equemene | |
42 | 1 | equemene | debug=valid('egrad_test') |
43 | 1 | equemene | |
44 | 1 | equemene | if (debug) WRITE(*,*) '================ Entering Egrad_test ===================' |
45 | 1 | equemene | if (debug) THEN |
46 | 1 | equemene | WRITE(*,*) "Cartesian Geometry" |
47 | 1 | equemene | DO I=1,Nat |
48 | 1 | equemene | WRITE(*,'(1X,I5,3(1X,F12.6))') I,Geom(i,1:3) |
49 | 1 | equemene | END DO |
50 | 1 | equemene | END IF |
51 | 1 | equemene | |
52 | 1 | equemene | ALLOCATE(XyZTmp(Nat,3),GradTmp(Nat,3)) |
53 | 1 | equemene | |
54 | 1 | equemene | e=Exyz(nat,Geom) |
55 | 1 | equemene | |
56 | 1 | equemene | ! We now calculate the gradients using numerical derivatives |
57 | 1 | equemene | Grad=0.d0 |
58 | 1 | equemene | GradTmp=0.d0 |
59 | 1 | equemene | do iat=1,3 |
60 | 1 | equemene | do jat=1,nat |
61 | 1 | equemene | xyztmp=geom |
62 | 1 | equemene | do i=1,6 |
63 | 1 | equemene | xyztmp(jat,iat)=geom(jat,iat)+ISCoef(i)*hh |
64 | 1 | equemene | gradTmp(jat,iat)=gradTmp(jat,iat)+IECoef(i)*Exyz(nat,xyztmp) |
65 | 1 | equemene | end do |
66 | 1 | equemene | end do |
67 | 1 | equemene | end do |
68 | 1 | equemene | gradTmp=gradTmp/(60.*hh) |
69 | 1 | equemene | do iat=1,nat |
70 | 1 | equemene | grad(3*iat-2:3*iat)=gradTmp(iat,1:3) |
71 | 1 | equemene | end do |
72 | 1 | equemene | |
73 | 1 | equemene | if (debug) THEN |
74 | 1 | equemene | WRITE(*,*) "Cartesian gradient GradTmp" |
75 | 1 | equemene | DO I=1,Nat |
76 | 1 | equemene | WRITE(*,'(1X,I5,3(1X,F12.6))') I,Gradtmp(i,1:3) |
77 | 1 | equemene | END DO |
78 | 1 | equemene | WRITE(*,*) "Cartesian gradient Grad" |
79 | 1 | equemene | WRITE(*,'(50(1X,F12.6))') Grad |
80 | 1 | equemene | |
81 | 1 | equemene | END IF |
82 | 1 | equemene | |
83 | 1 | equemene | |
84 | 1 | equemene | deallocate(xyztmp,gradTmp) |
85 | 1 | equemene | |
86 | 1 | equemene | |
87 | 1 | equemene | if (debug) WRITE(*,*) '================ Exiting Egrad_test ===================' |
88 | 1 | equemene | |
89 | 1 | equemene | ! ====================================================================== |
90 | 1 | equemene | end |
91 | 1 | equemene | |
92 | 1 | equemene | |
93 | 1 | equemene | |
94 | 1 | equemene | function Exyz(natoms,Xyz) |
95 | 1 | equemene | |
96 | 1 | equemene | use Path_module, only : order |
97 | 1 | equemene | |
98 | 1 | equemene | IMPLICIT NONE |
99 | 1 | equemene | integer, parameter :: KINT = kind(1) |
100 | 1 | equemene | integer, parameter :: KREAL = kind(1.0d0) |
101 | 1 | equemene | |
102 | 1 | equemene | |
103 | 1 | equemene | INTEGER(KINT) ,INTENT(IN) :: natoms |
104 | 1 | equemene | REAL(KREAL) ,INTENT(IN) :: Xyz(natoms,3) |
105 | 1 | equemene | REAL(KREAL) :: Exyz |
106 | 1 | equemene | |
107 | 1 | equemene | INTEGER(KINT) :: i |
108 | 1 | equemene | REAL(KREAL) :: dCH,dNH,dCN |
109 | 1 | equemene | |
110 | 1 | equemene | real(KREAL) :: autoA,autoeV |
111 | 1 | equemene | parameter (autoA=0.52917715d0) |
112 | 1 | equemene | parameter (autoeV=27.21183d0) |
113 | 1 | equemene | |
114 | 1 | equemene | |
115 | 1 | equemene | real(KREAL) :: Q(3) |
116 | 1 | equemene | real(KREAL) :: TT,gR,pR |
117 | 1 | equemene | |
118 | 1 | equemene | real(KREAL) :: mB,mC,mH |
119 | 1 | equemene | real(KREAL) :: T,RN,RC,r1,r2,r3 |
120 | 1 | equemene | |
121 | 1 | equemene | real(KREAL) :: Z1,Z12,V1 |
122 | 1 | equemene | real(KREAL) :: Z2,Z22,V2 |
123 | 1 | equemene | real(KREAL) :: Z3,Z32,V3 |
124 | 1 | equemene | |
125 | 1 | equemene | real(KREAL) :: S1,S2,S3,S12,S22,S32,POLY |
126 | 1 | equemene | real(KREAL) :: E1,E2,E3,HY1,HY2,HY3,SWITCH,V123 |
127 | 1 | equemene | |
128 | 1 | equemene | LOGICAL :: Debug |
129 | 1 | equemene | LOGICAL, SAVE :: First=.TRUE. |
130 | 1 | equemene | |
131 | 1 | equemene | INTERFACE |
132 | 1 | equemene | function valid(string) result (isValid) |
133 | 1 | equemene | CHARACTER(*), intent(in) :: string |
134 | 1 | equemene | logical :: isValid |
135 | 1 | equemene | END function VALID |
136 | 1 | equemene | |
137 | 1 | equemene | END INTERFACE |
138 | 1 | equemene | |
139 | 1 | equemene | debug=valid('exyz') |
140 | 1 | equemene | |
141 | 1 | equemene | |
142 | 1 | equemene | |
143 | 1 | equemene | dCN=0. |
144 | 1 | equemene | dCH=0. |
145 | 1 | equemene | dNH=0. |
146 | 1 | equemene | do i=1,3 |
147 | 1 | equemene | dCN=dCN+(xyz(Order(3),i)-xyz(order(2),i))**2 |
148 | 1 | equemene | dCH=dCH+(xyz(order(1),i)-xyz(order(2),i))**2 |
149 | 1 | equemene | dNH=dNH+(xyz(order(1),i)-xyz(order(3),i))**2 |
150 | 1 | equemene | end do |
151 | 1 | equemene | R1=sqrt(dCH) |
152 | 1 | equemene | R2=sqrt(dCN) |
153 | 1 | equemene | R3=sqrt(dNH) |
154 | 1 | equemene | |
155 | 1 | equemene | IF (debug.AND.First) THEN |
156 | 1 | equemene | WRITE(*,*) "Exyz in Test, dCH,dCN,dNH:",R1,R2,R3 |
157 | 1 | equemene | END IF |
158 | 1 | equemene | |
159 | 1 | equemene | ! R1=R1*autoA |
160 | 1 | equemene | ! R2=R2*autoA |
161 | 1 | equemene | ! R3=R3*autoA |
162 | 1 | equemene | |
163 | 1 | equemene | !.....CH |
164 | 1 | equemene | Z1=R1-1.0823 |
165 | 1 | equemene | Z12=Z1*Z1 |
166 | 1 | equemene | V1=-2.8521*(1.0+5.5297*Z1+8.7166*Z12+5.3082*Z1*Z12)*dexp(-5.5297*Z1) |
167 | 1 | equemene | !.....CN |
168 | 1 | equemene | Z2=R2-1.1718 |
169 | 1 | equemene | Z22=Z2*Z2 |
170 | 1 | equemene | V2=-7.9282*(1.0+5.2448*Z2+7.3416*Z22+4.9785*Z2*Z22)*dexp(-5.2448*Z2) |
171 | 1 | equemene | !.....NH |
172 | 1 | equemene | Z3=R3-1.0370 |
173 | 1 | equemene | Z32=Z3*Z3 |
174 | 1 | equemene | V3=-3.9938*(1.0+3.0704*Z3)*dexp(-3.0704*Z3) |
175 | 1 | equemene | |
176 | 1 | equemene | ! write(6,*) v1,v2,v3 |
177 | 1 | equemene | |
178 | 1 | equemene | !.....THREE BODY TERMS |
179 | 1 | equemene | Z1=R1-1.9607 |
180 | 1 | equemene | Z2=R2-2.2794 |
181 | 1 | equemene | Z3=R3-1.8687 |
182 | 1 | equemene | S1=0.4436*Z1+0.6091*Z2+0.6575*Z3 |
183 | 1 | equemene | S2=-.8941*Z1+0.2498*Z2+0.3718*Z3 |
184 | 1 | equemene | S3=0.0622*Z1-0.7527*Z2+0.6554*Z3 |
185 | 1 | equemene | |
186 | 1 | equemene | S12=S1*S1 |
187 | 1 | equemene | S22=S2*S2 |
188 | 1 | equemene | S32=S3*S3 |
189 | 1 | equemene | POLY=-3.0578*(1.0+1.9076*S1-0.5008*S2-0.0149*S3+0.6695*S12 & |
190 | 1 | equemene | -1.3535*S22-1.0501*S32+0.2698*S1*S2-1.1120*S1*S3 & |
191 | 1 | equemene | +1.9310*S2*S3-0.0877*S1*S12+0.0044*S2*S22+0.0700 & |
192 | 1 | equemene | *S3*S32+0.0898*S12*S2-1.0186*S1*S22-0.0911*S12 & |
193 | 1 | equemene | *S3+0.0017*S1*S32+0.4567*S22*S3-0.8840*S2*S32 & |
194 | 1 | equemene | +0.3333*S1*S2*S3-0.0367*S12*S12+0.4821*S22*S22 & |
195 | 1 | equemene | +0.2564*S32*S32-0.0017*S12*S1*S2-0.2278*S12*S22 & |
196 | 1 | equemene | -0.1287*S1*S2*S22+0.1759*S1*S12*S3-0.0399*S12*S32 & |
197 | 1 | equemene | -0.1447*S1*S3*S32-0.3147*S2*S22*S3+0.1233*S22*S32 & |
198 | 1 | equemene | +0.3161*S2*S3*S32+0.0919*S12*S2*S3-0.0954*S1*S22*S3 & |
199 | 1 | equemene | +0.1778*S1*S2*S32-0.1892*S22*S22*S2) |
200 | 1 | equemene | |
201 | 1 | equemene | |
202 | 1 | equemene | E1=dexp(3.9742*Z1/2.) |
203 | 1 | equemene | E2=dexp(4.3688*Z2/2.) |
204 | 1 | equemene | E3=dexp(1.5176*Z3/2.) |
205 | 1 | equemene | HY1=(E1-1.0/E1)/(E1+1.0/E1) |
206 | 1 | equemene | HY2=(E2-1.0/E2)/(E2+1.0/E2) |
207 | 1 | equemene | HY3=(E3-1.0/E3)/(E3+1.0/E3) |
208 | 1 | equemene | SWITCH=(1.0-HY1)*(1.0-HY2)*(1.0-HY3) |
209 | 1 | equemene | V123=SWITCH*POLY |
210 | 1 | equemene | |
211 | 1 | equemene | ! write(6,*) v123,V1+V2+V3+V123 |
212 | 1 | equemene | |
213 | 1 | equemene | Exyz=(V1+V2+V3+V123)/autoeV |
214 | 1 | equemene | |
215 | 1 | equemene | First=.FALSE. |
216 | 1 | equemene | |
217 | 1 | equemene | return |
218 | 1 | equemene | end function Exyz |
219 | 1 | equemene | |
220 | 1 | equemene | function Exyz2(natoms,Xyz) |
221 | 1 | equemene | |
222 | 1 | equemene | IMPLICIT NONE |
223 | 1 | equemene | integer, parameter :: KINT = kind(1) |
224 | 1 | equemene | integer, parameter :: KREAL = kind(1.0d0) |
225 | 1 | equemene | |
226 | 1 | equemene | |
227 | 1 | equemene | INTEGER(KINT) ,INTENT(IN) :: natoms |
228 | 1 | equemene | REAL(KREAL) ,INTENT(IN) :: Xyz(natoms,3) |
229 | 1 | equemene | REAL(KREAL) :: Exyz |
230 | 1 | equemene | |
231 | 1 | equemene | INTEGER(KINT) :: i,j,iat,jat |
232 | 1 | equemene | REAL(KREAL) :: Exyz2 |
233 | 1 | equemene | |
234 | 1 | equemene | real(KREAL) :: autoA,autoeV |
235 | 1 | equemene | parameter (autoA=0.52917715d0) |
236 | 1 | equemene | parameter (autoeV=27.21183d0) |
237 | 1 | equemene | |
238 | 1 | equemene | |
239 | 1 | equemene | real(KREAL) :: Q(3) |
240 | 1 | equemene | real(KREAL) :: TT,gR,pR |
241 | 1 | equemene | |
242 | 1 | equemene | real(KREAL) :: mB,mC,mH |
243 | 1 | equemene | real(KREAL) :: T,RN,RC,r1,r2,r3 |
244 | 1 | equemene | |
245 | 1 | equemene | real(KREAL) :: Z1,Z12,V1 |
246 | 1 | equemene | real(KREAL) :: Z2,Z22,V2 |
247 | 1 | equemene | real(KREAL) :: Z3,Z32,V3 |
248 | 1 | equemene | |
249 | 1 | equemene | real(KREAL) :: S1,S2,S3,S12,S22,S32,POLY |
250 | 1 | equemene | real(KREAL) :: E1,E2,E3,HY1,HY2,HY3,SWITCH,V123 |
251 | 1 | equemene | |
252 | 1 | equemene | Exyz=0. |
253 | 1 | equemene | do jat=1,natoms |
254 | 1 | equemene | do iat=1,3 |
255 | 1 | equemene | Exyz=Exyz+(3*iat-3+jat)*xyz(jat,iat)**2 |
256 | 1 | equemene | end do |
257 | 1 | equemene | end do |
258 | 1 | equemene | |
259 | 1 | equemene | Exyz2=Exyz |
260 | 1 | equemene | |
261 | 1 | equemene | return |
262 | 1 | equemene | end function Exyz2 |