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