Statistiques
| Révision :

root / src / Calc_baker_allGeomF.f90 @ 12

Historique | Voir | Annoter | Télécharger (8,61 ko)

1 1 pfleura2
SUBROUTINE Calc_baker_allGeomF()
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 12 pfleura2
9 12 pfleura2
!----------------------------------------------------------------------
10 12 pfleura2
!  Copyright 2003-2014 Ecole Normale Supérieure de Lyon,
11 12 pfleura2
!  Centre National de la Recherche Scientifique,
12 12 pfleura2
!  Université Claude Bernard Lyon 1. All rights reserved.
13 12 pfleura2
!
14 12 pfleura2
!  This work is registered with the Agency for the Protection of Programs
15 12 pfleura2
!  as IDDN.FR.001.100009.000.S.P.2014.000.30625
16 12 pfleura2
!
17 12 pfleura2
!  Authors: P. Fleurat-Lessard, P. Dayal
18 12 pfleura2
!  Contact: optnpath@gmail.com
19 12 pfleura2
!
20 12 pfleura2
! This file is part of "Opt'n Path".
21 12 pfleura2
!
22 12 pfleura2
!  "Opt'n Path" is free software: you can redistribute it and/or modify
23 12 pfleura2
!  it under the terms of the GNU Affero General Public License as
24 12 pfleura2
!  published by the Free Software Foundation, either version 3 of the License,
25 12 pfleura2
!  or (at your option) any later version.
26 12 pfleura2
!
27 12 pfleura2
!  "Opt'n Path" is distributed in the hope that it will be useful,
28 12 pfleura2
!  but WITHOUT ANY WARRANTY; without even the implied warranty of
29 12 pfleura2
!
30 12 pfleura2
!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31 12 pfleura2
!  GNU Affero General Public License for more details.
32 12 pfleura2
!
33 12 pfleura2
!  You should have received a copy of the GNU Affero General Public License
34 12 pfleura2
!  along with "Opt'n Path". If not, see <http://www.gnu.org/licenses/>.
35 12 pfleura2
!
36 12 pfleura2
! Contact The Office of Technology Licensing, valorisation@ens-lyon.fr,
37 12 pfleura2
! for commercial licensing opportunities.
38 12 pfleura2
!----------------------------------------------------------------------
39 8 pfleura2
  Use Path_module, only : BMat_BakerT,Nat,NCoord,UMatF, &
40 8 pfleura2
                          NPrim,BTransInvF,Coordinate, &
41 8 pfleura2
              ScanCoord,BprimT,BBT,BBT_inv,XprimitiveF, &
42 1 pfleura2
              NgeomF,XyzGeomF
43 1 pfleura2
  ! BMat_BakerT(3*Nat,NCoord), NCoord=3*Nat or NFree=3*Nat-6-Symmetry_elimination
44 1 pfleura2
  ! depending upon the coordinate choice. IntCoordI(NGeomI,NCoord) where
45 1 pfleura2
  ! UMatF(NGeomI,NPrim,NCoord), NCoord number of vectors in UMat matrix, i.e. NCoord
46 1 pfleura2
  ! Baker coordinates. NPrim is the number of primitive internal coordinates.
47 1 pfleura2
48 1 pfleura2
  Use Io_module
49 1 pfleura2
  IMPLICIT NONE
50 1 pfleura2
51 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: Geom(:,:) !(3,Nat)
52 1 pfleura2
  ! NPrim is the number of primitive coordinates and NCoord is the number
53 1 pfleura2
  ! of internal coordinates. BMat is actually (NPrim,3*Nat).
54 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: GMat(:,:) !(NPrim,NPrim)
55 1 pfleura2
  ! EigVec(..) contains ALL eigevectors of BMat times BprimT, NOT only Baker Coordinate vectors.
56 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: EigVec(:,:), EigVal(:) ! EigVec(NPrim,NPrim)
57 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: x(:), y(:), z(:)
58 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: XPrimRef(:) ! NPrim
59 1 pfleura2
  INTEGER(KINT) :: IGeom
60 1 pfleura2
61 1 pfleura2
62 2 pfleura2
  INTEGER(KINT) :: I, J, K
63 1 pfleura2
64 1 pfleura2
65 2 pfleura2
  LOGICAL :: debug
66 1 pfleura2
  LOGICAL :: DebugPFL
67 1 pfleura2
68 1 pfleura2
  INTERFACE
69 1 pfleura2
     function valid(string) result (isValid)
70 1 pfleura2
       CHARACTER(*), intent(in) :: string
71 1 pfleura2
       logical                  :: isValid
72 1 pfleura2
     END function VALID
73 1 pfleura2
74 1 pfleura2
     FUNCTION angle(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2)
75 1 pfleura2
       use Path_module, only :  Pi,KINT, KREAL
76 1 pfleura2
       real(KREAL) ::  v1x,v1y,v1z,norm1
77 1 pfleura2
       real(KREAL) ::  v2x,v2y,v2z,norm2
78 1 pfleura2
       real(KREAL) ::  angle
79 1 pfleura2
     END FUNCTION ANGLE
80 1 pfleura2
81 1 pfleura2
     FUNCTION angle_d(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2,v3x,v3y,v3z,norm3)
82 1 pfleura2
       use Path_module, only :  Pi,KINT, KREAL
83 1 pfleura2
       real(KREAL) ::  v1x,v1y,v1z,norm1
84 1 pfleura2
       real(KREAL) ::  v2x,v2y,v2z,norm2
85 1 pfleura2
       real(KREAL) ::  v3x,v3y,v3z,norm3
86 1 pfleura2
       real(KREAL) ::  angle_d,ca,sa
87 1 pfleura2
     END FUNCTION ANGLE_D
88 1 pfleura2
89 1 pfleura2
90 1 pfleura2
91 1 pfleura2
     SUBROUTINE Calc_Xprim(nat,x,y,z,Coordinate,NPrim,XPrimitive,XPrimRef)
92 1 pfleura2
       !
93 1 pfleura2
       ! This subroutine uses the description of a list of Coordinates
94 1 pfleura2
       ! to compute the values of the coordinates for a given geometry.
95 1 pfleura2
       !
96 1 pfleura2
!!!!!!!!!!
97 1 pfleura2
       ! Input:
98 1 pfleura2
       !   Na: INTEGER, Number of atoms
99 1 pfleura2
       !  x,y,z(Na): REAL, cartesian coordinates of the considered geometry
100 1 pfleura2
       ! Coordinate (Pointer(ListCoord)): description of the wanted coordiantes
101 1 pfleura2
       ! NPrim, INTEGER: Number of coordinates to compute
102 1 pfleura2
       !
103 1 pfleura2
       ! Optional: XPrimRef(NPrim) REAL: array that contains coordinates values for
104 1 pfleura2
       ! a former geometry. Useful for Dihedral angles evolution...
105 1 pfleura2
106 1 pfleura2
!!!!!!!!!!!
107 1 pfleura2
       ! Output:
108 1 pfleura2
       ! XPrimimite(NPrim) REAL: array that will contain the values of the coordinates
109 1 pfleura2
       !
110 1 pfleura2
!!!!!!!!!
111 1 pfleura2
112 1 pfleura2
       Use VarTypes
113 1 pfleura2
       Use Io_module
114 1 pfleura2
       Use Path_module, only : pi
115 1 pfleura2
116 1 pfleura2
       IMPLICIT NONE
117 1 pfleura2
118 1 pfleura2
       Type (ListCoord), POINTER :: Coordinate
119 1 pfleura2
       INTEGER(KINT), INTENT(IN) :: Nat,NPrim
120 1 pfleura2
       REAL(KREAL), INTENT(IN) :: x(Nat), y(Nat), z(Nat)
121 1 pfleura2
       REAL(KREAL), INTENT(IN), OPTIONAL :: XPrimRef(NPrim)
122 1 pfleura2
       REAL(KREAL), INTENT(OUT) :: XPrimitive(NPrim)
123 1 pfleura2
124 1 pfleura2
     END SUBROUTINE CALC_XPRIM
125 1 pfleura2
  END INTERFACE
126 1 pfleura2
127 1 pfleura2
128 1 pfleura2
129 1 pfleura2
130 1 pfleura2
  debug=valid("Calc_baker_allGeomF")
131 1 pfleura2
  debugPFL=valid("bakerPFL")
132 1 pfleura2
  if (debug) WRITE(*,*) '============ Entering Calc_baker_allGeomF ============='
133 1 pfleura2
134 1 pfleura2
  ALLOCATE(Geom(3,Nat),x(Nat),y(Nat),z(Nat))
135 1 pfleura2
  ALLOCATE(XPrimRef(NPrim))
136 1 pfleura2
137 1 pfleura2
  ! Now calculating values of all primitive bonds for all final geometries:
138 1 pfleura2
  DO IGeom=1, NGeomF
139 1 pfleura2
     x(1:Nat) = XyzGeomF(IGeom,1,1:Nat)
140 1 pfleura2
     y(1:Nat) = XyzGeomF(IGeom,2,1:Nat)
141 1 pfleura2
     z(1:Nat) = XyzGeomF(IGeom,3,1:Nat)
142 1 pfleura2
     XPrimREf=XPrimitiveF(IGeom,:)
143 1 pfleura2
     Call Calc_XPrim(nat,x,y,z,Coordinate,NPrim,XPrimitiveF(IGeom,:),XPrimRef)
144 1 pfleura2
  END DO ! matches DO IGeom=1, NGeomF
145 1 pfleura2
146 1 pfleura2
  ALLOCATE(BprimT(3*Nat,NPrim))
147 1 pfleura2
  ALLOCATE(Gmat(NPrim,NPrim))
148 1 pfleura2
  ALLOCATE(EigVal(NPrim),EigVec(NPrim,NPrim))
149 1 pfleura2
  ALLOCATE(BBT(NCoord,NCoord))
150 1 pfleura2
  ALLOCATE(BBT_inv(NCoord,NCoord))
151 1 pfleura2
  BTransInvF = 0.d0
152 1 pfleura2
153 1 pfleura2
  DO IGeom=1, NGeomF
154 1 pfleura2
     Geom(1,:)=XyzGeomF(IGeom,1,1:Nat) ! XyzGeomI(NGeomI,3,Nat)
155 1 pfleura2
     Geom(2,:)=XyzGeomF(IGeom,2,1:Nat)
156 1 pfleura2
     Geom(3,:)=XyzGeomF(IGeom,3,1:Nat)
157 1 pfleura2
158 1 pfleura2
   BprimT=0.d0
159 1 pfleura2
     ScanCoord=>Coordinate
160 1 pfleura2
     I=0
161 1 pfleura2
     DO WHILE (Associated(ScanCoord%next))
162 1 pfleura2
        I=I+1
163 1 pfleura2
        SELECT CASE (ScanCoord%Type)
164 1 pfleura2
        CASE ('BOND')
165 1 pfleura2
          CALL CONSTRAINTS_BONDLENGTH_DER(Nat,ScanCoord%at1,ScanCoord%AT2, &
166 1 pfleura2
               Geom,BprimT(1,I))
167 1 pfleura2
        CASE ('ANGLE')
168 1 pfleura2
          CALL CONSTRAINTS_BONDANGLE_DER(Nat,ScanCoord%At1,ScanCoord%AT2, &
169 1 pfleura2
               ScanCoord%At3,Geom,BprimT(1,I))
170 1 pfleura2
        CASE ('DIHEDRAL')
171 1 pfleura2
          CALL CONSTRAINTS_TORSION_DER2(Nat,ScanCoord%At1,ScanCoord%AT2, &
172 1 pfleura2
               ScanCoord%At3,ScanCoord%At4,Geom,BprimT(1,I))
173 1 pfleura2
      END SELECT
174 1 pfleura2
        ScanCoord => ScanCoord%next
175 1 pfleura2
     END DO
176 1 pfleura2
177 1 pfleura2
   ! BprimT(3*Nat,NPrim)
178 1 pfleura2
   ! We now compute G=B(BT) matrix
179 1 pfleura2
   GMat=0.d0
180 1 pfleura2
   DO I=1,NPrim
181 1 pfleura2
    DO J=1,3*Nat
182 1 pfleura2
           GMat(:,I)=Gmat(:,I)+BprimT(J,:)*BprimT(J,I) !*1.d0/mass(atome(int(K/3.d0)))
183 1 pfleura2
    END DO
184 1 pfleura2
   END DO
185 1 pfleura2
186 1 pfleura2
   ! Diagonalize G
187 1 pfleura2
   EigVal=0.d0
188 1 pfleura2
   EigVec=0.d0
189 1 pfleura2
   Call Jacobi(GMat,NPrim,EigVal,EigVec,NPrim)
190 1 pfleura2
   Call Trie(NPrim,EigVal,EigVec,NPrim)
191 1 pfleura2
   DO I=1,NPrim
192 1 pfleura2
    !WRITE(*,'(1X,"Vector ",I3,": e=",F8.3)') I,EigVal(i)
193 1 pfleura2
    !WRITE(*,'(20(1X,F8.4))') EigVec(1:min(20,NPrim),I)
194 1 pfleura2
   END DO
195 1 pfleura2
196 1 pfleura2
   ! UMatF is nonredundant vector set, i.e. set of eigenvectors of BB^T
197 1 pfleura2
   !  corresponding to eigenvalues > zero.
198 1 pfleura2
   ! BMat_BakerT(3*Nat,NCoord), allocated in Path.f90,
199 1 pfleura2
   ! NCoord=3*Nat-6
200 1 pfleura2
   BMat_BakerT = 0.d0
201 1 pfleura2
   J=0
202 1 pfleura2
   DO I=1,NPrim
203 1 pfleura2
    IF (abs(eigval(I))>=1e-6) THEN
204 1 pfleura2
       J=J+1
205 1 pfleura2
       DO K=1,NPrim
206 1 pfleura2
        ! BprimT is transpose of B^prim.
207 1 pfleura2
        ! B = UMatF^T B^prim, B^T = (B^prim)^T UMatF
208 1 pfleura2
        BMat_BakerT(:,J)=BMat_BakerT(:,J)+BprimT(:,K)*Eigvec(K,I)
209 1 pfleura2
       END DO
210 1 pfleura2
         IF(J .GT. 3*Nat-6) THEN
211 1 pfleura2
           WRITE(*,*) 'Number of vectors in Eigvec with eigval .GT. 1e-6(=UMatF) (=' &
212 1 pfleura2
                      ,J,') exceeded 3*Nat-6=',3*Nat-6, &
213 1 pfleura2
            'Stopping the calculation.'
214 1 pfleura2
           STOP
215 1 pfleura2
         END IF
216 1 pfleura2
         UMatF(IGeom,:,J) =  Eigvec(:,I)
217 1 pfleura2
    END IF
218 1 pfleura2
   END DO
219 1 pfleura2
220 1 pfleura2
!!!!!!!!!!!!!!!!!!!!
221 1 pfleura2
!
222 1 pfleura2
! Debug purposes
223 1 pfleura2
!
224 1 pfleura2
         if (debugPFL) THEN
225 1 pfleura2
        UMatF(IGeom,:,:)=0.
226 1 pfleura2
        DO J=1,3*Nat-6
227 1 pfleura2
           UMatF(IGeom,J,J)=1.
228 1 pfleura2
        END DO
229 1 pfleura2
        END IF
230 1 pfleura2
231 1 pfleura2
232 1 pfleura2
   !DO I=1, NPrim ! This loop is not needed because we already have IntCoordF
233 1 pfleura2
             ! from interpolation.
234 1 pfleura2
   ! Transpose of UMatF is needed below, that is why UMatF(IGeom,I,:).
235 1 pfleura2
   ! IntCoordF(IGeom,:) = IntCoordF(IGeom,:) + UMat(IGeom,I,:)*XprimitiveF(IGeom,I)
236 1 pfleura2
   !END DO
237 1 pfleura2
238 1 pfleura2
   ! Calculation of BTransInvF starts here:
239 1 pfleura2
   ! Calculation of BBT(3*Nat-6,3*Nat-6)=BB^T:
240 1 pfleura2
   ! BMat_BakerT(3*Nat,NCoord) is Transpose of B = UMatF^TB^prim
241 1 pfleura2
242 1 pfleura2
   BBT = 0.d0
243 1 pfleura2
   DO I=1, NCoord
244 1 pfleura2
      DO J=1, 3*Nat
245 1 pfleura2
       ! BBT(:,I) forms BB^T
246 1 pfleura2
       BBT(:,I) = BBT(:,I) + BMat_BakerT(J,:)*BMat_BakerT(J,I)
247 1 pfleura2
    END DO
248 1 pfleura2
   END DO
249 1 pfleura2
250 1 pfleura2
   Call GenInv(NCoord,BBT,BBT_inv,NCoord) ! GenInv is in Mat_util.f90
251 1 pfleura2
252 1 pfleura2
   ! Calculation of (B^T)^-1 = (BB^T)^-1B:
253 1 pfleura2
   DO I=1, 3*Nat
254 1 pfleura2
      DO J=1, NCoord
255 1 pfleura2
        BTransInvF(IGeom,:,I) = BTransInvF(IGeom,:,I) + BBT_inv(:,J)*BMat_BakerT(I,J)
256 1 pfleura2
      END DO
257 1 pfleura2
   END DO
258 1 pfleura2
259 1 pfleura2
  END DO !matches DO IGeom=1, NGeomF
260 1 pfleura2
261 1 pfleura2
  DEALLOCATE(BBT,BBT_inv,BprimT,GMat,EigVal,EigVec)
262 1 pfleura2
  DEALLOCATE(Geom,x,y,z,XprimRef)
263 1 pfleura2
264 1 pfleura2
  IF (debug) WRITE(*,*) "DBG Calc_baker_allGeomF over."
265 1 pfleura2
END SUBROUTINE Calc_baker_allGeomF