Statistiques
| Révision :

root / src / Calc_baker_allGeomF.f90 @ 4

Historique | Voir | Annoter | Télécharger (9,76 ko)

1 1 equemene
SUBROUTINE Calc_baker_allGeomF()
2 1 equemene
  !
3 1 equemene
  ! This subroutine analyses a geometry to construct the baker
4 1 equemene
  ! delocalized internal coordinates
5 1 equemene
  ! v1.0
6 1 equemene
  ! We use only one geometry
7 1 equemene
  !
8 1 equemene
  Use Path_module, only : Pi,a0,BMat_BakerT,Nat,NCoord,XyzGeomI,NGeomI,UMatF, &
9 1 equemene
                          NPrim,BTransInvF,IntCoordI,Coordinate,CurrentCoord, &
10 4 pfleura2
              ScanCoord,BprimT,BBT,BBT_inv,XprimitiveF,Symmetry_elimination, &
11 4 pfleura2
              NgeomF,XyzGeomF
12 1 equemene
  ! BMat_BakerT(3*Nat,NCoord), NCoord=3*Nat or NFree=3*Nat-6-Symmetry_elimination
13 1 equemene
  ! depending upon the coordinate choice. IntCoordI(NGeomI,NCoord) where
14 1 equemene
  ! UMatF(NGeomI,NPrim,NCoord), NCoord number of vectors in UMat matrix, i.e. NCoord
15 1 equemene
  ! Baker coordinates. NPrim is the number of primitive internal coordinates.
16 1 equemene
17 1 equemene
  Use Io_module
18 1 equemene
  IMPLICIT NONE
19 1 equemene
20 1 equemene
  REAL(KREAL), ALLOCATABLE :: Geom(:,:) !(3,Nat)
21 1 equemene
  ! NPrim is the number of primitive coordinates and NCoord is the number
22 1 equemene
  ! of internal coordinates. BMat is actually (NPrim,3*Nat).
23 1 equemene
  REAL(KREAL), ALLOCATABLE :: GMat(:,:) !(NPrim,NPrim)
24 1 equemene
  ! EigVec(..) contains ALL eigevectors of BMat times BprimT, NOT only Baker Coordinate vectors.
25 1 equemene
  REAL(KREAL), ALLOCATABLE :: EigVec(:,:), EigVal(:) ! EigVec(NPrim,NPrim)
26 1 equemene
  REAL(KREAL), ALLOCATABLE :: x(:), y(:), z(:)
27 1 equemene
  REAL(KREAL), ALLOCATABLE :: XPrimRef(:) ! NPrim
28 1 equemene
  INTEGER(KINT) :: IGeom
29 1 equemene
30 1 equemene
  real(KREAL) ::  vx,vy,vz,dist, Norm
31 1 equemene
  real(KREAL) ::  vx1,vy1,vz1,norm1
32 1 equemene
  real(KREAL) ::  vx2,vy2,vz2,norm2
33 1 equemene
  real(KREAL) ::  vx3,vy3,vz3,norm3
34 1 equemene
  real(KREAL) ::  vx4,vy4,vz4,norm4
35 1 equemene
  real(KREAL) ::  vx5,vy5,vz5,norm5
36 1 equemene
  real(KREAL) ::  val,val_d, Q, T
37 1 equemene
38 1 equemene
  INTEGER(KINT) :: I,J, n1,n2,n3,n4,IAt,IL,JL,IFrag,ITmp, K, KMax
39 1 equemene
  INTEGER(KINT) :: I0, IOld, IAtTmp, Izm, JAt, Kat, Lat, L, NOUT
40 1 equemene
41 1 equemene
  REAL(KREAL) :: sAngleIatIKat, sAngleIIatLat
42 1 equemene
  REAL(KREAL) :: DiheTmp
43 1 equemene
44 1 equemene
  LOGICAL :: debug, bond, AddPrimitiveCoord, FAIL
45 1 equemene
  LOGICAL :: DebugPFL
46 1 equemene
47 1 equemene
  INTERFACE
48 1 equemene
     function valid(string) result (isValid)
49 1 equemene
       CHARACTER(*), intent(in) :: string
50 1 equemene
       logical                  :: isValid
51 1 equemene
     END function VALID
52 1 equemene
53 1 equemene
     FUNCTION angle(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2)
54 1 equemene
       use Path_module, only :  Pi,KINT, KREAL
55 1 equemene
       real(KREAL) ::  v1x,v1y,v1z,norm1
56 1 equemene
       real(KREAL) ::  v2x,v2y,v2z,norm2
57 1 equemene
       real(KREAL) ::  angle
58 1 equemene
     END FUNCTION ANGLE
59 1 equemene
60 1 equemene
     FUNCTION angle_d(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2,v3x,v3y,v3z,norm3)
61 1 equemene
       use Path_module, only :  Pi,KINT, KREAL
62 1 equemene
       real(KREAL) ::  v1x,v1y,v1z,norm1
63 1 equemene
       real(KREAL) ::  v2x,v2y,v2z,norm2
64 1 equemene
       real(KREAL) ::  v3x,v3y,v3z,norm3
65 1 equemene
       real(KREAL) ::  angle_d,ca,sa
66 1 equemene
     END FUNCTION ANGLE_D
67 1 equemene
68 1 equemene
69 1 equemene
70 1 equemene
     SUBROUTINE Calc_Xprim(nat,x,y,z,Coordinate,NPrim,XPrimitive,XPrimRef)
71 1 equemene
       !
72 1 equemene
       ! This subroutine uses the description of a list of Coordinates
73 1 equemene
       ! to compute the values of the coordinates for a given geometry.
74 1 equemene
       !
75 1 equemene
!!!!!!!!!!
76 1 equemene
       ! Input:
77 1 equemene
       !   Na: INTEGER, Number of atoms
78 1 equemene
       !  x,y,z(Na): REAL, cartesian coordinates of the considered geometry
79 1 equemene
       ! Coordinate (Pointer(ListCoord)): description of the wanted coordiantes
80 1 equemene
       ! NPrim, INTEGER: Number of coordinates to compute
81 1 equemene
       !
82 1 equemene
       ! Optional: XPrimRef(NPrim) REAL: array that contains coordinates values for
83 1 equemene
       ! a former geometry. Useful for Dihedral angles evolution...
84 1 equemene
85 1 equemene
!!!!!!!!!!!
86 1 equemene
       ! Output:
87 1 equemene
       ! XPrimimite(NPrim) REAL: array that will contain the values of the coordinates
88 1 equemene
       !
89 1 equemene
!!!!!!!!!
90 1 equemene
91 1 equemene
       Use VarTypes
92 1 equemene
       Use Io_module
93 1 equemene
       Use Path_module, only : pi
94 1 equemene
95 1 equemene
       IMPLICIT NONE
96 1 equemene
97 1 equemene
       Type (ListCoord), POINTER :: Coordinate
98 1 equemene
       INTEGER(KINT), INTENT(IN) :: Nat,NPrim
99 1 equemene
       REAL(KREAL), INTENT(IN) :: x(Nat), y(Nat), z(Nat)
100 1 equemene
       REAL(KREAL), INTENT(IN), OPTIONAL :: XPrimRef(NPrim)
101 1 equemene
       REAL(KREAL), INTENT(OUT) :: XPrimitive(NPrim)
102 1 equemene
103 1 equemene
     END SUBROUTINE CALC_XPRIM
104 1 equemene
  END INTERFACE
105 1 equemene
106 1 equemene
107 1 equemene
108 1 equemene
109 1 equemene
  debug=valid("Calc_baker_allGeomF")
110 1 equemene
  debugPFL=valid("bakerPFL")
111 1 equemene
  if (debug) WRITE(*,*) '============ Entering Calc_baker_allGeomF ============='
112 1 equemene
113 1 equemene
  ALLOCATE(Geom(3,Nat),x(Nat),y(Nat),z(Nat))
114 1 equemene
  ALLOCATE(XPrimRef(NPrim))
115 1 equemene
116 1 equemene
  ! Now calculating values of all primitive bonds for all final geometries:
117 1 equemene
  DO IGeom=1, NGeomF
118 1 equemene
     x(1:Nat) = XyzGeomF(IGeom,1,1:Nat)
119 1 equemene
     y(1:Nat) = XyzGeomF(IGeom,2,1:Nat)
120 1 equemene
     z(1:Nat) = XyzGeomF(IGeom,3,1:Nat)
121 1 equemene
     XPrimREf=XPrimitiveF(IGeom,:)
122 1 equemene
     Call Calc_XPrim(nat,x,y,z,Coordinate,NPrim,XPrimitiveF(IGeom,:),XPrimRef)
123 1 equemene
!    ScanCoord=>Coordinate
124 1 equemene
!    I=0 ! index for the NPrim (NPrim is the number of primitive coordinates).
125 1 equemene
!    DO WHILE (Associated(ScanCoord%next))
126 1 equemene
!      I=I+1
127 1 equemene
!      SELECT CASE (ScanCoord%Type)
128 1 equemene
!       CASE ('BOND')
129 4 pfleura2
!       Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx2,vy2,vz2,Norm2)
130 4 pfleura2
!            XprimitiveF(IGeom,I) = Norm2
131 1 equemene
!       CASE ('ANGLE')
132 4 pfleura2
!     Call vecteur(ScanCoord%At2,ScanCoord%At3,x,y,z,vx1,vy1,vz1,Norm1)
133 4 pfleura2
!     Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx2,vy2,vz2,Norm2)
134 4 pfleura2
!          XprimitiveF(IGeom,I) = angle(vx1,vy1,vz1,Norm1,vx2,vy2,vz2,Norm2)*Pi/180.
135 4 pfleura2
!     CASE ('DIHEDRAL')
136 4 pfleura2
!     Call vecteur(ScanCoord%At3,ScanCoord%At2,x,y,z,vx2,vy2,vz2,Norm2)
137 4 pfleura2
!     Call vecteur(ScanCoord%At2,ScanCoord%At1,x,y,z,vx1,vy1,vz1,Norm1)
138 4 pfleura2
!     Call vecteur(ScanCoord%At3,ScanCoord%At4,x,y,z,vx3,vy3,vz3,Norm3)
139 4 pfleura2
!     Call produit_vect(vx3,vy3,vz3,norm3,vx2,vy2,vz2,norm2, &
140 1 equemene
!                         vx5,vy5,vz5,norm5)
141 4 pfleura2
!     Call produit_vect(vx1,vy1,vz1,norm1,vx2,vy2,vz2,norm2, &
142 1 equemene
!                         vx4,vy4,vz4,norm4)
143 1 equemene
!                 DiheTmp= angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, &
144 1 equemene
!                         vx2,vy2,vz2,norm2)
145 1 equemene
!                 XprimitiveF(IGeom,I) = DiheTmp*Pi/180.
146 1 equemene
!! We treat large dihedral angles differently as +180=-180 mathematically and physically
147 1 equemene
!! but this causes lots of troubles when converting baker to cart.
148 1 equemene
!! So we ensure that large dihedral angles always have the same sign
149 1 equemene
!                    if (abs(ScanCoord%SignDihedral).NE.1) THEN
150 1 equemene
!                        ScanCoord%SignDihedral=Int(Sign(1.d0,DiheTmp))
151 1 equemene
!                    ELSE
152 1 equemene
!                         If ((abs(DiheTmp).GE.170.D0).AND.(Sign(1.,DiheTmp)*ScanCoord%SignDihedral<0)) THEN
153 1 equemene
!                          XprimitiveF(IGeom,I) = DiheTmp*Pi/180.+ ScanCoord%SignDihedral*2.*Pi
154 1 equemene
!                        END IF
155 1 equemene
!                    END IF
156 1 equemene
!      END SELECT
157 1 equemene
!      ScanCoord => ScanCoord%next
158 1 equemene
!    END DO ! matches DO WHILE (Associated(ScanCoord%next))
159 1 equemene
  END DO ! matches DO IGeom=1, NGeomF
160 1 equemene
161 1 equemene
  ALLOCATE(BprimT(3*Nat,NPrim))
162 1 equemene
  ALLOCATE(Gmat(NPrim,NPrim))
163 1 equemene
  ALLOCATE(EigVal(NPrim),EigVec(NPrim,NPrim))
164 1 equemene
  ALLOCATE(BBT(NCoord,NCoord))
165 1 equemene
  ALLOCATE(BBT_inv(NCoord,NCoord))
166 1 equemene
  BTransInvF = 0.d0
167 1 equemene
168 1 equemene
  DO IGeom=1, NGeomF
169 1 equemene
     Geom(1,:)=XyzGeomF(IGeom,1,1:Nat) ! XyzGeomI(NGeomI,3,Nat)
170 1 equemene
     Geom(2,:)=XyzGeomF(IGeom,2,1:Nat)
171 1 equemene
     Geom(3,:)=XyzGeomF(IGeom,3,1:Nat)
172 1 equemene
173 4 pfleura2
   BprimT=0.d0
174 1 equemene
     ScanCoord=>Coordinate
175 1 equemene
     I=0
176 1 equemene
     DO WHILE (Associated(ScanCoord%next))
177 1 equemene
        I=I+1
178 1 equemene
        SELECT CASE (ScanCoord%Type)
179 1 equemene
        CASE ('BOND')
180 1 equemene
          CALL CONSTRAINTS_BONDLENGTH_DER(Nat,ScanCoord%at1,ScanCoord%AT2, &
181 1 equemene
               Geom,BprimT(1,I))
182 1 equemene
        CASE ('ANGLE')
183 1 equemene
          CALL CONSTRAINTS_BONDANGLE_DER(Nat,ScanCoord%At1,ScanCoord%AT2, &
184 1 equemene
               ScanCoord%At3,Geom,BprimT(1,I))
185 1 equemene
        CASE ('DIHEDRAL')
186 1 equemene
          CALL CONSTRAINTS_TORSION_DER2(Nat,ScanCoord%At1,ScanCoord%AT2, &
187 1 equemene
               ScanCoord%At3,ScanCoord%At4,Geom,BprimT(1,I))
188 4 pfleura2
      END SELECT
189 1 equemene
        ScanCoord => ScanCoord%next
190 1 equemene
     END DO
191 1 equemene
192 4 pfleura2
   ! BprimT(3*Nat,NPrim)
193 4 pfleura2
   ! We now compute G=B(BT) matrix
194 4 pfleura2
   GMat=0.d0
195 4 pfleura2
   DO I=1,NPrim
196 4 pfleura2
    DO J=1,3*Nat
197 1 equemene
           GMat(:,I)=Gmat(:,I)+BprimT(J,:)*BprimT(J,I) !*1.d0/mass(atome(int(K/3.d0)))
198 4 pfleura2
    END DO
199 4 pfleura2
   END DO
200 1 equemene
201 4 pfleura2
   ! Diagonalize G
202 4 pfleura2
   EigVal=0.d0
203 4 pfleura2
   EigVec=0.d0
204 4 pfleura2
   Call Jacobi(GMat,NPrim,EigVal,EigVec,NPrim)
205 4 pfleura2
   Call Trie(NPrim,EigVal,EigVec,NPrim)
206 4 pfleura2
   DO I=1,NPrim
207 4 pfleura2
    !WRITE(*,'(1X,"Vector ",I3,": e=",F8.3)') I,EigVal(i)
208 4 pfleura2
    !WRITE(*,'(20(1X,F8.4))') EigVec(1:min(20,NPrim),I)
209 4 pfleura2
   END DO
210 1 equemene
211 4 pfleura2
   ! UMatF is nonredundant vector set, i.e. set of eigenvectors of BB^T
212 4 pfleura2
   !  corresponding to eigenvalues > zero.
213 4 pfleura2
   ! BMat_BakerT(3*Nat,NCoord), allocated in Path.f90,
214 4 pfleura2
   ! NCoord=3*Nat-6
215 4 pfleura2
   BMat_BakerT = 0.d0
216 4 pfleura2
   J=0
217 4 pfleura2
   DO I=1,NPrim
218 4 pfleura2
    IF (abs(eigval(I))>=1e-6) THEN
219 4 pfleura2
       J=J+1
220 4 pfleura2
       DO K=1,NPrim
221 4 pfleura2
        ! BprimT is transpose of B^prim.
222 4 pfleura2
        ! B = UMatF^T B^prim, B^T = (B^prim)^T UMatF
223 4 pfleura2
        BMat_BakerT(:,J)=BMat_BakerT(:,J)+BprimT(:,K)*Eigvec(K,I)
224 4 pfleura2
       END DO
225 4 pfleura2
         IF(J .GT. 3*Nat-6) THEN
226 4 pfleura2
           WRITE(*,*) 'Number of vectors in Eigvec with eigval .GT. 1e-6(=UMatF) (=' &
227 1 equemene
                      ,J,') exceeded 3*Nat-6=',3*Nat-6, &
228 4 pfleura2
            'Stopping the calculation.'
229 4 pfleura2
           STOP
230 4 pfleura2
         END IF
231 4 pfleura2
         UMatF(IGeom,:,J) =  Eigvec(:,I)
232 4 pfleura2
    END IF
233 4 pfleura2
   END DO
234 1 equemene
235 1 equemene
!!!!!!!!!!!!!!!!!!!!
236 1 equemene
!
237 1 equemene
! Debug purposes
238 1 equemene
!
239 1 equemene
         if (debugPFL) THEN
240 1 equemene
        UMatF(IGeom,:,:)=0.
241 1 equemene
        DO J=1,3*Nat-6
242 1 equemene
           UMatF(IGeom,J,J)=1.
243 1 equemene
        END DO
244 1 equemene
        END IF
245 1 equemene
246 1 equemene
247 4 pfleura2
   !DO I=1, NPrim ! This loop is not needed because we already have IntCoordF
248 4 pfleura2
             ! from interpolation.
249 4 pfleura2
   ! Transpose of UMatF is needed below, that is why UMatF(IGeom,I,:).
250 4 pfleura2
   ! IntCoordF(IGeom,:) = IntCoordF(IGeom,:) + UMat(IGeom,I,:)*XprimitiveF(IGeom,I)
251 4 pfleura2
   !END DO
252 1 equemene
253 4 pfleura2
   ! Calculation of BTransInvF starts here:
254 4 pfleura2
   ! Calculation of BBT(3*Nat-6,3*Nat-6)=BB^T:
255 4 pfleura2
   ! BMat_BakerT(3*Nat,NCoord) is Transpose of B = UMatF^TB^prim
256 4 pfleura2
257 4 pfleura2
   BBT = 0.d0
258 4 pfleura2
   DO I=1, NCoord
259 4 pfleura2
      DO J=1, 3*Nat
260 4 pfleura2
       ! BBT(:,I) forms BB^T
261 4 pfleura2
       BBT(:,I) = BBT(:,I) + BMat_BakerT(J,:)*BMat_BakerT(J,I)
262 4 pfleura2
    END DO
263 4 pfleura2
   END DO
264 4 pfleura2
265 4 pfleura2
   Call GenInv(NCoord,BBT,BBT_inv,NCoord) ! GenInv is in Mat_util.f90
266 1 equemene
267 4 pfleura2
   ! Calculation of (B^T)^-1 = (BB^T)^-1B:
268 4 pfleura2
   DO I=1, 3*Nat
269 4 pfleura2
      DO J=1, NCoord
270 4 pfleura2
        BTransInvF(IGeom,:,I) = BTransInvF(IGeom,:,I) + BBT_inv(:,J)*BMat_BakerT(I,J)
271 4 pfleura2
      END DO
272 4 pfleura2
   END DO
273 4 pfleura2
274 1 equemene
  END DO !matches DO IGeom=1, NGeomF
275 1 equemene
276 1 equemene
  DEALLOCATE(BBT,BBT_inv,BprimT,GMat,EigVal,EigVec)
277 1 equemene
  DEALLOCATE(Geom,x,y,z,XprimRef)
278 1 equemene
279 1 equemene
  IF (debug) WRITE(*,*) "DBG Calc_baker_allGeomF over."
280 1 equemene
END SUBROUTINE Calc_baker_allGeomF