Statistiques
| Révision :

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