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