Statistiques
| Révision :

root / src / Calc_baker.f90 @ 5

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

1 1 pfleura2
SUBROUTINE Calc_baker(atome,r_cov,fact,frozen,IGeomRef)
2 1 pfleura2
  !
3 1 pfleura2
  ! This subroutine analyses a geometry to construct the baker
4 1 pfleura2
  ! delocalized internal coordinates
5 1 pfleura2
  ! v1.0
6 1 pfleura2
  ! We use only one geometry
7 1 pfleura2
  !
8 1 pfleura2
  Use Path_module, only : max_Z,NMaxL,Nom,MaxFroz,NFroz,Pi,Massat,a0,BMat_BakerT, &
9 1 pfleura2
       Nat,NCoord,XyzGeomI,NGeomI,NGeomF,UMat,NPrim,BTransInv, &
10 1 pfleura2
       IntCoordI,Coordinate,CurrentCoord,ScanCoord,BprimT,BBT, &
11 1 pfleura2
       BBT_inv,Xprimitive,XPrimitiveF,Symmetry_elimination,UMat_local, &
12 1 pfleura2
       BTransInv_local, UMatF,BTransInvF,      &
13 1 pfleura2
       indzmat, dzdc,renum,order,OrderInv
14 1 pfleura2
  ! BMat_BakerT(3*Nat,NCoord), NCoord=3*Nat or NFree=3*Nat-6-Symmetry_elimination
15 1 pfleura2
  ! depending upon the coordinate choice. IntCoordI(NGeomI,NCoord) where
16 1 pfleura2
  ! UMat(NPrim,NCoord), NCoord number of vectors in UMat matrix, i.e. NCoord
17 1 pfleura2
  ! Baker coordinates. NPrim is the number of primitive internal coordinates.
18 1 pfleura2
19 1 pfleura2
  Use Io_module
20 1 pfleura2
  IMPLICIT NONE
21 1 pfleura2
22 1 pfleura2
  ! IGeom: Geometry index, IGeomRef: Reference Geometry.
23 1 pfleura2
  INTEGER(KINT), INTENT(IN) :: atome(Nat),IGeomRef
24 1 pfleura2
  REAL(KREAL), INTENT(IN) :: fact
25 1 pfleura2
  REAL(KREAL), INTENT(IN)  :: r_cov(0:Max_Z)
26 1 pfleura2
  ! Frozen contains the indices of frozen atoms
27 1 pfleura2
  INTEGER(KINT), INTENT(IN) :: Frozen(*)
28 1 pfleura2
29 1 pfleura2
  INTEGER(KINT), ALLOCATABLE :: LIAISONS(:,:) ! (Nat,0:NMaxL)
30 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: Geom(:,:) !(3,Nat)
31 1 pfleura2
  ! NPrim is the number of primitive coordinates and NCoord is the number
32 1 pfleura2
  ! of internal coordinates. BMat is actually (NPrim,3*Nat).
33 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: GMat(:,:) !(NPrim,NPrim)
34 1 pfleura2
  ! EigVec(..) contains ALL eigevectors of BMat times BprimT, NOT only Baker Coordinate vectors.
35 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: EigVec(:,:), EigVal(:) ! EigVec(NPrim,NPrim)
36 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: x(:), y(:), z(:)
37 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: x_refGeom(:), y_refGeom(:), z_refGeom(:)
38 1 pfleura2
  !REAL(KREAL), ALLOCATABLE :: V(:,:) ! (3*Nat,3*Nat)
39 1 pfleura2
  !REAL(KREAL), ALLOCATABLE :: P(:) ! Used in Baker Coordinates: Matrix Inversion
40 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: UMat_tmp(:,:)
41 1 pfleura2
  INTEGER(KINT) :: NbBonds, NbAngles, NbDihedrals, IGeom
42 1 pfleura2
43 2 pfleura2
  real(KREAL) :: vx, vy, vz, Norm
44 1 pfleura2
  real(KREAL) :: vx1,vy1,vz1,norm1
45 1 pfleura2
  real(KREAL) :: vx2,vy2,vz2,norm2
46 1 pfleura2
  real(KREAL) :: vx3,vy3,vz3,norm3
47 1 pfleura2
  real(KREAL) :: vx4,vy4,vz4,norm4
48 1 pfleura2
  real(KREAL) :: vx5,vy5,vz5,norm5
49 1 pfleura2
50 2 pfleura2
  INTEGER(KINT) :: I, J, IAt, K
51 2 pfleura2
  INTEGER(KINT) :: Kat, Lat, L
52 1 pfleura2
53 1 pfleura2
  REAL(KREAL) :: sAngleIatIKat, sAngleIIatLat
54 1 pfleura2
55 2 pfleura2
  LOGICAL :: debug, bond, AddPrimitiveCoord
56 1 pfleura2
57 1 pfleura2
  INTERFACE
58 1 pfleura2
     function valid(string) result (isValid)
59 1 pfleura2
       CHARACTER(*), intent(in) :: string
60 1 pfleura2
       logical                  :: isValid
61 1 pfleura2
     END function VALID
62 1 pfleura2
63 1 pfleura2
64 1 pfleura2
     FUNCTION angle(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2)
65 1 pfleura2
       use Path_module, only :  Pi,KINT, KREAL
66 1 pfleura2
       real(KREAL) ::  v1x,v1y,v1z,norm1
67 1 pfleura2
       real(KREAL) ::  v2x,v2y,v2z,norm2
68 1 pfleura2
       real(KREAL) ::  angle
69 1 pfleura2
     END FUNCTION ANGLE
70 1 pfleura2
71 1 pfleura2
72 1 pfleura2
73 1 pfleura2
     FUNCTION angle_d(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2,v3x,v3y,v3z,norm3)
74 1 pfleura2
       use Path_module, only :  Pi,KINT, KREAL
75 1 pfleura2
       real(KREAL) ::  v1x,v1y,v1z,norm1
76 1 pfleura2
       real(KREAL) ::  v2x,v2y,v2z,norm2
77 1 pfleura2
       real(KREAL) ::  v3x,v3y,v3z,norm3
78 1 pfleura2
       real(KREAL) ::  angle_d,ca,sa
79 1 pfleura2
     END FUNCTION ANGLE_D
80 1 pfleura2
81 1 pfleura2
82 1 pfleura2
83 1 pfleura2
84 1 pfleura2
     SUBROUTINE Calc_Xprim(nat,x,y,z,Coordinate,NPrim,XPrimitive,XPrimRef)
85 1 pfleura2
       !
86 1 pfleura2
       ! This subroutine uses the description of a list of Coordinates
87 1 pfleura2
       ! to compute the values of the coordinates for a given geometry.
88 1 pfleura2
       !
89 1 pfleura2
!!!!!!!!!!
90 1 pfleura2
       ! Input:
91 1 pfleura2
       !   Na: INTEGER, Number of atoms
92 1 pfleura2
       !  x,y,z(Na): REAL, cartesian coordinates of the considered geometry
93 1 pfleura2
       ! Coordinate (Pointer(ListCoord)): description of the wanted coordiantes
94 1 pfleura2
       ! NPrim, INTEGER: Number of coordinates to compute
95 1 pfleura2
       !
96 1 pfleura2
       ! Optional: XPrimRef(NPrim) REAL: array that contains coordinates values for
97 1 pfleura2
       ! a former geometry. Useful for Dihedral angles evolution...
98 1 pfleura2
99 1 pfleura2
!!!!!!!!!!!
100 1 pfleura2
       ! Output:
101 1 pfleura2
       ! XPrimimite(NPrim) REAL: array that will contain the values of the coordinates
102 1 pfleura2
       !
103 1 pfleura2
!!!!!!!!!
104 1 pfleura2
105 1 pfleura2
       Use VarTypes
106 1 pfleura2
       Use Io_module
107 1 pfleura2
       Use Path_module, only : pi
108 1 pfleura2
109 1 pfleura2
       IMPLICIT NONE
110 1 pfleura2
111 1 pfleura2
       Type (ListCoord), POINTER :: Coordinate
112 1 pfleura2
       INTEGER(KINT), INTENT(IN) :: Nat,NPrim
113 1 pfleura2
       REAL(KREAL), INTENT(IN) :: x(Nat), y(Nat), z(Nat)
114 1 pfleura2
       REAL(KREAL), INTENT(IN), OPTIONAL :: XPrimRef(NPrim)
115 1 pfleura2
       REAL(KREAL), INTENT(OUT) :: XPrimitive(NPrim)
116 1 pfleura2
117 1 pfleura2
     END SUBROUTINE CALC_XPRIM
118 1 pfleura2
  END INTERFACE
119 1 pfleura2
120 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
121 1 pfleura2
!
122 1 pfleura2
!!!!!!!! PFL Debug
123 1 pfleura2
!
124 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
125 1 pfleura2
  INTEGER(KINT) :: I1,I2,I3,I4
126 1 pfleura2
  LOGICAL :: debugPFL
127 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: val_zmat(:,:)
128 1 pfleura2
  INTEGER(KINT), ALLOCATABLE :: indzmat0(:,:)
129 1 pfleura2
130 1 pfleura2
131 1 pfleura2
  debug=valid("Calc_baker")
132 1 pfleura2
  debugPFL=valid("BakerPFL")
133 1 pfleura2
  if (debug) WRITE(*,*) "============= Entering Cal_baker =============="
134 1 pfleura2
135 1 pfleura2
  IF (Nat.le.2) THEN
136 1 pfleura2
     WRITE(*,*) "I do not work for less than 2 atoms :-p"
137 1 pfleura2
     RETURN
138 1 pfleura2
  END IF
139 1 pfleura2
140 1 pfleura2
  IF (debug) THEN
141 1 pfleura2
     WRITE(*,*) "DBG Calc_baker, geom"
142 1 pfleura2
     DO I=1,Nat
143 1 pfleura2
        WRITE(*,'(1X,I5,":",I3,3(1X,F15.3))') I,atome(I),XyzGeomI(IGeomRef,1:3,I)
144 1 pfleura2
     END DO
145 1 pfleura2
  END IF
146 1 pfleura2
147 1 pfleura2
148 1 pfleura2
149 1 pfleura2
150 1 pfleura2
  ! we construct the list of bonds, valence angles and dihedral angles using this connectivity
151 1 pfleura2
  ALLOCATE(Coordinate)
152 1 pfleura2
  NULLIFY(Coordinate%next)
153 1 pfleura2
  NbBonds=0
154 1 pfleura2
  NbAngles=0
155 1 pfleura2
  NbDihedrals=0
156 1 pfleura2
157 1 pfleura2
  CurrentCoord => Coordinate
158 1 pfleura2
159 1 pfleura2
  ALLOCATE(Liaisons(Nat,0:NMaxL),Geom(3,Nat),x(Nat),y(Nat),z(Nat))
160 1 pfleura2
  ALLOCATE(x_refGeom(Nat),y_refGeom(Nat),z_refGeom(Nat))
161 1 pfleura2
162 1 pfleura2
  x_refGeom(1:Nat) = XyzGeomI(IGeomRef,1,1:Nat)
163 1 pfleura2
  y_refGeom(1:Nat) = XyzGeomI(IGeomRef,2,1:Nat)
164 1 pfleura2
  z_refGeom(1:Nat) = XyzGeomI(IGeomRef,3,1:Nat)
165 1 pfleura2
166 1 pfleura2
!!!!!!!!!!!!!!!!!!!!
167 1 pfleura2
     !
168 1 pfleura2
     !   PFL Debug
169 1 pfleura2
     !
170 1 pfleura2
!!!!!!!!!!!!!!!!!!!!
171 1 pfleura2
     if (debugPFL) THEN
172 1 pfleura2
        WRITE(*,*) "DBG PFL Calc_BAKER - Calculating Zmat"
173 1 pfleura2
     if (.not.ALLOCATED(indzmat)) THEN
174 1 pfleura2
        ALLOCATE(indzmat(Nat,5))
175 1 pfleura2
     END IF
176 1 pfleura2
     IF (.NOT.ALLOCATED(DzDc)) THEN
177 1 pfleura2
        ALLOCATE(DzDc(3,nat,3,Nat))
178 1 pfleura2
     END IF
179 1 pfleura2
     IF (.NOT.ALLOCATED(Val_zmat)) THEN
180 1 pfleura2
        ALLOCATE(val_zmat(nat,3))
181 1 pfleura2
     END IF
182 1 pfleura2
     IF (.NOT.ALLOCATED(indzmat0)) THEN
183 1 pfleura2
        ALLOCATE(indzmat0(nat,5))
184 1 pfleura2
     END IF
185 1 pfleura2
! We construct a Zmat
186 1 pfleura2
          IF (Frozen(1).NE.0) THEN
187 1 pfleura2
           Renum=.TRUE.
188 1 pfleura2
!!! remplcaer indzmat par indzmat0 puis renumerotation
189 1 pfleura2
           call Calc_zmat_const_frag(Nat,atome,IndZmat0,val_zmat, &
190 1 pfleura2
             x_refGeom,y_refGeom,z_refGeom, &
191 1 pfleura2
                r_cov,fact,frozen)
192 1 pfleura2
        ELSE
193 1 pfleura2
           !no zmat... we create our own
194 1 pfleura2
           call Calc_zmat_frag(Nat,atome,IndZmat0,val_zmat, &
195 1 pfleura2
             x_refGeom,y_refGeom,z_refGeom, &
196 1 pfleura2
                r_cov,fact)
197 1 pfleura2
        END IF
198 1 pfleura2
199 1 pfleura2
         DO I=1,Nat
200 1 pfleura2
           Order(IndZmat0(I,1))=I
201 1 pfleura2
           OrderInv(I)=IndZmat0(I,1)
202 1 pfleura2
        END DO
203 1 pfleura2
        IndZmat(1,1)=Order(IndZmat0(1,1))
204 1 pfleura2
        IndZmat(2,1)=Order(IndZmat0(2,1))
205 1 pfleura2
        IndZmat(2,2)=Order(IndZmat0(2,2))
206 1 pfleura2
        IndZmat(3,1)=Order(IndZmat0(3,1))
207 1 pfleura2
        IndZmat(3,2)=Order(IndZmat0(3,2))
208 1 pfleura2
        IndZmat(3,3)=Order(IndZmat0(3,3))
209 1 pfleura2
        DO I=4,Nat
210 1 pfleura2
           DO J=1,4
211 1 pfleura2
              IndZmat(I,J)=Order(IndZmat0(I,J))
212 1 pfleura2
           END DO
213 1 pfleura2
        end do
214 1 pfleura2
215 1 pfleura2
216 1 pfleura2
        WRITE(*,*) "DBG PFL CalcBaker, IndZmat0"
217 1 pfleura2
        DO I=1,Nat
218 1 pfleura2
            WRITE(*,*) I, indZmat0(I,:)
219 1 pfleura2
        end do
220 1 pfleura2
221 1 pfleura2
        WRITE(*,*) "DBG PFL CalcBaker, IndZmat"
222 1 pfleura2
        DO I=1,Nat
223 1 pfleura2
            WRITE(*,*) I, indZmat(I,:)
224 1 pfleura2
        end do
225 1 pfleura2
226 1 pfleura2
227 1 pfleura2
     DO I=1,Nat
228 1 pfleura2
        I1=indzmat0(I,1)
229 1 pfleura2
        I2=indzmat0(I,2)
230 1 pfleura2
        I3=indzmat0(I,3)
231 1 pfleura2
        I4=indzmat0(I,4)
232 1 pfleura2
! Adding BOND between at1 and at2
233 1 pfleura2
      WRITE(*,*)  "DBG Indzmat",I,I1,I2,I3,I4
234 1 pfleura2
         if (I2.NE.0) THEN
235 1 pfleura2
           NbBonds=NbBonds+1
236 1 pfleura2
    ! values of the coordinate (bond) is calculated for the reference geometry
237 1 pfleura2
    ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.)
238 1 pfleura2
    ! are determined using all geometries. vecteur is defined in bib_oper.f
239 1 pfleura2
                  Call vecteur(I1,I2,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
240 1 pfleura2
!                  CurrentCoord%value=Norm2
241 1 pfleura2
                  WRITE(*,'(1X,A,I5,A,2(1X,F12.6))') "Bond",NbBonds," Norm2,val_zmat",Norm2,val_zmat(I,1)
242 1 pfleura2
                  CurrentCoord%value=val_zmat(I,1)
243 1 pfleura2
                  CurrentCoord%SignDihedral = 0
244 1 pfleura2
                  CurrentCoord%At1=I1
245 1 pfleura2
                  CurrentCoord%At2=I2
246 1 pfleura2
                  CurrentCoord%Type="BOND"
247 1 pfleura2
                  IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
248 1 pfleura2
                     ALLOCATE(CurrentCoord%next)
249 1 pfleura2
                     NULLIFY(CurrentCoord%next%next)
250 1 pfleura2
                  END IF
251 1 pfleura2
                  CurrentCoord => CurrentCoord%next
252 1 pfleura2
        END IF !IE.NE.0
253 1 pfleura2
       if (I3.NE.0) THEN
254 1 pfleura2
255 1 pfleura2
                       NbAngles=NbAngles+1
256 1 pfleura2
                       ! values of the coordinate (bond) is calculated for the reference geometry
257 1 pfleura2
                       ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.) are
258 1 pfleura2
                       ! determined using all geometries.
259 1 pfleura2
                       Call vecteur(i2,I3,x_refGeom,y_refGeom,z_refGeom,vx1,vy1,vz1,Norm1)
260 1 pfleura2
                       Call vecteur(i2,I1,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
261 1 pfleura2
!                       CurrentCoord%value=angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180.
262 1 pfleura2
                  WRITE(*,'(1X,A,I5,A,2(1X,F12.6))') "Angle",NbAngles," angle,val_zmat", &
263 1 pfleura2
                       angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2),val_zmat(I,2)
264 1 pfleura2
                       CurrentCoord%value=val_zmat(I,2)*Pi/180.
265 1 pfleura2
                       CurrentCoord%SignDihedral = 0
266 1 pfleura2
                       CurrentCoord%At1=I1
267 1 pfleura2
                       CurrentCoord%At2=I2
268 1 pfleura2
                       CurrentCoord%At3=I3
269 1 pfleura2
                       CurrentCoord%Type="ANGLE"
270 1 pfleura2
                       IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
271 1 pfleura2
                          ALLOCATE(CurrentCoord%next)
272 1 pfleura2
                          NULLIFY(CurrentCoord%next%next)
273 1 pfleura2
                       END IF
274 1 pfleura2
                       CurrentCoord => CurrentCoord%next
275 1 pfleura2
                    END IF ! matches IF (I3.NE.0)
276 1 pfleura2
         if (I4.NE.0) THEN
277 1 pfleura2
                       NbDihedrals=NbDihedrals+1
278 1 pfleura2
              Call vecteur(I2,I1,x_refGeom,y_refGeom,z_refGeom,vx1,vy1,vz1,Norm1)
279 1 pfleura2
              Call vecteur(I2,I3,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
280 1 pfleura2
              Call vecteur(I3,I4,x_refGeom,y_refGeom,z_refGeom,vx3,vy3,vz3,Norm3)
281 2 pfleura2
                       CALL produit_vect(vx1,vy1,vz1,vx2,vy2,vz2, &
282 1 pfleura2
                            vx4,vy4,vz4,norm4)
283 2 pfleura2
                       CALL produit_vect(vx3,vy3,vz3,vx2,vy2,vz2, &
284 1 pfleura2
                            vx5,vy5,vz5,norm5)
285 1 pfleura2
!                       CurrentCoord%value=angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, &
286 1 pfleura2
!                            vx2,vy2,vz2,norm2)*Pi/180.
287 1 pfleura2
                  WRITE(*,'(1X,A,I5,A,2(1X,F12.6))') "Dihedral",NbDihedrals,    &
288 1 pfleura2
                       " angle_d,val_zmat", &
289 1 pfleura2
                       angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, &
290 1 pfleura2
                       vx2,vy2,vz2,norm2) &
291 1 pfleura2
                       ,val_zmat(I,3)
292 1 pfleura2
293 1 pfleura2
                       CurrentCoord%value = val_zmat(I,3)*Pi/180.
294 1 pfleura2
                       CurrentCoord%SignDihedral = int(sign(1.D0,val_zmat(I,3)))
295 1 pfleura2
                       CurrentCoord%At1=I1
296 1 pfleura2
                       CurrentCoord%At2=I2
297 1 pfleura2
                       CurrentCoord%At3=I3
298 1 pfleura2
                       CurrentCoord%At4=I4
299 1 pfleura2
                       CurrentCoord%Type="DIHEDRAL"
300 1 pfleura2
                       IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
301 1 pfleura2
                          ALLOCATE(CurrentCoord%next)
302 1 pfleura2
                          NULLIFY(CurrentCoord%next%next)
303 1 pfleura2
                       END IF
304 1 pfleura2
                       CurrentCoord => CurrentCoord%next
305 1 pfleura2
                    END IF ! matches IF (I4.NE.0)
306 1 pfleura2
              END DO ! matches DO I=1,Nat
307 1 pfleura2
      deallocate(indzmat0)
308 1 pfleura2
309 1 pfleura2
  ELSE !! if (debugPFL)
310 1 pfleura2
311 1 pfleura2
  DO IGeom=1, NGeomI
312 1 pfleura2
     !IGeom=1 ! need when using only first geometry.
313 1 pfleura2
     x(1:Nat) = XyzGeomI(IGeom,1,1:Nat)
314 1 pfleura2
     y(1:Nat) = XyzGeomI(IGeom,2,1:Nat)
315 1 pfleura2
     z(1:Nat) = XyzGeomI(IGeom,3,1:Nat)
316 1 pfleura2
317 1 pfleura2
     ! First step: we calculate the connectivity
318 1 pfleura2
     Liaisons=0
319 1 pfleura2
320 1 pfleura2
     Call CalcCnct(Nat,atome,x,y,z,LIAISONS,r_cov,fact)
321 1 pfleura2
322 1 pfleura2
     IF (debug) THEN
323 1 pfleura2
        WRITE(*,*) 'Connectivity done'
324 1 pfleura2
        DO I=1,Nat
325 1 pfleura2
           WRITE(*,'(1X,I5,":",I3,"=",15I4)') I,(Liaisons(I,J),J=0,NMaxL)
326 1 pfleura2
           WRITE(*,'(1X,I5,":",I3,"=",15I4)') I,(Liaisons(I,:))
327 1 pfleura2
        END DO
328 1 pfleura2
        DO I=1,Nat
329 1 pfleura2
           WRITE(*,'(1X,I5,":",I3," r_cov=",F15.6)') I,atome(I),r_cov(atome(I))
330 1 pfleura2
        END DO
331 1 pfleura2
     END IF
332 1 pfleura2
333 1 pfleura2
     DO I=1,Nat
334 1 pfleura2
        IF (Liaisons(I,0).NE.0) THEN
335 1 pfleura2
           DO J=1,Liaisons(I,0)
336 1 pfleura2
              ! We add the bond
337 1 pfleura2
              Iat=Liaisons(I,J)
338 1 pfleura2
              IF (Iat.GT.I) THEN
339 1 pfleura2
                 ! Checking the uniqueness of bond.
340 1 pfleura2
                 ! Duplicate bonds should not be added.
341 1 pfleura2
                 AddPrimitiveCoord=.True.
342 1 pfleura2
                 ScanCoord=>Coordinate
343 1 pfleura2
                 DO WHILE (Associated(ScanCoord%next))
344 1 pfleura2
                    IF (ScanCoord%Type .EQ. 'BOND') THEN
345 1 pfleura2
                       IF (ScanCoord%At1 .EQ. Iat) THEN
346 1 pfleura2
                          IF (ScanCoord%At2 .EQ. I) THEN
347 1 pfleura2
                             AddPrimitiveCoord=.False.
348 1 pfleura2
                          END IF
349 1 pfleura2
                       END IF
350 1 pfleura2
                    END IF
351 1 pfleura2
                    ScanCoord => ScanCoord%next
352 1 pfleura2
                 END DO
353 1 pfleura2
354 1 pfleura2
                 IF (AddPrimitiveCoord) THEN
355 1 pfleura2
                    NbBonds=NbBonds+1
356 1 pfleura2
                    ! values of the coordinate (bond) is calculated for the reference geometry
357 1 pfleura2
                    ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.)
358 1 pfleura2
                    ! are determined using all geometries. vecteur is defined in bib_oper.f
359 1 pfleura2
                    Call vecteur(I,Iat,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
360 1 pfleura2
                    CurrentCoord%value=Norm2
361 1 pfleura2
                    CurrentCoord%SignDihedral = 0
362 1 pfleura2
                    CurrentCoord%At1=Iat
363 1 pfleura2
                    CurrentCoord%At2=I
364 1 pfleura2
                    CurrentCoord%Type="BOND"
365 1 pfleura2
                    IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
366 1 pfleura2
                       ALLOCATE(CurrentCoord%next)
367 1 pfleura2
                       NULLIFY(CurrentCoord%next%next)
368 1 pfleura2
                    END IF
369 1 pfleura2
                    CurrentCoord => CurrentCoord%next
370 1 pfleura2
                 END IF ! matches IF (AddPrimitiveCoord) THEN
371 1 pfleura2
              END IF ! matches IF (Iat.GT.I) THEN
372 1 pfleura2
373 1 pfleura2
              !           Call Annul(Liaisons,IAt,I,Nat,NMaxL)
374 1 pfleura2
              !           Liaisons(Iat,0)=Liaisons(Iat,0)-1
375 1 pfleura2
376 1 pfleura2
              ! We add the valence angles
377 1 pfleura2
              DO K=J+1,Liaisons(I,0)
378 1 pfleura2
                 Kat=Liaisons(I,K)
379 1 pfleura2
                 IF (Kat.GT.I) THEN
380 1 pfleura2
                    ! Checking the uniqueness of valence angle.
381 1 pfleura2
                    ! Duplicate bonds should not be added.
382 1 pfleura2
                    AddPrimitiveCoord=.True.
383 1 pfleura2
                    ScanCoord=>Coordinate
384 1 pfleura2
                    DO WHILE (Associated(ScanCoord%next))
385 1 pfleura2
                       IF (ScanCoord%Type .EQ. 'ANGLE') THEN
386 1 pfleura2
                          IF (ScanCoord%At1 .EQ. Iat) THEN
387 1 pfleura2
                             IF (ScanCoord%At2 .EQ. I) THEN
388 1 pfleura2
                                IF (ScanCoord%At3 .EQ. Kat) THEN
389 1 pfleura2
                                   AddPrimitiveCoord=.False.
390 1 pfleura2
                                END IF
391 1 pfleura2
                             END IF
392 1 pfleura2
                          END IF
393 1 pfleura2
                       END IF
394 1 pfleura2
                       ScanCoord => ScanCoord%next
395 1 pfleura2
                    END DO ! matches DO WHILE (Associated(ScanCoord%next))
396 1 pfleura2
397 1 pfleura2
                    IF (AddPrimitiveCoord) THEN
398 1 pfleura2
                       IF (debug) WRITE(*,*) "Adding angle:",Iat,I,Kat
399 1 pfleura2
                       NbAngles=NbAngles+1
400 1 pfleura2
                       ! values of the coordinate (bond) is calculated for the reference geometry
401 1 pfleura2
                       ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.) are
402 1 pfleura2
                       ! determined using all geometries.
403 1 pfleura2
                       Call vecteur(i,kat,x_refGeom,y_refGeom,z_refGeom,vx1,vy1,vz1,Norm1)
404 1 pfleura2
                       Call vecteur(i,Iat,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
405 1 pfleura2
                       CurrentCoord%value=angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180.
406 1 pfleura2
                       CurrentCoord%SignDihedral = 0
407 1 pfleura2
                       sAngleIatIKat=abs(sin(angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180.))
408 1 pfleura2
                       CurrentCoord%At1=Iat
409 1 pfleura2
                       CurrentCoord%At2=I
410 1 pfleura2
                       CurrentCoord%At3=KAt
411 1 pfleura2
                       CurrentCoord%Type="ANGLE"
412 1 pfleura2
                       IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
413 1 pfleura2
                          ALLOCATE(CurrentCoord%next)
414 1 pfleura2
                          NULLIFY(CurrentCoord%next%next)
415 1 pfleura2
                       END IF
416 1 pfleura2
                       CurrentCoord => CurrentCoord%next
417 1 pfleura2
                    END IF ! matches IF (AddPrimitiveCoord) THEN
418 1 pfleura2
                 ELSE ! matches IF (Kat.GT.I) THEN
419 1 pfleura2
                    ! Kat is less than I. If there is a bond between I and Kat, then this angle
420 1 pfleura2
                    ! has already been taken into account.
421 1 pfleura2
                    if (debug) WRITE(*,*) "Testing angle:",Iat,I,Kat
422 1 pfleura2
                    Bond=.FALSE.
423 1 pfleura2
                    DO L=1,Liaisons(Iat,0)
424 1 pfleura2
                       IF (Liaisons(Iat,L).EQ.Kat) Bond=.TRUE.
425 1 pfleura2
                    END DO
426 1 pfleura2
                    IF (.NOT.Bond) THEN
427 1 pfleura2
                       IF (debug) WRITE(*,*) "Not Bond Adding angle:",Iat,I,Kat
428 1 pfleura2
429 1 pfleura2
                       ! Checking the uniqueness of valence angle.
430 1 pfleura2
                       ! Duplicate bonds should not be added.
431 1 pfleura2
                       AddPrimitiveCoord=.True.
432 1 pfleura2
                       ScanCoord=>Coordinate
433 1 pfleura2
                       DO WHILE (Associated(ScanCoord%next))
434 1 pfleura2
                          IF (ScanCoord%Type .EQ. 'ANGLE') THEN
435 1 pfleura2
                             IF (ScanCoord%At1 .EQ. Iat) THEN
436 1 pfleura2
                                IF (ScanCoord%At2 .EQ. I) THEN
437 1 pfleura2
                                   IF (ScanCoord%At3 .EQ. Kat) THEN
438 1 pfleura2
                                      AddPrimitiveCoord=.False.
439 1 pfleura2
                                   END IF
440 1 pfleura2
                                END IF
441 1 pfleura2
                             END IF
442 1 pfleura2
                          END IF
443 1 pfleura2
                          ScanCoord => ScanCoord%next
444 1 pfleura2
                       END DO
445 1 pfleura2
446 1 pfleura2
                       IF (AddPrimitiveCoord) THEN
447 1 pfleura2
                          NbAngles=NbAngles+1
448 1 pfleura2
                          ! values of the coordinate (bond) is calculated for the reference geometry
449 1 pfleura2
                          ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.)
450 1 pfleura2
                          ! are determined using all geometries.
451 1 pfleura2
                          Call vecteur(i,kat,x_refGeom,y_refGeom,z_refGeom,vx1,vy1,vz1,Norm1)
452 1 pfleura2
                          Call vecteur(i,Iat,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
453 1 pfleura2
                          CurrentCoord%value=angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180.
454 1 pfleura2
                           CurrentCoord%SignDihedral = 0
455 1 pfleura2
                          CurrentCoord%At1=Iat
456 1 pfleura2
                          CurrentCoord%At2=I
457 1 pfleura2
                          CurrentCoord%At3=KAt
458 1 pfleura2
                          CurrentCoord%Type="ANGLE"
459 1 pfleura2
                          IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
460 1 pfleura2
                             ALLOCATE(CurrentCoord%next)
461 1 pfleura2
                             NULLIFY(CurrentCoord%next%next)
462 1 pfleura2
                          END IF
463 1 pfleura2
                          CurrentCoord => CurrentCoord%next
464 1 pfleura2
                       END IF  ! matches IF (AddPrimitiveCoord) THEN
465 1 pfleura2
                    END IF ! matches IF (.NOT.Bond) THEN
466 1 pfleura2
                 END IF ! matches IF (Kat.GT.I) THEN, after else
467 1 pfleura2
              END DO ! matches DO K=J+1,Liaisons(I,0)
468 1 pfleura2
           END DO ! matches DO J=1,Liaisons(I,0)
469 1 pfleura2
        END IF ! matches IF (Liaisons(I,0).NE.0) THEN
470 1 pfleura2
471 1 pfleura2
        ! We add dihedral angles. We do not concentrate on necessary angles, ie those that are
472 1 pfleura2
        ! needed to build the molecule. Instead we collect all of them, and the choice of the best
473 1 pfleura2
        ! ones will be done when diagonalizing the Baker matrix.
474 1 pfleura2
        IF (Liaisons(I,0).GE.3) Then
475 1 pfleura2
           DO J=1,Liaisons(I,0)
476 1 pfleura2
              Iat=Liaisons(I,J)
477 1 pfleura2
              ! values of the coordinate (bond) is calculated for the reference geometry
478 1 pfleura2
              ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.) are
479 1 pfleura2
              ! determined using all geometries.
480 1 pfleura2
              Call vecteur(Iat,i,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
481 1 pfleura2
482 1 pfleura2
              DO K=J+1,Liaisons(I,0)
483 1 pfleura2
                 Kat=Liaisons(I,K)
484 1 pfleura2
                 Call vecteur(i,kat,x_refGeom,y_refGeom,z_refGeom,vx1,vy1,vz1,Norm1)
485 1 pfleura2
                 sAngleIatIKat=abs(sin(angle(vx1,vy1,vz1,Norm1,-vx2,-vy2,-vz2,Norm2)*Pi/180.))
486 1 pfleura2
487 1 pfleura2
                 DO L=K+1,Liaisons(I,0)
488 1 pfleura2
                    Lat=Liaisons(I,L)
489 1 pfleura2
                    if (debug) WRITE(*,*) "0-Dihe Kat,I,Iat:",Kat,I,Iat,angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)
490 1 pfleura2
                    Call vecteur(iat,lat,x_refGeom,y_refGeom,z_refGeom,vx3,vy3,vz3,Norm3)
491 1 pfleura2
                    sAngleIIatLat=abs(sin(angle(vx3,vy3,vz3,Norm3,vx2,vy2,vz2,Norm2)*Pi/180.))
492 1 pfleura2
                    if (debug) WRITE(*,*) "0-Dihe I,Iat,Lat:",angle(vx3,vy3,vz3,Norm3,vx2,vy2,vz2,Norm2)
493 1 pfleura2
                    IF ((sAngleIatIKat.ge.0.01d0).AND.(sAngleIIatLat.ge.0.01d0)) THEN
494 1 pfleura2
                       if (debug) WRITE(*,*) "Adding dihedral:",Kat,I,Iat,Lat
495 1 pfleura2
496 1 pfleura2
                       ! Checking for the uniqueness of valence angle.
497 1 pfleura2
                       ! Duplicate bonds should not be added.
498 1 pfleura2
                       AddPrimitiveCoord=.True.
499 1 pfleura2
                       ScanCoord=>Coordinate
500 1 pfleura2
                       DO WHILE (Associated(ScanCoord%next))
501 1 pfleura2
                          IF (ScanCoord%Type .EQ. 'DIHEDRAL') THEN
502 1 pfleura2
                             IF (ScanCoord%At1 .EQ. Kat) THEN
503 1 pfleura2
                                IF (ScanCoord%At2 .EQ. I) THEN
504 1 pfleura2
                                   IF (ScanCoord%At3 .EQ. Iat) THEN
505 1 pfleura2
                                      IF (ScanCoord%At4 .EQ. Lat) THEN
506 1 pfleura2
                                         AddPrimitiveCoord=.False.
507 1 pfleura2
                                      END IF
508 1 pfleura2
                                   END IF
509 1 pfleura2
                                END IF
510 1 pfleura2
                             END IF
511 1 pfleura2
                          END IF
512 1 pfleura2
                          ScanCoord => ScanCoord%next
513 1 pfleura2
                       END DO ! matches DO WHILE (Associated(ScanCoord%next))
514 1 pfleura2
515 1 pfleura2
                       ! IF (AddPrimitiveCoord) THEN
516 1 pfleura2
                       !   NbDihedrals=NbDihedrals+1
517 2 pfleura2
                       !  CALL produit_vect(vx3,vy3,vz3,vx2,vy2,vz2, &
518 1 pfleura2
                            !      vx5,vy5,vz5,norm5)
519 2 pfleura2
                       !CALL produit_vect(vx1,vy1,vz1,vx2,vy2,vz2, &
520 1 pfleura2
                            !    vx4,vy4,vz4,norm4)
521 1 pfleura2
                       !         CurrentCoord%value=angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, &
522 1 pfleura2
                       !             vx2,vy2,vz2,norm2)*Pi/180.
523 1 pfleura2
                       !          CurrentCoord%SignDihedral = 0
524 1 pfleura2
                       !       CurrentCoord%At1=Kat
525 1 pfleura2
                       !      CurrentCoord%At2=I
526 1 pfleura2
                       !     CurrentCoord%At3=IAt
527 1 pfleura2
                       !    CurrentCoord%At4=LAt
528 1 pfleura2
                       !WRITE(*,'(1X,":(dihed 1)",I5," - ",I5," - ",I5," - ",I5," = ",F15.6)') &
529 1 pfleura2
                       !        ScanCoord%At1,ScanCoord%At2,ScanCoord%At3,ScanCoord%At4,ScanCoord%Value*180./Pi
530 1 pfleura2
                       !         CurrentCoord%Type="DIHEDRAL"
531 1 pfleura2
                       !        IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
532 1 pfleura2
                       !          ALLOCATE(CurrentCoord%next)
533 1 pfleura2
                       !         NULLIFY(CurrentCoord%next%next)
534 1 pfleura2
                       !     END IF
535 1 pfleura2
                       !    CurrentCoord => CurrentCoord%next
536 1 pfleura2
                       !END IF ! matches IF (AddPrimitiveCoord) THEN
537 1 pfleura2
538 1 pfleura2
                    END IF ! matches IF ((sAngleIatIKat.ge.0.01d0).AND.(sAngleIIatLat.ge.0.01d0)) THEN
539 1 pfleura2
                 END DO ! matches DO L=K+1,Liaisons(I,0)
540 1 pfleura2
              END DO ! matches DO K=J+1,Liaisons(I,0)
541 1 pfleura2
           END DO ! matches DO J=1,Liaisons(I,0)
542 1 pfleura2
        END IF !matches  IF (Liaisons(I,0).GE.3) Then
543 1 pfleura2
544 1 pfleura2
        ! we now add other dihedrals
545 1 pfleura2
        DO J=1,Liaisons(I,0)
546 1 pfleura2
           Iat=Liaisons(I,J)
547 1 pfleura2
           If (Iat.LE.I) Cycle
548 1 pfleura2
           ! values of the coordinate (bond) is calculated for the reference geometry
549 1 pfleura2
           ! whereas the coordinates (bonds) (CurrentCoord%At1, CurrentCoord%At2, etc.) are
550 1 pfleura2
           ! determined using all geometries.
551 1 pfleura2
           Call vecteur(Iat,i,x_refGeom,y_refGeom,z_refGeom,vx2,vy2,vz2,Norm2)
552 1 pfleura2
553 1 pfleura2
           DO K=1,Liaisons(I,0)
554 1 pfleura2
              IF (Liaisons(I,K).EQ.Iat) Cycle
555 1 pfleura2
              Kat=Liaisons(I,K)
556 1 pfleura2
              Call vecteur(i,kat,x_refGeom,y_refGeom,z_refGeom,vx1,vy1,vz1,Norm1)
557 1 pfleura2
              sAngleIatIKat=abs(sin(angle(vx1,vy1,vz1,Norm1,-vx2,-vy2,-vz2,Norm2)*Pi/180.))
558 1 pfleura2
559 1 pfleura2
              DO L=1,Liaisons(Iat,0)
560 1 pfleura2
                 Lat=Liaisons(Iat,L)
561 1 pfleura2
                 IF (Lat.eq.I) Cycle
562 1 pfleura2
563 1 pfleura2
                 if (debug) WRITE(*,*) "Dihe Kat,I,Iat:",angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2),sAngleIatIKat
564 1 pfleura2
                 Call vecteur(iat,lat,x_refGeom,y_refGeom,z_refGeom,vx,vy,vz,Norm)
565 1 pfleura2
566 1 pfleura2
                 sAngleIIatLat=abs(sin(angle(vx,vy,vz,Norm,vx2,vy2,vz2,Norm2)*Pi/180.))
567 1 pfleura2
                 if (debug) WRITE(*,*) "Dihe I,Iat,Lat:",angle(vx,vy,vz,Norm,vx2,vy2,vz2,Norm2)
568 1 pfleura2
                 ! we add the dihedral angle Kat-I-Iat-Lat
569 1 pfleura2
                 if (debug) WRITE(*,*) "Trying dihedral:",Kat,I,Iat,Lat,sAngleIatIKat,sAngleIIatLat
570 1 pfleura2
                 IF ((Lat.NE.Kat).AND.(Lat.Ne.I).AND.(sAngleIatIKat.ge.0.01d0) &
571 1 pfleura2
                      .AND.(sAngleIIatLat.ge.0.01d0)) THEN
572 1 pfleura2
                    if (debug) WRITE(*,*) "Adding dihedral:",Kat,I,Iat,Lat
573 1 pfleura2
574 1 pfleura2
                    ! Checking for the uniqueness of valence angle.
575 1 pfleura2
                    ! Duplicate bonds should not be added.
576 1 pfleura2
                    AddPrimitiveCoord=.True.
577 1 pfleura2
                    ScanCoord=>Coordinate
578 1 pfleura2
                    DO WHILE (Associated(ScanCoord%next))
579 1 pfleura2
                       IF (ScanCoord%Type .EQ. 'DIHEDRAL') THEN
580 1 pfleura2
                          IF (ScanCoord%At1 .EQ. Kat) THEN
581 1 pfleura2
                             IF (ScanCoord%At2 .EQ. I) THEN
582 1 pfleura2
                                IF (ScanCoord%At3 .EQ. Iat) THEN
583 1 pfleura2
                                   IF (ScanCoord%At4 .EQ. Lat) THEN
584 1 pfleura2
                                      AddPrimitiveCoord=.False.
585 1 pfleura2
                                   END IF
586 1 pfleura2
                                END IF
587 1 pfleura2
                             END IF
588 1 pfleura2
                          END IF
589 1 pfleura2
                       END IF
590 1 pfleura2
                       ScanCoord => ScanCoord%next
591 1 pfleura2
                    END DO
592 1 pfleura2
593 1 pfleura2
                    IF (AddPrimitiveCoord) THEN
594 1 pfleura2
                       NbDihedrals=NbDihedrals+1
595 1 pfleura2
                       Call vecteur(iat,lat,x_refGeom,y_refGeom,z_refGeom,vx3,vy3,vz3,Norm3)
596 2 pfleura2
                       CALL produit_vect(vx3,vy3,vz3,vx2,vy2,vz2, &
597 1 pfleura2
                            vx5,vy5,vz5,norm5)
598 2 pfleura2
                       CALL produit_vect(vx1,vy1,vz1,vx2,vy2,vz2, &
599 1 pfleura2
                            vx4,vy4,vz4,norm4)
600 1 pfleura2
                       CurrentCoord%value=angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, &
601 1 pfleura2
                            vx2,vy2,vz2,norm2)*Pi/180.
602 1 pfleura2
                       CurrentCoord%At1=Kat
603 1 pfleura2
                       CurrentCoord%At2=I
604 1 pfleura2
                       CurrentCoord%At3=IAt
605 1 pfleura2
                       CurrentCoord%At4=LAt
606 1 pfleura2
                       CurrentCoord%Type="DIHEDRAL"
607 1 pfleura2
                       CurrentCoord%SignDihedral=int(sign(1.d0,angle_d(vx4,vy4,vz4,norm4,   &
608 1 pfleura2
                            vx5,vy5,vz5,norm5, vx2,vy2,vz2,norm2)))
609 1 pfleura2
                       WRITE(*,'(1X,":(dihed 2)",I5," - ",I5," - ",I5," - ",I5," = ",F15.6)') ScanCoord%At1,&
610 1 pfleura2
                            ScanCoord%At2, ScanCoord%At3,ScanCoord%At4,ScanCoord%Value*180./Pi
611 1 pfleura2
                       IF (.NOT.ASSOCIATED(CurrentCoord%next)) THEN
612 1 pfleura2
                          ALLOCATE(CurrentCoord%next)
613 1 pfleura2
                          NULLIFY(CurrentCoord%next%next)
614 1 pfleura2
                       END IF
615 1 pfleura2
                       CurrentCoord => CurrentCoord%next
616 1 pfleura2
                    END IF ! matches IF (AddPrimitiveCoord) THEN
617 1 pfleura2
                 END IF ! matches IF ((Lat.NE.Kat).AND.(Lat.Ne.I).AND.(sAngleIatIKat.ge.0.01d0) .....
618 1 pfleura2
              END DO ! matches DO L=1,Liaisons(Iat,0)
619 1 pfleura2
           END DO ! matches DO K=1,Liaisons(I,0)
620 1 pfleura2
        END DO ! matches DO J=1,Liaisons(I,0)
621 1 pfleura2
     END DO ! end of loop over all atoms, DO I=1, Nat
622 1 pfleura2
  END DO ! matches DO IGeom=1, NGeomI
623 1 pfleura2
624 1 pfleura2
625 1 pfleura2
626 1 pfleura2
 END IF ! if (debugPFL)
627 1 pfleura2
  DEALLOCATE(Liaisons)
628 1 pfleura2
629 1 pfleura2
  WRITE(*,*) "I have found"
630 1 pfleura2
  WRITE(*,*) NbBonds, " bonds"
631 1 pfleura2
  WRITE(*,*) NbAngles, " angles"
632 1 pfleura2
  WRITE(*,*) NbDihedrals, " dihedrals"
633 1 pfleura2
634 1 pfleura2
  WRITE(*,*) 'All in all...'
635 1 pfleura2
  ScanCoord=>Coordinate
636 1 pfleura2
  I=0
637 1 pfleura2
  DO WHILE (Associated(ScanCoord%next))
638 1 pfleura2
     I=I+1
639 1 pfleura2
     SELECT CASE (ScanCoord%Type)
640 1 pfleura2
     CASE ('BOND')
641 1 pfleura2
        !WRITE(IOOUT,'(1X,I3,":",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,ScanCoord%At2,ScanCoord%Value
642 1 pfleura2
        WRITE(*,'(1X,I3,":(bond )",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,ScanCoord%At2,ScanCoord%Value
643 1 pfleura2
     CASE ('ANGLE')
644 1 pfleura2
        !WRITE(IOOUT,'(1X,I3,":",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1, &
645 1 pfleura2
        !    ScanCoord%At2, ScanCoord%At3,ScanCoord%Value*180./Pi
646 1 pfleura2
        WRITE(*,'(1X,I3,":(angle)",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1, &
647 1 pfleura2
             ScanCoord%At2, ScanCoord%At3,ScanCoord%Value*180./Pi
648 1 pfleura2
     CASE ('DIHEDRAL')
649 1 pfleura2
        !WRITE(IOOUT,'(1X,I3,":",I5," - ",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,&
650 1 pfleura2
        !    ScanCoord%At2, ScanCoord%At3,ScanCoord%At4,ScanCoord%Value*180./Pi
651 1 pfleura2
        WRITE(*,'(1X,I3,":(dihed)",I5," - ",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,&
652 1 pfleura2
             ScanCoord%At2, ScanCoord%At3,ScanCoord%At4,ScanCoord%Value*180./Pi
653 1 pfleura2
     END SELECT
654 1 pfleura2
     ScanCoord => ScanCoord%next
655 1 pfleura2
  END DO
656 1 pfleura2
657 1 pfleura2
  ! NPrim is the number of primitive coordinates.
658 1 pfleura2
  NPrim=NbBonds+NbAngles+NbDihedrals
659 1 pfleura2
660 1 pfleura2
  ! Now calculating values of all primitive bonds for all geometries:
661 1 pfleura2
  ALLOCATE(Xprimitive(NgeomI,NPrim),XPrimitiveF(NGeomF,NPrim))
662 1 pfleura2
  ALLOCATE(UMatF(NGeomF,NPrim,NCoord))
663 1 pfleura2
  ALLOCATE(BTransInvF(NGeomF,NCoord,3*Nat))
664 1 pfleura2
665 1 pfleura2
! We calculate the Primitive values for the first geometry, this plays a special role
666 1 pfleura2
! as it will serve as a reference for other geometries !
667 1 pfleura2
668 1 pfleura2
  x(1:Nat) = XyzGeomI(1,1,1:Nat)
669 1 pfleura2
  y(1:Nat) = XyzGeomI(1,2,1:Nat)
670 1 pfleura2
  z(1:Nat) = XyzGeomI(1,3,1:Nat)
671 1 pfleura2
672 1 pfleura2
  Call Calc_Xprim(nat,x,y,z,Coordinate,NPrim,XPrimitive(1,:))
673 1 pfleura2
674 1 pfleura2
  DO IGeom=2, NGeomI
675 1 pfleura2
676 1 pfleura2
        x(1:Nat) = XyzGeomI(IGeom,1,1:Nat)
677 1 pfleura2
        y(1:Nat) = XyzGeomI(IGeom,2,1:Nat)
678 1 pfleura2
        z(1:Nat) = XyzGeomI(IGeom,3,1:Nat)
679 1 pfleura2
680 1 pfleura2
        Call Calc_Xprim(nat,x,y,z,Coordinate,NPrim,XPrimitive(IGeom,:),Xprimitive(1,:))
681 1 pfleura2
682 1 pfleura2
!      ScanCoord=>Coordinate
683 1 pfleura2
!      I=0 ! index for the NPrim (NPrim is the number of primitive coordinates).
684 1 pfleura2
!      DO WHILE (Associated(ScanCoord%next))
685 1 pfleura2
!         I=I+1
686 1 pfleura2
!         SELECT CASE (ScanCoord%Type)
687 1 pfleura2
!         CASE ('BOND')
688 1 pfleura2
!            Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx2,vy2,vz2,Norm2)
689 1 pfleura2
!            Xprimitive(IGeom,I) = Norm2
690 1 pfleura2
!         CASE ('ANGLE')
691 1 pfleura2
!            Call vecteur(ScanCoord%At2,ScanCoord%At3,x,y,z,vx1,vy1,vz1,Norm1)
692 1 pfleura2
!            Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx2,vy2,vz2,Norm2)
693 1 pfleura2
!            Xprimitive(IGeom,I) = angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180.
694 1 pfleura2
!         CASE ('DIHEDRAL')
695 1 pfleura2
696 1 pfleura2
697 1 pfleura2
!            Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx1,vy1,vz1,Norm1)
698 1 pfleura2
!            Call vecteur(ScanCoord%At2,ScanCoord%At3,x,y,z,vx2,vy2,vz2,Norm2)
699 1 pfleura2
!            Call vecteur(ScanCoord%At3,ScanCoord%At4,x,y,z,vx3,vy3,vz3,Norm3)
700 2 pfleura2
!            Call produit_vect(vx1,vy1,vz1,vx2,vy2,vz2, &
701 1 pfleura2
!                 vx4,vy4,vz4,norm4)
702 2 pfleura2
!            Call produit_vect(vx3,vy3,vz3,vx2,vy2,vz2, &
703 1 pfleura2
!                 vx5,vy5,vz5,norm5)
704 1 pfleura2
705 1 pfleura2
!                  DiheTmp= angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, &
706 1 pfleura2
!                          vx2,vy2,vz2,norm2)
707 1 pfleura2
!                  Xprimitive(IGeom,I) = DiheTmp*Pi/180.
708 1 pfleura2
! ! We treat large dihedral angles differently as +180=-180 mathematically and physically
709 1 pfleura2
! ! but this causes lots of troubles when converting baker to cart.
710 1 pfleura2
! ! So we ensure that large dihedral angles always have the same sign
711 1 pfleura2
!                     if (abs(ScanCoord%SignDihedral).NE.1) THEN
712 1 pfleura2
!                         ScanCoord%SignDihedral=Int(Sign(1.D0,DiheTmp))
713 1 pfleura2
!                     ELSE
714 1 pfleura2
!                         If ((abs(DiheTmp).GE.170.D0).AND.(Sign(1.,DiheTmp)*ScanCoord%SignDihedral<0)) THEN
715 1 pfleura2
!                           Xprimitive(IGeom,I) = DiheTmp*Pi/180.+ ScanCoord%SignDihedral*2.*Pi
716 1 pfleura2
!                        END IF
717 1 pfleura2
!                   END IF
718 1 pfleura2
! ! Another test... will all this be consistent ???
719 1 pfleura2
! ! We want the shortest path, so we check that the change in dihedral angles is less than Pi:
720 1 pfleura2
!                   IF (IGeom.GT.1) THEN
721 1 pfleura2
!                      IF (abs(Xprimitive(IGeom,I)-XPrimitive(IGeom-1,I)).GE.Pi) THEN
722 1 pfleura2
!                         if ((Xprimitive(IGeom,I)-XPrimitive(IGeom-1,I)).GE.Pi) THEN
723 1 pfleura2
!                            Xprimitive(IGeom,I)=Xprimitive(IGeom,I)-2.d0*Pi
724 1 pfleura2
!                         ELSE
725 1 pfleura2
!                            Xprimitive(IGeom,I)=Xprimitive(IGeom,I)+2.d0*Pi
726 1 pfleura2
!                         END IF
727 1 pfleura2
!                      END IF
728 1 pfleura2
!                   END IF
729 1 pfleura2
!         END SELECT
730 1 pfleura2
!         ScanCoord => ScanCoord%next
731 1 pfleura2
!      END DO ! matches DO WHILE (Associated(ScanCoord%next))
732 1 pfleura2
  END DO ! matches DO IGeom=1, NGeomI
733 1 pfleura2
734 1 pfleura2
  IF (debug) THEN
735 1 pfleura2
     WRITE(*,*) "DBG Calc_Baker Xprimitives for all geometries"
736 1 pfleura2
  DO IGeom=1, NGeomI
737 1 pfleura2
     WRITE(*,*) "Geometry ",IGeom
738 1 pfleura2
     ScanCoord=>Coordinate
739 1 pfleura2
     I=0 ! index for the NPrim (NPrim is the number of primitive coordinates).
740 1 pfleura2
     DO WHILE (Associated(ScanCoord%next))
741 1 pfleura2
        I=I+1
742 1 pfleura2
        SELECT CASE (ScanCoord%Type)
743 1 pfleura2
        CASE ('BOND')
744 1 pfleura2
           WRITE(*,'(1X,I3,":",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,ScanCoord%At2,Xprimitive(IGeom,I)
745 1 pfleura2
        CASE ('ANGLE')
746 1 pfleura2
           WRITE(*,'(1X,I3,":",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1, &
747 1 pfleura2
            ScanCoord%At2, ScanCoord%At3,Xprimitive(IGeom,I)*180./Pi
748 1 pfleura2
        CASE ('DIHEDRAL')
749 1 pfleura2
           WRITE(*,'(1X,I3,":",I5," - ",I5," - ",I5," - ",I5," = ",F15.6)') I,ScanCoord%At1,&
750 1 pfleura2
           ScanCoord%At2, ScanCoord%At3,ScanCoord%At4,Xprimitive(IGeom,I)*180./Pi
751 1 pfleura2
        END SELECT
752 1 pfleura2
        ScanCoord => ScanCoord%next
753 1 pfleura2
     END DO ! matches DO WHILE (Associated(ScanCoord%next))
754 1 pfleura2
  END DO ! matches DO IGeom=1, NGeomI
755 1 pfleura2
  END IF
756 1 pfleura2
  ! Here reference geometry is assigned to Geom. Earlier x,y,z(Nat) were assigned from XyzGeomI(...)
757 1 pfleura2
  ! before the call of this (Calc_baker) subroutine and passed to this subroutine as arguments of the
758 1 pfleura2
  ! subroutine.
759 1 pfleura2
! PFL 19 Feb 2008 ->
760 1 pfleura2
! In order to reproduce the B matrix in the Baker article, one has
761 1 pfleura2
! to divide Geom by a0.
762 1 pfleura2
! However, this is inconsitent with our way of storing geometries
763 1 pfleura2
! so we do not do it !
764 1 pfleura2
765 1 pfleura2
  Geom(1,:)=XyzGeomI(IGeomRef,1,1:Nat) ! XyzGeomI(NGeomI,3,Nat)
766 1 pfleura2
  Geom(2,:)=XyzGeomI(IGeomRef,2,1:Nat)
767 1 pfleura2
  Geom(3,:)=XyzGeomI(IGeomRef,3,1:Nat)
768 1 pfleura2
769 1 pfleura2
! <- PFL 19 Feb 2008
770 1 pfleura2
771 1 pfleura2
  ! We now have to compute dq/dx...
772 1 pfleura2
  ALLOCATE(BprimT(3*Nat,NPrim))
773 1 pfleura2
  BprimT=0.d0
774 1 pfleura2
775 1 pfleura2
  ScanCoord=>Coordinate
776 1 pfleura2
  I=0
777 1 pfleura2
  DO WHILE (Associated(ScanCoord%next))
778 1 pfleura2
     I=I+1
779 1 pfleura2
     SELECT CASE (ScanCoord%Type)
780 1 pfleura2
     CASE ('BOND')
781 1 pfleura2
        CALL CONSTRAINTS_BONDLENGTH_DER(Nat,ScanCoord%at1,ScanCoord%AT2, &
782 1 pfleura2
             Geom,BprimT(1,I))
783 1 pfleura2
     CASE ('ANGLE')
784 1 pfleura2
        CALL CONSTRAINTS_BONDANGLE_DER(Nat,ScanCoord%At1,ScanCoord%AT2, &
785 1 pfleura2
             ScanCoord%At3,Geom,BprimT(1,I))
786 1 pfleura2
     CASE ('DIHEDRAL')
787 1 pfleura2
        CALL CONSTRAINTS_TORSION_DER2(Nat,ScanCoord%At1,ScanCoord%AT2, &
788 1 pfleura2
             ScanCoord%At3,ScanCoord%At4,Geom,BprimT(1,I))
789 1 pfleura2
!        CALL CONSTRAINTS_TORSION_DER(Nat,ScanCoord%At1,ScanCoord%AT2, &
790 1 pfleura2
!             ScanCoord%At3,ScanCoord%At4,Geom,BprimT(1,I))
791 1 pfleura2
792 1 pfleura2
     END SELECT
793 1 pfleura2
     ScanCoord => ScanCoord%next
794 1 pfleura2
  END DO
795 1 pfleura2
796 1 pfleura2
797 1 pfleura2
!!!!!!!!!!!!!!!!!!!!
798 1 pfleura2
     !
799 1 pfleura2
     !   PFL Debug
800 1 pfleura2
     !
801 1 pfleura2
!!!!!!!!!!!!!!!!!!!!
802 1 pfleura2
803 1 pfleura2
     if (debugPFL) THEN
804 1 pfleura2
        WRITe(*,*) "DBG PFL Calc_Baker ====="
805 1 pfleura2
     DzDc=0.d0
806 1 pfleura2
     WRITE(*,*) "PFL DBG, DzdC"
807 1 pfleura2
  do I=1,Nat
808 1 pfleura2
  Geom(1,i)=XyzGeomI(IGeomRef,1,orderInv(i)) ! XyzGeomI(NGeomI,3,Nat)
809 1 pfleura2
  Geom(2,i)=XyzGeomI(IGeomRef,2,OrderInv(i))
810 1 pfleura2
  Geom(3,i)=XyzGeomI(IGeomRef,3,OrderInv(i))
811 1 pfleura2
  WRITE(*,*) I,OrderInv(I),Geom(:,I)
812 1 pfleura2
    end do
813 1 pfleura2
     CALL CalcBMat_int (nat, Geom, indzmat, dzdc, massat,atome)
814 1 pfleura2
815 1 pfleura2
     WRITE(*,*) "PFL DBG, BPrimT"
816 1 pfleura2
     DO I=1,NPrim
817 1 pfleura2
        WRITE(*,'(50(1X,F12.6))') BPrimT(:,I)
818 1 pfleura2
     END DO
819 1 pfleura2
        WRITe(*,*) "DBG PFL Calc_Baker ====="
820 1 pfleura2
     END IF
821 1 pfleura2
822 1 pfleura2
!!!!!!!!!!!!!!!!!!!!
823 1 pfleura2
     !
824 1 pfleura2
     !   PFL Debug
825 1 pfleura2
     !
826 1 pfleura2
!!!!!!!!!!!!!!!!!!!!
827 1 pfleura2
828 1 pfleura2
  DEALLOCATE(Geom)
829 1 pfleura2
830 1 pfleura2
  ! BprimT(3*Nat,NPrim)
831 1 pfleura2
  ! We now compute G=B(BT) matrix
832 1 pfleura2
  ALLOCATE(Gmat(NPrim,NPrim))
833 1 pfleura2
  GMat=0.d0
834 1 pfleura2
  DO I=1,NPrim
835 1 pfleura2
     DO J=1,3*Nat
836 1 pfleura2
        GMat(:,I)=Gmat(:,I)+BprimT(J,:)*BprimT(J,I) !*1.d0/mass(atome(int(K/3.d0)))
837 1 pfleura2
     END DO
838 1 pfleura2
  END DO
839 1 pfleura2
840 1 pfleura2
!!!!!!!!!!!!!!!!!!!!
841 1 pfleura2
     !
842 1 pfleura2
     !   PFL Debug --->
843 1 pfleura2
     !
844 1 pfleura2
!!!!!!!!!!!!!!!!!!!!
845 1 pfleura2
    if (debugPFL) THEN
846 1 pfleura2
  GMat=0.d0
847 1 pfleura2
  DO I=1,NPrim
848 1 pfleura2
        GMat(I,I)=1.
849 1 pfleura2
  END DO
850 1 pfleura2
   END IF
851 1 pfleura2
852 1 pfleura2
!!!!!!!!!!!!!!!!!!!!
853 1 pfleura2
     !
854 1 pfleura2
     !  <--- PFL Debug
855 1 pfleura2
     !
856 1 pfleura2
!!!!!!!!!!!!!!!!!!!!
857 1 pfleura2
858 1 pfleura2
  !DO I=1,NPrim
859 1 pfleura2
  !  WRITE(*,'(20(1X,F6.3))') GMat(1:min(20,NPrim),I)
860 1 pfleura2
  !END DO
861 1 pfleura2
862 1 pfleura2
  ! We diagonalize G
863 1 pfleura2
  ALLOCATE(EigVal(NPrim),EigVec(NPrim,NPrim))
864 1 pfleura2
  Call Jacobi(GMat,NPrim,EigVal,EigVec,NPrim)
865 1 pfleura2
  Call Trie(NPrim,EigVal,EigVec,NPrim)
866 1 pfleura2
  DO I=1,NPrim
867 1 pfleura2
     WRITE(*,'(1X,"Vector ",I3,": e=",F8.3)') I,EigVal(i)
868 1 pfleura2
     WRITE(*,'(20(1X,F8.4))') EigVec(1:min(20,NPrim),I)
869 1 pfleura2
  END DO
870 1 pfleura2
871 1 pfleura2
  !DO I=1,NPrim
872 1 pfleura2
  ! WRITE(*,'(1X,"Vector ",I3,(20(F8.3)))') I,EigVec(1:min(20,NPrim),I)
873 1 pfleura2
  ! END DO
874 1 pfleura2
875 1 pfleura2
  !DO I=1,NPrim
876 1 pfleura2
  !  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 1 pfleura2
  ! 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 1 pfleura2
  !EigVec(2,I),EigVec(3,I),EigVec(5,I),EigVec(12,I),EigVec(13,I),EigVec(15,I),EigVec(7,I),&
879 1 pfleura2
       !EigVec(8,I),EigVec(9,I),EigVec(10,I),EigVec(11,I),EigVec(17,I)
880 1 pfleura2
  !END DO
881 1 pfleura2
882 1 pfleura2
  ! We construct the new DzDc(b=baker) matrix
883 1 pfleura2
  ! UMat is nonredundant vector set, i.e. set of eigenvectors of BB^T corresponding
884 1 pfleura2
  ! to eigenvalues > zero.
885 1 pfleura2
  ALLOCATE(UMat(NPrim,NCoord))
886 1 pfleura2
  ALLOCATE(UMat_local(NPrim,NCoord))
887 1 pfleura2
  ALLOCATE(UMat_tmp(NPrim,3*Nat-6))
888 1 pfleura2
  ! BMat_BakerT(3*Nat,NCoord), allocated in Path.f90,
889 1 pfleura2
  ! NCoord=3*Nat-6
890 1 pfleura2
  BMat_BakerT = 0.d0
891 1 pfleura2
  J=0
892 1 pfleura2
  UMat=0.d0
893 1 pfleura2
  UMat_tmp=0.d0
894 1 pfleura2
  DO I=1,NPrim
895 1 pfleura2
     IF (abs(eigval(I))>=1e-6) THEN
896 1 pfleura2
        J=J+1
897 1 pfleura2
        DO K=1,NPrim
898 1 pfleura2
           !DzDcb(:,J)=DzDcb(:,J)+Eigvec(K,I)*BprimT(:,K) ! original
899 1 pfleura2
           ! BprimT is transpose of B^prim.
900 1 pfleura2
           ! B = UMat^T B^prim, B^T = (B^prim)^T UMat
901 1 pfleura2
           BMat_BakerT(:,J)=BMat_BakerT(:,J)+BprimT(:,K)*Eigvec(K,I)
902 1 pfleura2
           !Dzdcb(:,J)=DzDcb(:,J)+Eigvec(K,:)*BprimT(I,K)
903 1 pfleura2
        END DO
904 1 pfleura2
        IF(J .GT. 3*Nat-6) THEN
905 1 pfleura2
           WRITE(*,*) 'Number of vectors in Eigvec with eigval .GT. 1e-6(=UMat) (=' &
906 1 pfleura2
                ,J,') exceeded 3*Nat-6=',3*Nat-6, &
907 1 pfleura2
                'Stopping the calculation.'
908 1 pfleura2
           STOP
909 1 pfleura2
        END IF
910 1 pfleura2
        UMat_tmp(:,J) =  Eigvec(:,I)
911 1 pfleura2
     END IF
912 1 pfleura2
  END DO
913 1 pfleura2
914 1 pfleura2
  if (debug) THEN
915 1 pfleura2
     WRITE(*,*) "DBG Calc_Baker: UMat"
916 1 pfleura2
     DO I=1,3*Nat-6
917 1 pfleura2
        WRITE(*,'(50(1X,F12.8))') UMat_tmp(:,I)
918 1 pfleura2
     END DO
919 1 pfleura2
  END IF
920 1 pfleura2
921 1 pfleura2
  ! THIS IS TO BE CORRECTED:
922 1 pfleura2
  UMat = UMat_tmp
923 1 pfleura2
  !J=0
924 1 pfleura2
  !DO I=1, 3*Nat-6
925 1 pfleura2
  !  IF ((I .NE. 6) .AND. (I .NE. 7) .AND. (I .NE. 9)) Then
926 1 pfleura2
  !   J=J+1
927 1 pfleura2
  !  Print *, 'J=', J, ' I=', I
928 1 pfleura2
  ! UMat(:,J) = UMat_tmp(:,I)
929 1 pfleura2
  !END IF
930 1 pfleura2
  !END DO
931 1 pfleura2
  ! BMat_BakerT=0.d0
932 1 pfleura2
  !DO I=1,NCoord
933 1 pfleura2
  !  DO J=1,NPrim
934 1 pfleura2
  ! B = UMat^T B^prim, B^T = (B^prim)^T UMat
935 1 pfleura2
  !   BMat_BakerT(:,I)=BMat_BakerT(:,I)+BprimT(:,J)*UMat(J,I)
936 1 pfleura2
  !    END DO
937 1 pfleura2
  !END DO
938 1 pfleura2
  ! TO BE CORRECTED, ENDS HERE.
939 1 pfleura2
940 1 pfleura2
  IntCoordI=0.d0
941 1 pfleura2
  DO IGeom=1, NGeomI
942 1 pfleura2
     DO I=1, NPrim
943 1 pfleura2
        ! Transpose of UMat is needed below, that is why UMat(I,:).
944 1 pfleura2
        IntCoordI(IGeom,:) = IntCoordI(IGeom,:) + UMat(I,:)*Xprimitive(IGeom,I)
945 1 pfleura2
     END DO
946 1 pfleura2
  END DO
947 1 pfleura2
948 1 pfleura2
  if (debug) THEN
949 1 pfleura2
     WRITE(*,*) "DBG Calc_Baker IntCoordI"
950 1 pfleura2
     DO IGeom=1, NGeomI
951 1 pfleura2
        WRITE(*,'(1X,I5,":",30(1X,F10.6))') IGeom,IntCoordI(IGeom,:)
952 1 pfleura2
     END DO
953 1 pfleura2
  END IF
954 1 pfleura2
955 1 pfleura2
956 1 pfleura2
  ! the following might be used to get rid of some coordinates that
957 1 pfleura2
  ! do not respect the symmetry of the problem.
958 1 pfleura2
959 1 pfleura2
  ! ! We look at the group symmetry of the molecule. Nothing complicate here
960 1 pfleura2
  ! ! we just look for planar symmetry.
961 1 pfleura2
  ! ! We first place it into the standard orientation
962 1 pfleura2
  !   Call Std_ori(Nat,x,y,z,a,b,c,massat)
963 1 pfleura2
964 1 pfleura2
  ! ! Is the molecule planar
965 1 pfleura2
  !   DO I=1,Nat
966 1 pfleura2
  !      WRITE(*,*) nom(atome(i)),x(i),y(i),z(i)
967 1 pfleura2
  !      END DO
968 1 pfleura2
  DEALLOCATE(BprimT,GMat,EigVal,EigVec) ! BprimT is B^prim^T
969 1 pfleura2
  ! Calculation of BTransInv starts here:
970 1 pfleura2
  ! Calculation of BBT(3*Nat-6,3*Nat-6)=BB^T:
971 1 pfleura2
  ! BMat_BakerT(3*Nat,NCoord) is Transpose of B = UMat^TB^prim
972 1 pfleura2
  ALLOCATE(BBT(NCoord,NCoord))
973 1 pfleura2
  BBT = 0.d0
974 1 pfleura2
  DO I=1, NCoord
975 1 pfleura2
     DO J=1, 3*Nat
976 1 pfleura2
        ! BBT(:,I) forms BB^T
977 1 pfleura2
        BBT(:,I) = BBT(:,I) + BMat_BakerT(J,:)*BMat_BakerT(J,I)
978 1 pfleura2
     END DO
979 1 pfleura2
  END DO
980 1 pfleura2
981 1 pfleura2
  !ALLOCATE(V(3*Nat,3*Nat))
982 1 pfleura2
  !Call GINVSE(BBT,3*Nat,3*Nat,BBT_inv,3*Nat,3*Nat,3*Nat,1e-6,V,3*Nat,FAIL,NOUT)
983 1 pfleura2
  !DEALLOCATE(V)
984 1 pfleura2
  ALLOCATE(BBT_inv(NCoord,NCoord))
985 1 pfleura2
  ! GenInv is in Mat_util.f90
986 1 pfleura2
  Call GenInv(NCoord,BBT,BBT_inv,NCoord)
987 1 pfleura2
988 1 pfleura2
  ! Calculation of (B^T)^-1 = (BB^T)^-1B:
989 1 pfleura2
  !ALLOCATE(BTransInv(3*Nat-6,3*Nat))    ! allocated in Path.f90
990 1 pfleura2
  BTransInv = 0.d0
991 1 pfleura2
  DO I=1, 3*Nat
992 1 pfleura2
     DO J=1, NCoord
993 1 pfleura2
        BTransInv(:,I) = BTransInv(:,I) + BBT_inv(:,J)*BMat_BakerT(I,J)
994 1 pfleura2
     END DO
995 1 pfleura2
  END DO
996 1 pfleura2
  BTransInv_local = BTransInv
997 1 pfleura2
  UMat_local = UMat
998 1 pfleura2
  DEALLOCATE(BBT,BBT_inv,UMat_tmp)
999 1 pfleura2
  DEALLOCATE(x_refGeom,y_refGeom,z_refGeom,x,y,z)
1000 1 pfleura2
  IF (debug) WRITE(*,*) "DBG Calc_baker over."
1001 1 pfleura2
END SUBROUTINE Calc_baker