Statistiques
| Révision :

root / src / Calc_baker.f90 @ 5

Historique | Voir | Annoter | Télécharger (40,28 ko)

1
SUBROUTINE Calc_baker(atome,r_cov,fact,frozen,IGeomRef)
2
  !     
3
  ! This subroutine analyses a geometry to construct the baker
4
  ! delocalized internal coordinates
5
  ! v1.0
6
  ! We use only one geometry
7
  !     
8
  Use Path_module, only : max_Z,NMaxL,Nom,MaxFroz,NFroz,Pi,Massat,a0,BMat_BakerT, &
9
       Nat,NCoord,XyzGeomI,NGeomI,NGeomF,UMat,NPrim,BTransInv, &
10
       IntCoordI,Coordinate,CurrentCoord,ScanCoord,BprimT,BBT, &
11
       BBT_inv,Xprimitive,XPrimitiveF,Symmetry_elimination,UMat_local, &
12
       BTransInv_local, UMatF,BTransInvF,      &
13
       indzmat, dzdc,renum,order,OrderInv
14
  ! BMat_BakerT(3*Nat,NCoord), NCoord=3*Nat or NFree=3*Nat-6-Symmetry_elimination
15
  ! depending upon the coordinate choice. IntCoordI(NGeomI,NCoord) where 
16
  ! UMat(NPrim,NCoord), NCoord number of vectors in UMat matrix, i.e. NCoord
17
  ! Baker coordinates. NPrim is the number of primitive internal coordinates.
18

    
19
  Use Io_module
20
  IMPLICIT NONE
21

    
22
  ! IGeom: Geometry index, IGeomRef: Reference Geometry.
23
  INTEGER(KINT), INTENT(IN) :: atome(Nat),IGeomRef
24
  REAL(KREAL), INTENT(IN) :: fact
25
  REAL(KREAL), INTENT(IN)  :: r_cov(0:Max_Z)
26
  ! Frozen contains the indices of frozen atoms
27
  INTEGER(KINT), INTENT(IN) :: Frozen(*)
28

    
29
  INTEGER(KINT), ALLOCATABLE :: LIAISONS(:,:) ! (Nat,0:NMaxL)
30
  REAL(KREAL), ALLOCATABLE :: Geom(:,:) !(3,Nat)
31
  ! NPrim is the number of primitive coordinates and NCoord is the number
32
  ! of internal coordinates. BMat is actually (NPrim,3*Nat).
33
  REAL(KREAL), ALLOCATABLE :: GMat(:,:) !(NPrim,NPrim)
34
  ! EigVec(..) contains ALL eigevectors of BMat times BprimT, NOT only Baker Coordinate vectors.
35
  REAL(KREAL), ALLOCATABLE :: EigVec(:,:), EigVal(:) ! EigVec(NPrim,NPrim)
36
  REAL(KREAL), ALLOCATABLE :: x(:), y(:), z(:)
37
  REAL(KREAL), ALLOCATABLE :: x_refGeom(:), y_refGeom(:), z_refGeom(:)
38
  !REAL(KREAL), ALLOCATABLE :: V(:,:) ! (3*Nat,3*Nat)
39
  !REAL(KREAL), ALLOCATABLE :: P(:) ! Used in Baker Coordinates: Matrix Inversion
40
  REAL(KREAL), ALLOCATABLE :: UMat_tmp(:,:)
41
  INTEGER(KINT) :: NbBonds, NbAngles, NbDihedrals, IGeom
42

    
43
  real(KREAL) :: vx, vy, vz, Norm
44
  real(KREAL) :: vx1,vy1,vz1,norm1
45
  real(KREAL) :: vx2,vy2,vz2,norm2
46
  real(KREAL) :: vx3,vy3,vz3,norm3
47
  real(KREAL) :: vx4,vy4,vz4,norm4
48
  real(KREAL) :: vx5,vy5,vz5,norm5
49

    
50
  INTEGER(KINT) :: I, J, IAt, K
51
  INTEGER(KINT) :: Kat, Lat, L
52

    
53
  REAL(KREAL) :: sAngleIatIKat, sAngleIIatLat
54

    
55
  LOGICAL :: debug, bond, AddPrimitiveCoord
56

    
57
  INTERFACE
58
     function valid(string) result (isValid)
59
       CHARACTER(*), intent(in) :: string
60
       logical                  :: isValid
61
     END function VALID
62

    
63

    
64
     FUNCTION angle(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2)
65
       use Path_module, only :  Pi,KINT, KREAL
66
       real(KREAL) ::  v1x,v1y,v1z,norm1
67
       real(KREAL) ::  v2x,v2y,v2z,norm2
68
       real(KREAL) ::  angle
69
     END FUNCTION ANGLE
70

    
71

    
72

    
73
     FUNCTION angle_d(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2,v3x,v3y,v3z,norm3)
74
       use Path_module, only :  Pi,KINT, KREAL
75
       real(KREAL) ::  v1x,v1y,v1z,norm1
76
       real(KREAL) ::  v2x,v2y,v2z,norm2
77
       real(KREAL) ::  v3x,v3y,v3z,norm3
78
       real(KREAL) ::  angle_d,ca,sa
79
     END FUNCTION ANGLE_D
80

    
81
 
82

    
83

    
84
     SUBROUTINE Calc_Xprim(nat,x,y,z,Coordinate,NPrim,XPrimitive,XPrimRef)
85
       !     
86
       ! This subroutine uses the description of a list of Coordinates
87
       ! to compute the values of the coordinates for a given geometry.
88
       !
89
!!!!!!!!!!
90
       ! Input:
91
       !   Na: INTEGER, Number of atoms
92
       !  x,y,z(Na): REAL, cartesian coordinates of the considered geometry
93
       ! Coordinate (Pointer(ListCoord)): description of the wanted coordiantes
94
       ! NPrim, INTEGER: Number of coordinates to compute
95
       !
96
       ! Optional: XPrimRef(NPrim) REAL: array that contains coordinates values for
97
       ! a former geometry. Useful for Dihedral angles evolution...
98

    
99
!!!!!!!!!!!
100
       ! Output:
101
       ! XPrimimite(NPrim) REAL: array that will contain the values of the coordinates
102
       !
103
!!!!!!!!!
104

    
105
       Use VarTypes
106
       Use Io_module
107
       Use Path_module, only : pi
108

    
109
       IMPLICIT NONE
110

    
111
       Type (ListCoord), POINTER :: Coordinate
112
       INTEGER(KINT), INTENT(IN) :: Nat,NPrim
113
       REAL(KREAL), INTENT(IN) :: x(Nat), y(Nat), z(Nat)
114
       REAL(KREAL), INTENT(IN), OPTIONAL :: XPrimRef(NPrim) 
115
       REAL(KREAL), INTENT(OUT) :: XPrimitive(NPrim)
116

    
117
     END SUBROUTINE CALC_XPRIM
118
  END INTERFACE
119

    
120
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
121
!
122
!!!!!!!! PFL Debug
123
!
124
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
125
  INTEGER(KINT) :: I1,I2,I3,I4
126
  LOGICAL :: debugPFL
127
  REAL(KREAL), ALLOCATABLE :: val_zmat(:,:)
128
  INTEGER(KINT), ALLOCATABLE :: indzmat0(:,:)
129

    
130

    
131
  debug=valid("Calc_baker")
132
  debugPFL=valid("BakerPFL")
133
  if (debug) WRITE(*,*) "============= Entering Cal_baker =============="
134

    
135
  IF (Nat.le.2) THEN
136
     WRITE(*,*) "I do not work for less than 2 atoms :-p"
137
     RETURN
138
  END IF
139

    
140
  IF (debug) THEN
141
     WRITE(*,*) "DBG Calc_baker, geom"
142
     DO I=1,Nat
143
        WRITE(*,'(1X,I5,":",I3,3(1X,F15.3))') I,atome(I),XyzGeomI(IGeomRef,1:3,I)
144
     END DO
145
  END IF
146

    
147

    
148

    
149

    
150
  ! we construct the list of bonds, valence angles and dihedral angles using this connectivity
151
  ALLOCATE(Coordinate)
152
  NULLIFY(Coordinate%next)
153
  NbBonds=0
154
  NbAngles=0
155
  NbDihedrals=0
156

    
157
  CurrentCoord => Coordinate
158

    
159
  ALLOCATE(Liaisons(Nat,0:NMaxL),Geom(3,Nat),x(Nat),y(Nat),z(Nat))
160
  ALLOCATE(x_refGeom(Nat),y_refGeom(Nat),z_refGeom(Nat))
161

    
162
  x_refGeom(1:Nat) = XyzGeomI(IGeomRef,1,1:Nat)
163
  y_refGeom(1:Nat) = XyzGeomI(IGeomRef,2,1:Nat)
164
  z_refGeom(1:Nat) = XyzGeomI(IGeomRef,3,1:Nat) 
165

    
166
!!!!!!!!!!!!!!!!!!!!
167
     !
168
     !   PFL Debug
169
     !
170
!!!!!!!!!!!!!!!!!!!!
171
     if (debugPFL) THEN
172
        WRITE(*,*) "DBG PFL Calc_BAKER - Calculating Zmat"
173
     if (.not.ALLOCATED(indzmat)) THEN
174
        ALLOCATE(indzmat(Nat,5))
175
     END IF
176
     IF (.NOT.ALLOCATED(DzDc)) THEN
177
        ALLOCATE(DzDc(3,nat,3,Nat))
178
     END IF
179
     IF (.NOT.ALLOCATED(Val_zmat)) THEN
180
        ALLOCATE(val_zmat(nat,3))
181
     END IF
182
     IF (.NOT.ALLOCATED(indzmat0)) THEN
183
        ALLOCATE(indzmat0(nat,5))
184
     END IF
185
! We construct a Zmat
186
          IF (Frozen(1).NE.0) THEN 
187
           Renum=.TRUE.
188
!!! remplcaer indzmat par indzmat0 puis renumerotation
189
           call Calc_zmat_const_frag(Nat,atome,IndZmat0,val_zmat, &
190
             x_refGeom,y_refGeom,z_refGeom, &
191
                r_cov,fact,frozen)
192
        ELSE
193
           !no zmat... we create our own 
194
           call Calc_zmat_frag(Nat,atome,IndZmat0,val_zmat, &
195
             x_refGeom,y_refGeom,z_refGeom, &
196
                r_cov,fact)
197
        END IF
198

    
199
         DO I=1,Nat
200
           Order(IndZmat0(I,1))=I
201
           OrderInv(I)=IndZmat0(I,1)
202
        END DO
203
        IndZmat(1,1)=Order(IndZmat0(1,1))
204
        IndZmat(2,1)=Order(IndZmat0(2,1))
205
        IndZmat(2,2)=Order(IndZmat0(2,2))
206
        IndZmat(3,1)=Order(IndZmat0(3,1))
207
        IndZmat(3,2)=Order(IndZmat0(3,2))
208
        IndZmat(3,3)=Order(IndZmat0(3,3))
209
        DO I=4,Nat
210
           DO J=1,4
211
              IndZmat(I,J)=Order(IndZmat0(I,J))
212
           END DO
213
        end do
214

    
215

    
216
        WRITE(*,*) "DBG PFL CalcBaker, IndZmat0"
217
        DO I=1,Nat
218
            WRITE(*,*) I, indZmat0(I,:)
219
        end do
220

    
221
        WRITE(*,*) "DBG PFL CalcBaker, IndZmat"
222
        DO I=1,Nat
223
            WRITE(*,*) I, indZmat(I,:)
224
        end do
225

    
226

    
227
     DO I=1,Nat
228
        I1=indzmat0(I,1)
229
        I2=indzmat0(I,2)
230
        I3=indzmat0(I,3)
231
        I4=indzmat0(I,4)
232
! Adding BOND between at1 and at2
233
      WRITE(*,*)  "DBG Indzmat",I,I1,I2,I3,I4
234
         if (I2.NE.0) THEN
235
           NbBonds=NbBonds+1
236
    ! values of the coordinate (bond) is calculated for the reference geometry
237
    ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.)
238
    ! are determined using all geometries. vecteur is defined in bib_oper.f
239
                  Call vecteur(I1,I2,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
240
!                  CurrentCoord%value=Norm2
241
                  WRITE(*,'(1X,A,I5,A,2(1X,F12.6))') "Bond",NbBonds," Norm2,val_zmat",Norm2,val_zmat(I,1)
242
                  CurrentCoord%value=val_zmat(I,1)
243
                  CurrentCoord%SignDihedral = 0
244
                  CurrentCoord%At1=I1
245
                  CurrentCoord%At2=I2
246
                  CurrentCoord%Type="BOND"
247
                  IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
248
                     ALLOCATE(CurrentCoord%next)
249
                     NULLIFY(CurrentCoord%next%next)
250
                  END IF
251
                  CurrentCoord => CurrentCoord%next
252
        END IF !IE.NE.0
253
       if (I3.NE.0) THEN
254

    
255
                       NbAngles=NbAngles+1
256
                       ! values of the coordinate (bond) is calculated for the reference geometry
257
                       ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.) are 
258
                       ! determined using all geometries.
259
                       Call vecteur(i2,I3,x_refGeom,y_refGeom,z_refGeom,vx1,vy1,vz1,Norm1)
260
                       Call vecteur(i2,I1,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
261
!                       CurrentCoord%value=angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180.
262
                  WRITE(*,'(1X,A,I5,A,2(1X,F12.6))') "Angle",NbAngles," angle,val_zmat", &
263
                       angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2),val_zmat(I,2)
264
                       CurrentCoord%value=val_zmat(I,2)*Pi/180.
265
                       CurrentCoord%SignDihedral = 0
266
                       CurrentCoord%At1=I1
267
                       CurrentCoord%At2=I2
268
                       CurrentCoord%At3=I3
269
                       CurrentCoord%Type="ANGLE"
270
                       IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
271
                          ALLOCATE(CurrentCoord%next)
272
                          NULLIFY(CurrentCoord%next%next)
273
                       END IF
274
                       CurrentCoord => CurrentCoord%next
275
                    END IF ! matches IF (I3.NE.0)
276
         if (I4.NE.0) THEN
277
                       NbDihedrals=NbDihedrals+1
278
              Call vecteur(I2,I1,x_refGeom,y_refGeom,z_refGeom,vx1,vy1,vz1,Norm1)
279
              Call vecteur(I2,I3,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
280
              Call vecteur(I3,I4,x_refGeom,y_refGeom,z_refGeom,vx3,vy3,vz3,Norm3)
281
                       CALL produit_vect(vx1,vy1,vz1,vx2,vy2,vz2, &
282
                            vx4,vy4,vz4,norm4)
283
                       CALL produit_vect(vx3,vy3,vz3,vx2,vy2,vz2, &
284
                            vx5,vy5,vz5,norm5)
285
!                       CurrentCoord%value=angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, &
286
!                            vx2,vy2,vz2,norm2)*Pi/180.
287
                  WRITE(*,'(1X,A,I5,A,2(1X,F12.6))') "Dihedral",NbDihedrals,    &
288
                       " angle_d,val_zmat", &
289
                       angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, &
290
                       vx2,vy2,vz2,norm2) &
291
                       ,val_zmat(I,3)
292

    
293
                       CurrentCoord%value = val_zmat(I,3)*Pi/180.
294
                       CurrentCoord%SignDihedral = int(sign(1.D0,val_zmat(I,3)))
295
                       CurrentCoord%At1=I1
296
                       CurrentCoord%At2=I2
297
                       CurrentCoord%At3=I3
298
                       CurrentCoord%At4=I4
299
                       CurrentCoord%Type="DIHEDRAL"
300
                       IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
301
                          ALLOCATE(CurrentCoord%next)
302
                          NULLIFY(CurrentCoord%next%next)
303
                       END IF
304
                       CurrentCoord => CurrentCoord%next
305
                    END IF ! matches IF (I4.NE.0)
306
              END DO ! matches DO I=1,Nat
307
      deallocate(indzmat0)
308

    
309
  ELSE !! if (debugPFL)
310

    
311
  DO IGeom=1, NGeomI
312
     !IGeom=1 ! need when using only first geometry.
313
     x(1:Nat) = XyzGeomI(IGeom,1,1:Nat)
314
     y(1:Nat) = XyzGeomI(IGeom,2,1:Nat)
315
     z(1:Nat) = XyzGeomI(IGeom,3,1:Nat) 
316

    
317
     ! First step: we calculate the connectivity
318
     Liaisons=0
319

    
320
     Call CalcCnct(Nat,atome,x,y,z,LIAISONS,r_cov,fact)
321

    
322
     IF (debug) THEN 
323
        WRITE(*,*) 'Connectivity done'
324
        DO I=1,Nat
325
           WRITE(*,'(1X,I5,":",I3,"=",15I4)') I,(Liaisons(I,J),J=0,NMaxL)
326
           WRITE(*,'(1X,I5,":",I3,"=",15I4)') I,(Liaisons(I,:))
327
        END DO
328
        DO I=1,Nat
329
           WRITE(*,'(1X,I5,":",I3," r_cov=",F15.6)') I,atome(I),r_cov(atome(I))
330
        END DO
331
     END IF
332

    
333
     DO I=1,Nat
334
        IF (Liaisons(I,0).NE.0) THEN
335
           DO J=1,Liaisons(I,0)
336
              ! We add the bond
337
              Iat=Liaisons(I,J)
338
              IF (Iat.GT.I) THEN
339
                 ! Checking the uniqueness of bond.
340
                 ! Duplicate bonds should not be added.
341
                 AddPrimitiveCoord=.True.
342
                 ScanCoord=>Coordinate
343
                 DO WHILE (Associated(ScanCoord%next))
344
                    IF (ScanCoord%Type .EQ. 'BOND') THEN
345
                       IF (ScanCoord%At1 .EQ. Iat) THEN
346
                          IF (ScanCoord%At2 .EQ. I) THEN
347
                             AddPrimitiveCoord=.False.
348
                          END IF
349
                       END IF
350
                    END IF
351
                    ScanCoord => ScanCoord%next
352
                 END DO
353

    
354
                 IF (AddPrimitiveCoord) THEN
355
                    NbBonds=NbBonds+1
356
                    ! values of the coordinate (bond) is calculated for the reference geometry
357
                    ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.)
358
                    ! are determined using all geometries. vecteur is defined in bib_oper.f
359
                    Call vecteur(I,Iat,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
360
                    CurrentCoord%value=Norm2
361
                    CurrentCoord%SignDihedral = 0
362
                    CurrentCoord%At1=Iat
363
                    CurrentCoord%At2=I
364
                    CurrentCoord%Type="BOND"
365
                    IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
366
                       ALLOCATE(CurrentCoord%next)
367
                       NULLIFY(CurrentCoord%next%next)
368
                    END IF
369
                    CurrentCoord => CurrentCoord%next
370
                 END IF ! matches IF (AddPrimitiveCoord) THEN
371
              END IF ! matches IF (Iat.GT.I) THEN
372

    
373
              !           Call Annul(Liaisons,IAt,I,Nat,NMaxL)
374
              !           Liaisons(Iat,0)=Liaisons(Iat,0)-1
375

    
376
              ! We add the valence angles
377
              DO K=J+1,Liaisons(I,0)
378
                 Kat=Liaisons(I,K)
379
                 IF (Kat.GT.I) THEN
380
                    ! Checking the uniqueness of valence angle.
381
                    ! Duplicate bonds should not be added.
382
                    AddPrimitiveCoord=.True.
383
                    ScanCoord=>Coordinate
384
                    DO WHILE (Associated(ScanCoord%next))
385
                       IF (ScanCoord%Type .EQ. 'ANGLE') THEN
386
                          IF (ScanCoord%At1 .EQ. Iat) THEN
387
                             IF (ScanCoord%At2 .EQ. I) THEN
388
                                IF (ScanCoord%At3 .EQ. Kat) THEN
389
                                   AddPrimitiveCoord=.False.
390
                                END IF
391
                             END IF
392
                          END IF
393
                       END IF
394
                       ScanCoord => ScanCoord%next
395
                    END DO ! matches DO WHILE (Associated(ScanCoord%next))
396

    
397
                    IF (AddPrimitiveCoord) THEN      
398
                       IF (debug) WRITE(*,*) "Adding angle:",Iat,I,Kat
399
                       NbAngles=NbAngles+1
400
                       ! values of the coordinate (bond) is calculated for the reference geometry
401
                       ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.) are 
402
                       ! determined using all geometries.
403
                       Call vecteur(i,kat,x_refGeom,y_refGeom,z_refGeom,vx1,vy1,vz1,Norm1)
404
                       Call vecteur(i,Iat,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
405
                       CurrentCoord%value=angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180.
406
                       CurrentCoord%SignDihedral = 0
407
                       sAngleIatIKat=abs(sin(angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180.))
408
                       CurrentCoord%At1=Iat
409
                       CurrentCoord%At2=I
410
                       CurrentCoord%At3=KAt
411
                       CurrentCoord%Type="ANGLE"
412
                       IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
413
                          ALLOCATE(CurrentCoord%next)
414
                          NULLIFY(CurrentCoord%next%next)
415
                       END IF
416
                       CurrentCoord => CurrentCoord%next
417
                    END IF ! matches IF (AddPrimitiveCoord) THEN
418
                 ELSE ! matches IF (Kat.GT.I) THEN
419
                    ! Kat is less than I. If there is a bond between I and Kat, then this angle
420
                    ! has already been taken into account.
421
                    if (debug) WRITE(*,*) "Testing angle:",Iat,I,Kat
422
                    Bond=.FALSE.
423
                    DO L=1,Liaisons(Iat,0)
424
                       IF (Liaisons(Iat,L).EQ.Kat) Bond=.TRUE.
425
                    END DO
426
                    IF (.NOT.Bond) THEN
427
                       IF (debug) WRITE(*,*) "Not Bond Adding angle:",Iat,I,Kat
428

    
429
                       ! Checking the uniqueness of valence angle.
430
                       ! Duplicate bonds should not be added.        
431
                       AddPrimitiveCoord=.True.
432
                       ScanCoord=>Coordinate
433
                       DO WHILE (Associated(ScanCoord%next))
434
                          IF (ScanCoord%Type .EQ. 'ANGLE') THEN
435
                             IF (ScanCoord%At1 .EQ. Iat) THEN
436
                                IF (ScanCoord%At2 .EQ. I) THEN
437
                                   IF (ScanCoord%At3 .EQ. Kat) THEN
438
                                      AddPrimitiveCoord=.False.
439
                                   END IF
440
                                END IF
441
                             END IF
442
                          END IF
443
                          ScanCoord => ScanCoord%next
444
                       END DO
445

    
446
                       IF (AddPrimitiveCoord) THEN  
447
                          NbAngles=NbAngles+1
448
                          ! values of the coordinate (bond) is calculated for the reference geometry
449
                          ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.) 
450
                          ! are determined using all geometries.
451
                          Call vecteur(i,kat,x_refGeom,y_refGeom,z_refGeom,vx1,vy1,vz1,Norm1)
452
                          Call vecteur(i,Iat,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
453
                          CurrentCoord%value=angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180.
454
                           CurrentCoord%SignDihedral = 0
455
                          CurrentCoord%At1=Iat
456
                          CurrentCoord%At2=I
457
                          CurrentCoord%At3=KAt
458
                          CurrentCoord%Type="ANGLE"
459
                          IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
460
                             ALLOCATE(CurrentCoord%next)
461
                             NULLIFY(CurrentCoord%next%next)
462
                          END IF
463
                          CurrentCoord => CurrentCoord%next
464
                       END IF  ! matches IF (AddPrimitiveCoord) THEN
465
                    END IF ! matches IF (.NOT.Bond) THEN
466
                 END IF ! matches IF (Kat.GT.I) THEN, after else
467
              END DO ! matches DO K=J+1,Liaisons(I,0)
468
           END DO ! matches DO J=1,Liaisons(I,0)
469
        END IF ! matches IF (Liaisons(I,0).NE.0) THEN
470

    
471
        ! We add dihedral angles. We do not concentrate on necessary angles, ie those that are
472
        ! needed to build the molecule. Instead we collect all of them, and the choice of the best
473
        ! ones will be done when diagonalizing the Baker matrix.
474
        IF (Liaisons(I,0).GE.3) Then
475
           DO J=1,Liaisons(I,0)
476
              Iat=Liaisons(I,J)
477
              ! values of the coordinate (bond) is calculated for the reference geometry
478
              ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.) are 
479
              ! determined using all geometries.
480
              Call vecteur(Iat,i,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
481

    
482
              DO K=J+1,Liaisons(I,0)
483
                 Kat=Liaisons(I,K)
484
                 Call vecteur(i,kat,x_refGeom,y_refGeom,z_refGeom,vx1,vy1,vz1,Norm1)
485
                 sAngleIatIKat=abs(sin(angle(vx1,vy1,vz1,Norm1,-vx2,-vy2,-vz2,Norm2)*Pi/180.))
486

    
487
                 DO L=K+1,Liaisons(I,0)
488
                    Lat=Liaisons(I,L)
489
                    if (debug) WRITE(*,*) "0-Dihe Kat,I,Iat:",Kat,I,Iat,angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)
490
                    Call vecteur(iat,lat,x_refGeom,y_refGeom,z_refGeom,vx3,vy3,vz3,Norm3)
491
                    sAngleIIatLat=abs(sin(angle(vx3,vy3,vz3,Norm3,vx2,vy2,vz2,Norm2)*Pi/180.))
492
                    if (debug) WRITE(*,*) "0-Dihe I,Iat,Lat:",angle(vx3,vy3,vz3,Norm3,vx2,vy2,vz2,Norm2)
493
                    IF ((sAngleIatIKat.ge.0.01d0).AND.(sAngleIIatLat.ge.0.01d0)) THEN
494
                       if (debug) WRITE(*,*) "Adding dihedral:",Kat,I,Iat,Lat
495

    
496
                       ! Checking for the uniqueness of valence angle.
497
                       ! Duplicate bonds should not be added.
498
                       AddPrimitiveCoord=.True.
499
                       ScanCoord=>Coordinate
500
                       DO WHILE (Associated(ScanCoord%next))
501
                          IF (ScanCoord%Type .EQ. 'DIHEDRAL') THEN
502
                             IF (ScanCoord%At1 .EQ. Kat) THEN
503
                                IF (ScanCoord%At2 .EQ. I) THEN
504
                                   IF (ScanCoord%At3 .EQ. Iat) THEN
505
                                      IF (ScanCoord%At4 .EQ. Lat) THEN
506
                                         AddPrimitiveCoord=.False.
507
                                      END IF
508
                                   END IF
509
                                END IF
510
                             END IF
511
                          END IF
512
                          ScanCoord => ScanCoord%next
513
                       END DO ! matches DO WHILE (Associated(ScanCoord%next))
514

    
515
                       ! IF (AddPrimitiveCoord) THEN
516
                       !   NbDihedrals=NbDihedrals+1
517
                       !  CALL produit_vect(vx3,vy3,vz3,vx2,vy2,vz2, &
518
                            !      vx5,vy5,vz5,norm5)
519
                       !CALL produit_vect(vx1,vy1,vz1,vx2,vy2,vz2, &
520
                            !    vx4,vy4,vz4,norm4)
521
                       !         CurrentCoord%value=angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, &
522
                       !             vx2,vy2,vz2,norm2)*Pi/180.
523
                       !          CurrentCoord%SignDihedral = 0
524
                       !       CurrentCoord%At1=Kat
525
                       !      CurrentCoord%At2=I
526
                       !     CurrentCoord%At3=IAt
527
                       !    CurrentCoord%At4=LAt
528
                       !WRITE(*,'(1X,":(dihed 1)",I5," - ",I5," - ",I5," - ",I5," = ",F15.6)') &
529
                       !        ScanCoord%At1,ScanCoord%At2,ScanCoord%At3,ScanCoord%At4,ScanCoord%Value*180./Pi
530
                       !         CurrentCoord%Type="DIHEDRAL"
531
                       !        IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
532
                       !          ALLOCATE(CurrentCoord%next)
533
                       !         NULLIFY(CurrentCoord%next%next)
534
                       !     END IF
535
                       !    CurrentCoord => CurrentCoord%next
536
                       !END IF ! matches IF (AddPrimitiveCoord) THEN
537

    
538
                    END IF ! matches IF ((sAngleIatIKat.ge.0.01d0).AND.(sAngleIIatLat.ge.0.01d0)) THEN
539
                 END DO ! matches DO L=K+1,Liaisons(I,0)
540
              END DO ! matches DO K=J+1,Liaisons(I,0)
541
           END DO ! matches DO J=1,Liaisons(I,0)
542
        END IF !matches  IF (Liaisons(I,0).GE.3) Then
543

    
544
        ! we now add other dihedrals
545
        DO J=1,Liaisons(I,0)
546
           Iat=Liaisons(I,J)
547
           If (Iat.LE.I) Cycle
548
           ! values of the coordinate (bond) is calculated for the reference geometry
549
           ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.) are 
550
           ! determined using all geometries.
551
           Call vecteur(Iat,i,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
552

    
553
           DO K=1,Liaisons(I,0)
554
              IF (Liaisons(I,K).EQ.Iat) Cycle 
555
              Kat=Liaisons(I,K)
556
              Call vecteur(i,kat,x_refGeom,y_refGeom,z_refGeom,vx1,vy1,vz1,Norm1)
557
              sAngleIatIKat=abs(sin(angle(vx1,vy1,vz1,Norm1,-vx2,-vy2,-vz2,Norm2)*Pi/180.))
558

    
559
              DO L=1,Liaisons(Iat,0)
560
                 Lat=Liaisons(Iat,L)
561
                 IF (Lat.eq.I) Cycle
562

    
563
                 if (debug) WRITE(*,*) "Dihe Kat,I,Iat:",angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2),sAngleIatIKat
564
                 Call vecteur(iat,lat,x_refGeom,y_refGeom,z_refGeom,vx,vy,vz,Norm)
565

    
566
                 sAngleIIatLat=abs(sin(angle(vx,vy,vz,Norm,vx2,vy2,vz2,Norm2)*Pi/180.))
567
                 if (debug) WRITE(*,*) "Dihe I,Iat,Lat:",angle(vx,vy,vz,Norm,vx2,vy2,vz2,Norm2)
568
                 ! we add the dihedral angle Kat-I-Iat-Lat
569
                 if (debug) WRITE(*,*) "Trying dihedral:",Kat,I,Iat,Lat,sAngleIatIKat,sAngleIIatLat
570
                 IF ((Lat.NE.Kat).AND.(Lat.Ne.I).AND.(sAngleIatIKat.ge.0.01d0) &
571
                      .AND.(sAngleIIatLat.ge.0.01d0)) THEN
572
                    if (debug) WRITE(*,*) "Adding dihedral:",Kat,I,Iat,Lat
573

    
574
                    ! Checking for the uniqueness of valence angle.
575
                    ! Duplicate bonds should not be added.
576
                    AddPrimitiveCoord=.True.
577
                    ScanCoord=>Coordinate
578
                    DO WHILE (Associated(ScanCoord%next))
579
                       IF (ScanCoord%Type .EQ. 'DIHEDRAL') THEN
580
                          IF (ScanCoord%At1 .EQ. Kat) THEN
581
                             IF (ScanCoord%At2 .EQ. I) THEN
582
                                IF (ScanCoord%At3 .EQ. Iat) THEN
583
                                   IF (ScanCoord%At4 .EQ. Lat) THEN
584
                                      AddPrimitiveCoord=.False.
585
                                   END IF
586
                                END IF
587
                             END IF
588
                          END IF
589
                       END IF
590
                       ScanCoord => ScanCoord%next
591
                    END DO
592

    
593
                    IF (AddPrimitiveCoord) THEN
594
                       NbDihedrals=NbDihedrals+1
595
                       Call vecteur(iat,lat,x_refGeom,y_refGeom,z_refGeom,vx3,vy3,vz3,Norm3)
596
                       CALL produit_vect(vx3,vy3,vz3,vx2,vy2,vz2, &
597
                            vx5,vy5,vz5,norm5)
598
                       CALL produit_vect(vx1,vy1,vz1,vx2,vy2,vz2, &
599
                            vx4,vy4,vz4,norm4)
600
                       CurrentCoord%value=angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, &
601
                            vx2,vy2,vz2,norm2)*Pi/180.
602
                       CurrentCoord%At1=Kat
603
                       CurrentCoord%At2=I
604
                       CurrentCoord%At3=IAt
605
                       CurrentCoord%At4=LAt
606
                       CurrentCoord%Type="DIHEDRAL"
607
                       CurrentCoord%SignDihedral=int(sign(1.d0,angle_d(vx4,vy4,vz4,norm4,   &
608
                            vx5,vy5,vz5,norm5, vx2,vy2,vz2,norm2)))
609
                       WRITE(*,'(1X,":(dihed 2)",I5," - ",I5," - ",I5," - ",I5," = ",F15.6)') ScanCoord%At1,&
610
                            ScanCoord%At2, ScanCoord%At3,ScanCoord%At4,ScanCoord%Value*180./Pi
611
                       IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
612
                          ALLOCATE(CurrentCoord%next)
613
                          NULLIFY(CurrentCoord%next%next)
614
                       END IF
615
                       CurrentCoord => CurrentCoord%next
616
                    END IF ! matches IF (AddPrimitiveCoord) THEN
617
                 END IF ! matches IF ((Lat.NE.Kat).AND.(Lat.Ne.I).AND.(sAngleIatIKat.ge.0.01d0) .....
618
              END DO ! matches DO L=1,Liaisons(Iat,0)
619
           END DO ! matches DO K=1,Liaisons(I,0)
620
        END DO ! matches DO J=1,Liaisons(I,0)
621
     END DO ! end of loop over all atoms, DO I=1, Nat
622
  END DO ! matches DO IGeom=1, NGeomI
623

    
624

    
625

    
626
 END IF ! if (debugPFL)
627
  DEALLOCATE(Liaisons)
628

    
629
  WRITE(*,*) "I have found"
630
  WRITE(*,*) NbBonds, " bonds"
631
  WRITE(*,*) NbAngles, " angles"
632
  WRITE(*,*) NbDihedrals, " dihedrals"
633

    
634
  WRITE(*,*) 'All in all...'
635
  ScanCoord=>Coordinate
636
  I=0
637
  DO WHILE (Associated(ScanCoord%next))
638
     I=I+1
639
     SELECT CASE (ScanCoord%Type)
640
     CASE ('BOND')
641
        !WRITE(IOOUT,'(1X,I3,":",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,ScanCoord%At2,ScanCoord%Value
642
        WRITE(*,'(1X,I3,":(bond )",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,ScanCoord%At2,ScanCoord%Value
643
     CASE ('ANGLE')
644
        !WRITE(IOOUT,'(1X,I3,":",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1, &
645
        !    ScanCoord%At2, ScanCoord%At3,ScanCoord%Value*180./Pi
646
        WRITE(*,'(1X,I3,":(angle)",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1, &
647
             ScanCoord%At2, ScanCoord%At3,ScanCoord%Value*180./Pi   
648
     CASE ('DIHEDRAL')
649
        !WRITE(IOOUT,'(1X,I3,":",I5," - ",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,&
650
        !    ScanCoord%At2, ScanCoord%At3,ScanCoord%At4,ScanCoord%Value*180./Pi
651
        WRITE(*,'(1X,I3,":(dihed)",I5," - ",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,&
652
             ScanCoord%At2, ScanCoord%At3,ScanCoord%At4,ScanCoord%Value*180./Pi
653
     END SELECT
654
     ScanCoord => ScanCoord%next
655
  END DO
656

    
657
  ! NPrim is the number of primitive coordinates.
658
  NPrim=NbBonds+NbAngles+NbDihedrals
659

    
660
  ! Now calculating values of all primitive bonds for all geometries:
661
  ALLOCATE(Xprimitive(NgeomI,NPrim),XPrimitiveF(NGeomF,NPrim))
662
  ALLOCATE(UMatF(NGeomF,NPrim,NCoord))
663
  ALLOCATE(BTransInvF(NGeomF,NCoord,3*Nat))
664

    
665
! We calculate the Primitive values for the first geometry, this plays a special role
666
! as it will serve as a reference for other geometries !
667

    
668
  x(1:Nat) = XyzGeomI(1,1,1:Nat)
669
  y(1:Nat) = XyzGeomI(1,2,1:Nat)
670
  z(1:Nat) = XyzGeomI(1,3,1:Nat)
671

    
672
  Call Calc_Xprim(nat,x,y,z,Coordinate,NPrim,XPrimitive(1,:))
673

    
674
  DO IGeom=2, NGeomI
675

    
676
        x(1:Nat) = XyzGeomI(IGeom,1,1:Nat)
677
        y(1:Nat) = XyzGeomI(IGeom,2,1:Nat)
678
        z(1:Nat) = XyzGeomI(IGeom,3,1:Nat)
679

    
680
        Call Calc_Xprim(nat,x,y,z,Coordinate,NPrim,XPrimitive(IGeom,:),Xprimitive(1,:))
681

    
682
!      ScanCoord=>Coordinate
683
!      I=0 ! index for the NPrim (NPrim is the number of primitive coordinates).
684
!      DO WHILE (Associated(ScanCoord%next))
685
!         I=I+1
686
!         SELECT CASE (ScanCoord%Type)
687
!         CASE ('BOND')
688
!            Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx2,vy2,vz2,Norm2)
689
!            Xprimitive(IGeom,I) = Norm2  
690
!         CASE ('ANGLE')
691
!            Call vecteur(ScanCoord%At2,ScanCoord%At3,x,y,z,vx1,vy1,vz1,Norm1)
692
!            Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx2,vy2,vz2,Norm2)
693
!            Xprimitive(IGeom,I) = angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180.
694
!         CASE ('DIHEDRAL')
695

    
696

    
697
!            Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx1,vy1,vz1,Norm1)
698
!            Call vecteur(ScanCoord%At2,ScanCoord%At3,x,y,z,vx2,vy2,vz2,Norm2)
699
!            Call vecteur(ScanCoord%At3,ScanCoord%At4,x,y,z,vx3,vy3,vz3,Norm3)
700
!            Call produit_vect(vx1,vy1,vz1,vx2,vy2,vz2, &
701
!                 vx4,vy4,vz4,norm4)
702
!            Call produit_vect(vx3,vy3,vz3,vx2,vy2,vz2, &
703
!                 vx5,vy5,vz5,norm5)
704

    
705
!                  DiheTmp= angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, &
706
!                          vx2,vy2,vz2,norm2)
707
!                  Xprimitive(IGeom,I) = DiheTmp*Pi/180.
708
! ! We treat large dihedral angles differently as +180=-180 mathematically and physically
709
! ! but this causes lots of troubles when converting baker to cart.
710
! ! So we ensure that large dihedral angles always have the same sign
711
!                     if (abs(ScanCoord%SignDihedral).NE.1) THEN
712
!                         ScanCoord%SignDihedral=Int(Sign(1.D0,DiheTmp))
713
!                     ELSE
714
!                         If ((abs(DiheTmp).GE.170.D0).AND.(Sign(1.,DiheTmp)*ScanCoord%SignDihedral<0)) THEN
715
!                           Xprimitive(IGeom,I) = DiheTmp*Pi/180.+ ScanCoord%SignDihedral*2.*Pi
716
!                        END IF
717
!                   END IF
718
! ! Another test... will all this be consistent ??? 
719
! ! We want the shortest path, so we check that the change in dihedral angles is less than Pi:
720
!                   IF (IGeom.GT.1) THEN
721
!                      IF (abs(Xprimitive(IGeom,I)-XPrimitive(IGeom-1,I)).GE.Pi) THEN
722
!                         if ((Xprimitive(IGeom,I)-XPrimitive(IGeom-1,I)).GE.Pi) THEN
723
!                            Xprimitive(IGeom,I)=Xprimitive(IGeom,I)-2.d0*Pi
724
!                         ELSE
725
!                            Xprimitive(IGeom,I)=Xprimitive(IGeom,I)+2.d0*Pi
726
!                         END IF
727
!                      END IF
728
!                   END IF
729
!         END SELECT
730
!         ScanCoord => ScanCoord%next
731
!      END DO ! matches DO WHILE (Associated(ScanCoord%next))
732
  END DO ! matches DO IGeom=1, NGeomI
733

    
734
  IF (debug) THEN
735
     WRITE(*,*) "DBG Calc_Baker Xprimitives for all geometries"
736
  DO IGeom=1, NGeomI
737
     WRITE(*,*) "Geometry ",IGeom
738
     ScanCoord=>Coordinate
739
     I=0 ! index for the NPrim (NPrim is the number of primitive coordinates).
740
     DO WHILE (Associated(ScanCoord%next))
741
        I=I+1
742
        SELECT CASE (ScanCoord%Type)
743
        CASE ('BOND')
744
           WRITE(*,'(1X,I3,":",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,ScanCoord%At2,Xprimitive(IGeom,I)
745
        CASE ('ANGLE')
746
           WRITE(*,'(1X,I3,":",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1, &
747
            ScanCoord%At2, ScanCoord%At3,Xprimitive(IGeom,I)*180./Pi
748
        CASE ('DIHEDRAL')
749
           WRITE(*,'(1X,I3,":",I5," - ",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,&
750
           ScanCoord%At2, ScanCoord%At3,ScanCoord%At4,Xprimitive(IGeom,I)*180./Pi
751
        END SELECT
752
        ScanCoord => ScanCoord%next
753
     END DO ! matches DO WHILE (Associated(ScanCoord%next))
754
  END DO ! matches DO IGeom=1, NGeomI
755
  END IF
756
  ! Here reference geometry is assigned to Geom. Earlier x,y,z(Nat) were assigned from XyzGeomI(...)
757
  ! before the call of this (Calc_baker) subroutine and passed to this subroutine as arguments of the
758
  ! subroutine.
759
! PFL 19 Feb 2008 ->
760
! In order to reproduce the B matrix in the Baker article, one has
761
! to divide Geom by a0. 
762
! However, this is inconsitent with our way of storing geometries
763
! so we do not do it !
764

    
765
  Geom(1,:)=XyzGeomI(IGeomRef,1,1:Nat) ! XyzGeomI(NGeomI,3,Nat)
766
  Geom(2,:)=XyzGeomI(IGeomRef,2,1:Nat)
767
  Geom(3,:)=XyzGeomI(IGeomRef,3,1:Nat)
768

    
769
! <- PFL 19 Feb 2008
770

    
771
  ! We now have to compute dq/dx...
772
  ALLOCATE(BprimT(3*Nat,NPrim))
773
  BprimT=0.d0
774

    
775
  ScanCoord=>Coordinate
776
  I=0
777
  DO WHILE (Associated(ScanCoord%next))
778
     I=I+1
779
     SELECT CASE (ScanCoord%Type)
780
     CASE ('BOND') 
781
        CALL CONSTRAINTS_BONDLENGTH_DER(Nat,ScanCoord%at1,ScanCoord%AT2, &
782
             Geom,BprimT(1,I))
783
     CASE ('ANGLE')
784
        CALL CONSTRAINTS_BONDANGLE_DER(Nat,ScanCoord%At1,ScanCoord%AT2, &
785
             ScanCoord%At3,Geom,BprimT(1,I))
786
     CASE ('DIHEDRAL')
787
        CALL CONSTRAINTS_TORSION_DER2(Nat,ScanCoord%At1,ScanCoord%AT2, &
788
             ScanCoord%At3,ScanCoord%At4,Geom,BprimT(1,I))
789
!        CALL CONSTRAINTS_TORSION_DER(Nat,ScanCoord%At1,ScanCoord%AT2, &
790
!             ScanCoord%At3,ScanCoord%At4,Geom,BprimT(1,I))
791

    
792
     END SELECT
793
     ScanCoord => ScanCoord%next
794
  END DO
795

    
796

    
797
!!!!!!!!!!!!!!!!!!!!
798
     !
799
     !   PFL Debug
800
     !
801
!!!!!!!!!!!!!!!!!!!!
802

    
803
     if (debugPFL) THEN
804
        WRITe(*,*) "DBG PFL Calc_Baker ====="
805
     DzDc=0.d0
806
     WRITE(*,*) "PFL DBG, DzdC"
807
  do I=1,Nat
808
  Geom(1,i)=XyzGeomI(IGeomRef,1,orderInv(i)) ! XyzGeomI(NGeomI,3,Nat)
809
  Geom(2,i)=XyzGeomI(IGeomRef,2,OrderInv(i))
810
  Geom(3,i)=XyzGeomI(IGeomRef,3,OrderInv(i))
811
  WRITE(*,*) I,OrderInv(I),Geom(:,I)
812
    end do
813
     CALL CalcBMat_int (nat, Geom, indzmat, dzdc, massat,atome)     
814

    
815
     WRITE(*,*) "PFL DBG, BPrimT"
816
     DO I=1,NPrim
817
        WRITE(*,'(50(1X,F12.6))') BPrimT(:,I)
818
     END DO
819
        WRITe(*,*) "DBG PFL Calc_Baker ====="
820
     END IF
821

    
822
!!!!!!!!!!!!!!!!!!!!
823
     !
824
     !   PFL Debug
825
     !
826
!!!!!!!!!!!!!!!!!!!!
827

    
828
  DEALLOCATE(Geom)
829

    
830
  ! BprimT(3*Nat,NPrim)
831
  ! We now compute G=B(BT) matrix
832
  ALLOCATE(Gmat(NPrim,NPrim))
833
  GMat=0.d0
834
  DO I=1,NPrim
835
     DO J=1,3*Nat
836
        GMat(:,I)=Gmat(:,I)+BprimT(J,:)*BprimT(J,I) !*1.d0/mass(atome(int(K/3.d0)))
837
     END DO
838
  END DO
839

    
840
!!!!!!!!!!!!!!!!!!!!
841
     !
842
     !   PFL Debug --->
843
     !
844
!!!!!!!!!!!!!!!!!!!!
845
    if (debugPFL) THEN
846
  GMat=0.d0
847
  DO I=1,NPrim
848
        GMat(I,I)=1.
849
  END DO
850
   END IF
851

    
852
!!!!!!!!!!!!!!!!!!!!
853
     !
854
     !  <--- PFL Debug
855
     !
856
!!!!!!!!!!!!!!!!!!!!
857

    
858
  !DO I=1,NPrim
859
  !  WRITE(*,'(20(1X,F6.3))') GMat(1:min(20,NPrim),I)
860
  !END DO
861

    
862
  ! We diagonalize G
863
  ALLOCATE(EigVal(NPrim),EigVec(NPrim,NPrim))
864
  Call Jacobi(GMat,NPrim,EigVal,EigVec,NPrim)
865
  Call Trie(NPrim,EigVal,EigVec,NPrim)
866
  DO I=1,NPrim
867
     WRITE(*,'(1X,"Vector ",I3,": e=",F8.3)') I,EigVal(i)
868
     WRITE(*,'(20(1X,F8.4))') EigVec(1:min(20,NPrim),I)
869
  END DO
870

    
871
  !DO I=1,NPrim
872
  ! WRITE(*,'(1X,"Vector ",I3,(20(F8.3)))') I,EigVec(1:min(20,NPrim),I)
873
  ! END DO
874

    
875
  !DO I=1,NPrim
876
  !  WRITE(*,'(1X,"Vector ",I3,F8.3,F8.3,F8.3,F8.3,F8.3,F8.3,F8.3,F8.3,F8.3,F8.3,F8.3,F8.3,&
877
  ! F8.3,F8.3,F8.3,F8.3,F8.3)') I,EigVec(1,I),EigVec(4,I),EigVec(6,I),EigVec(14,I),EigVec(16,I),&
878
  !EigVec(2,I),EigVec(3,I),EigVec(5,I),EigVec(12,I),EigVec(13,I),EigVec(15,I),EigVec(7,I),&
879
       !EigVec(8,I),EigVec(9,I),EigVec(10,I),EigVec(11,I),EigVec(17,I)
880
  !END DO
881

    
882
  ! We construct the new DzDc(b=baker) matrix
883
  ! UMat is nonredundant vector set, i.e. set of eigenvectors of BB^T corresponding
884
  ! to eigenvalues > zero.
885
  ALLOCATE(UMat(NPrim,NCoord))
886
  ALLOCATE(UMat_local(NPrim,NCoord))
887
  ALLOCATE(UMat_tmp(NPrim,3*Nat-6))
888
  ! BMat_BakerT(3*Nat,NCoord), allocated in Path.f90, 
889
  ! NCoord=3*Nat-6
890
  BMat_BakerT = 0.d0
891
  J=0
892
  UMat=0.d0
893
  UMat_tmp=0.d0
894
  DO I=1,NPrim
895
     IF (abs(eigval(I))>=1e-6) THEN
896
        J=J+1
897
        DO K=1,NPrim
898
           !DzDcb(:,J)=DzDcb(:,J)+Eigvec(K,I)*BprimT(:,K) ! original
899
           ! BprimT is transpose of B^prim.
900
           ! B = UMat^T B^prim, B^T = (B^prim)^T UMat
901
           BMat_BakerT(:,J)=BMat_BakerT(:,J)+BprimT(:,K)*Eigvec(K,I)
902
           !Dzdcb(:,J)=DzDcb(:,J)+Eigvec(K,:)*BprimT(I,K)       
903
        END DO
904
        IF(J .GT. 3*Nat-6) THEN
905
           WRITE(*,*) 'Number of vectors in Eigvec with eigval .GT. 1e-6(=UMat) (=' &
906
                ,J,') exceeded 3*Nat-6=',3*Nat-6, &
907
                'Stopping the calculation.'
908
           STOP
909
        END IF
910
        UMat_tmp(:,J) =  Eigvec(:,I)
911
     END IF
912
  END DO
913

    
914
  if (debug) THEN
915
     WRITE(*,*) "DBG Calc_Baker: UMat"
916
     DO I=1,3*Nat-6
917
        WRITE(*,'(50(1X,F12.8))') UMat_tmp(:,I)
918
     END DO
919
  END IF
920

    
921
  ! THIS IS TO BE CORRECTED:
922
  UMat = UMat_tmp
923
  !J=0
924
  !DO I=1, 3*Nat-6
925
  !  IF ((I .NE. 6) .AND. (I .NE. 7) .AND. (I .NE. 9)) Then
926
  !   J=J+1
927
  !  Print *, 'J=', J, ' I=', I
928
  ! UMat(:,J) = UMat_tmp(:,I)
929
  !END IF
930
  !END DO
931
  ! BMat_BakerT=0.d0
932
  !DO I=1,NCoord
933
  !  DO J=1,NPrim
934
  ! B = UMat^T B^prim, B^T = (B^prim)^T UMat
935
  !   BMat_BakerT(:,I)=BMat_BakerT(:,I)+BprimT(:,J)*UMat(J,I)
936
  !    END DO
937
  !END DO
938
  ! TO BE CORRECTED, ENDS HERE.
939

    
940
  IntCoordI=0.d0
941
  DO IGeom=1, NGeomI
942
     DO I=1, NPrim
943
        ! Transpose of UMat is needed below, that is why UMat(I,:).
944
        IntCoordI(IGeom,:) = IntCoordI(IGeom,:) + UMat(I,:)*Xprimitive(IGeom,I)
945
     END DO
946
  END DO
947

    
948
  if (debug) THEN
949
     WRITE(*,*) "DBG Calc_Baker IntCoordI"
950
     DO IGeom=1, NGeomI
951
        WRITE(*,'(1X,I5,":",30(1X,F10.6))') IGeom,IntCoordI(IGeom,:)
952
     END DO
953
  END IF
954

    
955

    
956
  ! the following might be used to get rid of some coordinates that 
957
  ! do not respect the symmetry of the problem.
958

    
959
  ! ! We look at the group symmetry of the molecule. Nothing complicate here
960
  ! ! we just look for planar symmetry.
961
  ! ! We first place it into the standard orientation
962
  !   Call Std_ori(Nat,x,y,z,a,b,c,massat)
963

    
964
  ! ! Is the molecule planar
965
  !   DO I=1,Nat
966
  !      WRITE(*,*) nom(atome(i)),x(i),y(i),z(i)
967
  !      END DO
968
  DEALLOCATE(BprimT,GMat,EigVal,EigVec) ! BprimT is B^prim^T
969
  ! Calculation of BTransInv starts here:
970
  ! Calculation of BBT(3*Nat-6,3*Nat-6)=BB^T:
971
  ! BMat_BakerT(3*Nat,NCoord) is Transpose of B = UMat^TB^prim
972
  ALLOCATE(BBT(NCoord,NCoord))
973
  BBT = 0.d0
974
  DO I=1, NCoord
975
     DO J=1, 3*Nat
976
        ! BBT(:,I) forms BB^T
977
        BBT(:,I) = BBT(:,I) + BMat_BakerT(J,:)*BMat_BakerT(J,I)
978
     END DO
979
  END DO
980

    
981
  !ALLOCATE(V(3*Nat,3*Nat))
982
  !Call GINVSE(BBT,3*Nat,3*Nat,BBT_inv,3*Nat,3*Nat,3*Nat,1e-6,V,3*Nat,FAIL,NOUT)
983
  !DEALLOCATE(V)
984
  ALLOCATE(BBT_inv(NCoord,NCoord))
985
  ! GenInv is in Mat_util.f90
986
  Call GenInv(NCoord,BBT,BBT_inv,NCoord)
987

    
988
  ! Calculation of (B^T)^-1 = (BB^T)^-1B:
989
  !ALLOCATE(BTransInv(3*Nat-6,3*Nat))    ! allocated in Path.f90
990
  BTransInv = 0.d0
991
  DO I=1, 3*Nat
992
     DO J=1, NCoord
993
        BTransInv(:,I) = BTransInv(:,I) + BBT_inv(:,J)*BMat_BakerT(I,J)
994
     END DO
995
  END DO
996
  BTransInv_local = BTransInv
997
  UMat_local = UMat
998
  DEALLOCATE(BBT,BBT_inv,UMat_tmp)
999
  DEALLOCATE(x_refGeom,y_refGeom,z_refGeom,x,y,z)
1000
  IF (debug) WRITE(*,*) "DBG Calc_baker over."
1001
END SUBROUTINE Calc_baker