root / src / IntCoord_der.f90 @ 4
Historique | Voir | Annoter | Télécharger (50,73 ko)
1 | 1 | equemene | |
---|---|---|---|
2 | 1 | equemene | SUBROUTINE VPRD(X,Y,Z) |
3 | 1 | equemene | ! ****************************************************************** |
4 | 1 | equemene | ! ** CROSS PRODUCT (VECTOR PRODUCT OF TWO VECTORS) ** |
5 | 1 | equemene | ! ****************************************************************** |
6 | 1 | equemene | Use VarTypes |
7 | 1 | equemene | IMPLICIT NONE |
8 | 1 | equemene | REAL(KREAL),INTENT(IN) :: X(3) |
9 | 1 | equemene | REAL(KREAL),INTENT(IN) :: Y(3) |
10 | 1 | equemene | REAL(KREAL),INTENT(OUT):: Z(3) |
11 | 1 | equemene | ! ****************************************************************** |
12 | 1 | equemene | Z(1)=X(2)*Y(3)-X(3)*Y(2) |
13 | 1 | equemene | Z(2)=X(3)*Y(1)-X(1)*Y(3) |
14 | 1 | equemene | Z(3)=X(1)*Y(2)-X(2)*Y(1) |
15 | 1 | equemene | RETURN |
16 | 1 | equemene | END |
17 | 1 | equemene | |
18 | 1 | equemene | ! .................................................................. |
19 | 1 | equemene | SUBROUTINE CONSTRAINTS_BONDLENGTH_DER(NAT,IAT1,IAT2,R0,B) |
20 | 1 | equemene | ! ****************************************************************** |
21 | 1 | equemene | ! ** ** |
22 | 1 | equemene | ! ** BOND-LENGTH CONSTRAINT : SET UP COORDINATES ** |
23 | 1 | equemene | ! ** ** |
24 | 1 | equemene | ! ****************************************************************** |
25 | 1 | equemene | Use VarTypes |
26 | 1 | equemene | IMPLICIT NONE |
27 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: NAT |
28 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT1 |
29 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT2 |
30 | 1 | equemene | REAL(KREAL) ,INTENT(IN) :: R0(3,NAT) |
31 | 1 | equemene | REAL(KREAL) ,INTENT(OUT):: B(3,NAT) |
32 | 1 | equemene | |
33 | 1 | equemene | INTEGER(KINT) :: I,J |
34 | 1 | equemene | REAL(KREAL) :: DIS,DI,DJ |
35 | 1 | equemene | REAL(KREAL) :: DELTAK |
36 | 1 | equemene | REAL(KREAL) :: SVAR |
37 | 1 | equemene | real(KREAL) :: dr(3) |
38 | 1 | equemene | ! ****************************************************************** |
39 | 1 | equemene | DR(:)=R0(:,IAT2)-R0(:,IAT1) |
40 | 1 | equemene | ! |
41 | 1 | equemene | ! ================================================================== |
42 | 1 | equemene | ! == CALCULATE VALUE AND FIRST TWO DERIVATIVES OF D=|R_2-R_2| == |
43 | 1 | equemene | ! ================================================================== |
44 | 1 | equemene | DIS=DSQRT(DOT_PRODUCT(DR,DR)) |
45 | 1 | equemene | DO I=1,3 |
46 | 1 | equemene | DI=DR(I)/DIS |
47 | 1 | equemene | B(I,IAT2)=DI |
48 | 1 | equemene | B(I,IAT1)=-DI |
49 | 1 | equemene | ENDDO |
50 | 1 | equemene | RETURN |
51 | 1 | equemene | END SUBROUTINE CONSTRAINTS_BONDLENGTH_DER |
52 | 1 | equemene | |
53 | 1 | equemene | SUBROUTINE CONSTRAINTS_GLC_DER(NAT,VEC,B) |
54 | 1 | equemene | ! ****************************************************************** |
55 | 1 | equemene | ! ** CONSTRAINTS_SETGLC ** |
56 | 1 | equemene | ! ** SET GENERAL LINEAR CONSTRAINT (GLC) CONST+VEC*R=0 ** |
57 | 1 | equemene | ! ** ** |
58 | 1 | equemene | ! ** APPROXIMATES CONSTRAINT FUNCTION (WITHOUT VALUE) ** |
59 | 1 | equemene | ! ** BY AN QUADRATIC POLYNOM IN A+B*R+0.5*R*C*R ** |
60 | 1 | equemene | ! ** THE CONSTRAINT IS THE POLYNOMIAL MINUS THE VALUE FROM THE ** |
61 | 1 | equemene | ! ** REFERENCE STRUCTURE ** |
62 | 1 | equemene | ! ****************************************************************** |
63 | 1 | equemene | Use VarTypes |
64 | 1 | equemene | IMPLICIT NONE |
65 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: NAT |
66 | 1 | equemene | REAL(KREAL) ,INTENT(IN) :: VEC(3,NAT) |
67 | 1 | equemene | REAL(KREAL) ,INTENT(OUT):: B(3,NAT) |
68 | 1 | equemene | INTEGER(KINT) :: IAT,I |
69 | 1 | equemene | ! ****************************************************************** |
70 | 1 | equemene | DO IAT=1,NAT |
71 | 1 | equemene | DO I=1,3 |
72 | 1 | equemene | B(I,IAT)=VEC(I,IAT) |
73 | 1 | equemene | ENDDO |
74 | 1 | equemene | ENDDO |
75 | 1 | equemene | RETURN |
76 | 1 | equemene | END SUBROUTINE CONSTRAINTS_GLC_DER |
77 | 1 | equemene | |
78 | 1 | equemene | |
79 | 1 | equemene | SUBROUTINE CONSTRAINTS_SUBSTITUTION_DER(NAT,IAT1,IAT2,IAT3,R0,B) |
80 | 1 | equemene | ! ****************************************************************** |
81 | 1 | equemene | ! ** CONSTRAINTS_SETsubstitution ** |
82 | 1 | equemene | ! ** APPROXIMATES CONSTRAINT FUNCTION (WITHOUT VALUE) ** |
83 | 1 | equemene | ! ** BY AN QUADRATIC POLYNOMial IN A+B*R+0.5*R*C*R ** |
84 | 1 | equemene | ! ** THE CONSTRAINT IS THE POLYNOMIAL MINUS THE VALUE FROM THE ** |
85 | 1 | equemene | ! ** REFERENCE STRUCTURE ** |
86 | 1 | equemene | ! ** CONSTRAINS THE difference OF THE BOND DISTANCES BETWEEN ** |
87 | 1 | equemene | ! ** R1-R2 AND R2-R3 ** |
88 | 1 | equemene | ! ****************************************************************** |
89 | 1 | equemene | Use Vartypes |
90 | 1 | equemene | implicit none |
91 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: NAT |
92 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT1 |
93 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT2 |
94 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT3 |
95 | 1 | equemene | REAL(KREAL) ,INTENT(OUT):: B(3,NAT) |
96 | 1 | equemene | REAL(KREAL) ,INTENT(IN) :: R0(3,NAT) |
97 | 1 | equemene | REAL(KREAL) :: X(9),DI(9) |
98 | 1 | equemene | real(KREAL) :: phi |
99 | 1 | equemene | REAL(KREAL) :: X1X2,Y1Y2,Z1Z2,X2X3,Y2Y3,Z2Z3,D12,D22, & |
100 | 1 | equemene | D1,D2,D13,D23 |
101 | 1 | equemene | integer(KINT) :: i,j |
102 | 1 | equemene | ! ****************************************************************** |
103 | 1 | equemene | ! |
104 | 1 | equemene | ! --- TRANSFER R0 TO X ARRAY TO MAKE HANDLING AND PASSING EASIER |
105 | 1 | equemene | DO I=1,3 |
106 | 1 | equemene | X(I) =R0(I,IAT1) |
107 | 1 | equemene | X(I+3)=R0(I,IAT2) |
108 | 1 | equemene | X(I+6)=R0(I,IAT3) |
109 | 1 | equemene | ENDDO |
110 | 1 | equemene | ! |
111 | 1 | equemene | ! --- FOR THE FOLLOWING, THE CONSTRAINT ITSELF WILL BE CALLED PHI |
112 | 1 | equemene | ! --- CALCULATE PHI,D PHI/D X_I, D^2 PHI/D X_I D X_J |
113 | 1 | equemene | ! |
114 | 1 | equemene | X1X2=X(1)-X(4) |
115 | 1 | equemene | Y1Y2=X(2)-X(5) |
116 | 1 | equemene | Z1Z2=X(3)-X(6) |
117 | 1 | equemene | X2X3=X(4)-X(7) |
118 | 1 | equemene | Y2Y3=X(5)-X(8) |
119 | 1 | equemene | Z2Z3=X(6)-X(9) |
120 | 1 | equemene | ! |
121 | 1 | equemene | D12=(X1X2)**2 + (Y1Y2)**2 + (Z1Z2)**2 |
122 | 1 | equemene | D22=(X2X3)**2 + (Y2Y3)**2 + (Z2Z3)**2 |
123 | 1 | equemene | D1= SQRT(D12) |
124 | 1 | equemene | D2= SQRT(D22) |
125 | 1 | equemene | D13= D1**3 |
126 | 1 | equemene | D23= D2**3 |
127 | 1 | equemene | PHI= D1 - D2 |
128 | 1 | equemene | ! |
129 | 1 | equemene | B(1,IAT1)= (X1X2)/D1 |
130 | 1 | equemene | B(1,IAT2)= -((X1X2)/D1) - (X2X3)/D2 |
131 | 1 | equemene | B(1,IAT3)= (X2X3)/D2 |
132 | 1 | equemene | B(2,IAT1)= (Y1Y2)/D1 |
133 | 1 | equemene | B(2,IAT2)= -((Y1Y2)/D1) - (Y2Y3)/D2 |
134 | 1 | equemene | B(2,IAT3)= (Y2Y3)/D2 |
135 | 1 | equemene | B(3,IAT1)= (Z1Z2)/D1 |
136 | 1 | equemene | B(3,IAT2)= -((Z1Z2)/D1) - (Z2Z3)/D2 |
137 | 1 | equemene | B(3,IAT3)= (Z2Z3)/D2 |
138 | 1 | equemene | ! |
139 | 1 | equemene | RETURN |
140 | 1 | equemene | END SUBROUTINE CONSTRAINTS_SUBSTITUTION_DER |
141 | 1 | equemene | |
142 | 1 | equemene | ! .................................................................. |
143 | 1 | equemene | SUBROUTINE CONSTRAINTS_BONDANGLE_DER(NAT,IAT1,IAT2,IAT3,R0,B) |
144 | 1 | equemene | ! ****************************************************************** |
145 | 1 | equemene | ! ** |
146 | 1 | equemene | ! ** CONSTRAINS THE ANGLE ENCLOSED BETWEEN ATOMS IAT1--IAT2--IAT3 |
147 | 1 | equemene | ! ** In the followin, IAT1 is also denoted by A, IAT2 by B and IAT3 by C |
148 | 1 | equemene | ! ** |
149 | 1 | equemene | ! ****************************************************************** |
150 | 1 | equemene | Use VarTypes |
151 | 1 | equemene | IMPLICIT none |
152 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: NAT |
153 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT1 |
154 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT2 |
155 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT3 |
156 | 1 | equemene | REAL(KREAL) ,INTENT(OUT):: B(3,NAT) |
157 | 1 | equemene | REAL(KREAL) ,INTENT(IN) :: R0(3,NAT) |
158 | 1 | equemene | REAL(KREAL) :: X(9),DI(9),DIDJ(9,9),B1(9) |
159 | 1 | equemene | real(KREAL) :: phi |
160 | 1 | equemene | integer(KINT) :: i,j,ichk, iat |
161 | 1 | equemene | REAL(KREAL) :: UU ! U*U |
162 | 1 | equemene | REAL(KREAL) :: VV ! V*V |
163 | 1 | equemene | REAL(KREAL) :: UV ! U*V |
164 | 1 | equemene | REAL(KREAL) :: D ! 1/SQRT(A*B) |
165 | 1 | equemene | REAL(KREAL) :: DADX(9) |
166 | 1 | equemene | REAL(KREAL) :: DBDX(9) |
167 | 1 | equemene | REAL(KREAL) :: DCDX(9) |
168 | 1 | equemene | REAL(KREAL) :: DDDX(9) |
169 | 1 | equemene | REAL(KREAL) :: DJDX(9) |
170 | 1 | equemene | REAL(KREAL) :: DVDX(9) |
171 | 1 | equemene | REAL(KREAL) :: DGDX(9) ! D(A*B)/DX |
172 | 1 | equemene | REAL(KREAL) :: AB,AB2N,V,PREFAC |
173 | 1 | equemene | REAL(KREAL) :: COSPHI,SINPHI |
174 | 1 | equemene | REAL(KREAL) :: DIVDX,AI |
175 | 1 | equemene | ! |
176 | 1 | equemene | ! Variable used in case of a linear molecule with three atoms call A,B and C |
177 | 1 | equemene | ! Phi is the ABC angle |
178 | 1 | equemene | ! Threshold use to decide that sin(Phi)=0. |
179 | 1 | equemene | REAL(KREAL), PARAMETER :: ThreshSin=1e-7 |
180 | 1 | equemene | ! Sine and Cosine of the euler Phi angle between ABC and x axis |
181 | 1 | equemene | REAL(KREAL) :: CosP,SinP |
182 | 1 | equemene | ! Sine and Cosine of the euler theta angle between ABC and z axis |
183 | 1 | equemene | REAL(KREAL) :: CosTheta,SinTheta |
184 | 1 | equemene | ! Vectors CB, CA,AB |
185 | 1 | equemene | REAL(KREAL) ::vCB(3),vCA(3),vAB(3) |
186 | 1 | equemene | ! distance AB in the xAy plane |
187 | 1 | equemene | REAL(KREAL) :: dABxy |
188 | 1 | equemene | ! cosine of the BAC angle |
189 | 1 | equemene | REAL(KREAL) :: CosBAC |
190 | 1 | equemene | ! cosine of the BCA angle |
191 | 1 | equemene | REAL(KREAL) :: CosBCA |
192 | 1 | equemene | |
193 | 1 | equemene | ! |
194 | 1 | equemene | ! For debugginh purposes: |
195 | 1 | equemene | LOGICAL, PARAMETER :: Debug=.False. |
196 | 1 | equemene | |
197 | 1 | equemene | |
198 | 1 | equemene | IF (Debug) WRITE(*,*) "================ Entering CONSTRAINTS_BONDANGLE_DER ==========" |
199 | 1 | equemene | ! ****************************************************************** |
200 | 1 | equemene | ! |
201 | 1 | equemene | ! ================================================================== |
202 | 1 | equemene | ! == SET UP CONSTRAINT IN COORDINATE SPACE == |
203 | 1 | equemene | ! ================================================================== |
204 | 1 | equemene | ! |
205 | 1 | equemene | ! ================================================================== |
206 | 1 | equemene | ! == CALCULATE VALUE AND FIRST TWO DERIVATIVES OF == |
207 | 1 | equemene | ! == PHI=<X1-X2|X3-X2>/SQRT(<X1-X2|X1-X2><X3-X2|X3-X2>) == |
208 | 1 | equemene | ! ================================================================== |
209 | 1 | equemene | ! --- TRANSFER R0 TO X ARRAY TO MAKE HANDLING AND PASSING EASIER |
210 | 1 | equemene | DO I=1,3 |
211 | 1 | equemene | X(I) =R0(I,IAT1) |
212 | 1 | equemene | X(I+3)=R0(I,IAT2) |
213 | 1 | equemene | X(I+6)=R0(I,IAT3) |
214 | 1 | equemene | ENDDO |
215 | 1 | equemene | |
216 | 1 | equemene | if (debug) THEN |
217 | 1 | equemene | WRITE(*,*) "X=",X |
218 | 1 | equemene | WRITE(*,*) "A=",X(1)-X(4),X(2)-X(5),X(3)-X(6) |
219 | 1 | equemene | WRITE(*,*) "B=",X(7)-X(4),X(8)-X(5),X(9)-X(6) |
220 | 1 | equemene | END IF |
221 | 1 | equemene | |
222 | 1 | equemene | ! ---------------------------------------------------------------- |
223 | 1 | equemene | ! --- R1=X(1:3) R2=X(4:6) R3=X(7:9) |
224 | 1 | equemene | ! --- U=R1-R2 V=R3-R2 |
225 | 1 | equemene | ! --- A=U*U=d(At1-At2)**2 |
226 | 1 | equemene | ! --- B=V*V=d(At2-At3)**2 |
227 | 1 | equemene | ! --- C=U*V=vec(At2-At1)*vec(At2-At3) |
228 | 1 | equemene | ! ---------------------------------------------------------------- |
229 | 1 | equemene | UU=(X(1)-X(4))**2 + (X(2)-X(5))**2 + (X(3)-X(6))**2 |
230 | 1 | equemene | VV=(X(7)-X(4))**2 + (X(8)-X(5))**2 + (X(9)-X(6))**2 |
231 | 1 | equemene | UV=(X(1)-X(4))*(X(7)-X(4)) & |
232 | 1 | equemene | +(X(2)-X(5))*(X(8)-X(5)) & |
233 | 1 | equemene | +(X(3)-X(6))*(X(9)-X(6)) |
234 | 1 | equemene | AB=UU*VV |
235 | 1 | equemene | D=SQRT(AB) |
236 | 1 | equemene | COSPHI=UV/D !=COS(PHI) |
237 | 1 | equemene | PHI=DACOS(COSPHI) |
238 | 1 | equemene | SINPHI=DSQRT(1.D0-COSPHI**2) |
239 | 1 | equemene | |
240 | 1 | equemene | IF (SINPHI.GE.ThreshSin) THEN |
241 | 1 | equemene | ! The following evaluation of the derivative involves |
242 | 1 | equemene | ! 1/sinphi... so we test that it is not 0 :-) |
243 | 1 | equemene | ! --- CALCULATE DADX |
244 | 1 | equemene | DADX(1)= 2.D0*(X(1)-X(4)) |
245 | 1 | equemene | DADX(2)= 2.D0*(X(2)-X(5)) |
246 | 1 | equemene | DADX(3)= 2.D0*(X(3)-X(6)) |
247 | 1 | equemene | DADX(4)=-2.D0*(X(1)-X(4)) |
248 | 1 | equemene | DADX(5)=-2.D0*(X(2)-X(5)) |
249 | 1 | equemene | DADX(6)=-2.D0*(X(3)-X(6)) |
250 | 1 | equemene | DADX(7)= 0.D0 |
251 | 1 | equemene | DADX(8)= 0.D0 |
252 | 1 | equemene | DADX(9)= 0.D0 |
253 | 1 | equemene | ! --- CALCULATE DBDX |
254 | 1 | equemene | DBDX(1)= 0.D0 |
255 | 1 | equemene | DBDX(2)= 0.D0 |
256 | 1 | equemene | DBDX(3)= 0.D0 |
257 | 1 | equemene | DBDX(4)=-2.D0*(X(7)-X(4)) |
258 | 1 | equemene | DBDX(5)=-2.D0*(X(8)-X(5)) |
259 | 1 | equemene | DBDX(6)=-2.D0*(X(9)-X(6)) |
260 | 1 | equemene | DBDX(7)= 2.D0*(X(7)-X(4)) |
261 | 1 | equemene | DBDX(8)= 2.D0*(X(8)-X(5)) |
262 | 1 | equemene | DBDX(9)= 2.D0*(X(9)-X(6)) |
263 | 1 | equemene | ! --- CALCULATE DCDX |
264 | 1 | equemene | DCDX(1)= X(7)-X(4) |
265 | 1 | equemene | DCDX(2)= X(8)-X(5) |
266 | 1 | equemene | DCDX(3)= X(9)-X(6) |
267 | 1 | equemene | DCDX(4)=-X(7)+2.D0*X(4)-X(1) |
268 | 1 | equemene | DCDX(5)=-X(8)+2.D0*X(5)-X(2) |
269 | 1 | equemene | DCDX(6)=-X(9)+2.D0*X(6)-X(3) |
270 | 1 | equemene | DCDX(7)= X(1)-X(4) |
271 | 1 | equemene | DCDX(8)= X(2)-X(5) |
272 | 1 | equemene | DCDX(9)= X(3)-X(6) |
273 | 1 | equemene | |
274 | 1 | equemene | ! WRITE(*,*) 'PFL DER ANGLE' |
275 | 1 | equemene | ! WRITE(*,'(15(1X,F10.6))') DADX |
276 | 1 | equemene | ! WRITE(*,'(15(1X,F10.6))') DBDX |
277 | 1 | equemene | ! WRITE(*,'(15(1X,F10.6))') DCDX |
278 | 1 | equemene | |
279 | 1 | equemene | ! ================================================================== |
280 | 1 | equemene | ! == CALCULATE PHI ETC =========================================== |
281 | 1 | equemene | ! ================================================================== |
282 | 1 | equemene | ! --- CALCULATE DERIVATIVE OF ARCCOS |
283 | 1 | equemene | V=-1.D0/SINPHI !=-SIN(PHI)=D(ACOS(PHI))/D(COSPHI) |
284 | 1 | equemene | ! --- CALCULATE FIRST DERIVATIVES OF G=A*B |
285 | 1 | equemene | DO I=1,9 |
286 | 1 | equemene | DGDX(I)=DADX(I)*VV+UU*DBDX(I) |
287 | 1 | equemene | ENDDO |
288 | 1 | equemene | ! --- CALCULATE DDDX |
289 | 1 | equemene | AB2N=0.5D0/D |
290 | 1 | equemene | DO I=1,9 |
291 | 1 | equemene | DDDX(I)=AB2N*DGDX(I) |
292 | 1 | equemene | ENDDO |
293 | 1 | equemene | ! --- CALCULATE FIRST DERIVATIVES OF J |
294 | 1 | equemene | PREFAC=1.D0/AB |
295 | 1 | equemene | DO I=1,9 |
296 | 1 | equemene | DJDX(I)=(DCDX(I)*D-UV*DDDX(I))*PREFAC |
297 | 1 | equemene | ENDDO |
298 | 1 | equemene | ! --- CALCULATE FIRST DERIVATIVE |
299 | 1 | equemene | DO I=1,9 |
300 | 1 | equemene | DI(I)=DJDX(I)*V |
301 | 1 | equemene | ENDDO |
302 | 1 | equemene | ! |
303 | 1 | equemene | ! Store it back to B |
304 | 1 | equemene | DO I=1,3 |
305 | 1 | equemene | B(I,IAT1)=DI(I) |
306 | 1 | equemene | B(I,IAT2)=DI(I+3) |
307 | 1 | equemene | B(I,IAT3)=DI(I+6) |
308 | 1 | equemene | ENDDO |
309 | 1 | equemene | |
310 | 1 | equemene | ELSE |
311 | 1 | equemene | ! First calculate cosP, sinP, CosTheta, SinTheta |
312 | 1 | equemene | dABxy=sqrt((X(4)-X(1))**2+(X(5)-X(2))**2) |
313 | 1 | equemene | cosP=abs((X(7)-X(1)))/sqrt((X(7)-X(1))**2+(X(8)-X(2))**2) |
314 | 1 | equemene | ! SinP=(X(8)-X(2))/sqrt((X(7)-X(1))**2+(X(8)-X(2))**2) |
315 | 1 | equemene | sinP=sqrt(1.d0-cosP**2) |
316 | 1 | equemene | cosTheta=(X(6)-X(3))/(sqrt(UU)) |
317 | 1 | equemene | SinTheta=dABxy/(sqrt(UU)) |
318 | 1 | equemene | IF (SinTheta.le.ThreshSin) THEN |
319 | 1 | equemene | ! Theta=0, so that the euler Phi angle is ill-defined. We put it to 0: |
320 | 1 | equemene | CosP=1.d0 |
321 | 1 | equemene | SinP=0.d0 |
322 | 1 | equemene | END IF |
323 | 1 | equemene | IF (Debug) WRITE(*,*) "CosP,SinP ",CosP,SinP |
324 | 1 | equemene | if (debug) WRITE(*,*) "CosTheta,SinTheta",CosTheta,SinTheta |
325 | 1 | equemene | ! We calculate cos(BAC) and cos(BCA) because they are needed to calculate |
326 | 1 | equemene | ! the derivatives for the centre atom (B) |
327 | 1 | equemene | DO I=1,3 |
328 | 1 | equemene | vCB(I)=X(3+I)-X(6+I) |
329 | 1 | equemene | vCA(I)=X(I)-X(6+I) |
330 | 1 | equemene | vAB(I)=x(3+I)-x(I) |
331 | 1 | equemene | END DO |
332 | 1 | equemene | CosBCA=DOT_PRODUCT(vCB,vCA)/sqrt(DOT_PRODUCT(vCB,vCB)*DOT_PRODUCT(vCA,vCA)) |
333 | 1 | equemene | CosBAC=-DOT_PRODUCT(vAB,vCA)/sqrt(DOT_PRODUCT(vAB,vAB)*DOT_PRODUCT(vCA,vCA)) |
334 | 1 | equemene | if (debug) WRITE(*,*) "CosBAC,CosBCA:",CosBAC,CosBCA |
335 | 1 | equemene | ! Sign of the derivatives are -1 for Phi=Pi and 1 for Phi=0 |
336 | 1 | equemene | ! ie is cos(Phi). |
337 | 1 | equemene | DI(1)=COSPHI/sqrt(UU) |
338 | 1 | equemene | DI(2)=DI(1) |
339 | 1 | equemene | DI(3)=0.d0 |
340 | 1 | equemene | DI(7)=COSPHI/sqrt(VV) |
341 | 1 | equemene | DI(8)=DI(7) |
342 | 1 | equemene | DI(9)=0.d0 |
343 | 1 | equemene | DI(4)=CosBCA*DI(1)+cosBAC*DI(7) |
344 | 1 | equemene | DI(5)=DI(4) |
345 | 1 | equemene | DI(6)=0.D0 |
346 | 1 | equemene | if (debug) WRITE(*,'(A,9(1X,F12.6))') 'DI=',DI(1:9) |
347 | 1 | equemene | if (debug) THEN |
348 | 1 | equemene | WRITE(*,'(3(1X,F12.6))') cosTheta*CosP,sinP,-cosP*sinTheta |
349 | 1 | equemene | WRITE(*,'(3(1X,F12.6))') -cosTheta*sinP,cosP,sinP*sinTheta |
350 | 1 | equemene | WRITE(*,'(3(1X,F12.6))') sinTheta,0.,cosTheta |
351 | 1 | equemene | END IF |
352 | 1 | equemene | ! We now take care of the fact that the three fragment are |
353 | 1 | equemene | ! not along the Z-axis |
354 | 1 | equemene | B(1,Iat1)=cosTheta*CosP*DI(1)+sinP*DI(2)-cosP*sinTheta*DI(3) |
355 | 1 | equemene | B(1,Iat2)=cosTheta*CosP*DI(4)+sinP*DI(5)-cosP*sinTheta*DI(6) |
356 | 1 | equemene | B(1,Iat3)=cosTheta*CosP*DI(7)+sinP*DI(8)-cosP*sinTheta*DI(9) |
357 | 1 | equemene | B(2,Iat1)=-cosTheta*SinP*DI(1)+cosP*DI(2)+sinP*sinTheta*DI(3) |
358 | 1 | equemene | B(2,Iat2)=-cosTheta*SinP*DI(4)+cosP*DI(5)+sinP*sinTheta*DI(6) |
359 | 1 | equemene | B(2,Iat3)=-cosTheta*SinP*DI(7)+cosP*DI(8)+sinP*sinTheta*DI(9) |
360 | 1 | equemene | B(3,Iat1)=sinTheta*DI(1)+cosTheta*DI(3) |
361 | 1 | equemene | B(3,Iat2)=sinTheta*DI(4)+cosTheta*DI(6) |
362 | 1 | equemene | B(3,Iat3)=sinTheta*DI(7)+cosTheta*DI(9) |
363 | 1 | equemene | END IF |
364 | 1 | equemene | |
365 | 1 | equemene | IF (Debug) WRITE(*,*) "================ Exiting CONSTRAINTS_BONDANGLE_DER ==========" |
366 | 1 | equemene | END SUBROUTINE CONSTRAINTS_BONDANGLE_DER |
367 | 1 | equemene | |
368 | 1 | equemene | |
369 | 1 | equemene | ! .................................................................. |
370 | 1 | equemene | SUBROUTINE CONSTRAINTS_TORSION_DER(NAT,IAT1,IAT2,IAT3,IAT4,R0,B) |
371 | 1 | equemene | ! ****************************************************************** |
372 | 1 | equemene | ! ** |
373 | 1 | equemene | ! ** CONSTRAINS THE TORSION OF IAT1-IAT2---IAT3-IAT4 |
374 | 1 | equemene | ! ** |
375 | 1 | equemene | ! ****************************************************************** |
376 | 1 | equemene | Use VarTypes |
377 | 1 | equemene | IMPLICIT none |
378 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: NAT |
379 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT1 |
380 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT2 |
381 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT3 |
382 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT4 |
383 | 1 | equemene | REAL(KREAL) ,INTENT(IN) :: R0(3,NAT) |
384 | 1 | equemene | REAL(KREAL) ,INTENT(OUT):: B(3,NAT) |
385 | 1 | equemene | REAL(KREAL) :: X(12),DI(12),DIDJ(12,12),B1(12) |
386 | 1 | equemene | REAL(KREAL) :: P(3),Q(3),T(3),U(3),R(3),W(3) |
387 | 1 | equemene | real(KREAL) :: phi |
388 | 1 | equemene | integer(KINT) :: i,j,ichk,k |
389 | 1 | equemene | |
390 | 1 | equemene | REAL(KREAL) :: TORS, PP,QQ, PQ |
391 | 1 | equemene | REAL(KREAL) :: DADX(12),DBDX(12),DCDX(12) |
392 | 1 | equemene | REAL(KREAL) :: DDDX(12),DJDX(12),DVDX(12),DGDX(12),DPDX(3,12),DQDX(3,12) |
393 | 1 | equemene | REAL(KREAL) :: D2QDX2(3,12,12),D2PDX2(3,12,12) |
394 | 1 | equemene | REAL(KREAL) :: D2BDX2(12,12),D2ADX2(12,12),D2CDX2(12,12),D2DDX2(12,12) |
395 | 1 | equemene | real(KREAL) :: d,coverd,abyb2n,abyb,ai,divdx,prefac,v |
396 | 1 | equemene | |
397 | 1 | equemene | ! ****************************************************************** |
398 | 1 | equemene | ! |
399 | 1 | equemene | ! --- TRANSFER R0 TO X ARRAY TO MAKE HANDLING AND PASSING EASIER |
400 | 1 | equemene | DO I=1,3 |
401 | 1 | equemene | X(I)=R0(I,IAT1) |
402 | 1 | equemene | X(I+3)=R0(I,IAT2) |
403 | 1 | equemene | X(I+6)=R0(I,IAT3) |
404 | 1 | equemene | X(I+9)=R0(I,IAT4) |
405 | 1 | equemene | ENDDO |
406 | 1 | equemene | ! |
407 | 1 | equemene | ! --- CALCULATE PHI,D PHI/D X_I, D^2 PHI/D X_I D X_J |
408 | 1 | equemene | T(:)=X(1:3) -X(4:6) |
409 | 1 | equemene | U(:)=X(7:9) -X(4:6) |
410 | 1 | equemene | R(:)=X(10:12)-X(7:9) |
411 | 1 | equemene | W(:)=X(4:6) -X(7:9) |
412 | 1 | equemene | CALL VPRD(T,U,P) |
413 | 1 | equemene | CALL VPRD(W,R,Q) |
414 | 1 | equemene | PQ=DOT_PRODUCT(P,Q) |
415 | 1 | equemene | PP=DOT_PRODUCT(P,P) |
416 | 1 | equemene | QQ=DOT_PRODUCT(Q,Q) |
417 | 1 | equemene | ! |
418 | 1 | equemene | ABYB=PP*QQ |
419 | 1 | equemene | D=ABYB**0.5D0 |
420 | 1 | equemene | COVERD=PQ/D |
421 | 1 | equemene | ABYB2N=0.5D0/D |
422 | 1 | equemene | ! |
423 | 1 | equemene | TORS=DACOS(COVERD) |
424 | 1 | equemene | WRITE(*,*) "Torsion derivs Phi=", Tors*180./3.1415926,Iat1,Iat2,Iat3,Iat4 |
425 | 1 | equemene | ! |
426 | 1 | equemene | ! ---------------------------------------------------------------- |
427 | 1 | equemene | ! --- CALCULATE FIRST DERIVATIVES |
428 | 1 | equemene | ! ---------------------------------------------------------------- |
429 | 1 | equemene | ! --- CALCULATE DERIVATIVE OF ARCCOS |
430 | 1 | equemene | IF (dabs(DABS(COVERD)-1.d0) < 1.D-9) THEN |
431 | 1 | equemene | WRITE(*,*) 'WARNING: DERIVATIVE OF TORSION AT ZERO AND PI IS UNDEFINED!' |
432 | 1 | equemene | COVERD=sign(0.999d0,COVERD) |
433 | 1 | equemene | TORS=DACOS(COVERD) |
434 | 1 | equemene | !WRITE(*,*) "Torsion derivs, Phi=", Tors |
435 | 1 | equemene | |
436 | 1 | equemene | ! V=0.D0 |
437 | 1 | equemene | ! ELSE |
438 | 1 | equemene | END IF |
439 | 1 | equemene | V=-1.D0/DSQRT(1.D0-(COVERD)**2.D0) |
440 | 1 | equemene | ! ENDIF |
441 | 1 | equemene | ! --- CALCULATE DPDX |
442 | 1 | equemene | ! --- ZERO OUT SPARSE MATRIX |
443 | 1 | equemene | DO J=1,3 |
444 | 1 | equemene | DO I=1,12 |
445 | 1 | equemene | DPDX(J,I)=0.D0 |
446 | 1 | equemene | DQDX(J,I)=0.D0 |
447 | 1 | equemene | ENDDO |
448 | 1 | equemene | ENDDO |
449 | 1 | equemene | DPDX(1,2)=X(9)-X(6) |
450 | 1 | equemene | DPDX(1,3)=X(5)-X(8) |
451 | 1 | equemene | DPDX(1,5)=X(3)-X(9) |
452 | 1 | equemene | DPDX(1,6)=X(8)-X(2) |
453 | 1 | equemene | DPDX(1,8)=X(6)-X(3) |
454 | 1 | equemene | DPDX(1,9)=X(2)-X(5) |
455 | 1 | equemene | DPDX(2,1)=X(6)-X(9) |
456 | 1 | equemene | DPDX(2,3)=X(7)-X(4) |
457 | 1 | equemene | DPDX(2,4)=X(9)-X(3) |
458 | 1 | equemene | DPDX(2,6)=X(1)-X(7) |
459 | 1 | equemene | DPDX(2,7)=X(3)-X(6) |
460 | 1 | equemene | DPDX(2,9)=X(4)-X(1) |
461 | 1 | equemene | DPDX(3,1)=X(8)-X(5) |
462 | 1 | equemene | DPDX(3,2)=X(4)-X(7) |
463 | 1 | equemene | DPDX(3,4)=X(2)-X(8) |
464 | 1 | equemene | DPDX(3,5)=X(7)-X(1) |
465 | 1 | equemene | DPDX(3,7)=X(5)-X(2) |
466 | 1 | equemene | DPDX(3,8)=X(1)-X(4) |
467 | 1 | equemene | ! --- CALCULATE DQDX |
468 | 1 | equemene | DQDX(1,5)=X(12)-X(9) |
469 | 1 | equemene | DQDX(1,6)=X(8)-X(11) |
470 | 1 | equemene | DQDX(1,8)=X(6)-X(12) |
471 | 1 | equemene | DQDX(1,9)=X(11)-X(5) |
472 | 1 | equemene | DQDX(1,11)=X(9)-X(6) |
473 | 1 | equemene | DQDX(1,12)=X(5)-X(8) |
474 | 1 | equemene | DQDX(2,4)=X(9)-X(12) |
475 | 1 | equemene | DQDX(2,6)=X(10)-X(7) |
476 | 1 | equemene | DQDX(2,7)=X(12)-X(6) |
477 | 1 | equemene | DQDX(2,9)=X(4)-X(10) |
478 | 1 | equemene | DQDX(2,10)=X(6)-X(9) |
479 | 1 | equemene | DQDX(2,12)=X(7)-X(4) |
480 | 1 | equemene | DQDX(3,4)=X(11)-X(8) |
481 | 1 | equemene | DQDX(3,5)=X(7)-X(10) |
482 | 1 | equemene | DQDX(3,7)=X(5)-X(11) |
483 | 1 | equemene | DQDX(3,8)=X(10)-X(4) |
484 | 1 | equemene | DQDX(3,10)=X(8)-X(5) |
485 | 1 | equemene | DQDX(3,11)=X(4)-X(7) |
486 | 1 | equemene | |
487 | 1 | equemene | ! WRITE(*,*) 'DP/DX(1) ' |
488 | 1 | equemene | ! WRITE(*,'(1X,12(F9.5,1X))') DPDX(1,:) |
489 | 1 | equemene | ! WRITE(*,*) 'DP/DX(2) ' |
490 | 1 | equemene | ! WRITE(*,'(1X,12(F9.5,1X))') DPDX(2,:) |
491 | 1 | equemene | ! WRITE(*,*) 'DP/DX(3) ' |
492 | 1 | equemene | ! WRITE(*,'(1X,12(F9.5,1X))') DPDX(3,:) |
493 | 1 | equemene | ! WRITE(*,*) 'DQ/DX(1) ' |
494 | 1 | equemene | ! WRITE(*,'(1X,12(F9.5,1X))') DQDX(1,:) |
495 | 1 | equemene | ! WRITE(*,*) 'DQ/DX(2) ' |
496 | 1 | equemene | ! WRITE(*,'(1X,12(F9.5,1X))') DQDX(2,:) |
497 | 1 | equemene | ! WRITE(*,*) 'DQ/DX(3) ' |
498 | 1 | equemene | ! WRITE(*,'(1X,12(F9.5,1X))') DQDX(3,:) |
499 | 1 | equemene | |
500 | 1 | equemene | ! --- CALCULATE DADX |
501 | 1 | equemene | DO I=1,12 |
502 | 1 | equemene | DADX(I)=0.D0 |
503 | 1 | equemene | DBDX(I)=0.D0 |
504 | 1 | equemene | DCDX(I)=0.D0 |
505 | 1 | equemene | DO J=1,3 |
506 | 1 | equemene | DADX(I)=DADX(I)+2.D0*P(J)*DPDX(J,I) |
507 | 1 | equemene | DBDX(I)=DBDX(I)+2.D0*Q(J)*DQDX(J,I) |
508 | 1 | equemene | DCDX(I)=DCDX(I)+DPDX(J,I)*Q(J)+P(J)*DQDX(J,I) |
509 | 1 | equemene | ENDDO |
510 | 1 | equemene | ENDDO |
511 | 1 | equemene | |
512 | 1 | equemene | ! --- CALCULATE FIRST DERIVATIVES OF G |
513 | 1 | equemene | DO I=1,12 |
514 | 1 | equemene | DGDX(I)=DADX(I)*QQ+PP*DBDX(I) |
515 | 1 | equemene | ENDDO |
516 | 1 | equemene | ! --- CALCULATE DDDX |
517 | 1 | equemene | DO I=1,12 |
518 | 1 | equemene | DDDX(I)=ABYB2N*DGDX(I) |
519 | 1 | equemene | ENDDO |
520 | 1 | equemene | ! --- CALCULATE FIRST DERIVATIVES OF J |
521 | 1 | equemene | PREFAC=1.D0/ABYB |
522 | 1 | equemene | DO I=1,12 |
523 | 1 | equemene | DJDX(I)=(DCDX(I)*D-PQ*DDDX(I))*PREFAC |
524 | 1 | equemene | ENDDO |
525 | 1 | equemene | ! --- CALCULATE FIRST DERIVATIVE |
526 | 1 | equemene | DO I=1,12 |
527 | 1 | equemene | DI(I)=DJDX(I)*V |
528 | 1 | equemene | ENDDO |
529 | 1 | equemene | |
530 | 1 | equemene | ! WRITE(*,*) 'PFL 1st DER TORSION' |
531 | 1 | equemene | ! WRITE(*,'(15(1X,F10.6))') DADX(:) |
532 | 1 | equemene | ! WRITE(*,'(15(1X,F10.6))') DBDX(:) |
533 | 1 | equemene | ! WRITE(*,'(15(1X,F10.6))') DCDX(:) |
534 | 1 | equemene | ! WRITE(*,'(15(1X,F10.6))') DGDX(:) |
535 | 1 | equemene | ! WRITE(*,'(15(1X,F10.6))') DDDX(:) |
536 | 1 | equemene | ! WRITE(*,'(15(1X,F10.6))') DJDX(:) |
537 | 1 | equemene | ! WRITE(*,'(15(1X,F10.6))') DI(:) |
538 | 1 | equemene | |
539 | 1 | equemene | |
540 | 1 | equemene | ! ------------------------------------------------------------- |
541 | 1 | equemene | ! --- CALCULATE B |
542 | 1 | equemene | ! ------------------------------------------------------------- |
543 | 1 | equemene | |
544 | 1 | equemene | WRITE(*,*) 'DER TOR 1' |
545 | 1 | equemene | WRITE(*,*) DI(1:3) |
546 | 1 | equemene | WRITE(*,*) DI(4:6) |
547 | 1 | equemene | WRITE(*,*) DI(7:9) |
548 | 1 | equemene | WRITE(*,*) DI(10:12) |
549 | 1 | equemene | |
550 | 1 | equemene | DO I=1,3 |
551 | 1 | equemene | B(I,IAT1)=DI(I) |
552 | 1 | equemene | B(I,IAT2)=DI(I+3) |
553 | 1 | equemene | B(I,IAT3)=DI(I+6) |
554 | 1 | equemene | B(I,IAT4)=DI(I+9) |
555 | 1 | equemene | END DO |
556 | 1 | equemene | END SUBROUTINE CONSTRAINTS_TORSION_DER |
557 | 1 | equemene | |
558 | 1 | equemene | |
559 | 1 | equemene | ! .................................................................. |
560 | 1 | equemene | SUBROUTINE CONSTRAINTS_TORSION_DER3(NAT,IAT1,IAT2,IAT3,IAT4,R0,B) |
561 | 1 | equemene | ! ****************************************************************** |
562 | 1 | equemene | ! ** |
563 | 1 | equemene | ! ** CONSTRAINS THE TORSION OF IAT1-IAT2---IAT3-IAT4 |
564 | 1 | equemene | ! ** |
565 | 1 | equemene | ! ****************************************************************** |
566 | 1 | equemene | use VarTypes |
567 | 1 | equemene | IMPLICIT none |
568 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: NAT |
569 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT1 |
570 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT2 |
571 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT3 |
572 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT4 |
573 | 1 | equemene | REAL(KREAL) ,INTENT(IN) :: R0(3,NAT) |
574 | 1 | equemene | REAL(KREAL) ,INTENT(OUT):: B(3,NAT) |
575 | 1 | equemene | REAL(KREAL) :: X(12),DI(12),DIDJ(12,12),B1(12) |
576 | 1 | equemene | REAL(KREAL) :: P(3),Q(3),T(3),U(3),R(3),W(3) |
577 | 1 | equemene | REAL(KREAL) :: Rij(3), rkj(3), rkl(3),rmj(3),rnk(3) |
578 | 1 | equemene | REAL(KREAL) :: Nrij, Nrkj, Nrkl, Nrmj, Nrnk |
579 | 1 | equemene | REAL(KREAL) :: SignPhi |
580 | 1 | equemene | real(KREAL) :: phi |
581 | 1 | equemene | integer(KINT) :: i,j,ichk,k |
582 | 1 | equemene | |
583 | 1 | equemene | REAL(KREAL) :: TORS, PP,QQ, PQ |
584 | 1 | equemene | REAL(KREAL) :: DADX(12),DBDX(12),DCDX(12) |
585 | 1 | equemene | REAL(KREAL) :: DDDX(12),DJDX(12),DVDX(12),DGDX(12),DPDX(3,12),DQDX(3,12) |
586 | 1 | equemene | REAL(KREAL) :: D2QDX2(3,12,12),D2PDX2(3,12,12) |
587 | 1 | equemene | REAL(KREAL) :: D2BDX2(12,12),D2ADX2(12,12),D2CDX2(12,12),D2DDX2(12,12) |
588 | 1 | equemene | real(KREAL) :: d,coverd,abyb2n,abyb,ai,divdx,prefac,v |
589 | 1 | equemene | |
590 | 1 | equemene | LOGICAL :: Debug=.TRUE. |
591 | 1 | equemene | |
592 | 1 | equemene | ! ****************************************************************** |
593 | 1 | equemene | ! |
594 | 1 | equemene | if (debug) WRITE(*,*) "============= Entering CONSTRAINTS_TORSION_DER3 ===============" |
595 | 1 | equemene | |
596 | 1 | equemene | ! --- TRANSFER R0 TO X ARRAY TO MAKE HANDLING AND PASSING EASIER |
597 | 1 | equemene | |
598 | 1 | equemene | DO I=1,3 |
599 | 1 | equemene | X(I)=R0(I,IAT1) |
600 | 1 | equemene | X(I+3)=R0(I,IAT2) |
601 | 1 | equemene | X(I+6)=R0(I,IAT3) |
602 | 1 | equemene | X(I+9)=R0(I,IAT4) |
603 | 1 | equemene | ENDDO |
604 | 1 | equemene | |
605 | 1 | equemene | if (debug) THEN |
606 | 1 | equemene | WRITE(*,'(1X,I5,3(1X,F10.6))') IAt1,R0(:,IAT1) |
607 | 1 | equemene | WRITE(*,'(1X,I5,3(1X,F10.6))') IAt2,R0(:,IAT2) |
608 | 1 | equemene | WRITE(*,'(1X,I5,3(1X,F10.6))') IAt3,R0(:,IAT3) |
609 | 1 | equemene | WRITE(*,'(1X,I5,3(1X,F10.6))') IAt4,R0(:,IAT4) |
610 | 1 | equemene | END IF |
611 | 1 | equemene | ! |
612 | 1 | equemene | Rij=X(4:6)-X(1:3) |
613 | 1 | equemene | Rkj=X(4:6)-X(7:9) |
614 | 1 | equemene | Rkl=X(10:12)-X(7:9) |
615 | 1 | equemene | |
616 | 1 | equemene | Call VPRD(Rij,Rkj,Rmj) |
617 | 1 | equemene | Call Vprd(Rkj,Rkl,Rnk) |
618 | 1 | equemene | NRmj=DOT_PRODUCT(Rmj,Rmj) |
619 | 1 | equemene | NRnk=DOT_PRODUCT(Rnk,Rnk) |
620 | 1 | equemene | NRkj=sqrt(DOT_PRODUCT(Rkj,Rkj)) |
621 | 1 | equemene | |
622 | 1 | equemene | Coverd=DOT_PRODUCT(Rmj,Rnk)/sqrt(NRmj*NRnk) |
623 | 1 | equemene | CALL VPRD(Rmj,Rnk,T) |
624 | 1 | equemene | SignPhi=Sign(1.d0,DOT_PRODUCT(Rkj,T)) |
625 | 1 | equemene | ! SignPhi=Sign(1.d0,DOT_PRODUCT(Rkj,T)) |
626 | 1 | equemene | ! WRITE(*,*) "DBG Tor 2 signphi, dacos(coverd), sign(1.d0,signphi)", & |
627 | 1 | equemene | ! signphi, dacos(coverd), sign(1.d0,signphi) |
628 | 1 | equemene | ! |
629 | 1 | equemene | TORS=-1.d0*DACOS(COVERD)*signPhi |
630 | 1 | equemene | |
631 | 1 | equemene | if (debug) WRITE(*,*) "Torsion derivs 3, Phi=", Tors*180./3.1415926,Iat1,Iat2,Iat3,Iat4 |
632 | 1 | equemene | ! |
633 | 1 | equemene | ! ---------------------------------------------------------------- |
634 | 1 | equemene | ! --- CALCULATE FIRST DERIVATIVES |
635 | 1 | equemene | ! ---------------------------------------------------------------- |
636 | 1 | equemene | DI(1:3)=NRkj/NRmj*Rmj |
637 | 1 | equemene | DI(10:12)=-NRkj/NRnk*Rnk |
638 | 1 | equemene | DI(4:6)=(DOT_PRODUCT(Rij,Rkj)/Nrkj**2-1.d0)*DI(1:3)-(DOT_PRODUCT(Rkl,Rkj)/NRkj**2)*DI(10:12) |
639 | 1 | equemene | DI(7:9)=(DOT_PRODUCT(Rkl,Rkj)/Nrkj**2-1.d0)*DI(10:12)-(DOT_PRODUCT(Rij,Rkj)/NRkj**2)*DI(1:3) |
640 | 1 | equemene | |
641 | 1 | equemene | |
642 | 1 | equemene | DI=DI*SignPhi |
643 | 1 | equemene | |
644 | 1 | equemene | if (debug) THEN |
645 | 1 | equemene | WRITE(*,*) 'DER TOR 3' |
646 | 1 | equemene | WRITE(*,*) DI(1:3) |
647 | 1 | equemene | WRITE(*,*) DI(4:6) |
648 | 1 | equemene | WRITE(*,*) DI(7:9) |
649 | 1 | equemene | WRITE(*,*) DI(10:12) |
650 | 1 | equemene | END IF |
651 | 1 | equemene | |
652 | 1 | equemene | DO I=1,3 |
653 | 1 | equemene | B(I,IAT1)=DI(I) |
654 | 1 | equemene | B(I,IAT2)=DI(I+3) |
655 | 1 | equemene | B(I,IAT3)=DI(I+6) |
656 | 1 | equemene | B(I,IAT4)=DI(I+9) |
657 | 1 | equemene | END DO |
658 | 1 | equemene | |
659 | 1 | equemene | if (debug) WRITE(*,*) "============= CONSTRAINTS_TORSION_DER3 over ===============" |
660 | 1 | equemene | |
661 | 1 | equemene | END SUBROUTINE CONSTRAINTS_TORSION_DER3 |
662 | 1 | equemene | |
663 | 1 | equemene | |
664 | 1 | equemene | ! .................................................................. |
665 | 1 | equemene | SUBROUTINE CONSTRAINTS_TORSION_DER2(NAT,IAT1,IAT2,IAT3,IAT4,R0,DZDC) |
666 | 1 | equemene | ! ****************************************************************** |
667 | 1 | equemene | ! ** |
668 | 1 | equemene | ! ** CONSTRAINS THE TORSION OF IAT1-IAT2---IAT3-IAT4 |
669 | 1 | equemene | ! |
670 | 1 | equemene | ! corresponding to P - Q - R - S atoms iun the following |
671 | 1 | equemene | ! This comes from ADF, and in turns comes from formulas from: "Vibrational States", S.Califano (Wiley, 1976) |
672 | 1 | equemene | ! derivatives w.r.t P: (a*b)B/abs(a*b)**2) |
673 | 1 | equemene | ! w.r.t. S : (b*c)B/abs(b*c)**2 |
674 | 1 | equemene | ! w.r.t. Q : 1/B**2 x ( C*dS + (a-b)*dP ) * b |
675 | 1 | equemene | ! where * stands for vector product and capitals denote lengths |
676 | 1 | equemene | ! ------------------------------------------------------------- |
677 | 1 | equemene | ! a=P-Q |
678 | 1 | equemene | ! b=R-Q |
679 | 1 | equemene | ! theta=angle(a,b) |
680 | 1 | equemene | ! phi (negative of the dihedral angle) |
681 | 1 | equemene | ! c=S-R |
682 | 1 | equemene | |
683 | 1 | equemene | ! ** |
684 | 1 | equemene | ! ****************************************************************** |
685 | 1 | equemene | use VarTypes |
686 | 1 | equemene | IMPLICIT none |
687 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: NAT |
688 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT1 |
689 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT2 |
690 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT3 |
691 | 1 | equemene | INTEGER(KINT),INTENT(IN) :: IAT4 |
692 | 1 | equemene | REAL(KREAL) ,INTENT(IN) :: R0(3,NAT) |
693 | 1 | equemene | REAL(KREAL) ,INTENT(OUT):: DZDC(3,NAT) |
694 | 1 | equemene | REAL(KREAL) :: DI(12) |
695 | 1 | equemene | REAL(KREAL) :: A(3),B(3),C(3),Vec(3) |
696 | 1 | equemene | REAL(KREAL) :: U(3),V(3) |
697 | 1 | equemene | real(KREAL) :: phi |
698 | 1 | equemene | integer(KINT) :: i,j,ichk,k |
699 | 1 | equemene | |
700 | 1 | equemene | REAL(KREAL) :: norm1,norm2,norm3 |
701 | 1 | equemene | real(KREAL) :: s,bleng |
702 | 1 | equemene | |
703 | 1 | equemene | REAL(KREAL), PARAMETER :: eps=1e-10 |
704 | 1 | equemene | |
705 | 1 | equemene | LOGICAL :: Debug,Failed,valid |
706 | 1 | equemene | EXTERNAL :: Valid |
707 | 1 | equemene | |
708 | 1 | equemene | ! ****************************************************************** |
709 | 1 | equemene | ! |
710 | 1 | equemene | debug=valid('TORSION_DER') |
711 | 1 | equemene | if (debug) WRITE(*,*) "============= Entering CONSTRAINTS_TORSION_DER2 ===============" |
712 | 1 | equemene | |
713 | 1 | equemene | if (debug) THEN |
714 | 1 | equemene | WRITE(*,'(1X,I5,3(1X,F10.6))') IAt1,R0(:,IAT1) |
715 | 1 | equemene | WRITE(*,'(1X,I5,3(1X,F10.6))') IAt2,R0(:,IAT2) |
716 | 1 | equemene | WRITE(*,'(1X,I5,3(1X,F10.6))') IAt3,R0(:,IAT3) |
717 | 1 | equemene | WRITE(*,'(1X,I5,3(1X,F10.6))') IAt4,R0(:,IAT4) |
718 | 1 | equemene | END IF |
719 | 1 | equemene | ! |
720 | 1 | equemene | A=R0(:,IAT1)-R0(:,IAT2) |
721 | 1 | equemene | B=R0(:,IAT3)-R0(:,IAT2) |
722 | 1 | equemene | C=R0(:,IAT4)-R0(:,IAT3) |
723 | 1 | equemene | DZDC=0. |
724 | 1 | equemene | |
725 | 1 | equemene | |
726 | 1 | equemene | ! ---------------------------------------------------------------- |
727 | 1 | equemene | ! --- We check that PQR and QRS are not aligned. |
728 | 1 | equemene | ! If they are, we return 0. as derivatives instead of just crashing. |
729 | 1 | equemene | ! ---------------------------------------------------------------- |
730 | 1 | equemene | call produit_vect (b(1),b(2),b(3),Norm1,c(1),c(2),c(3),Norm2, vec(1),vec(2),vec(3),Norm3) |
731 | 1 | equemene | norm1=sqrt(dot_product(b,b)) |
732 | 1 | equemene | norm2=sqrt(dot_product(c,c)) |
733 | 1 | equemene | Failed=.FALSE. |
734 | 1 | equemene | |
735 | 1 | equemene | if (Norm3 <= eps) then |
736 | 1 | equemene | WRITE(*,*) '*** WARNING: ILL-DEFINED DIHEDRAL ANGLE(S)' |
737 | 1 | equemene | write (*,*) 'QRS aligned',iat2,iat3,iat4 |
738 | 1 | equemene | Failed=.TRUE. |
739 | 1 | equemene | end if |
740 | 1 | equemene | call produit_vect (b(1),b(2),b(3),Norm1,a(1),a(2),a(3),Norm2, vec(1),vec(2),vec(3),Norm3) |
741 | 1 | equemene | if (norm3 <= eps) then |
742 | 1 | equemene | WRITE(*,*) '*** WARNING: ILL-DEFINED DIHEDRAL ANGLE(S)' |
743 | 1 | equemene | write (*,*) 'PQR aligned',iat1,iat2,iat3 |
744 | 1 | equemene | Failed=.TRUE. |
745 | 1 | equemene | end if |
746 | 1 | equemene | |
747 | 1 | equemene | ! ---------------------------------------------------------------- |
748 | 1 | equemene | ! --- CALCULATE FIRST DERIVATIVES |
749 | 1 | equemene | ! ---------------------------------------------------------------- |
750 | 1 | equemene | |
751 | 1 | equemene | bleng = sqrt (b(1)**2 + b(2)**2 + b(3)**2) |
752 | 1 | equemene | call produit_vect (a(1),a(2),a(3),Norm1,b(1),b(2),b(3),Norm2, vec(1),vec(2),vec(3),Norm3) |
753 | 1 | equemene | s = bleng / (vec(1)**2 + vec(2)**2 + vec(3)**2) |
754 | 1 | equemene | ! dzdc(:,ip,3,ip) = s * vec |
755 | 1 | equemene | dzdc(:,iat1) = s * vec |
756 | 1 | equemene | |
757 | 1 | equemene | call produit_vect (b(1),b(2),b(3),Norm1,c(1),c(2),c(3),Norm2, vec(1),vec(2),vec(3),Norm3) |
758 | 1 | equemene | s = bleng / (vec(1)**2 + vec(2)**2 + vec(3)**2) |
759 | 1 | equemene | ! dzdc(:,is,3,ip) = s * vec |
760 | 1 | equemene | dzdc(:,iat4) = s * vec |
761 | 1 | equemene | |
762 | 1 | equemene | |
763 | 1 | equemene | call produit_vect (c(1),c(2),c(3),Norm1, & |
764 | 1 | equemene | dzdc(1,iat4), dzdc(2,iat4), dzdc(3,iat4), Norm2, & |
765 | 1 | equemene | u(1),u(2),u(3),Norm3) |
766 | 1 | equemene | vec = a - b |
767 | 1 | equemene | call produit_vect (vec(1),vec(2),vec(3),Norm1, & |
768 | 1 | equemene | dzdc(1,iat1), dzdc(2,iat1), dzdc(3,iat1), Norm2, & |
769 | 1 | equemene | v(1),v(2),v(3),Norm3) |
770 | 1 | equemene | vec = u + v |
771 | 1 | equemene | call produit_vect (vec(1),vec(2),vec(3),Norm1, & |
772 | 1 | equemene | b(1), b(2), b(3), Norm2, & |
773 | 1 | equemene | u(1),u(2),u(3),Norm3) |
774 | 1 | equemene | |
775 | 1 | equemene | ! dzdc(:,iq,3,ip) = u / bleng**2 |
776 | 1 | equemene | ! dzdc(:,ir,3,ip) = - (dzdc(:,ip,3,ip) + dzdc(:,iq,3,ip) + dzdc(:,is,3,ip)) |
777 | 1 | equemene | dzdc(:,iat2) = u / bleng**2 |
778 | 1 | equemene | dzdc(:,iat3) = - (dzdc(:,iat1) + dzdc(:,iat2) + dzdc(:,iat4)) |
779 | 1 | equemene | |
780 | 1 | equemene | if (debug) THEN |
781 | 1 | equemene | WRITE(*,*) 'DER TOR 2' |
782 | 1 | equemene | WRITE(*,*) DZDC(:,IAT1) |
783 | 1 | equemene | WRITE(*,*) DZDC(:,IAT2) |
784 | 1 | equemene | WRITE(*,*) DZDC(:,IAT3) |
785 | 1 | equemene | WRITE(*,*) DZDC(:,IAT4) |
786 | 1 | equemene | END IF |
787 | 1 | equemene | |
788 | 1 | equemene | if (Failed) DZDC=0. |
789 | 1 | equemene | |
790 | 1 | equemene | if (debug) WRITE(*,*) "============= CONSTRAINTS_TORSION_DER2 over ===============" |
791 | 1 | equemene | |
792 | 1 | equemene | END SUBROUTINE CONSTRAINTS_TORSION_DER2 |
793 | 1 | equemene | |
794 | 1 | equemene | ! Not yet implemented |
795 | 1 | equemene | |
796 | 1 | equemene | |
797 | 1 | equemene | ! ! .................................................................. |
798 | 1 | equemene | ! SUBROUTINE CONSTRAINTS_COGSEP_DER(NAT,GROUP1,GROUP2,R0,RMass,B) |
799 | 1 | equemene | ! ! ****************************************************************** |
800 | 1 | equemene | ! ! ** SET UP CONSTRAINT IN COORDINATE SPACE ** |
801 | 1 | equemene | ! ! ** CONSTRAINT IS THE DISTANCE BETWEEN THE CENTER OF GRAVITIES ** |
802 | 1 | equemene | ! ! ** OF TWO NAMED GROUPS ** |
803 | 1 | equemene | ! ! ** ** |
804 | 1 | equemene | ! ! ** THE CONSTRAINT IS EXPRESSED AS A+B*R+0.5*R*C*R=0 ** |
805 | 1 | equemene | ! ! ** ** |
806 | 1 | equemene | ! ! ****************************************************************** |
807 | 1 | equemene | ! use Geometry_module |
808 | 1 | equemene | |
809 | 1 | equemene | ! Use VarTypes |
810 | 1 | equemene | ! IMPLICIT NONE |
811 | 1 | equemene | ! INTEGER(KINT) ,INTENT(IN) :: NAT |
812 | 1 | equemene | ! CHARACTER(*),INTENT(IN) :: GROUP1 ! NAME OF FIRST GROUP |
813 | 1 | equemene | ! CHARACTER(*),INTENT(IN) :: GROUP2 ! NAME OF SECOND GROUP |
814 | 1 | equemene | ! REAL(KREAL) ,INTENT(OUT):: B(3,NAT) |
815 | 1 | equemene | ! REAL(KREAL) ,INTENT(IN) :: R0(3,NAT) |
816 | 1 | equemene | ! REAL(KREAL) :: RMASS(NAT),A |
817 | 1 | equemene | ! LOGICAL(4) :: TMEMBER1(NAT) |
818 | 1 | equemene | ! LOGICAL(4) :: TMEMBER2(NAT) |
819 | 1 | equemene | ! REAL(KREAL) :: SUMMASS1,SUMMASS2 |
820 | 1 | equemene | ! REAL(KREAL) :: COG1(3) ! COG OF FIRST GROUP |
821 | 1 | equemene | ! REAL(KREAL) :: COG2(3) ! COG OF SECOND GROUP |
822 | 1 | equemene | ! REAL(KREAL) :: X(3) ! COG1-COG2 |
823 | 1 | equemene | ! REAL(KREAL) :: COGSEP |
824 | 1 | equemene | ! REAL(KREAL) :: DADX(3) |
825 | 1 | equemene | ! INTEGER(KINT) :: I,J,IAT,IAT1,IAT2 |
826 | 1 | equemene | ! ! ****************************************************************** |
827 | 1 | equemene | |
828 | 1 | equemene | ! CALL GROUPLIST_MEMBERS(GROUP1,TMEMBER1) |
829 | 1 | equemene | ! CALL GROUPLIST_MEMBERS(GROUP2,TMEMBER2) |
830 | 1 | equemene | ! ! |
831 | 1 | equemene | ! ! ================================================================== |
832 | 1 | equemene | ! ! == CALCULATE CENTERS OF GRAVITY == |
833 | 1 | equemene | ! ! ================================================================== |
834 | 1 | equemene | ! SUMMASS1=0.D0 |
835 | 1 | equemene | ! SUMMASS2=0.D0 |
836 | 1 | equemene | ! COG1(:)=0.D0 |
837 | 1 | equemene | ! COG2(:)=0.D0 |
838 | 1 | equemene | ! DO IAT=1,NAT |
839 | 1 | equemene | ! IF(TMEMBER1(IAT)) THEN |
840 | 1 | equemene | ! SUMMASS1=SUMMASS1+RMASS(IAT) |
841 | 1 | equemene | ! COG1(:)=COG1(:)+RMASS(IAT)*R0(:,IAT) |
842 | 1 | equemene | ! ENDIF |
843 | 1 | equemene | ! IF(TMEMBER2(IAT)) THEN |
844 | 1 | equemene | ! SUMMASS2=SUMMASS2+RMASS(IAT) |
845 | 1 | equemene | ! COG2(:)=COG2(:)+RMASS(IAT)*R0(:,IAT) |
846 | 1 | equemene | ! ENDIF |
847 | 1 | equemene | ! ENDDO |
848 | 1 | equemene | ! COG1(:)=COG1(:)/SUMMASS1 |
849 | 1 | equemene | ! COG2(:)=COG2(:)/SUMMASS2 |
850 | 1 | equemene | ! ! |
851 | 1 | equemene | ! ! ============================================================= |
852 | 1 | equemene | ! ! == SEPARATION BETWEEN THE CENTERS OF GRAVITY == |
853 | 1 | equemene | ! ! ============================================================= |
854 | 1 | equemene | ! X(:)=COG1(:)-COG2(:) |
855 | 1 | equemene | ! ! |
856 | 1 | equemene | ! ! ============================================================= |
857 | 1 | equemene | ! ! == CALCULATE A(X) AND ITS DERIVATIVES == |
858 | 1 | equemene | ! ! ============================================================= |
859 | 1 | equemene | ! A=SQRT(DOT_PRODUCT(X(:),X(:))) |
860 | 1 | equemene | ! DADX(:)=X(:)/A |
861 | 1 | equemene | |
862 | 1 | equemene | ! DO IAT1=1,NAT |
863 | 1 | equemene | ! IF(TMEMBER1(IAT1)) THEN |
864 | 1 | equemene | ! B(:,IAT1)=B(:,IAT1)+DADX(:)*RMASS(IAT1)/SUMMASS1 |
865 | 1 | equemene | ! END IF |
866 | 1 | equemene | ! IF(TMEMBER2(IAT1)) THEN |
867 | 1 | equemene | ! B(:,IAT1)=B(:,IAT1)-DADX(:)*RMASS(IAT1)/SUMMASS2 |
868 | 1 | equemene | ! END IF |
869 | 1 | equemene | ! END DO |
870 | 1 | equemene | |
871 | 1 | equemene | ! END SUBROUTINE CONSTRAINTS_COGSEP_DER |
872 | 1 | equemene | |
873 | 1 | equemene | |
874 | 1 | equemene | ! ! .................................................................. |
875 | 1 | equemene | ! SUBROUTINE CONSTRAINTS_COGANG_DER(NAT,GROUP1,GROUP2,GROUP3,R0,RMass,B) |
876 | 1 | equemene | ! ! ****************************************************************** |
877 | 1 | equemene | ! ! ** SET UP CONSTRAINT IN COORDINATE SPACE ** |
878 | 1 | equemene | ! ! ** CONSTRAINT IS THE ANGLE BETWEEN THE CENTER OF GRAVITIES ** |
879 | 1 | equemene | ! ! ** OF THREE NAMED GROUPS ** |
880 | 1 | equemene | ! ! ** ** |
881 | 1 | equemene | ! ! ** THE CONSTRAINT IS EXPRESSED AS A+B*R+0.5*R*C*R=0 ** |
882 | 1 | equemene | ! ! This makes heavy use of BONDANGLEDERIVS |
883 | 1 | equemene | ! ! ** ** |
884 | 1 | equemene | ! ! ****************************************************************** |
885 | 1 | equemene | ! IMPLICIT NONE |
886 | 1 | equemene | ! INTEGER(KINT) ,INTENT(IN) :: NAT |
887 | 1 | equemene | ! CHARACTER(*),INTENT(IN) :: GROUP1 ! NAME OF FIRST GROUP |
888 | 1 | equemene | ! CHARACTER(*),INTENT(IN) :: GROUP2 ! NAME OF SECOND GROUP |
889 | 1 | equemene | ! CHARACTER(*),INTENT(IN) :: GROUP3 ! NAME OF THIRD GROUP |
890 | 1 | equemene | ! REAL(KREAL) ,INTENT(OUT):: B(3,NAT) |
891 | 1 | equemene | ! REAL(KREAL) ,INTENT(IN) :: R0(3,NAT) |
892 | 1 | equemene | ! REAL(KREAL) :: RMASS(NAT) |
893 | 1 | equemene | ! LOGICAL(4) :: TMEMBER1(NAT) |
894 | 1 | equemene | ! LOGICAL(4) :: TMEMBER2(NAT) |
895 | 1 | equemene | ! LOGICAL(4) :: TMEMBER3(NAT) |
896 | 1 | equemene | ! REAL(KREAL) :: SUMMASS1,SUMMASS2, SUMMASS3 |
897 | 1 | equemene | ! REAL(KREAL) :: COG1(3) ! COG OF FIRST GROUP |
898 | 1 | equemene | ! REAL(KREAL) :: COG2(3) ! COG OF SECOND GROUP |
899 | 1 | equemene | ! REAL(KREAL) :: COG3(3) ! COG OF THIRD GROUP |
900 | 1 | equemene | ! REAL(KREAL) :: DCOG1(3,NAT), DCOG2(3,NAT), DCOG3(3,NAT) |
901 | 1 | equemene | ! REAL(KREAL) :: vecU(3), vecV(3) |
902 | 1 | equemene | ! REAL(KREAL) :: UU, VV, UV |
903 | 1 | equemene | ! INTEGER(KINT) :: I,J,IAT,IAT1,IAT2,JAT |
904 | 1 | equemene | ! REAL(KREAL) :: Pi |
905 | 1 | equemene | ! ! From BONDANGLEDERIVS |
906 | 1 | equemene | ! REAL(KREAL) :: D ! 1/SQRT(A*B) |
907 | 1 | equemene | ! REAL(KREAL) :: DUUDX(3,NAT) |
908 | 1 | equemene | ! REAL(KREAL) :: DVVDX(3,NAT) |
909 | 1 | equemene | ! REAL(KREAL) :: DUVDX(3,NAT) |
910 | 1 | equemene | ! REAL(KREAL) :: DDDX(3,NAT) |
911 | 1 | equemene | ! REAL(KREAL) :: DJDX(3,NAT) |
912 | 1 | equemene | ! REAL(KREAL) :: DVDX(3,NAT) |
913 | 1 | equemene | ! REAL(KREAL) :: DGDX(3,NAT) ! D(A*B)/DX |
914 | 1 | equemene | ! REAL(KREAL) :: AB,AB2N,V,PREFAC |
915 | 1 | equemene | ! REAL(KREAL) :: PHI,COSPHI,SINPHI |
916 | 1 | equemene | ! REAL(KREAL) :: DIVDX,AI |
917 | 1 | equemene | |
918 | 1 | equemene | |
919 | 1 | equemene | ! ! ****************************************************************** |
920 | 1 | equemene | ! CALL GROUPLIST_MEMBERS(GROUP1,TMEMBER1) |
921 | 1 | equemene | ! CALL GROUPLIST_MEMBERS(GROUP2,TMEMBER2) |
922 | 1 | equemene | ! CALL GROUPLIST_MEMBERS(GROUP3,TMEMBER3) |
923 | 1 | equemene | ! ! |
924 | 1 | equemene | ! ! ================================================================== |
925 | 1 | equemene | ! ! == CALCULATE CENTERS OF GRAVITY == |
926 | 1 | equemene | ! ! ================================================================== |
927 | 1 | equemene | ! SUMMASS1=0.D0 |
928 | 1 | equemene | ! SUMMASS2=0.D0 |
929 | 1 | equemene | ! SUMMASS3=0.D0 |
930 | 1 | equemene | ! COG1(:)=0.D0 |
931 | 1 | equemene | ! COG2(:)=0.D0 |
932 | 1 | equemene | ! COG3(:)=0.D0 |
933 | 1 | equemene | ! DO IAT=1,NAT |
934 | 1 | equemene | ! IF(TMEMBER1(IAT)) THEN |
935 | 1 | equemene | ! SUMMASS1=SUMMASS1+RMASS(IAT) |
936 | 1 | equemene | ! COG1(:)=COG1(:)+RMASS(IAT)*R0(:,IAT) |
937 | 1 | equemene | ! ENDIF |
938 | 1 | equemene | ! IF(TMEMBER2(IAT)) THEN |
939 | 1 | equemene | ! SUMMASS2=SUMMASS2+RMASS(IAT) |
940 | 1 | equemene | ! COG2(:)=COG2(:)+RMASS(IAT)*R0(:,IAT) |
941 | 1 | equemene | ! ENDIF |
942 | 1 | equemene | ! IF(TMEMBER3(IAT)) THEN |
943 | 1 | equemene | ! SUMMASS3=SUMMASS3+RMASS(IAT) |
944 | 1 | equemene | ! COG3(:)=COG3(:)+RMASS(IAT)*R0(:,IAT) |
945 | 1 | equemene | ! ENDIF |
946 | 1 | equemene | |
947 | 1 | equemene | ! ENDDO |
948 | 1 | equemene | ! COG1(:)=COG1(:)/SUMMASS1 |
949 | 1 | equemene | ! COG2(:)=COG2(:)/SUMMASS2 |
950 | 1 | equemene | ! COG3(:)=COG3(:)/SUMMASS3 |
951 | 1 | equemene | ! ! |
952 | 1 | equemene | ! ! |
953 | 1 | equemene | ! vecU(:)=COG1(:)-COG2(:) |
954 | 1 | equemene | ! vecV(:)=COG3(:)-COG2(:) |
955 | 1 | equemene | |
956 | 1 | equemene | ! UV=DOT_PRODUCT(vecU,vecV) |
957 | 1 | equemene | ! UU=DOT_PRODUCT(vecU,vecU) |
958 | 1 | equemene | ! VV=DOT_PRODUCT(vecV,vecV) |
959 | 1 | equemene | ! ! We now calculate the first derivatives of the COG vs the atomic |
960 | 1 | equemene | ! ! Coords... |
961 | 1 | equemene | ! DCOG1=0. |
962 | 1 | equemene | ! DCOG2=0. |
963 | 1 | equemene | ! DCOG3=0. |
964 | 1 | equemene | ! DO IAT=1,NAT |
965 | 1 | equemene | ! IF (TMEMBER1(IAT)) DCOG1(:,IAT)=RMASS(IAT)/SUMMASS1 |
966 | 1 | equemene | ! IF (TMEMBER2(IAT)) DCOG2(:,IAT)=RMASS(IAT)/SUMMASS2 |
967 | 1 | equemene | ! IF (TMEMBER3(IAT)) DCOG3(:,IAT)=RMASS(IAT)/SUMMASS3 |
968 | 1 | equemene | ! END DO |
969 | 1 | equemene | ! ! We now calculate the first derivatives of UU, VV, UV |
970 | 1 | equemene | ! DUUDX=0. |
971 | 1 | equemene | ! DVVDX=0. |
972 | 1 | equemene | ! DUVDX=0. |
973 | 1 | equemene | ! DO IAT=1,NAT |
974 | 1 | equemene | ! DUUDX(:,IAT)=2.D0*(COG1(:)-COG2(:))*(DCOG1(:,IAT)-DCOG2(:,IAT)) |
975 | 1 | equemene | ! DVVDX(:,IAT)=2.D0*(COG3(:)-COG2(:))*(DCOG3(:,IAT)-DCOG2(:,IAT)) |
976 | 1 | equemene | ! DUVDX(:,IAT)=(COG3(:)-COG2(:))*(DCOG1(:,IAT)-DCOG2(:,IAT)) + & |
977 | 1 | equemene | ! (DCOG3(:,IAT)-DCOG2(:,IAT))*(COG1(:)-COG2(:)) |
978 | 1 | equemene | ! END DO |
979 | 1 | equemene | |
980 | 1 | equemene | ! ! WRITE(*,*) 'PFL DER COGANGLE' |
981 | 1 | equemene | ! ! WRITE(*,'(15(1X,F10.6))') DUUDX(:,:) |
982 | 1 | equemene | ! ! WRITE(*,'(15(1X,F10.6))') DVVDX(:,:) |
983 | 1 | equemene | ! ! WRITE(*,'(15(1X,F10.6))') DUVDX(:,:) |
984 | 1 | equemene | |
985 | 1 | equemene | |
986 | 1 | equemene | ! ! We now go for the hard part: calculate Phi, dPhi/dx, d2Phi/dxidxj |
987 | 1 | equemene | ! Pi=DACOS(-1.D0) |
988 | 1 | equemene | ! AB=UU*VV |
989 | 1 | equemene | ! D=SQRT(AB) |
990 | 1 | equemene | ! COSPHI=UV/D !=COS(PHI) |
991 | 1 | equemene | ! PHI=DACOS(COSPHI) |
992 | 1 | equemene | ! ! WRITE(*,*) 'COGANGLE Phi=',Phi,Phi*180/Pi |
993 | 1 | equemene | ! ! --- CALCULATE DERIVATIVE OF ARCCOS |
994 | 1 | equemene | ! SINPHI=DSQRT(1.D0-COSPHI**2) |
995 | 1 | equemene | ! V=-1.D0/SINPHI !=-SIN(PHI)=D(ACOS(PHI))/D(COSPHI) |
996 | 1 | equemene | ! ! --- CALCULATE FIRST DERIVATIVES OF G=A*B |
997 | 1 | equemene | ! DGDX(:,:)=DUUDX(:,:)*VV+DVVDX(:,:)*UU |
998 | 1 | equemene | ! ! --- CALCULATE DDDX |
999 | 1 | equemene | ! AB2N=0.5D0/D |
1000 | 1 | equemene | ! DDDX(:,:)=AB2N*DGDX(:,:) |
1001 | 1 | equemene | ! ! --- CALCULATE FIRST DERIVATIVES OF J = COS(PHI) |
1002 | 1 | equemene | ! PREFAC=1.D0/AB |
1003 | 1 | equemene | ! DJDX(:,:)=(DUVDX(:,:)*D-UV*DDDX(:,:))*PREFAC |
1004 | 1 | equemene | ! ! --- CALCULATE FIRST DERIVATIVE |
1005 | 1 | equemene | ! B(:,:)=DJDX(:,:)*V |
1006 | 1 | equemene | |
1007 | 1 | equemene | ! END SUBROUTINE CONSTRAINTS_COGANG_DER |
1008 | 1 | equemene | |
1009 | 1 | equemene | ! ! .................................................................. |
1010 | 1 | equemene | ! SUBROUTINE CONSTRAINTS_COGTORSION_DER(NAT,GROUP1,GROUP2, GROUP3,GROUP4, R0,RMAss,B) |
1011 | 1 | equemene | ! ! ****************************************************************** |
1012 | 1 | equemene | ! ! ** SET UP CONSTRAINT IN COORDINATE SPACE ** |
1013 | 1 | equemene | ! ! ** CONSTRAINT IS THE ANGLE BETWEEN THE CENTER OF GRAVITIES ** |
1014 | 1 | equemene | ! ! ** OF THREE NAMED GROUPS ** |
1015 | 1 | equemene | ! ! ** ** |
1016 | 1 | equemene | ! ! ** THE CONSTRAINT IS EXPRESSED AS A+B*R+0.5*R*C*R=0 ** |
1017 | 1 | equemene | ! ! This makes heavy use of BONDANGLEDERIVS |
1018 | 1 | equemene | ! ! ** ** |
1019 | 1 | equemene | ! ! ****************************************************************** |
1020 | 1 | equemene | ! IMPLICIT NONE |
1021 | 1 | equemene | ! INTEGER(KINT) ,INTENT(IN) :: NAT |
1022 | 1 | equemene | ! CHARACTER(*),INTENT(IN) :: GROUP1 ! NAME OF FIRST GROUP |
1023 | 1 | equemene | ! CHARACTER(*),INTENT(IN) :: GROUP2 ! NAME OF SECOND GROUP |
1024 | 1 | equemene | ! CHARACTER(*),INTENT(IN) :: GROUP3 ! NAME OF THIRD GROUP |
1025 | 1 | equemene | ! CHARACTER(*),INTENT(IN) :: GROUP4 ! NAME OF FOURTH GROUP |
1026 | 1 | equemene | ! REAL(KREAL) ,INTENT(OUT):: B(3,NAT) |
1027 | 1 | equemene | ! REAL(KREAL) ,INTENT(IN) :: R0(3,NAT) |
1028 | 1 | equemene | ! REAL(KREAL) :: RMASS(NAT) |
1029 | 1 | equemene | ! LOGICAL(4) :: TMEMBER1(NAT) |
1030 | 1 | equemene | ! LOGICAL(4) :: TMEMBER2(NAT) |
1031 | 1 | equemene | ! LOGICAL(4) :: TMEMBER3(NAT) |
1032 | 1 | equemene | ! LOGICAL(4) :: TMEMBER4(NAT) |
1033 | 1 | equemene | ! REAL(KREAL) :: SUMMASS1,SUMMASS2, SUMMASS3, SUMMASS4 |
1034 | 1 | equemene | ! REAL(KREAL) :: COG1(3) ! COG OF FIRST GROUP |
1035 | 1 | equemene | ! REAL(KREAL) :: COG2(3) ! COG OF SECOND GROUP |
1036 | 1 | equemene | ! REAL(KREAL) :: COG3(3) ! COG OF THIRD GROUP |
1037 | 1 | equemene | ! REAL(KREAL) :: COG4(3) ! COG OF FOURTH GROUP |
1038 | 1 | equemene | ! ! Even thought D COG(i)/DXj =0 (ie COG_x depends only on x-coordinates |
1039 | 1 | equemene | ! ! of the atoms, not on y or z), we store a 3,3*NAT matrix to make |
1040 | 1 | equemene | ! ! handling easier below |
1041 | 1 | equemene | ! REAL(KREAL) :: DCOG1(3,3,NAT), DCOG2(3,3,NAT), & |
1042 | 1 | equemene | ! DCOG3(3,3,NAT), DCOG4(3,3,NAT) |
1043 | 1 | equemene | ! REAL(KREAL) :: T(3), U(3), R(3), W(3), P(3), Q(3) |
1044 | 1 | equemene | ! REAL(KREAL) :: PP, QQ, PQ |
1045 | 1 | equemene | ! INTEGER(KINT) :: I,J,IAT,IAT1,IAT2,JAT |
1046 | 1 | equemene | ! REAL(KREAL) :: Pi, Phi |
1047 | 1 | equemene | ! ! From BONDANGLEDERIVS |
1048 | 1 | equemene | ! REAL(KREAL) :: D ! SQRT(PP*QQ) |
1049 | 1 | equemene | ! REAL(KREAL) :: DPDX(3,3,NAT) |
1050 | 1 | equemene | ! REAL(KREAL) :: DQDX(3,3,NAT) |
1051 | 1 | equemene | ! REAL(KREAL) :: DPPDX(3,NAT) |
1052 | 1 | equemene | ! REAL(KREAL) :: DQQDX(3,NAT) |
1053 | 1 | equemene | ! REAL(KREAL) :: DPQDX(3,NAT) |
1054 | 1 | equemene | ! REAL(KREAL) :: DDDX(3,NAT) |
1055 | 1 | equemene | ! REAL(KREAL) :: DJDX(3,NAT) ! D(C/D)/DX*D2 |
1056 | 1 | equemene | ! REAL(KREAL) :: DVDX(3,NAT) |
1057 | 1 | equemene | ! REAL(KREAL) :: DGDX(3,NAT) ! D(A*B)/DX |
1058 | 1 | equemene | ! REAL(KREAL) :: AB,AB2N,V,PREFAC,ABYB,ABYB2N |
1059 | 1 | equemene | ! REAL(KREAL) :: COSPHI,SINPHI |
1060 | 1 | equemene | |
1061 | 1 | equemene | |
1062 | 1 | equemene | ! ! ****************************************************************** |
1063 | 1 | equemene | |
1064 | 1 | equemene | ! ! WRITE(*,*) 'ENTERING SET_COGTORSION' |
1065 | 1 | equemene | ! ! WRITE(*,*) 'G1:',TRIM(GROUP1),' G2:',TRIM(GROUP2),' G3:',TRIM(GROUP3),' G4:',TRIM(GROUP4) |
1066 | 1 | equemene | |
1067 | 1 | equemene | ! ! ================================================================== |
1068 | 1 | equemene | ! ! == DETERMINE GROUPS AND ATOM-MASSES |
1069 | 1 | equemene | ! ! ================================================================== |
1070 | 1 | equemene | |
1071 | 1 | equemene | ! CALL GROUPLIST_MEMBERS(GROUP1,TMEMBER1) |
1072 | 1 | equemene | ! CALL GROUPLIST_MEMBERS(GROUP2,TMEMBER2) |
1073 | 1 | equemene | ! CALL GROUPLIST_MEMBERS(GROUP3,TMEMBER3) |
1074 | 1 | equemene | ! CALL GROUPLIST_MEMBERS(GROUP4,TMEMBER4) |
1075 | 1 | equemene | |
1076 | 1 | equemene | ! ! |
1077 | 1 | equemene | ! ! ================================================================== |
1078 | 1 | equemene | ! ! == CALCULATE CENTER OF GRAVITY FOR GROUPS |
1079 | 1 | equemene | ! ! ================================================================== |
1080 | 1 | equemene | ! SUMMASS1=0.D0 |
1081 | 1 | equemene | ! SUMMASS2=0.D0 |
1082 | 1 | equemene | ! SUMMASS3=0.D0 |
1083 | 1 | equemene | ! SUMMASS4=0.D0 |
1084 | 1 | equemene | |
1085 | 1 | equemene | ! COG1=0.D0 |
1086 | 1 | equemene | ! COG2=0.D0 |
1087 | 1 | equemene | ! COG3=0.D0 |
1088 | 1 | equemene | ! COG4=0.D0 |
1089 | 1 | equemene | |
1090 | 1 | equemene | ! DO IAT=1,NAT |
1091 | 1 | equemene | ! ! One atom can belong to many groups as we are looking at |
1092 | 1 | equemene | ! ! center of gravity of the groups |
1093 | 1 | equemene | ! IF (TMEMBER1(IAT)) THEN |
1094 | 1 | equemene | ! SUMMASS1=SUMMASS1+RMASS(IAT) |
1095 | 1 | equemene | ! COG1(:)=COG1(:)+RMASS(IAT)*R0(:,IAT) |
1096 | 1 | equemene | ! END IF |
1097 | 1 | equemene | ! IF (TMEMBER2(IAT)) THEN |
1098 | 1 | equemene | ! SUMMASS2=SUMMASS2+RMASS(IAT) |
1099 | 1 | equemene | ! COG2(:)=COG2(:)+RMASS(IAT)*R0(:,IAT) |
1100 | 1 | equemene | ! END IF |
1101 | 1 | equemene | ! IF (TMEMBER3(IAT)) THEN |
1102 | 1 | equemene | ! SUMMASS3=SUMMASS3+RMASS(IAT) |
1103 | 1 | equemene | ! COG3(:)=COG3(:)+RMASS(IAT)*R0(:,IAT) |
1104 | 1 | equemene | ! END IF |
1105 | 1 | equemene | ! IF (TMEMBER4(IAT)) THEN |
1106 | 1 | equemene | ! SUMMASS4=SUMMASS4+RMASS(IAT) |
1107 | 1 | equemene | ! COG4(:)=COG4(:)+RMASS(IAT)*R0(:,IAT) |
1108 | 1 | equemene | ! END IF |
1109 | 1 | equemene | ! ENDDO |
1110 | 1 | equemene | |
1111 | 1 | equemene | ! COG1(:)=COG1(:)/SUMMASS1 |
1112 | 1 | equemene | ! COG2(:)=COG2(:)/SUMMASS2 |
1113 | 1 | equemene | ! COG3(:)=COG3(:)/SUMMASS3 |
1114 | 1 | equemene | ! COG4(:)=COG4(:)/SUMMASS4 |
1115 | 1 | equemene | ! T(:)=COG1(:)-COG2(:) |
1116 | 1 | equemene | ! U(:)=COG3(:)-COG2(:) |
1117 | 1 | equemene | ! R(:)=COG4(:)-COG3(:) |
1118 | 1 | equemene | ! W(:)=COG2(:)-COG3(:) |
1119 | 1 | equemene | |
1120 | 1 | equemene | ! CALL VPRD(T,U,P) ! P=CROSS-PRODUCT(T,U) |
1121 | 1 | equemene | ! CALL VPRD(W,R,Q) |
1122 | 1 | equemene | ! PQ=DOT_PRODUCT(P,Q) |
1123 | 1 | equemene | ! PP=DOT_PRODUCT(P,P) |
1124 | 1 | equemene | ! QQ=DOT_PRODUCT(Q,Q) |
1125 | 1 | equemene | ! ABYB=PP*QQ |
1126 | 1 | equemene | ! D=SQRT(ABYB) |
1127 | 1 | equemene | |
1128 | 1 | equemene | ! ABYB2N=0.5D0/D |
1129 | 1 | equemene | ! COSPHI=PQ/D |
1130 | 1 | equemene | ! Phi=DACOS(COSPHI) |
1131 | 1 | equemene | ! Pi=DACOS(-1.0D0) |
1132 | 1 | equemene | ! SINPHI=DSQRT(1.D0-(COSPHI)**2.D0) |
1133 | 1 | equemene | |
1134 | 1 | equemene | ! ! --- CALCULATE DERIVATIVE OF ARCCOS |
1135 | 1 | equemene | ! IF (dabs(DABS(COSPHI)-1.d0) < 1.D-9) THEN |
1136 | 1 | equemene | ! WRITE(*,*) 'WARNING: DERIVATIVE OF TORSION AT ZERO AND PI IS |
1137 | 1 | equemene | ! &UNDEFINED!' |
1138 | 1 | equemene | ! V=0.D0 |
1139 | 1 | equemene | ! ELSE |
1140 | 1 | equemene | ! V=-1.D0/SINPHI |
1141 | 1 | equemene | ! ENDIF |
1142 | 1 | equemene | |
1143 | 1 | equemene | ! ! WRITE(*,*) 'Phi et al',Phi,Phi*180./Pi,cosphi,sinphi,V |
1144 | 1 | equemene | |
1145 | 1 | equemene | ! ! We now calculate the first derivatives of the COG vs the atomic |
1146 | 1 | equemene | ! ! Coords... |
1147 | 1 | equemene | ! DCOG1=0. |
1148 | 1 | equemene | ! DCOG2=0. |
1149 | 1 | equemene | ! DCOG3=0. |
1150 | 1 | equemene | ! DCOG4=0. |
1151 | 1 | equemene | ! DO IAT=1,NAT |
1152 | 1 | equemene | ! IF (TMEMBER1(IAT)) THEN |
1153 | 1 | equemene | ! DO J=1,3 |
1154 | 1 | equemene | ! DCOG1(J,J,IAT)=RMASS(IAT)/SUMMASS1 |
1155 | 1 | equemene | ! END DO |
1156 | 1 | equemene | ! END IF |
1157 | 1 | equemene | ! IF (TMEMBER2(IAT)) THEN |
1158 | 1 | equemene | ! DO J=1,3 |
1159 | 1 | equemene | ! DCOG2(J,J,IAT)=RMASS(IAT)/SUMMASS2 |
1160 | 1 | equemene | ! END DO |
1161 | 1 | equemene | ! END IF |
1162 | 1 | equemene | ! IF (TMEMBER3(IAT)) THEN |
1163 | 1 | equemene | ! DO J=1,3 |
1164 | 1 | equemene | ! DCOG3(J,J,IAT)=RMASS(IAT)/SUMMASS3 |
1165 | 1 | equemene | ! END DO |
1166 | 1 | equemene | ! END IF |
1167 | 1 | equemene | ! IF (TMEMBER4(IAT)) THEN |
1168 | 1 | equemene | ! DO J=1,3 |
1169 | 1 | equemene | ! DCOG4(J,J,IAT)=RMASS(IAT)/SUMMASS4 |
1170 | 1 | equemene | ! END DO |
1171 | 1 | equemene | ! END IF |
1172 | 1 | equemene | ! END DO |
1173 | 1 | equemene | |
1174 | 1 | equemene | ! ! We now calculate the first derivatives of P, Q |
1175 | 1 | equemene | ! DPDX=0. |
1176 | 1 | equemene | ! DQDX=0. |
1177 | 1 | equemene | ! DO I=1,NAT |
1178 | 1 | equemene | ! DO J=1,3 |
1179 | 1 | equemene | ! DPDX(1,J,I)=(DCOG1(2,J,I)-DCOG2(2,J,I))*(COG3(3)-COG2(3)) & |
1180 | 1 | equemene | ! & +(COG1(2)-COG2(2))*(DCOG3(3,J,I)-DCOG2(3,J,I)) & |
1181 | 1 | equemene | ! & -(DCOG1(3,J,I)-DCOG2(3,J,I))*(COG3(2)-COG2(2)) & |
1182 | 1 | equemene | ! & -(COG1(3)-COG2(3))*(DCOG3(2,J,I)-DCOG2(2,J,I)) |
1183 | 1 | equemene | ! DPDX(2,J,I)=(DCOG1(3,J,I)-DCOG2(3,J,I))*(COG3(1)-COG2(1)) & |
1184 | 1 | equemene | ! & +(COG1(3)-COG2(3))*(DCOG3(1,J,I)-DCOG2(1,J,I)) & |
1185 | 1 | equemene | ! & -(DCOG1(1,J,I)-DCOG2(1,J,I))*(COG3(3)-COG2(3)) & |
1186 | 1 | equemene | ! & -( COG1(1)-COG2(1))*(DCOG3(3,J,I)-DCOG2(3,J,I)) |
1187 | 1 | equemene | ! DPDX(3,J,I)=(DCOG1(1,J,I)-DCOG2(1,J,I))*(COG3(2)-COG2(2)) & |
1188 | 1 | equemene | ! & +(COG1(1)-COG2(1))*(DCOG3(2,J,I)-DCOG2(2,J,I)) & |
1189 | 1 | equemene | ! & -(DCOG1(2,J,I)-DCOG2(2,J,I))*(COG3(1)-COG2(1)) & |
1190 | 1 | equemene | ! & -(COG1(2)-COG2(2))*(DCOG3(1,J,I)-DCOG2(1,J,I)) |
1191 | 1 | equemene | ! DQDX(1,J,I)=(DCOG2(2,J,I)-DCOG3(2,J,I))*(COG4(3)-COG3(3)) & |
1192 | 1 | equemene | ! & +(COG2(2)-COG3(2))*(DCOG4(3,J,I)-DCOG3(3,J,I)) & |
1193 | 1 | equemene | ! & -(DCOG2(3,J,I)-DCOG3(3,J,I))*(COG4(2)-COG3(2)) & |
1194 | 1 | equemene | ! & -(COG2(3)-COG3(3))*(DCOG4(2,J,I)-DCOG3(2,J,I)) |
1195 | 1 | equemene | ! DQDX(2,J,I)=(DCOG2(3,J,I)-DCOG3(3,J,I))*(COG4(1)-COG3(1)) & |
1196 | 1 | equemene | ! & +(COG2(3)-COG3(3))*(DCOG4(1,J,I)-DCOG3(1,J,I)) & |
1197 | 1 | equemene | ! & -(DCOG2(1,J,I)-DCOG3(1,J,I))*(COG4(3)-COG3(3)) & |
1198 | 1 | equemene | ! & -( COG2(1)-COG3(1))*(DCOG4(3,J,I)-DCOG3(3,J,I)) |
1199 | 1 | equemene | ! DQDX(3,J,I)=(DCOG2(1,J,I)-DCOG3(1,J,I))*(COG4(2)-COG3(2)) & |
1200 | 1 | equemene | ! & +(COG2(1)-COG3(1))*(DCOG4(2,J,I)-DCOG3(2,J,I)) & |
1201 | 1 | equemene | ! & -(DCOG2(2,J,I)-DCOG3(2,J,I))*(COG4(1)-COG3(1)) & |
1202 | 1 | equemene | ! & -(COG2(2)-COG3(2))*(DCOG4(1,J,I)-DCOG3(1,J,I)) |
1203 | 1 | equemene | |
1204 | 1 | equemene | ! END DO |
1205 | 1 | equemene | ! END DO |
1206 | 1 | equemene | |
1207 | 1 | equemene | |
1208 | 1 | equemene | ! ! WRITE(*,*) 'DP/DX(1) ' |
1209 | 1 | equemene | ! ! WRITE(*,'(1X,12(F9.5,1X))') DPDX(1,1:3,5:8) |
1210 | 1 | equemene | ! ! WRITE(*,*) 'DP/DX(2) ' |
1211 | 1 | equemene | ! ! WRITE(*,'(1X,12(F9.5,1X))') DPDX(2,1:3,5:8) |
1212 | 1 | equemene | ! ! WRITE(*,*) 'DP/DX(3) ' |
1213 | 1 | equemene | ! ! WRITE(*,'(1X,12(F9.5,1X))') DPDX(3,1:3,5:8) |
1214 | 1 | equemene | ! ! WRITE(*,*) 'DQ/DX(1) ' |
1215 | 1 | equemene | ! ! WRITE(*,'(1X,12(F9.5,1X))') DQDX(1,1:3,5:8) |
1216 | 1 | equemene | ! ! WRITE(*,*) 'DQ/DX(2) ' |
1217 | 1 | equemene | ! ! WRITE(*,'(1X,12(F9.5,1X))') DQDX(2,1:3,5:8) |
1218 | 1 | equemene | ! ! WRITE(*,*) 'DQ/DX(3) ' |
1219 | 1 | equemene | ! ! WRITE(*,'(1X,12(F9.5,1X))') DQDX(3,1:3,5:8) |
1220 | 1 | equemene | |
1221 | 1 | equemene | ! ! We now calculate the first derivatives of PP, QQ and PQ and DD/DX*2D |
1222 | 1 | equemene | |
1223 | 1 | equemene | ! DPPDX=0. |
1224 | 1 | equemene | ! DQQDX=0. |
1225 | 1 | equemene | ! DPQDX=0. |
1226 | 1 | equemene | ! PREFAC=1.d0/ABYB |
1227 | 1 | equemene | ! DO IAT=1,NAT |
1228 | 1 | equemene | ! DO J=1,3 |
1229 | 1 | equemene | ! DPPDX(J,IAT)=2.D0*(P(1)*DPDX(1,J,IAT)+P(2)*DPDX(2,J,IAT)+ |
1230 | 1 | equemene | ! & P(3)*DPDX(3,J,IAT)) |
1231 | 1 | equemene | ! DQQDX(J,IAT)=2.D0*(Q(1)*DQDX(1,J,IAT)+Q(2)*DQDX(2,J,IAT)+ |
1232 | 1 | equemene | ! & Q(3)*DQDX(3,J,IAT)) |
1233 | 1 | equemene | ! DPQDX(J,IAT)=P(1)*DQDX(1,J,IAT)+DPDX(1,J,IAT)*Q(1) |
1234 | 1 | equemene | ! & +P(2)*DQDX(2,J,IAT)+DPDX(2,J,IAT)*Q(2) |
1235 | 1 | equemene | ! & +P(3)*DQDX(3,J,IAT)+DPDX(3,J,IAT)*Q(3) |
1236 | 1 | equemene | ! DGDX(J,IAT)=DPPDX(J,IAT)*QQ+PP*DQQDX(J,IAT) |
1237 | 1 | equemene | ! DDDX(J,IAT)=DGDX(J,IAT)*ABYB2N |
1238 | 1 | equemene | ! DJDX(J,IAT)=(DPQDX(J,IAT)*D-PQ*DDDX(J,IAT))*PREFAC |
1239 | 1 | equemene | ! B(J,IAT)=DJDX(J,IAT)*V |
1240 | 1 | equemene | ! END DO |
1241 | 1 | equemene | ! END DO |
1242 | 1 | equemene | |
1243 | 1 | equemene | ! END SUBROUTINE CONSTRAINTS_COGTORSION_DER |
1244 | 1 | equemene | |
1245 | 1 | equemene | |
1246 | 1 | equemene | ! ! .................................................................. |
1247 | 1 | equemene | ! SUBROUTINE CONSTRAINTS_COGDIFF_DER(NAT,GROUP1,GROUP2, |
1248 | 1 | equemene | ! & GROUP3,R0,RMAss,B) |
1249 | 1 | equemene | ! ! ****************************************************************** |
1250 | 1 | equemene | ! ! ** SET UP CONSTRAINT IN COORDINATE SPACE ** |
1251 | 1 | equemene | ! ! ** CONSTRAINT IS THE DIFFERENCE BETWEEN THE DISTANCES BETWEEN ** |
1252 | 1 | equemene | ! ! ** THE CENTER OF GRAVITIES OF THREE NAMED GROUPS ** |
1253 | 1 | equemene | ! ! ** ** |
1254 | 1 | equemene | ! ! ** THE CONSTRAINT IS EXPRESSED AS A+B*R+0.5*R*C*R=0 ** |
1255 | 1 | equemene | ! ! ** ** |
1256 | 1 | equemene | ! ! ****************************************************************** |
1257 | 1 | equemene | ! IMPLICIT NONE |
1258 | 1 | equemene | ! INTEGER(KINT) ,INTENT(IN) :: NAT |
1259 | 1 | equemene | ! CHARACTER(*),INTENT(IN) :: GROUP1 ! NAME OF FIRST GROUP |
1260 | 1 | equemene | ! CHARACTER(*),INTENT(IN) :: GROUP2 ! NAME OF SECOND GROUP |
1261 | 1 | equemene | ! CHARACTER(*),INTENT(IN) :: GROUP3 ! NAME OF THIRD GROUP |
1262 | 1 | equemene | ! REAL(KREAL) ,INTENT(OUT):: B(3,NAT) |
1263 | 1 | equemene | ! REAL(KREAL) ,INTENT(IN) :: R0(3,NAT) |
1264 | 1 | equemene | ! REAL(KREAL) ,INTENT(IN) :: RMASS(NAT) |
1265 | 1 | equemene | ! LOGICAL(4) :: TMEMBER1(NAT) |
1266 | 1 | equemene | ! LOGICAL(4) :: TMEMBER2(NAT) |
1267 | 1 | equemene | ! LOGICAL(4) :: TMEMBER3(NAT) |
1268 | 1 | equemene | ! REAL(KREAL) :: SUMMASS1,SUMMASS2, SUMMASS3 |
1269 | 1 | equemene | ! REAL(KREAL) :: COG1(3) ! COG OF FIRST GROUP |
1270 | 1 | equemene | ! REAL(KREAL) :: COG2(3) ! COG OF SECOND GROUP |
1271 | 1 | equemene | ! REAL(KREAL) :: COG3(3) ! COG OF THIRD GROUP |
1272 | 1 | equemene | ! REAL(KREAL) :: DCOG1(3,NAT), DCOG2(3,NAT), DCOG3(3,NAT) |
1273 | 1 | equemene | ! REAL(KREAL) :: vecU(3), vecV(3) |
1274 | 1 | equemene | ! REAL(KREAL) :: UU, VV, UV |
1275 | 1 | equemene | ! INTEGER(KINT) :: I,J,IAT,IAT1,IAT2,JAT |
1276 | 1 | equemene | ! REAL(KREAL) :: Pi |
1277 | 1 | equemene | ! ! From BONDANGLEDERIVS |
1278 | 1 | equemene | ! REAL(KREAL) :: D1,D2 |
1279 | 1 | equemene | ! REAL(KREAL) :: DUUDX(3,NAT) |
1280 | 1 | equemene | ! REAL(KREAL) :: DVVDX(3,NAT) |
1281 | 1 | equemene | ! REAL(KREAL) :: DUVDX(3,NAT) |
1282 | 1 | equemene | ! REAL(KREAL) :: DDDX(3,NAT) |
1283 | 1 | equemene | ! REAL(KREAL) :: DJDX(3,NAT) |
1284 | 1 | equemene | ! REAL(KREAL) :: DVDX(3,NAT) |
1285 | 1 | equemene | ! REAL(KREAL) :: DGDX(3,NAT) ! D(A*B)/DX |
1286 | 1 | equemene | ! REAL(KREAL) :: DIDJ(3,NAT,3,NAT), DI(3,NAT) |
1287 | 1 | equemene | ! REAL(KREAL) :: AB,AB2N,V,PREFAC |
1288 | 1 | equemene | ! REAL(KREAL) :: PHI,COSPHI,SINPHI |
1289 | 1 | equemene | ! REAL(KREAL) :: DIVDX,AI |
1290 | 1 | equemene | |
1291 | 1 | equemene | |
1292 | 1 | equemene | ! ! ****************************************************************** |
1293 | 1 | equemene | |
1294 | 1 | equemene | ! CALL GROUPLIST_MEMBERS(GROUP1,TMEMBER1) |
1295 | 1 | equemene | ! CALL GROUPLIST_MEMBERS(GROUP2,TMEMBER2) |
1296 | 1 | equemene | ! CALL GROUPLIST_MEMBERS(GROUP3,TMEMBER3) |
1297 | 1 | equemene | ! ! |
1298 | 1 | equemene | ! ! ================================================================== |
1299 | 1 | equemene | ! ! == CALCULATE CENTERS OF GRAVITY == |
1300 | 1 | equemene | ! ! ================================================================== |
1301 | 1 | equemene | ! SUMMASS1=0.D0 |
1302 | 1 | equemene | ! SUMMASS2=0.D0 |
1303 | 1 | equemene | ! SUMMASS3=0.D0 |
1304 | 1 | equemene | ! COG1(:)=0.D0 |
1305 | 1 | equemene | ! COG2(:)=0.D0 |
1306 | 1 | equemene | ! COG3(:)=0.D0 |
1307 | 1 | equemene | ! DO IAT=1,NAT |
1308 | 1 | equemene | ! IF(TMEMBER1(IAT)) THEN |
1309 | 1 | equemene | ! SUMMASS1=SUMMASS1+RMASS(IAT) |
1310 | 1 | equemene | ! COG1(:)=COG1(:)+RMASS(IAT)*R0(:,IAT) |
1311 | 1 | equemene | ! ENDIF |
1312 | 1 | equemene | ! IF(TMEMBER2(IAT)) THEN |
1313 | 1 | equemene | ! SUMMASS2=SUMMASS2+RMASS(IAT) |
1314 | 1 | equemene | ! COG2(:)=COG2(:)+RMASS(IAT)*R0(:,IAT) |
1315 | 1 | equemene | ! ENDIF |
1316 | 1 | equemene | ! IF(TMEMBER3(IAT)) THEN |
1317 | 1 | equemene | ! SUMMASS3=SUMMASS3+RMASS(IAT) |
1318 | 1 | equemene | ! COG3(:)=COG3(:)+RMASS(IAT)*R0(:,IAT) |
1319 | 1 | equemene | ! ENDIF |
1320 | 1 | equemene | |
1321 | 1 | equemene | ! ENDDO |
1322 | 1 | equemene | ! COG1(:)=COG1(:)/SUMMASS1 |
1323 | 1 | equemene | ! COG2(:)=COG2(:)/SUMMASS2 |
1324 | 1 | equemene | ! COG3(:)=COG3(:)/SUMMASS3 |
1325 | 1 | equemene | ! ! |
1326 | 1 | equemene | ! ! |
1327 | 1 | equemene | ! vecU(:)=COG1(:)-COG2(:) |
1328 | 1 | equemene | ! vecV(:)=COG3(:)-COG2(:) |
1329 | 1 | equemene | |
1330 | 1 | equemene | ! UU=DOT_PRODUCT(vecU,vecU) |
1331 | 1 | equemene | ! VV=DOT_PRODUCT(vecV,vecV) |
1332 | 1 | equemene | ! ! We now calculate the first derivatives of the COG vs the atomic |
1333 | 1 | equemene | ! ! Coords... |
1334 | 1 | equemene | ! DCOG1=0. |
1335 | 1 | equemene | ! DCOG2=0. |
1336 | 1 | equemene | ! DCOG3=0. |
1337 | 1 | equemene | ! DO IAT=1,NAT |
1338 | 1 | equemene | ! IF (TMEMBER1(IAT)) DCOG1(:,IAT)=RMASS(IAT)/SUMMASS1 |
1339 | 1 | equemene | ! IF (TMEMBER2(IAT)) DCOG2(:,IAT)=RMASS(IAT)/SUMMASS2 |
1340 | 1 | equemene | ! IF (TMEMBER3(IAT)) DCOG3(:,IAT)=RMASS(IAT)/SUMMASS3 |
1341 | 1 | equemene | ! END DO |
1342 | 1 | equemene | ! ! We now calculate the first derivatives of UU, VV |
1343 | 1 | equemene | ! DUUDX=0. |
1344 | 1 | equemene | ! DVVDX=0. |
1345 | 1 | equemene | ! DO IAT=1,NAT |
1346 | 1 | equemene | ! DUUDX(:,IAT)=2.D0*(COG1(:)-COG2(:))*(DCOG1(:,IAT)-DCOG2(:,IAT)) |
1347 | 1 | equemene | ! DVVDX(:,IAT)=2.D0*(COG3(:)-COG2(:))*(DCOG3(:,IAT)-DCOG2(:,IAT)) |
1348 | 1 | equemene | ! END DO |
1349 | 1 | equemene | ! ! WRITE(*,*) 'PFL DER COGDIFF' |
1350 | 1 | equemene | ! ! WRITE(*,'(15(1X,F10.6))') DUUDX(:,:) |
1351 | 1 | equemene | ! ! WRITE(*,'(15(1X,F10.6))') DVVDX(:,:) |
1352 | 1 | equemene | |
1353 | 1 | equemene | ! ! We now use the fact that Sigma=sqrt(UU) - sqrt(VV) to calculate the |
1354 | 1 | equemene | ! ! first derivatives of Sigma along R |
1355 | 1 | equemene | |
1356 | 1 | equemene | ! ! Calculate the first derivatives and second derivatives. |
1357 | 1 | equemene | ! D1=dsqrt(UU) |
1358 | 1 | equemene | ! D2=dsqrt(VV) |
1359 | 1 | equemene | ! B(:,:)=0.5d0*( DUUDX(:,:)/D1 - DVVDX(:,:)/D2 ) |
1360 | 1 | equemene | |
1361 | 1 | equemene | ! END SUBROUTINE CONSTRAINTS_COGDIFF_DER |