root / src / ConvertBakerInternal_cart.f90 @ 3
Historique | Voir | Annoter | Télécharger (24,41 ko)
1 |
SUBROUTINE ConvertBakerInternal_cart(IntCoord_k,IntCoord,x_k,y_k,z_k,x,y,z,XPrim,XPrimRef) |
---|---|
2 |
|
3 |
!================================================================ |
4 |
! Converts the positions in Baker Coordinates to cartesian coordinates |
5 |
!================================================================ |
6 |
! |
7 |
! Input: |
8 |
! Incoord_k(NCoord) REAL: Starting internal coordinates |
9 |
! IntCoord(NCoord) REAL: Coordinate to convert to cartesian coordinates |
10 |
! x_k,y_k,z_k(Nat) REAL: Starting cartesian geometry |
11 |
! XPrimRef(NPrim) REAL: Reference values for Primitives coordinates (mainly for dihedral) |
12 |
! |
13 |
! Output: |
14 |
! x,y,z(Nat) REAL: Cartesian coordinates corresponding to IntCoord |
15 |
! XPrim(NPrim) REAL: Primitives for the cartesian coordinates. (This is a by-product) |
16 |
! |
17 |
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
18 |
|
19 |
! BTransInv,UMat should be passed as arguments of this subroutine. |
20 |
|
21 |
|
22 |
! IdxGeom: geometry index. |
23 |
! Internal coordinates IntCoord(NCoord) is to be converted |
24 |
! into Cartesian coordinates x(Nat),y(Nat),z(Nat). |
25 |
|
26 |
use Path_module, only : Nat,AtName,IntCoordI,XyzGeomI,BMat_BakerT,NPrim,& |
27 |
BTransInv,BBT,BBT_inv,BprimT,a0,ScanCoord,Coordinate,& |
28 |
Xprimitive,Pi,NGeomI,IntCoordF,BTransInv_local,Xprimitive_t,& |
29 |
Symmetry_elimination,NCoord,UMat_local |
30 |
! UMat_local is allocated in Calc_baker.f90 |
31 |
! XyzGeomI(NGeomI,3,Nat),BMat_BakerT(3*Nat,NCoord),a0=0.529177249d0 |
32 |
|
33 |
Use Io_Module |
34 |
use VarTypes |
35 |
IMPLICIT NONE |
36 |
|
37 |
REAL(KREAL), INTENT(OUT) :: x(Nat),y(Nat),z(Nat) |
38 |
REAL(KREAL), INTENT(IN) :: x_k(Nat),y_k(Nat),z_k(Nat) |
39 |
REAL(KREAL), INTENT(IN) :: IntCoord(NCoord) |
40 |
REAL(KREAL), INTENT(INOUT) :: IntCoord_k(NCoord) |
41 |
REAL(KREAL), INTENT(IN) :: XPrimRef(NPrim) |
42 |
REAL(KREAL), INTENT(OUT) :: XPrim(NPrim) |
43 |
|
44 |
|
45 |
! IdxGeom: geometry index. |
46 |
Integer(KINT) :: n1,n2,n3,I,J,K,Counter |
47 |
REAL(KREAL) :: normDeltaX_int |
48 |
|
49 |
REAL(KREAL), ALLOCATABLE :: DeltaX_int(:) !DeltaX_int(NPrim,3*Nat-6), 3*Nat-6?? |
50 |
REAL(KREAL), ALLOCATABLE :: DeltaX_cart(:) !DeltaX_cart(3*Nat) |
51 |
REAL(KREAL), ALLOCATABLE :: Geom(:,:) !(3,Nat) |
52 |
REAL(KREAL), ALLOCATABLE :: X_cart_k(:,:) ! (3,Nat) |
53 |
REAL(KREAL), ALLOCATABLE :: GMat(:,:) !(NPrim,NPrim) |
54 |
REAL(KREAL), ALLOCATABLE :: EigVec(:,:), EigVal(:) ! EigVec(NPrim,NPrim) |
55 |
REAL(KREAL), ALLOCATABLE :: UMat_tmp(:,:) |
56 |
REAL(KREAL), ALLOCATABLE :: V(:,:) ! (NCoord,NCoord) |
57 |
|
58 |
REAL(KREAL) :: vx,vy,vz,dist,Norm |
59 |
REAL(KREAL) :: vx1,vy1,vz1,norm1 |
60 |
REAL(KREAL) :: vx2,vy2,vz2,norm2 |
61 |
REAL(KREAL) :: vx3,vy3,vz3,norm3 |
62 |
REAL(KREAL) :: vx4,vy4,vz4,norm4 |
63 |
REAL(KREAL) :: vx5,vy5,vz5,norm5 |
64 |
REAL(KREAL) :: val,val_d, Q, T |
65 |
REAL(KREAL) :: Angle, angle_d, tol,Delta,DiheTmp |
66 |
REAL(KREAL) :: MRot(3,3), Rmsd |
67 |
REAL(KREAL), PARAMETER :: Crit=1e-08 |
68 |
|
69 |
EXTERNAL Angle, angle_d |
70 |
LOGICAL :: debug, FAIL |
71 |
|
72 |
INTEGER(KINT), PARAMETER :: NbItMax=50 |
73 |
|
74 |
|
75 |
INTERFACE |
76 |
function valid(string) result (isValid) |
77 |
CHARACTER(*), intent(in) :: string |
78 |
logical :: isValid |
79 |
END function VALID |
80 |
|
81 |
|
82 |
|
83 |
SUBROUTINE Calc_Xprim(nat,x,y,z,Coordinate,NPrim,XPrimitive,XPrimRef) |
84 |
! |
85 |
! This subroutine uses the description of a list of Coordinates |
86 |
! to compute the values of the coordinates for a given geometry. |
87 |
! |
88 |
!!!!!!!!!! |
89 |
! Input: |
90 |
! Na: INTEGER, Number of atoms |
91 |
! x,y,z(Na): REAL, cartesian coordinates of the considered geometry |
92 |
! Coordinate (Pointer(ListCoord)): description of the wanted coordiantes |
93 |
! NPrim, INTEGER: Number of coordinates to compute |
94 |
! |
95 |
! Optional: XPrimRef(NPrim) REAL: array that contains coordinates values for |
96 |
! a former geometry. Useful for Dihedral angles evolution... |
97 |
|
98 |
!!!!!!!!!!! |
99 |
! Output: |
100 |
! XPrimimite(NPrim) REAL: array that will contain the values of the coordinates |
101 |
! |
102 |
!!!!!!!!! |
103 |
|
104 |
Use VarTypes |
105 |
Use Io_module |
106 |
Use Path_module, only : pi |
107 |
|
108 |
IMPLICIT NONE |
109 |
|
110 |
Type (ListCoord), POINTER :: Coordinate |
111 |
INTEGER(KINT), INTENT(IN) :: Nat,NPrim |
112 |
REAL(KREAL), INTENT(IN) :: x(Nat), y(Nat), z(Nat) |
113 |
REAL(KREAL), INTENT(IN), OPTIONAL :: XPrimRef(NPrim) |
114 |
REAL(KREAL), INTENT(OUT) :: XPrimitive(NPrim) |
115 |
|
116 |
END SUBROUTINE CALC_XPRIM |
117 |
END INTERFACE |
118 |
|
119 |
|
120 |
debug=valid('ConvertBakerInternal_cart') |
121 |
if (debug) WRITE(*,*) '=======Entering ConvertBakerInternal_cart=======' |
122 |
|
123 |
FAIL = .FALSE. |
124 |
|
125 |
!!!!!! |
126 |
! Allocation phase |
127 |
|
128 |
ALLOCATE(DeltaX_int(NCoord),DeltaX_cart(3*Nat)) |
129 |
ALLOCATE(UMat_tmp(NPrim,NCoord)) |
130 |
ALLOCATE(X_cart_k(3,Nat)) |
131 |
ALLOCATE(Geom(3,Nat),BprimT(3*Nat,NPrim)) |
132 |
ALLOCATE(BBT(NCoord,NCoord)) |
133 |
ALLOCATE(BBT_inv(NCoord,NCoord)) |
134 |
ALLOCATE(Gmat(NPrim,NPrim)) |
135 |
ALLOCATE(EigVal(NPrim),EigVec(NPrim,NPrim)) |
136 |
|
137 |
|
138 |
if (debug) THEN |
139 |
WRITE(*,*) "Checking purposes...." |
140 |
WRITE(*,*) "Trying ot convert Xint initial (IntCoord)" |
141 |
WRITE(*,'(50(1X,F12.8))') IntCoord(:) |
142 |
WRITE(*,*) "BTransInv_local" |
143 |
DO J=1,3*Nat |
144 |
WRITE(*,'(50(1X,F12.8))') BTransInv_local(:,J) |
145 |
END DO |
146 |
WRITE(*,*) "Xint initial (IntCoord_k)" |
147 |
WRITE(*,'(50(1X,F12.8))') IntCoord_k(:) |
148 |
WRITE(*,*) "Cartesian coordinates" |
149 |
WRITE(*,*) Nat |
150 |
WRITE(*,*) 'GeomCart in ConvertBakerInternal_cart' |
151 |
DO I=1,Nat |
152 |
WRITE(*,'(1X,A,I4,3(1X,F12.4))') AtName(I),I,X_k(I),Y_k(i),Z_k(i) |
153 |
END DO |
154 |
WRITE(*,*) "Calculating actual values using x_k,y_k,z_k" |
155 |
|
156 |
! WRITE(*,*) "First, with Calc_XPrim" |
157 |
! WRITE(*,*) "Coordinate:",associated(Coordinate) |
158 |
Call Calc_Xprim(nat,x_k,y_k,z_k,Coordinate,NPrim,XPrimitive_t,XPrimRef) |
159 |
|
160 |
! I=0 ! index for the NPrim (NPrim is the number of ! primitive coordinates). |
161 |
! ScanCoord=>Coordinate |
162 |
! DO WHILE (Associated(ScanCoord%next)) |
163 |
! I=I+1 |
164 |
! SELECT CASE (ScanCoord%Type) |
165 |
! CASE ('BOND') |
166 |
! Print *, I, ':', ScanCoord%At1, '-', ScanCoord%At2, '=', Xprimitive_t(I) |
167 |
! CASE ('ANGLE') |
168 |
! Print *, I, ':', ScanCoord%At1, '-', ScanCoord%At2,'-',ScanCoord%At3, '=', Xprimitive_t(I)*180./Pi |
169 |
! CASE ('DIHEDRAL') |
170 |
! Print *, I, ':', ScanCoord%At1, '-',ScanCoord%At2,'-',ScanCoord%At3,'-',& |
171 |
! ScanCoord%At4,'=',Xprimitive_t(I)*180./Pi |
172 |
! END SELECT |
173 |
! ScanCoord => ScanCoord%next |
174 |
! END DO ! matches DO WHILE (Associated(ScanCoord%next)) |
175 |
|
176 |
! WRITE(*,*) "Second with normal proc" |
177 |
! I=0 ! index for the NPrim (NPrim is the number of ! primitive coordinates). |
178 |
! Xprimitive_t=0.d0 |
179 |
! ScanCoord=>Coordinate |
180 |
! DO WHILE (Associated(ScanCoord%next)) |
181 |
! I=I+1 |
182 |
! SELECT CASE (ScanCoord%Type) |
183 |
! CASE ('BOND') |
184 |
! Call vecteur(ScanCoord%At2,ScanCoord%At1,x_k,y_k,z_k,vx2,vy2,vz2,Norm2) |
185 |
! Xprimitive_t(I) = Norm2 |
186 |
! Print *, I, ':', ScanCoord%At1, '-', ScanCoord%At2, '=', Xprimitive_t(I) |
187 |
! CASE ('ANGLE') |
188 |
! Call vecteur(ScanCoord%At2,ScanCoord%At3,x_k,y_k,z_k,vx1,vy1,vz1,Norm1) |
189 |
! Call vecteur(ScanCoord%At2,ScanCoord%At1,x_k,y_k,z_k,vx2,vy2,vz2,Norm2) |
190 |
! Xprimitive_t(I) = angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180. |
191 |
! Print *, I, ':', ScanCoord%At1, '-', ScanCoord%At2,'-',ScanCoord%At3, '=', Xprimitive_t(I)*180./Pi |
192 |
! CASE ('DIHEDRAL') |
193 |
! Call vecteur(ScanCoord%At2,ScanCoord%At1,x_k,y_k,z_k,vx1,vy1,vz1,Norm1) |
194 |
! Call vecteur(ScanCoord%At2,ScanCoord%At3,x_k,y_k,z_k,vx2,vy2,vz2,Norm2) |
195 |
! Call vecteur(ScanCoord%At3,ScanCoord%At4,x_k,y_k,z_k,vx3,vy3,vz3,Norm3) |
196 |
! Call produit_vect(vx3,vy3,vz3,norm3,vx2,vy2,vz2,norm2,vx5,vy5,vz5,norm5) |
197 |
! Call produit_vect(vx1,vy1,vz1,norm1,vx2,vy2,vz2,norm2,vx4,vy4,vz4,norm4) |
198 |
! !!! PFL 28 Feb 2008 Test to be sure that angle does not change by more than Pi |
199 |
! ! Xprimitive_t(I)=angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5,vx2,vy2,vz2,norm2)*Pi/180. |
200 |
! DiheTmp= angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, & |
201 |
! vx2,vy2,vz2,norm2) |
202 |
! Xprimitive_t(I) = DiheTmp*Pi/180. |
203 |
! ! We treat large dihedral angles differently as +180=-180 mathematically and physically |
204 |
! ! but this causes lots of troubles when converting baker to cart. |
205 |
! ! So we ensure that large dihedral angles always have the same sign |
206 |
! if (abs(ScanCoord%SignDihedral).NE.1) THEN |
207 |
! ScanCoord%SignDihedral=Int(Sign(1.,DiheTmp)) |
208 |
! ELSE |
209 |
! If ((abs(DiheTmp).GE.170.D0).AND.(Sign(1.,DiheTmp)*ScanCoord%SignDihedral<0)) THEN |
210 |
! Xprimitive_t(I) = DiheTmp*Pi/180.+ ScanCoord%SignDihedral*2.*Pi |
211 |
! END IF |
212 |
! END IF |
213 |
|
214 |
! IF (abs(Xprimitive_t(I)-XPrimRef(I)).GE.Pi) THEN |
215 |
! if ((Xprimitive_t(I)-XPrimRef(I)).GE.Pi) THEN |
216 |
! Xprimitive_t(I)=Xprimitive_t(I)-2.d0*Pi |
217 |
! ELSE |
218 |
! Xprimitive_t(I)=Xprimitive_t(I)+2.d0*Pi |
219 |
! END IF |
220 |
! END IF |
221 |
|
222 |
! Print *, I, ':', ScanCoord%At1, '-',ScanCoord%At2,'-',ScanCoord%At3,'-',& |
223 |
! ScanCoord%At4,'=',Xprimitive_t(I)*180./Pi |
224 |
! END SELECT |
225 |
! ScanCoord => ScanCoord%next |
226 |
! END DO ! matches DO WHILE (Associated(ScanCoord%next)) |
227 |
|
228 |
IntCoord_k=0.d0 |
229 |
DO I=1, NPrim |
230 |
! Transpose of UMat is needed below, that is why UMat(I,:). |
231 |
IntCoord_k(:)=IntCoord_k(:)+UMat_local(I,:)*Xprimitive_t(I) |
232 |
END DO |
233 |
WRITE(*,*) "Xint (intCoord_k) cooresponding to x_k,y_k,z_k" |
234 |
WRITE(*,'(50(1X,F12.8))') IntCoord_k(:) |
235 |
WRITE(*,*) "UMat_local" |
236 |
DO I=1, NPrim |
237 |
WRITE(*,'(50(1X,F12.8))') UMat_local(I,:) |
238 |
END DO |
239 |
|
240 |
! Geom(1,:)=X_k(1:Nat)/a0 |
241 |
! Geom(2,:)=y_k(1:Nat)/a0 |
242 |
! Geom(3,:)=z_k(1:Nat)/a0 |
243 |
|
244 |
Geom(1,:)=X_k(1:Nat) |
245 |
Geom(2,:)=y_k(1:Nat) |
246 |
Geom(3,:)=z_k(1:Nat) |
247 |
|
248 |
! Computing B^prim: |
249 |
BprimT=0.d0 |
250 |
ScanCoord=>Coordinate |
251 |
I=0 |
252 |
DO WHILE (Associated(ScanCoord%next)) |
253 |
I=I+1 |
254 |
SELECT CASE (ScanCoord%Type) |
255 |
CASE ('BOND') |
256 |
CALL CONSTRAINTS_BONDLENGTH_DER(Nat,ScanCoord%at1,ScanCoord%AT2,Geom,BprimT(1,I)) |
257 |
CASE ('ANGLE') |
258 |
CALL CONSTRAINTS_BONDANGLE_DER(Nat,ScanCoord%At1,ScanCoord%AT2,ScanCoord%At3,Geom,BprimT(1,I)) |
259 |
CASE ('DIHEDRAL') |
260 |
CALL CONSTRAINTS_TORSION_DER2(Nat,ScanCoord%At1,ScanCoord%AT2,ScanCoord%At3,ScanCoord%At4,Geom,BprimT(1,I)) |
261 |
END SELECT |
262 |
ScanCoord => ScanCoord%next |
263 |
END DO |
264 |
|
265 |
! if (debug) THEN |
266 |
! WRITE(*,*) "PFL DBG, I,NPrim,BPrimT",I,NPrim |
267 |
! DO I=1,NPrim |
268 |
! WRITE(*,'(50(1X,F12.6))') BPrimT(:,I) |
269 |
! END DO |
270 |
! END IF |
271 |
|
272 |
BMat_BakerT = 0.d0 |
273 |
DO I=1,NCoord |
274 |
DO J=1,NPrim |
275 |
!BprimT is transpose of B^prim. |
276 |
!B = UMat^T B^prim, B^T = (B^prim)^T UMat |
277 |
BMat_BakerT(:,I)=BMat_BakerT(:,I)+BprimT(:,J)*UMat_local(J,I) |
278 |
END DO |
279 |
END DO |
280 |
|
281 |
BBT = 0.d0 |
282 |
DO I=1,NCoord |
283 |
DO J=1,3*Nat ! BBT(:,I) forms BB^T |
284 |
BBT(:,I) = BBT(:,I) + BMat_BakerT(J,:)*BMat_BakerT(J,I) |
285 |
END DO |
286 |
END DO |
287 |
|
288 |
BBT_inv = 0.d0 |
289 |
|
290 |
!Print *, 'NCoord=', NCoord |
291 |
!Print *, 'BBT=' |
292 |
DO J=1,NCoord |
293 |
! WRITE(*,'(50(1X,F12.6))') BBT(:,J) |
294 |
END DO |
295 |
!Print *, 'End of BBT' |
296 |
! GenInv is in Mat_util.f90 |
297 |
Call GenInv(NCoord,BBT,BBT_inv,NCoord) |
298 |
! ALLOCATE(V(NCoord,NCoord)) |
299 |
! tol = 1e-12 |
300 |
! ! BBT is destroyed by GINVSE |
301 |
! Call GINVSE(BBT,NCoord,NCoord,BBT_inv,NCoord,NCoord,NCoord,tol,V,NCoord,FAIL,IOOUT) |
302 |
! DEALLOCATE(V) |
303 |
! IF(Fail) Then |
304 |
! WRITE (*,*) "Failed in generalized inverse, L220, ConvertBaker...f90" |
305 |
! STOP |
306 |
! END IF |
307 |
|
308 |
!Print *, 'BBT_inv=' |
309 |
DO J=1,NCoord |
310 |
! WRITE(*,'(50(1X,F10.2))') BBT_inv(:,J) |
311 |
! Print *, BBT_inv(:,J) |
312 |
END DO |
313 |
!Print *, 'End of BBT_inv' |
314 |
|
315 |
! Calculation of (B^T)^-1 = (BB^T)^-1B: |
316 |
BTransInv_local = 0.d0 |
317 |
DO I=1,3*Nat |
318 |
DO J=1,NCoord |
319 |
BTransInv_local(:,I)=BTransInv_local(:,I)+BBT_inv(:,J)*BMat_BakerT(I,J) |
320 |
END DO |
321 |
END DO |
322 |
|
323 |
!Print *, 'BMat_BakerT=' |
324 |
DO J=1,3*Nat |
325 |
!WRITE(*,'(50(1X,F12.8))') BMat_BakerT(:,J) |
326 |
END DO |
327 |
!Print *, 'End of BMat_BakerT' |
328 |
|
329 |
WRITE(*,*) "BTransInv_local Trans corresponding to x_k,y_k,z_k" |
330 |
DO J=1,3*Nat |
331 |
WRITE(*,'(50(1X,F12.8))') BTransInv_local(:,J) |
332 |
END DO |
333 |
|
334 |
|
335 |
END IF |
336 |
|
337 |
DeltaX_int(:) = IntCoord(:)-IntCoord_k(:) |
338 |
|
339 |
X_cart_k(1,:) = x_k(:) |
340 |
X_cart_k(2,:) = y_k(:) |
341 |
X_cart_k(3,:) = z_k(:) |
342 |
|
343 |
normDeltaX_int=0.d0 ! This is to be implemented. |
344 |
DO I=1, NCoord |
345 |
normDeltaX_int=normDeltaX_int+DeltaX_int(I)*DeltaX_int(I) |
346 |
END DO |
347 |
normDeltaX_int = sqrt(normDeltaX_int) |
348 |
! I just need initial value of normDeltaX_int to be .GT. 1d-11, |
349 |
! that is why it is initialized to 1.d0 |
350 |
!normDeltaX_int = 1.d0 |
351 |
|
352 |
if (debug) WRITE(*,*) "Entering the loop" |
353 |
Counter = 0 |
354 |
DO While ((normDeltaX_int .GT. Crit) .AND. (Counter .LT. NbItMax)) |
355 |
!DO While (normDeltaX_int .GT. 1d-6) |
356 |
Counter = Counter + 1 |
357 |
DeltaX_cart = 0.d0 |
358 |
! if (normDeltaX_int.LE.1e-4) THEN |
359 |
! DeltaX_int=DeltaX_int*1e4 |
360 |
! END IF |
361 |
DO I=1,NCoord |
362 |
! below BTransInv_local(I,:) is used because actually we need Transpose of BTransInv_local. |
363 |
DeltaX_cart(:)=DeltaX_cart(:)+BTransInv_local(I,:)*DeltaX_int(I) |
364 |
END DO |
365 |
! if (normDeltaX_int.LE.1e-4) THEN |
366 |
! DeltaX_int=DeltaX_int*1e-4 |
367 |
! DeltaX_cart=DeltaX_cart*1e-4 |
368 |
! END IF |
369 |
|
370 |
|
371 |
if (debug) THEN |
372 |
WRITE(*,*) "Info for iteration:",counter |
373 |
Print *, 'DeltaX_int=' |
374 |
WRITE(*,'(50(1X,F12.8))') DeltaX_int |
375 |
Print *, 'DeltaX_cart,norm',sqrt(dot_product(DeltaX_cart,DeltaX_cart)) |
376 |
DO J=1,Nat |
377 |
WRITE(*,'(1X,A4,3(1X,F15.11),3(1X,D25.15))') AtName(J),DeltaX_cart(3*J-2:3*J),DeltaX_cart(3*J-2:3*J) |
378 |
END DO |
379 |
Print *, 'BTransInv_local Trans=' |
380 |
DO J=1,3*Nat |
381 |
WRITE(*,'(50(1X,F12.8))') BTransInv_local(:,J) |
382 |
END DO |
383 |
Print *, 'DeltaX_int=' |
384 |
WRITE(*,'(50(1X,F12.8))') DeltaX_int |
385 |
END IF |
386 |
|
387 |
! Finite precision error correction step: |
388 |
! DO I=1,3*Nat |
389 |
! IF (DeltaX_cart(I) .NE. 0.d0) Then |
390 |
! IF(abs(DeltaX_cart(I)) .LT. 1d-10) Then |
391 |
! !Print *, 'Correcting DeltaX_cart(',I,')=', DeltaX_cart(I) |
392 |
! DeltaX_cart(I) = 0.d0 |
393 |
! END IF |
394 |
! END IF |
395 |
! END DO |
396 |
|
397 |
! new cartesian coordinates: |
398 |
DO I=1, Nat |
399 |
X_cart_k(1,I) = X_cart_k(1,I) + DeltaX_cart(3*I-2) |
400 |
X_cart_k(2,I) = X_cart_k(2,I) + DeltaX_cart(3*I-1) |
401 |
X_cart_k(3,I) = X_cart_k(3,I) + DeltaX_cart(3*I) |
402 |
END DO |
403 |
|
404 |
! Geom(1,:)=X_cart_k(1,1:Nat)/a0 |
405 |
! Geom(2,:)=X_cart_k(2,1:Nat)/a0 |
406 |
! Geom(3,:)=X_cart_k(3,1:Nat)/a0 |
407 |
Geom(1,:)=X_cart_k(1,1:Nat) |
408 |
Geom(2,:)=X_cart_k(2,1:Nat) |
409 |
Geom(3,:)=X_cart_k(3,1:Nat) |
410 |
|
411 |
if (debug) THEN |
412 |
WRITE(*,*) 'GeomCart used to compute BPrim' |
413 |
DO I=1,Nat |
414 |
WRITE(*,'(1X,A,I4,3(1X,F12.4))') AtName(I),I,Geom(1,I),Geom(2,i),Geom(3,i) |
415 |
END DO |
416 |
END IF |
417 |
|
418 |
! Computing B^prim: |
419 |
BprimT=0.d0 |
420 |
ScanCoord=>Coordinate |
421 |
I=0 |
422 |
DO WHILE (Associated(ScanCoord%next)) |
423 |
I=I+1 |
424 |
SELECT CASE (ScanCoord%Type) |
425 |
CASE ('BOND') |
426 |
CALL CONSTRAINTS_BONDLENGTH_DER(Nat,ScanCoord%at1,ScanCoord%AT2,Geom,BprimT(1,I)) |
427 |
CASE ('ANGLE') |
428 |
CALL CONSTRAINTS_BONDANGLE_DER(Nat,ScanCoord%At1,ScanCoord%AT2,ScanCoord%At3,Geom,BprimT(1,I)) |
429 |
CASE ('DIHEDRAL') |
430 |
CALL CONSTRAINTS_TORSION_DER2(Nat,ScanCoord%At1,ScanCoord%AT2,ScanCoord%At3,ScanCoord%At4,Geom,BprimT(1,I)) |
431 |
END SELECT |
432 |
ScanCoord => ScanCoord%next |
433 |
END DO |
434 |
|
435 |
if (debug) THEN |
436 |
WRITE(*,*) "Bprim " |
437 |
DO J=1,3*Nat |
438 |
WRITE(*,'(50(1X,F12.6))') BprimT(J,:) |
439 |
END DO |
440 |
END IF |
441 |
|
442 |
|
443 |
BMat_BakerT = 0.d0 |
444 |
DO I=1,NCoord |
445 |
DO J=1,NPrim |
446 |
!BprimT is transpose of B^prim. |
447 |
!B = UMat^T B^prim, B^T = (B^prim)^T UMat |
448 |
BMat_BakerT(:,I)=BMat_BakerT(:,I)+BprimT(:,J)*UMat_local(J,I) |
449 |
END DO |
450 |
END DO |
451 |
|
452 |
! ADDED FROM HERE: |
453 |
! We now compute G=B(BT) matrix |
454 |
!IF (IOptt .EQ. 5000) Then |
455 |
!GMat=0.d0 |
456 |
!DO I=1,NPrim |
457 |
! DO J=1,3*Nat |
458 |
! GMat(:,I)=Gmat(:,I)+BprimT(J,:)*BprimT(J,I) !*1.d0/mass(atome(int(K/3.d0))) |
459 |
!END DO |
460 |
!END DO |
461 |
|
462 |
! We diagonalize G |
463 |
!Call Jacobi(GMat,NPrim,EigVal,EigVec,NPrim) |
464 |
!Call Trie(NPrim,EigVal,EigVec,NPrim) |
465 |
|
466 |
! We construct the new DzDc(b=baker) matrix |
467 |
! UMat is nonredundant vector set, i.e. set of eigenvectors of |
468 |
! BB^T corresponding to eigenvalues > zero. |
469 |
|
470 |
!UMat=0.d0 |
471 |
!UMat_tmp=0.d0 |
472 |
!BMat_BakerT = 0.d0 |
473 |
!J=0 |
474 |
!DO I=1,NPrim |
475 |
! IF (abs(eigval(I))>=1e-6) THEN |
476 |
! J=J+1 |
477 |
! DO K=1,NPrim |
478 |
! BprimT is transpose of B^prim. |
479 |
! B = UMat^T B^prim, B^T = (B^prim)^T UMat |
480 |
!BMat_BakerT(:,J)=BMat_BakerT(:,J)+BprimT(:,K)*Eigvec(K,I) |
481 |
! END DO |
482 |
!IF(J .GT. 3*Nat-6) THEN |
483 |
!WRITE(*,*) 'Number of vectors in Eigvec with eigval .GT. & |
484 |
! 1e-6 (=UMat) (=' ,J,') exceeded 3*Nat-6=',3*Nat-6, & |
485 |
! 'Stopping the calculation.' |
486 |
! STOP |
487 |
! END IF |
488 |
! UMat_tmp(:,J) = Eigvec(:,I) |
489 |
! END IF |
490 |
!END DO |
491 |
|
492 |
! THIS IS TO BE CORRECTED, A special case for debugging C2H3F case: |
493 |
!J=0 |
494 |
!DO I=1, 3*Nat-6 |
495 |
! IF ((I .NE. 6) .AND. (I .NE. 7) .AND. (I .NE. 9)) Then |
496 |
! J=J+1 |
497 |
! Print *, 'J=', J, ' I=', I |
498 |
!UMat(:,J) = UMat_tmp(:,I) |
499 |
! END IF |
500 |
! END DO |
501 |
!BMat_BakerT=0.d0 |
502 |
! DO I=1,NCoord |
503 |
! DO J=1,NPrim |
504 |
! B = UMat^T B^prim, B^T = (B^prim)^T UMat |
505 |
! BMat_BakerT(:,I)=BMat_BakerT(:,I)+BprimT(:,J)*UMat(J,I) |
506 |
! END DO |
507 |
!END DO |
508 |
! TO BE CORRECTED, ENDS HERE. |
509 |
|
510 |
!END IF |
511 |
! END of the new changes. |
512 |
|
513 |
BBT = 0.d0 |
514 |
DO I=1,NCoord |
515 |
DO J=1,3*Nat ! BBT(:,I) forms BB^T |
516 |
BBT(:,I) = BBT(:,I) + BMat_BakerT(J,:)*BMat_BakerT(J,I) |
517 |
END DO |
518 |
END DO |
519 |
|
520 |
BBT_inv = 0.d0 |
521 |
|
522 |
!Print *, 'NCoord=', NCoord |
523 |
!Print *, 'BBT=' |
524 |
DO J=1,NCoord |
525 |
! WRITE(*,'(50(1X,F12.6))') BBT(:,J) |
526 |
END DO |
527 |
!Print *, 'End of BBT' |
528 |
! GenInv is in Mat_util.f90 |
529 |
Call GenInv(NCoord,BBT,BBT_inv,NCoord) |
530 |
! if (debug) THEN |
531 |
! WRITE(*,*) 'BBT_inv by GenInv' |
532 |
! DO J=1,NCoord |
533 |
! WRITE(*,'(50(1X,F12.6))') BBT_inv(:,J) |
534 |
! END DO |
535 |
! END IF |
536 |
|
537 |
! ALLOCATE(V(NCoord,NCoord)) |
538 |
! tol = 1e-12 |
539 |
! ! BBT is destroyed by GINVSE |
540 |
! Call GINVSE(BBT,NCoord,NCoord,BBT_inv,NCoord,NCoord,NCoord,tol,V,NCoord,FAIL,IOOUT) |
541 |
! DEALLOCATE(V) |
542 |
! IF(Fail) Then |
543 |
! WRITE (*,*) "Failed in generalized inverse, L220, ConvertBaker...f90" |
544 |
! STOP |
545 |
! END IF |
546 |
|
547 |
! if (debug) THEN |
548 |
! WRITE(*,*) 'BBT_inv by Genvse' |
549 |
! DO J=1,NCoord |
550 |
! WRITE(*,'(50(1X,F12.6))') BBT_inv(:,J) |
551 |
! END DO |
552 |
! END IF |
553 |
|
554 |
!Print *, 'End of BBT_inv' |
555 |
|
556 |
! Calculation of (B^T)^-1 = (BB^T)^-1B: |
557 |
BTransInv_local = 0.d0 |
558 |
DO I=1,3*Nat |
559 |
DO J=1,NCoord |
560 |
BTransInv_local(:,I)=BTransInv_local(:,I)+BBT_inv(:,J)*BMat_BakerT(I,J) |
561 |
END DO |
562 |
END DO |
563 |
|
564 |
! if (debug) THEN |
565 |
! Print *, 'BMat_BakerT=' |
566 |
! DO J=1,3*Nat |
567 |
! WRITE(*,'(50(1X,F12.6))') BMat_BakerT(:,J) |
568 |
! END DO |
569 |
! Print *, 'End of BMat_BakerT' |
570 |
! END IF |
571 |
|
572 |
! if (debug) THEN |
573 |
! Print *, 'BTransInv_local Trans=' |
574 |
! DO J=1,3*Nat |
575 |
! WRITE(*,'(50(1X,F16.6))') BTransInv_local(:,J) |
576 |
! END DO |
577 |
! Print *, 'End of BTransInv_local Trans' |
578 |
! END IF |
579 |
|
580 |
! New cartesian cooordinates: |
581 |
x(:) = X_cart_k(1,:) |
582 |
y(:) = X_cart_k(2,:) |
583 |
z(:) = X_cart_k(3,:) |
584 |
|
585 |
|
586 |
Call Calc_Xprim(nat,x,y,z,Coordinate,NPrim,XPrimitive_t,XPrimRef) |
587 |
|
588 |
! I=0 ! index for the NPrim (NPrim is the number of |
589 |
! ! primitive coordinates). |
590 |
! Xprimitive_t=0.d0 |
591 |
! ScanCoord=>Coordinate |
592 |
! DO WHILE (Associated(ScanCoord%next)) |
593 |
! I=I+1 |
594 |
! SELECT CASE (ScanCoord%Type) |
595 |
! CASE ('BOND') |
596 |
! Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx2,vy2,vz2,Norm2) |
597 |
! Xprimitive_t(I) = Norm2 |
598 |
! !Print *, I, ':', ScanCoord%At1, '-', ScanCoord%At2, '=', Xprimitive_t(I) |
599 |
! CASE ('ANGLE') |
600 |
! Call vecteur(ScanCoord%At2,ScanCoord%At3,x,y,z,vx1,vy1,vz1,Norm1) |
601 |
! Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx2,vy2,vz2,Norm2) |
602 |
! Xprimitive_t(I) = angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180. |
603 |
! !Print *, I, ':', ScanCoord%At1, '-', ScanCoord%At2,'-',ScanCoord%At3, '=', Xprimitive_t(I)*180./Pi |
604 |
! CASE ('DIHEDRAL') |
605 |
! Call vecteur(ScanCoord%At2,ScanCoord%At3,x,y,z,vx2,vy2,vz2,Norm2) |
606 |
! Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx1,vy1,vz1,Norm1) |
607 |
! Call vecteur(ScanCoord%At3,ScanCoord%At4,x,y,z,vx3,vy3,vz3,Norm3) |
608 |
! Call produit_vect(vx3,vy3,vz3,norm3,vx2,vy2,vz2,norm2,vx5,vy5,vz5,norm5) |
609 |
! Call produit_vect(vx1,vy1,vz1,norm1,vx2,vy2,vz2,norm2,vx4,vy4,vz4,norm4) |
610 |
! !!! PFL 28 Feb 2008 Test to be sure that angle does not change by more than Pi |
611 |
! ! Xprimitive_t(I)=angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5,vx2,vy2,vz2,norm2)*Pi/180. |
612 |
! DiheTmp=angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5,vx2,vy2,vz2,norm2) |
613 |
! Xprimitive_t(I) = DiheTmp*Pi/180. |
614 |
! ! We treat large dihedral angles differently as +180=-180 mathematically and physically |
615 |
! ! but this causes lots of troubles when converting baker to cart. |
616 |
! ! So we ensure that large dihedral angles always have the same sign |
617 |
! if (abs(ScanCoord%SignDihedral).NE.1) THEN |
618 |
! ScanCoord%SignDihedral=Int(Sign(1.d0,DiheTmp)) |
619 |
! ELSE |
620 |
! If ((abs(DiheTmp).GE.170.D0).AND.(Sign(1.,DiheTmp)*ScanCoord%SignDihedral<0)) THEN |
621 |
! Xprimitive_t(I) = DiheTmp*Pi/180.+ ScanCoord%SignDihedral*2.*Pi |
622 |
! END IF |
623 |
! END IF |
624 |
|
625 |
|
626 |
|
627 |
! !Print *, I, ':', ScanCoord%At1, '-',ScanCoord%At2,'-',ScanCoord%At3,'-',& |
628 |
! !ScanCoord%At4,'=',Xprimitive_t(I)*180./Pi |
629 |
! END SELECT |
630 |
! ScanCoord => ScanCoord%next |
631 |
! END DO ! matches DO WHILE (Associated(ScanCoord%next)) |
632 |
|
633 |
! if (debug) THEN |
634 |
! WRITE(*,*) "Xprimitive_t" |
635 |
! WRITE(*,'(50(1X,F12.6))') Xprimitive_t |
636 |
! END IF |
637 |
|
638 |
IntCoord_k=0.d0 |
639 |
DO I=1, NPrim |
640 |
! Transpose of UMat is needed below, that is why UMat(I,:). |
641 |
IntCoord_k(:)=IntCoord_k(:)+UMat_local(I,:)*Xprimitive_t(I) |
642 |
END DO |
643 |
|
644 |
if (debug) THEN |
645 |
WRITE(*,*) "New Xint (IntCoord_k)" |
646 |
WRITE(*,'(50(1X,F12.8))') IntCoord_k |
647 |
WRITE(*,*) "Target (IntCoord)" |
648 |
WRITE(*,'(50(1X,F12.8))') IntCoord |
649 |
|
650 |
END IF |
651 |
|
652 |
|
653 |
! Computing DeltaX_int |
654 |
|
655 |
DeltaX_int(:) = IntCoord(:)-IntCoord_k(:) |
656 |
|
657 |
|
658 |
|
659 |
|
660 |
! norm2 of DeltaX_int is being calculated here: |
661 |
normDeltaX_int=0.d0 |
662 |
DO I=1, NCoord |
663 |
normDeltaX_int=normDeltaX_int+DeltaX_int(I)*DeltaX_int(I) |
664 |
END DO |
665 |
normDeltaX_int = sqrt(normDeltaX_int) |
666 |
|
667 |
if (debug) THEN |
668 |
WRITE(*,*) "New Delta_Xint (deltaX_int)" |
669 |
WRITE(*,'(50(1X,F12.6))') DeltaX_int |
670 |
WRITE(*,*) "Norm:",normDeltaX_int |
671 |
END IF |
672 |
|
673 |
!IF (Counter .GE. 400) THEN |
674 |
!Print *, 'Counter=', Counter, 'normDeltaX_int=', normDeltaX_int |
675 |
!Print *, 'DeltaX_int=' |
676 |
!WRITE(*,'(50(1X,F8.2))') DeltaX_int |
677 |
!END IF |
678 |
|
679 |
IF (Mod(Counter,1).EQ.0) THEN |
680 |
!WRITE(*,*) Nat |
681 |
!WRITE(*,*) 'GeomCart in ConvertBakerInternal_cart' |
682 |
DO I=1,Nat |
683 |
! WRITE(*,'(1X,A,I4,3(1X,F12.4))') AtName(I),I,X_Cart_k(1:3,I) |
684 |
END DO |
685 |
END IF |
686 |
|
687 |
!call two_norm(DeltaX_int,normDeltaX_int,3*Nat) |
688 |
END DO !matches DO While (normDeltaX_int .GT. 1d-11) |
689 |
|
690 |
IF (debug) THEN |
691 |
WRITE(*,*) 'GeomCart in ConvertBakerInternal_cart' |
692 |
DO I=1,Nat |
693 |
WRITE(*,'(1X,A,I4,3(1X,F12.4))') AtName(I),I,X_Cart_k(1:3,I) |
694 |
END DO |
695 |
END IF |
696 |
|
697 |
if (debug) THEN |
698 |
WRITE(*,*) "Bmat_bakerT" |
699 |
DO J=1,NCoord |
700 |
WRITE(*,'(50(1X,F12.6))') BMat_BakerT(:,J) |
701 |
END DO |
702 |
END IF |
703 |
|
704 |
|
705 |
|
706 |
!IF (IOptt .GE. 2) THEN |
707 |
! Print *, 'Counter=', Counter |
708 |
!END IF |
709 |
IF (Counter .GE. NbItMax) Then |
710 |
Print *, 'Counter GE 500, Stopping, normDeltaX_int=', normDeltaX_int |
711 |
STOP |
712 |
END IF |
713 |
|
714 |
|
715 |
x(:) = X_cart_k(1,:) |
716 |
y(:) = X_cart_k(2,:) |
717 |
z(:) = X_cart_k(3,:) |
718 |
|
719 |
|
720 |
! call CalcRmsd(Nat,x_k,y_k,z_k,x,y,z,MRot,rmsd,.TRUE.,.TRUE.) |
721 |
|
722 |
|
723 |
if (debug) WRITE(*,*) "COnverted in ",counter," iterations" |
724 |
|
725 |
DEALLOCATE(Geom,DeltaX_int,DeltaX_cart) |
726 |
DEALLOCATE(BprimT,BBT,BBT_inv,UMat_tmp) |
727 |
DEALLOCATE(X_cart_k) |
728 |
DEALLOCATE(GMat,EigVal,EigVec) |
729 |
|
730 |
XPrim=Xprimitive_t |
731 |
|
732 |
if (debug) WRITE(*,*) '=====ConvertBakerInternal_cart Over=====' |
733 |
|
734 |
END SUBROUTINE ConvertBakerInternal_cart |