root / utils / Xyz2Path.f @ 4
Historique | Voir | Annoter | Télécharger (27,98 ko)
1 | 1 | equemene | program Xyz2Path |
---|---|---|---|
2 | 1 | equemene | ! This programs reads a XYZ file and converts it into distances, |
3 | 1 | equemene | ! valence angle and dihedral angles. |
4 | 1 | equemene | ! It prints them as a function of the irc distance... |
5 | 1 | equemene | !----------------------------------------------- |
6 | 1 | equemene | ! Input: name of the XYZ File |
7 | 1 | equemene | ! it also needs a file call list which has the following structure: |
8 | 1 | equemene | ! one line contains the type of the value you want to follow, it can be |
9 | 1 | equemene | ! b for a Bond distance |
10 | 1 | equemene | ! a for an angle |
11 | 1 | equemene | ! d for a dihedral |
12 | 1 | equemene | ! this descriptor is followed by the number of the atoms involved ! |
13 | 1 | equemene | ! a typical file can be: |
14 | 1 | equemene | ! b 1 2 |
15 | 1 | equemene | ! b 2 3 |
16 | 1 | equemene | ! a 1 2 3 |
17 | 1 | equemene | !---------------------------------------------- |
18 | 1 | equemene | ! Ouput: A files call Scan.dat |
19 | 1 | equemene | ! wich contains in the first lines the input file (as a reminder) |
20 | 1 | equemene | ! and then for each step the wanted values |
21 | 1 | equemene | !------------------------------------------------ |
22 | 1 | equemene | ! Second version also reads the energy (as to be written after E= on |
23 | 1 | equemene | ! the comment line) |
24 | 1 | equemene | !------------------------------------------------ |
25 | 1 | equemene | ! Third version contains a new command: c for Center of Mass |
26 | 1 | equemene | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
27 | 1 | equemene | ! v 3.1 the c command now creates the center of mass... and allows |
28 | 1 | equemene | ! people to do whatever they want with it... |
29 | 1 | equemene | ! Syntax: c NbAt ListAt |
30 | 1 | equemene | |
31 | 1 | equemene | |
32 | 1 | equemene | IMPLICIT NONE |
33 | 1 | equemene | |
34 | 1 | equemene | INCLUDE "Xyz2Path.param" |
35 | 1 | equemene | |
36 | 1 | equemene | character*40 f1 |
37 | 1 | equemene | REAL*8 geos(3,maxnat), geos1(3,maxnat) |
38 | 1 | equemene | character*33 fmt |
39 | 1 | equemene | character*3 atoms(maxnat) |
40 | 1 | equemene | character*5 Type |
41 | 1 | equemene | Character*120 line |
42 | 1 | equemene | INTEGER*4 NbPrint |
43 | 1 | equemene | REAL*8 AU2PS,Pi |
44 | 1 | equemene | REAL*8 Mass(MaxNat), Ener, Conv, Ds, s |
45 | 1 | equemene | REAL*8 MassAt(0:86) |
46 | 1 | equemene | INTEGER*4 At1,At2,At3,At4,IOOUT,Iat |
47 | 1 | equemene | INTEGER*4 IArg, I, NNN, Ng, J |
48 | 1 | equemene | |
49 | 1 | equemene | INTEGER*4 Nat,NbDist, NbAngle, NbDie,NbCOM |
50 | 1 | equemene | INTEGER*4 At1B(MaxNat),At2B(MaxNat) |
51 | 1 | equemene | INTEGER*4 At1A(MaxNat),At2A(MaxNat),At3A(MaxNat) |
52 | 1 | equemene | INTEGER*4 At1D(MaxNat),At2D(MaxNat),At3D(MaxNat),At4D(MaxNat) |
53 | 1 | equemene | INTEGER*4 AtCom(0:MaxNat,MaxNat) |
54 | 1 | equemene | REAL*8 VB(MaxNat),VA(MaxNat),VD(MaxNat),VCOM(MaxNat) |
55 | 1 | equemene | |
56 | 1 | equemene | REAL*8 MRot(3,3), Rmsd |
57 | 1 | equemene | LOGICAL FExist,FRot,FAlign,Debug |
58 | 1 | equemene | |
59 | 1 | equemene | INTEGER*4 ConvertNumAt |
60 | 1 | equemene | external ConvertNumAt |
61 | 1 | equemene | |
62 | 1 | equemene | COMMON /Indices/Nat,NbDist,NbAngle,NbDie,NbCom, At1B,At2B, |
63 | 1 | equemene | & At1A,At2A,At3A,At1D,At2D,At3D,At4D,AtCom |
64 | 1 | equemene | COMMON /Values/VB,VA,VD,VCom |
65 | 1 | equemene | COMMON /Const/AU2ps,Pi |
66 | 1 | equemene | |
67 | 1 | equemene | DATA MassAt/0.0D0, |
68 | 1 | equemene | $ 1.0078D0, 4.0026D0, |
69 | 1 | equemene | $ 7.0160D0, 9.0122D0,11.0093D0, |
70 | 1 | equemene | $ 12.0000D0,14.0031D0,15.9949D0,18.9984D0,19.9924D0, |
71 | 1 | equemene | $ 22.9898D0,23.9850D0,26.9815D0, |
72 | 1 | equemene | $ 27.9769D0,30.9738D0,31.9721D0,34.9688D0,39.9624D0, |
73 | 1 | equemene | $ 39.0983D0,40.08D0, |
74 | 1 | equemene | $ 44.9559D0, 47.88D0, 50.9415D0, 51.996D0, 54.9380D0, |
75 | 1 | equemene | $ 55.847D0, 58.9332D0, 58.69D0, 63.546D0, 65.39D0, |
76 | 1 | equemene | $ 69.72D0,72.59D0,74.9216D0,78.96D0,79.904D0,83.80D0, |
77 | 1 | equemene | $ 85.4678D0,87.62D0,88.9059D0,91.224D0,92.9064D0, |
78 | 1 | equemene | $ 95.94D0,98D0,101.07D0,102.906D0,106.42D0,107.868D0,112.41D0, |
79 | 1 | equemene | $ 114.82D0,118.71D0,121.75D0,127.60D0,126.905D0,131.29D0, |
80 | 1 | equemene | ! 6 'CS','BA', |
81 | 1 | equemene | $ 132.905,137.34, |
82 | 1 | equemene | ! 6 'LA', |
83 | 1 | equemene | ! 'CE','PR','ND','PM','SM','EU','GD', |
84 | 1 | equemene | ! 'TB','DY','HO', 'ER','TM','YB','LU', |
85 | 1 | equemene | $ 138.91, |
86 | 1 | equemene | $ 140.12, 130.91, 144.24,147.,150.35, 151.96,157.25, |
87 | 1 | equemene | $ 158.924, 162.50, 164.93, 167.26,168.93,173.04,174.97, |
88 | 1 | equemene | ! 6 'HF','TA',' W','RE','OS','IR','PT', |
89 | 1 | equemene | ! 'AU','HG', |
90 | 1 | equemene | ! 6 'TL','PB','BI','PO','AT','RN'/ |
91 | 1 | equemene | $ 178.49, 180.95, 183.85, 186.2, 190.2, 192.2, 195.09, |
92 | 1 | equemene | $ 196.97, 200.59, |
93 | 1 | equemene | $ 204.37, 207.19,208.98,210.,210.,222. / |
94 | 1 | equemene | |
95 | 1 | equemene | |
96 | 1 | equemene | AU2PS=1./41341.37 |
97 | 1 | equemene | NbPrint=100 |
98 | 1 | equemene | Pi=dacos(-1.d0) |
99 | 1 | equemene | IOOUT=13 |
100 | 1 | equemene | Conv=1. |
101 | 1 | equemene | FRot=.TRUE. |
102 | 1 | equemene | FAlign=.TRUE. |
103 | 1 | equemene | Debug=.FALSE. |
104 | 1 | equemene | NbDist=0 |
105 | 1 | equemene | NbAngle=0 |
106 | 1 | equemene | NbDie=0 |
107 | 1 | equemene | |
108 | 1 | equemene | iarg=command_argument_count() |
109 | 1 | equemene | if (iarg.lt.1) then |
110 | 1 | equemene | write(*,*) 'XYZ filename:' |
111 | 1 | equemene | read(*,'(a)') f1 |
112 | 1 | equemene | else |
113 | 1 | equemene | call getarg(1,f1) |
114 | 1 | equemene | endif |
115 | 1 | equemene | |
116 | 1 | equemene | open(13,file='Scan.dat') |
117 | 1 | equemene | |
118 | 1 | equemene | INQUIRE(File='list',Exist=FExist) |
119 | 1 | equemene | if (.NOT.FExist) THEN |
120 | 1 | equemene | WRITE(*,*) "No file 'list', just printing Energy" |
121 | 1 | equemene | END IF |
122 | 1 | equemene | |
123 | 1 | equemene | open(11,file=f1) |
124 | 1 | equemene | call rtraitem(11,nnn,ener,geos1,atoms) |
125 | 1 | equemene | close(11) |
126 | 1 | equemene | |
127 | 1 | equemene | DO I=1,nnn |
128 | 1 | equemene | Iat=ConvertNumAt(atoms(I)) |
129 | 1 | equemene | Mass(I)=MassAt(Iat) |
130 | 1 | equemene | ! write(*,*) I,Atoms(I),Mass(I),geos1(:,I) |
131 | 1 | equemene | END DO |
132 | 1 | equemene | |
133 | 3 | pfleura2 | Nat=nnn |
134 | 3 | pfleura2 | |
135 | 1 | equemene | if (FExist) THEN |
136 | 1 | equemene | open(14,file='list') |
137 | 1 | equemene | Type="d" |
138 | 1 | equemene | DO WHILE (Type.ne."E") |
139 | 1 | equemene | CALL READLINE(14,Type,Line) |
140 | 1 | equemene | ! WRITE(*,*) Line,Type |
141 | 1 | equemene | if (Type.eq."b") THEN |
142 | 1 | equemene | NbDist=NbDist+1 |
143 | 1 | equemene | READ(Line,*) At1,At2 |
144 | 1 | equemene | At1B(NbDist)=At1 |
145 | 1 | equemene | At2B(NbDist)=At2 |
146 | 1 | equemene | WRITE(13,'("# b ",2(A3,I3))') Atoms(At1),At1,Atoms(At2),At2 |
147 | 1 | equemene | WRITE(*,'("# b ",2(A3,I3))') Atoms(At1),At1,Atoms(At2),At2 |
148 | 1 | equemene | END IF |
149 | 1 | equemene | if (Type.eq."a") THEN |
150 | 1 | equemene | NbAngle=NbAngle+1 |
151 | 1 | equemene | READ(Line,*) At1,At2,At3 |
152 | 1 | equemene | At1A(NbAngle)=At1 |
153 | 1 | equemene | At2A(NbAngle)=At2 |
154 | 1 | equemene | At3A(NbAngle)=At3 |
155 | 1 | equemene | WRITE(13,'("# a ",3(A3,I3))') Atoms(At1),At1,Atoms(At2), |
156 | 1 | equemene | & At2, Atoms(At3),At3 |
157 | 1 | equemene | WRITE(*,'("# a ",3(A3,I3))') Atoms(At1),At1,Atoms(At2), |
158 | 1 | equemene | & At2, Atoms(At3),At3 |
159 | 1 | equemene | END IF |
160 | 1 | equemene | if (Type.eq."d") THEN |
161 | 1 | equemene | NbDie=NbDie+1 |
162 | 1 | equemene | READ(Line,*) At1,At2,At3,At4 |
163 | 1 | equemene | At1D(NbDie)=At1 |
164 | 1 | equemene | At2D(NbDie)=At2 |
165 | 1 | equemene | At3D(NbDie)=At3 |
166 | 1 | equemene | At4D(NbDie)=At4 |
167 | 1 | equemene | WRITE(13,'("# d ",4(A3,I3))') Atoms(At1),At1,Atoms(At2),At2, |
168 | 1 | equemene | & Atoms(At3),At3,Atoms(At4),At4 |
169 | 1 | equemene | WRITE(*,'("# d ",4(A3,I3))') Atoms(At1),At1,Atoms(At2),At2, |
170 | 1 | equemene | & Atoms(At3),At3,Atoms(At4),At4 |
171 | 1 | equemene | |
172 | 1 | equemene | END IF |
173 | 1 | equemene | if (Type.eq."c") THEN |
174 | 1 | equemene | NbCOM=NbCOM+1 |
175 | 1 | equemene | READ(Line,*) At1,(AtCom(j,NbCOM),j=1,At1) |
176 | 1 | equemene | AtCom(0,NbCOM)=At1 |
177 | 1 | equemene | Atoms(nat+NbCom)="G" |
178 | 1 | equemene | WRITE(13,'("# c ",I4,20(A3,I3))') At1, |
179 | 1 | equemene | & (Atoms(AtCom(i,NbCoM)),AtCom(i,NbCOM),i=1,At1) |
180 | 1 | equemene | WRITE(*,'("# c ",I4,20(A3,I3))') At1, |
181 | 1 | equemene | & (Atoms(AtCom(i,NbCoM)),AtCom(i,NbCOM),i=1,At1) |
182 | 1 | equemene | END IF |
183 | 1 | equemene | |
184 | 1 | equemene | END DO |
185 | 1 | equemene | END IF |
186 | 1 | equemene | |
187 | 1 | equemene | |
188 | 1 | equemene | |
189 | 1 | equemene | fmt='( (1X,F12.5),1X,F15.6)' |
190 | 1 | equemene | write(fmt(2:4),'(i3)') NbDist+NbAngle+NbDie+1 |
191 | 1 | equemene | ! write(*,*) nat3 |
192 | 1 | equemene | ! write(*,*) 'fmt:',fmt |
193 | 1 | equemene | |
194 | 1 | equemene | ng=1 |
195 | 1 | equemene | |
196 | 1 | equemene | s=0. |
197 | 1 | equemene | |
198 | 1 | equemene | open(11,file=f1) |
199 | 1 | equemene | |
200 | 1 | equemene | 10 call rtraitem(11,nnn,ener,geos,atoms) |
201 | 1 | equemene | ! WRITE(*,*) nnn |
202 | 1 | equemene | if (nnn.gt.0) then |
203 | 1 | equemene | |
204 | 1 | equemene | call CalcRmsd(nnn, geos1, geos,MRot,rmsd,FRot,FAlign,debug) |
205 | 1 | equemene | ds=0. |
206 | 1 | equemene | DO I=1,nnn |
207 | 1 | equemene | DO J=1,3 |
208 | 1 | equemene | ds=ds+mass(I)*(geos(J,I)-geos1(J,I))**2 |
209 | 1 | equemene | ! write(*,*) I,J,geos(J,I),Geos1(J,I),ds |
210 | 1 | equemene | geos1(J,I)=Geos(J,I) |
211 | 1 | equemene | END DO |
212 | 1 | equemene | END DO |
213 | 1 | equemene | s=s+sqrt(ds) |
214 | 1 | equemene | |
215 | 1 | equemene | ! We convert coordinates in a0 into Angstroem |
216 | 1 | equemene | ! write(*,*) "Analyse !" |
217 | 1 | equemene | if (FExist) THEN |
218 | 1 | equemene | Call Analyse(geos) |
219 | 1 | equemene | |
220 | 1 | equemene | write(IOOUT,fmt) s,(VB(j)/Conv,j=1,NbDist), |
221 | 1 | equemene | & (VA(j),j=1,NbAngle), |
222 | 1 | equemene | & (VD(j),j=1,NbDie),ener |
223 | 1 | equemene | write(*,fmt) s,(VB(j)/Conv,j=1,NbDist), |
224 | 1 | equemene | & (VA(j),j=1,NbAngle), |
225 | 1 | equemene | & (VD(j),j=1,NbDie),ener |
226 | 1 | equemene | ELSE |
227 | 1 | equemene | write(IOOUT,fmt) s,ener |
228 | 1 | equemene | write(*,fmt) s,ener |
229 | 1 | equemene | END IF |
230 | 1 | equemene | ng=ng+1 |
231 | 1 | equemene | goto 10 |
232 | 1 | equemene | endif |
233 | 1 | equemene | WRITE(*,*) 'Found ',ng-1,' geometries' |
234 | 1 | equemene | close(11) |
235 | 1 | equemene | end |
236 | 1 | equemene | |
237 | 1 | equemene | !-------------------------------------------------------------- |
238 | 1 | equemene | subroutine rtraitem(ifil,nnn,E,tab,atoms) |
239 | 1 | equemene | ! implicit real*8 (a-h,o-z) |
240 | 1 | equemene | IMPLICIT NONE |
241 | 1 | equemene | character*120 line |
242 | 1 | equemene | character*3 Atoms(*) |
243 | 1 | equemene | integer*4 nnn, IFil, Idx, I, J |
244 | 1 | equemene | REAL*8 Tab(3,*), E |
245 | 1 | equemene | |
246 | 1 | equemene | |
247 | 1 | equemene | read(ifil,*,err=99,end=99) nnn |
248 | 1 | equemene | read(ifil,'(A)') line |
249 | 1 | equemene | idx=index(line,'E') |
250 | 1 | equemene | ! WRITE(*,*) 'idx,line',idx,line |
251 | 1 | equemene | if (idx/=0) THEN |
252 | 1 | equemene | line=line(idx+2:) |
253 | 1 | equemene | idx=index(line,"=") |
254 | 1 | equemene | if (idx/=0) line=line(idx+1:) |
255 | 1 | equemene | idx=index(line,":") |
256 | 1 | equemene | if (idx/=0) line=line(idx+1:) |
257 | 1 | equemene | read(line,*) E |
258 | 1 | equemene | ELSE |
259 | 1 | equemene | E=0. |
260 | 1 | equemene | END IF |
261 | 1 | equemene | |
262 | 1 | equemene | ! write(*,*) 'coucou',line |
263 | 1 | equemene | do i=1,nnn |
264 | 1 | equemene | read(ifil,'(A)',err=99,end=99) Line |
265 | 1 | equemene | do while (line(1:1)==' ') |
266 | 1 | equemene | line=line(2:) |
267 | 1 | equemene | end do |
268 | 1 | equemene | atoms(i)=line(1:3) |
269 | 1 | equemene | ! write(*,*) 'coucou atoms',atoms(i) |
270 | 1 | equemene | do while (line(1:1).ne.' ') |
271 | 1 | equemene | line=line(2:) |
272 | 1 | equemene | end do |
273 | 1 | equemene | ! WRITE(*,*) 'coucou2:',i,line |
274 | 1 | equemene | read(line,*) (tab(j,i),j=1,3) |
275 | 1 | equemene | end do |
276 | 1 | equemene | ! WRITE(*,*) 'coucou:',nnn,tab(1,1) |
277 | 1 | equemene | return |
278 | 1 | equemene | 99 nnn=0 |
279 | 1 | equemene | ! WRITE(*,*) 'Erreur lecture',ifil,nnn |
280 | 1 | equemene | return |
281 | 1 | equemene | end |
282 | 1 | equemene | |
283 | 1 | equemene | !-------------------------------------------------------------- |
284 | 1 | equemene | |
285 | 1 | equemene | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
286 | 1 | equemene | ! READLINE |
287 | 1 | equemene | ! This subroutine reads a line for a file, and converts |
288 | 1 | equemene | ! the first field into a character variable, and the rest into 4 integers |
289 | 1 | equemene | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
290 | 1 | equemene | |
291 | 1 | equemene | SUBROUTINE READLINE(IOIN,Type,Line) |
292 | 1 | equemene | |
293 | 1 | equemene | IMPLICIT NONE |
294 | 1 | equemene | CHARACTER Type*5,LINE*120 |
295 | 1 | equemene | INTEGER i,IOIN |
296 | 1 | equemene | READ(IOIN,'(A120)',ERR=999,END=999) LINE |
297 | 1 | equemene | ! WRITE(*,*) Line |
298 | 1 | equemene | DO WHILE (LINE(1:1).eq.' ') |
299 | 1 | equemene | LINE=LINE(2:) |
300 | 1 | equemene | END DO |
301 | 1 | equemene | |
302 | 1 | equemene | i=1 |
303 | 1 | equemene | DO WHILE (LINE(i:i).ne.' ') |
304 | 1 | equemene | i=i+1 |
305 | 1 | equemene | END DO |
306 | 1 | equemene | |
307 | 1 | equemene | if (i.ge.6) THEN |
308 | 1 | equemene | WRITE(*,*) 'Pb with READLINE:',LINE |
309 | 1 | equemene | GOTO 999 |
310 | 1 | equemene | END IF |
311 | 1 | equemene | Type=LINE(1:i-1) |
312 | 1 | equemene | LINE=LINE(i:120) // " 0 0 0 0" |
313 | 1 | equemene | |
314 | 1 | equemene | RETURN |
315 | 1 | equemene | 999 Type="E" |
316 | 1 | equemene | END |
317 | 1 | equemene | |
318 | 1 | equemene | |
319 | 1 | equemene | |
320 | 1 | equemene | SUBROUTINE Analyse(geos) |
321 | 1 | equemene | |
322 | 1 | equemene | IMPLICIT NONE |
323 | 1 | equemene | INCLUDE "Xyz2Path.param" |
324 | 1 | equemene | |
325 | 1 | equemene | REAL*8 geos(3,maxnat) |
326 | 1 | equemene | REAL*8 AU2PS,Pi |
327 | 1 | equemene | INTEGER*4 i,j,k |
328 | 1 | equemene | REAL*8 V1x,V1y,V1z,V2x,V2y,V2z,V3x,V3y,V3z |
329 | 1 | equemene | REAL*8 d1,d2,ca,sa |
330 | 1 | equemene | REAL*8 V4x,v4y,v4z,v5x,v5y,v5z |
331 | 1 | equemene | REAL*8 COG(3) |
332 | 1 | equemene | |
333 | 1 | equemene | INTEGER*4 Nat,NbDist, NbAngle, NbDie,NbCOM |
334 | 1 | equemene | INTEGER*4 At1B(MaxNat),At2B(MaxNat) |
335 | 1 | equemene | INTEGER*4 At1A(MaxNat),At2A(MaxNat),At3A(MaxNat) |
336 | 1 | equemene | INTEGER*4 At1D(MaxNat),At2D(MaxNat),At3D(MaxNat),At4D(MaxNat) |
337 | 1 | equemene | INTEGER*4 AtCom(0:MaxNat,MaxNat) |
338 | 1 | equemene | REAL*8 VB(MaxNat),VA(MaxNat),VD(MaxNat),VCOM(MaxNat) |
339 | 1 | equemene | |
340 | 1 | equemene | COMMON /Indices/Nat,NbDist,NbAngle,NbDie,NbCom, |
341 | 1 | equemene | & At1B,At2B,At1A,At2A,At3A,At1D,At2D,At3D,At4D,AtCom |
342 | 1 | equemene | COMMON /Values/VB,VA,VD,VCom |
343 | 1 | equemene | COMMON /Const/AU2ps,Pi |
344 | 1 | equemene | |
345 | 1 | equemene | DO I=1,Nat |
346 | 1 | equemene | WRITE(*,'(1X,I3,3(1X,F15.6))') i,(geos(j,i),j=1,3) |
347 | 1 | equemene | END DO |
348 | 1 | equemene | |
349 | 1 | equemene | ! First, we create the Centre of Mass atoms |
350 | 1 | equemene | DO i=1,NbCOM |
351 | 1 | equemene | COG(1)=0. |
352 | 1 | equemene | COG(2)=0. |
353 | 1 | equemene | COG(3)=0. |
354 | 1 | equemene | DO j=1,AtCOm(0,i) |
355 | 1 | equemene | DO k=1,3 |
356 | 1 | equemene | COG(k)=COG(k)+geos(k,AtCom(j,i)) |
357 | 1 | equemene | END DO |
358 | 1 | equemene | END DO |
359 | 1 | equemene | DO k=1,3 |
360 | 1 | equemene | COG(k)=COG(k)/AtCOM(0,i) |
361 | 1 | equemene | geos(k,Nat+i)=COG(k) |
362 | 1 | equemene | END DO |
363 | 1 | equemene | END DO |
364 | 1 | equemene | |
365 | 1 | equemene | |
366 | 1 | equemene | DO i=1,NbDist |
367 | 1 | equemene | VB(i)=sqrt((geos(1,At1B(i))-geos(1,At2B(i)))**2+ |
368 | 1 | equemene | & (geos(2,At1B(i))-geos(2,At2B(i)))**2+ |
369 | 1 | equemene | & (geos(3,At1B(i))-geos(3,At2B(i)))**2) |
370 | 1 | equemene | END DO |
371 | 1 | equemene | DO i=1,NbAngle |
372 | 1 | equemene | v1x=geos(1,At1A(i))-geos(1,At2A(i)) |
373 | 1 | equemene | v1y=geos(2,At1A(i))-geos(2,At2A(i)) |
374 | 1 | equemene | v1z=geos(3,At1A(i))-geos(3,At2A(i)) |
375 | 1 | equemene | d1=sqrt(v1x**2+v1y**2+v1z**2) |
376 | 1 | equemene | v2x=geos(1,At3A(i))-geos(1,At2A(i)) |
377 | 1 | equemene | v2y=geos(2,At3A(i))-geos(2,At2A(i)) |
378 | 1 | equemene | v2z=geos(3,At3A(i))-geos(3,At2A(i)) |
379 | 1 | equemene | d2=sqrt(v2x**2+v2y**2+v2z**2) |
380 | 1 | equemene | VA(i)=acos((v1x*v2x+v1y*v2y+v1z*v2z)/(d1*d2))*180./Pi |
381 | 1 | equemene | END DO |
382 | 1 | equemene | DO i=1,NbDie |
383 | 1 | equemene | ! WRITE(*,*) At1D(i),At2D(i),At3D(i),At4D(i) |
384 | 1 | equemene | ! WRITE(*,*) geos(1,At1D(i)),geos(2,At1D(i)),geos(3,At1D(i)) |
385 | 1 | equemene | ! WRITE(*,*) geos(1,At2D(i)),geos(2,At2D(i)),geos(3,At2D(i)) |
386 | 1 | equemene | v1x=geos(1,At1D(i))-geos(1,At2D(i)) |
387 | 1 | equemene | v1y=geos(2,At1D(i))-geos(2,At2D(i)) |
388 | 1 | equemene | v1z=geos(3,At1D(i))-geos(3,At2D(i)) |
389 | 1 | equemene | v2x=geos(1,At3D(i))-geos(1,At2D(i)) |
390 | 1 | equemene | v2y=geos(2,At3D(i))-geos(2,At2D(i)) |
391 | 1 | equemene | v2z=geos(3,At3D(i))-geos(3,At2D(i)) |
392 | 1 | equemene | v3x=geos(1,At4D(i))-geos(1,At3D(i)) |
393 | 1 | equemene | v3y=geos(2,At4D(i))-geos(2,At3D(i)) |
394 | 1 | equemene | v3z=geos(3,At4D(i))-geos(3,At3D(i)) |
395 | 1 | equemene | |
396 | 1 | equemene | v4x=v1y*v2z-v1z*v2y |
397 | 1 | equemene | v4y=v1z*v2x-v1x*v2z |
398 | 1 | equemene | v4z=v1x*v2y-v1y*v2x |
399 | 1 | equemene | d1=sqrt(v4x**2+v4y**2+v4z**2) |
400 | 1 | equemene | v5x=-v2y*v3z+v2z*v3y |
401 | 1 | equemene | v5y=-v2z*v3x+v2x*v3z |
402 | 1 | equemene | v5z=-v2x*v3y+v2y*v3x |
403 | 1 | equemene | d2=sqrt(v5x**2+v5y**2+v5z**2) |
404 | 1 | equemene | ca=(v4x*v5x+v4y*v5y+v4z*v5z)/(d1*d2) |
405 | 1 | equemene | sa=v1x*v5x+v1y*v5y+v1z*v5z |
406 | 1 | equemene | VD(i)=acos(ca)*180./Pi |
407 | 1 | equemene | if (sa<0.) VD(i)=-VD(i) |
408 | 1 | equemene | ! WRITE(*,*) "Dihe",v5x,v5y,v5z,v4x,v4y,v4z,d1,d2, |
409 | 1 | equemene | ! &(v4x*v5x+v4y*v5y+v4z*v5z)/(d1*d2),pi |
410 | 1 | equemene | !!!!!!!!! Another solution, more elegant ? |
411 | 1 | equemene | ! norm2=sqrt(v2x**2+v2y**2+v2z**2) |
412 | 1 | equemene | ! sa=(v4x*(v5y*v2z-v5z*v2y) |
413 | 1 | equemene | ! * -v4y*(v5x*v2z-v5z*v2x) |
414 | 1 | equemene | ! * +v4z*(v5x*v2y-v5y*v2x)) |
415 | 1 | equemene | ! * /(d1*norm2*d2) |
416 | 1 | equemene | ! angle_d=datan2(sa,ca)*180./Pi |
417 | 1 | equemene | ! WRITE(*,*) sa,ca,angle_d,d1,d2,norm2 |
418 | 1 | equemene | ! WRITE(*,*) VD(i),angle_d |
419 | 1 | equemene | END DO |
420 | 1 | equemene | |
421 | 1 | equemene | END |
422 | 1 | equemene | |
423 | 1 | equemene | C================================================================ |
424 | 1 | equemene | C Convertit un nom d'atome (2 lettres) en nombre de masse (entier) |
425 | 1 | equemene | C cette fonction a ete modifiee pour pouvoir convertir un nom |
426 | 1 | equemene | C d'atome avec un numero a la fin... |
427 | 1 | equemene | C================================================================ |
428 | 1 | equemene | |
429 | 1 | equemene | FUNCTION ConvertNumAt(ATOM) |
430 | 1 | equemene | |
431 | 1 | equemene | |
432 | 1 | equemene | IMPLICIT NONE |
433 | 1 | equemene | |
434 | 1 | equemene | INTEGER*4 I,Long,ConvertNumAt,IC |
435 | 1 | equemene | character*2 ATOM*2,ATOME*3,L_Atom*2 |
436 | 1 | equemene | INTEGER*4 Max_Z |
437 | 1 | equemene | PARAMETER (Max_Z=86) |
438 | 1 | equemene | CHARACTER*2 Nom(0:Max_Z) |
439 | 1 | equemene | |
440 | 1 | equemene | DATA NOM/ ' X',' H', 'HE', |
441 | 1 | equemene | $ 'LI','BE', ' B',' C',' N',' O',' F','NE', |
442 | 1 | equemene | $ 'NA','MG', 'AL','SI',' P',' S','CL','AR', |
443 | 1 | equemene | $ ' K','CA', |
444 | 1 | equemene | $ 'SC','TI',' V','CR','MN','FE','CO','NI','CU','ZN', |
445 | 1 | equemene | $ 'GA','GE','AS','SE','BR','KR', |
446 | 1 | equemene | $ 'RB','SR', |
447 | 1 | equemene | $ ' Y','ZR','NB','MO','TC','RU','RH','PD','AG','CD', |
448 | 1 | equemene | $ 'IN','SN','SB','TE',' I','XE', |
449 | 1 | equemene | $ 'CS','BA', |
450 | 1 | equemene | $ 'LA', |
451 | 1 | equemene | $ 'CE','PR','ND','PM','SM','EU','GD','TB','DY','HO', |
452 | 1 | equemene | $ 'ER','TM','YB','LU', |
453 | 1 | equemene | $ 'HF','TA',' W','RE','OS','IR','PT','AU','HG', |
454 | 1 | equemene | $ 'TL','PB','BI','PO','AT','RN'/ |
455 | 1 | equemene | |
456 | 1 | equemene | |
457 | 1 | equemene | C Verifie qu'il n'y a que des lettres et des espaces dans ATOM |
458 | 1 | equemene | ! WRITE(*,*) 'DBG CNVNUMAT, ATOM:',ATOM |
459 | 1 | equemene | |
460 | 1 | equemene | L_atom=Atom |
461 | 1 | equemene | IF (ATOM(1:1).LT.'A') L_ATOM(1:1)=' ' |
462 | 1 | equemene | IC=Ichar(ATOM(1:1)) |
463 | 1 | equemene | IF ((ic.le.123).AND.(ic.ge.97)) L_ATOM(1:1)=CHAr(IC-32) |
464 | 1 | equemene | IF (ATOM(2:2).LT.'A') L_ATOM(2:2)=' ' |
465 | 1 | equemene | IC=Ichar(ATOM(2:2)) |
466 | 1 | equemene | IF ((ic.le.123).AND.(ic.ge.97)) L_ATOM(2:2)=CHAr(IC-32) |
467 | 1 | equemene | C Justifie le nom sur la droite (et non sur la gauche comme souvent...) |
468 | 1 | equemene | Long=INDEX(L_ATOM,' ')-1 |
469 | 1 | equemene | ATOME=' ' // L_ATOM |
470 | 1 | equemene | IF (Long.EQ.1) L_ATOM=ATOME(1:2) |
471 | 1 | equemene | ! WRITE(*,*) 'DBG CNVNUMAT, L_ATOM:',L_ATOM |
472 | 1 | equemene | I=max_Z |
473 | 1 | equemene | DO WHILE ((nom(I).NE.L_ATOM) .AND. (I.GT.0)) |
474 | 1 | equemene | I=I-1 |
475 | 1 | equemene | END DO |
476 | 1 | equemene | ConvertNumAT=I |
477 | 1 | equemene | END |
478 | 1 | equemene | ! This subroutine calculates RMSD using quaternions. |
479 | 1 | equemene | ! It is based on the F90 routine bu E. Coutsias |
480 | 1 | equemene | ! http://www.math.unm.edu/~vageli/homepage.html |
481 | 1 | equemene | ! I (PFL) have just translated it, and I have changed the diagonalization |
482 | 1 | equemene | ! subroutine. |
483 | 1 | equemene | ! I also made some changes to make it suitable for Cart package. |
484 | 1 | equemene | !---------------------------------------------------------------------- |
485 | 1 | equemene | !---------------------------------------------------------------------- |
486 | 1 | equemene | ! Copyright (C) 2004, 2005 Chaok Seok, Evangelos Coutsias and Ken Dill |
487 | 1 | equemene | ! UCSF, Univeristy of New Mexico, Seoul National University |
488 | 1 | equemene | ! Witten by Chaok Seok and Evangelos Coutsias 2004. |
489 | 1 | equemene | |
490 | 1 | equemene | ! This library is free software; you can redistribute it and/or |
491 | 1 | equemene | ! modify it under the terms of the GNU Lesser General Public |
492 | 1 | equemene | ! License as published by the Free Software Foundation; either |
493 | 1 | equemene | ! version 2.1 of the License, or (at your option) any later version. |
494 | 1 | equemene | ! |
495 | 1 | equemene | |
496 | 1 | equemene | ! This library is distributed in the hope that it will be useful, |
497 | 1 | equemene | ! but WITHOUT ANY WARRANTY; without even the implied warranty of |
498 | 1 | equemene | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
499 | 1 | equemene | ! Lesser General Public License for more details. |
500 | 1 | equemene | ! |
501 | 1 | equemene | |
502 | 1 | equemene | ! You should have received a copy of the GNU Lesser General Public |
503 | 1 | equemene | ! License along with this library; if not, write to the Free Software |
504 | 1 | equemene | ! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
505 | 1 | equemene | !---------------------------------------------------------------------------- |
506 | 1 | equemene | |
507 | 1 | equemene | subroutine CalcRmsd(na, geom,geom2,U,rmsd,FRot,FAlign,debug) |
508 | 1 | equemene | !----------------------------------------------------------------------- |
509 | 1 | equemene | ! This subroutine calculates the least square rmsd of two coordinate |
510 | 1 | equemene | ! sets coord1(3,n) and coord2(3,n) using a method based on quaternion. |
511 | 1 | equemene | ! It then calculate the rotation matrix U and the centers of coord, and uses |
512 | 1 | equemene | ! them to align the two molecules. |
513 | 1 | equemene | !----------------------------------------------------------------------- |
514 | 1 | equemene | |
515 | 1 | equemene | |
516 | 1 | equemene | IMPLICIT NONE |
517 | 1 | equemene | |
518 | 1 | equemene | INCLUDE "Xyz2Path.param" |
519 | 1 | equemene | |
520 | 1 | equemene | INTEGER*4 IOIN, IOOUT, IOSCRN, IOPRNT, IOTAMP |
521 | 1 | equemene | COMMON/IODEFS/IOIN,IOOUT,IOSCRN,IOPRNT,IOTAMP |
522 | 1 | equemene | |
523 | 1 | equemene | integer*4 na |
524 | 1 | equemene | real*8 geom(3,MaxNAt), Geom2(3,MaxNAt) |
525 | 1 | equemene | real*8 U(3,3), rmsd |
526 | 1 | equemene | LOGICAL FRot,FAlign,Debug |
527 | 1 | equemene | |
528 | 1 | equemene | REAL*8 Coord1(3,MaxNAt), Coord2(3,MaxNAt) |
529 | 1 | equemene | real*8 xc1,yc1,zc1, xc2,yc2,zc2 |
530 | 1 | equemene | |
531 | 1 | equemene | |
532 | 1 | equemene | integer*4 i, j, ia |
533 | 1 | equemene | real*8 x_norm, y_norm, lambda |
534 | 1 | equemene | real*8 Rmatrix(3,3) |
535 | 1 | equemene | real*8 S(4,4) |
536 | 1 | equemene | real*8 EigVec(4,4), EigVal(4) |
537 | 1 | equemene | |
538 | 1 | equemene | |
539 | 1 | equemene | |
540 | 1 | equemene | ! calculate the barycenters, centroidal coordinates, and the norms |
541 | 1 | equemene | x_norm = 0.0d0 |
542 | 1 | equemene | y_norm = 0.0d0 |
543 | 1 | equemene | xc1=0. |
544 | 1 | equemene | yc1=0. |
545 | 1 | equemene | zc1=0. |
546 | 1 | equemene | xc2=0. |
547 | 1 | equemene | yc2=0. |
548 | 1 | equemene | zc2=0. |
549 | 1 | equemene | do ia=1,na |
550 | 1 | equemene | xc1=xc1+geom(1,ia) |
551 | 1 | equemene | xc2=xc2+geom2(1,ia) |
552 | 1 | equemene | yc1=yc1+geom(2,ia) |
553 | 1 | equemene | yc2=yc2+geom2(2,ia) |
554 | 1 | equemene | zc1=zc1+geom(3,ia) |
555 | 1 | equemene | zc2=zc2+geom2(3,ia) |
556 | 1 | equemene | ! if (debug) WRITE(*,'(A,I5,4(1X,F10.4))') 'ia...',ia,x(ia), |
557 | 1 | equemene | ! & x2(ia),xc1,xc2 |
558 | 1 | equemene | END DO |
559 | 1 | equemene | xc1=xc1/dble(na) |
560 | 1 | equemene | yc1=yc1/dble(na) |
561 | 1 | equemene | zc1=zc1/dble(na) |
562 | 1 | equemene | xc2=xc2/dble(na) |
563 | 1 | equemene | yc2=yc2/dble(na) |
564 | 1 | equemene | zc2=zc2/dble(na) |
565 | 1 | equemene | |
566 | 1 | equemene | IF (debug) WRITE(*,'(1X,A,3(1X,F10.4))') 'Center1',xc1,yc1,zc1 |
567 | 1 | equemene | IF (debug) WRITE(*,'(1X,A,3(1X,F10.4))') 'Center2',xc2,yc2,zc2 |
568 | 1 | equemene | do i=1,na |
569 | 1 | equemene | Coord1(1,i)=geom(1,i)-xc1 |
570 | 1 | equemene | Coord1(2,i)=geom(2,i)-yc1 |
571 | 1 | equemene | Coord1(3,i)=geom(3,i)-zc1 |
572 | 1 | equemene | Coord2(1,i)=geom2(1,i)-xc2 |
573 | 1 | equemene | Coord2(2,i)=geom2(2,i)-yc2 |
574 | 1 | equemene | Coord2(3,i)=geom2(3,i)-zc2 |
575 | 1 | equemene | x_norm=x_norm+Coord1(1,i)**2+Coord1(2,i)**2+Coord1(3,i)**2 |
576 | 1 | equemene | y_norm=y_norm+Coord2(1,i)**2+Coord2(2,i)**2+Coord2(3,i)**2 |
577 | 1 | equemene | end do |
578 | 1 | equemene | |
579 | 1 | equemene | IF (debug) THEN |
580 | 1 | equemene | WRITE(*,*) "R matrix" |
581 | 1 | equemene | DO I=1,3 |
582 | 1 | equemene | WRITE(*,*) (RMatrix(I,j),j=1,3) |
583 | 1 | equemene | END DO |
584 | 1 | equemene | END IF |
585 | 1 | equemene | |
586 | 1 | equemene | ! calculate the R matrix |
587 | 1 | equemene | do i = 1, 3 |
588 | 1 | equemene | do j = 1, 3 |
589 | 1 | equemene | Rmatrix(i,j)=0. |
590 | 1 | equemene | do ia=1,na |
591 | 1 | equemene | Rmatrix(i,j) = Rmatrix(i,j)+Coord1(i,ia)*Coord2(j,ia) |
592 | 1 | equemene | END DO |
593 | 1 | equemene | end do |
594 | 1 | equemene | end do |
595 | 1 | equemene | |
596 | 1 | equemene | IF (debug) THEN |
597 | 1 | equemene | WRITE(*,*) "R matrix" |
598 | 1 | equemene | DO I=1,3 |
599 | 1 | equemene | WRITE(*,*) (RMatrix(I,j),j=1,3) |
600 | 1 | equemene | END DO |
601 | 1 | equemene | END IF |
602 | 1 | equemene | |
603 | 1 | equemene | |
604 | 1 | equemene | ! S matrix |
605 | 1 | equemene | S(1, 1) = Rmatrix(1, 1) + Rmatrix(2, 2) + Rmatrix(3, 3) |
606 | 1 | equemene | S(2, 1) = Rmatrix(2, 3) - Rmatrix(3, 2) |
607 | 1 | equemene | S(3, 1) = Rmatrix(3, 1) - Rmatrix(1, 3) |
608 | 1 | equemene | S(4, 1) = Rmatrix(1, 2) - Rmatrix(2, 1) |
609 | 1 | equemene | |
610 | 1 | equemene | S(1, 2) = S(2, 1) |
611 | 1 | equemene | S(2, 2) = Rmatrix(1, 1) - Rmatrix(2, 2) - Rmatrix(3, 3) |
612 | 1 | equemene | S(3, 2) = Rmatrix(1, 2) + Rmatrix(2, 1) |
613 | 1 | equemene | S(4, 2) = Rmatrix(1, 3) + Rmatrix(3, 1) |
614 | 1 | equemene | |
615 | 1 | equemene | S(1, 3) = S(3, 1) |
616 | 1 | equemene | S(2, 3) = S(3, 2) |
617 | 1 | equemene | S(3, 3) =-Rmatrix(1, 1) + Rmatrix(2, 2) - Rmatrix(3, 3) |
618 | 1 | equemene | S(4, 3) = Rmatrix(2, 3) + Rmatrix(3, 2) |
619 | 1 | equemene | |
620 | 1 | equemene | S(1, 4) = S(4, 1) |
621 | 1 | equemene | S(2, 4) = S(4, 2) |
622 | 1 | equemene | S(3, 4) = S(4, 3) |
623 | 1 | equemene | S(4, 4) =-Rmatrix(1, 1) - Rmatrix(2, 2) + Rmatrix(3, 3) |
624 | 1 | equemene | |
625 | 1 | equemene | |
626 | 1 | equemene | ! PFL : I use my usual Jacobi diagonalisation |
627 | 1 | equemene | ! Calculate eigenvalues and eigenvectors, and |
628 | 1 | equemene | ! take the maximum eigenvalue lambda and the corresponding eigenvector q. |
629 | 1 | equemene | |
630 | 1 | equemene | IF (debug) THEN |
631 | 1 | equemene | WRITE(*,*) "S matrix" |
632 | 1 | equemene | DO I=1,4 |
633 | 1 | equemene | WRITE(*,*) (S(I,j),j=1,4) |
634 | 1 | equemene | END DO |
635 | 1 | equemene | END IF |
636 | 1 | equemene | |
637 | 1 | equemene | Call Jacobi(S,4,EigVal,EigVec,4) |
638 | 1 | equemene | |
639 | 1 | equemene | Call Trie(4,EigVal,EigVec,4) |
640 | 1 | equemene | |
641 | 1 | equemene | Lambda=EigVal(4) |
642 | 1 | equemene | |
643 | 1 | equemene | ! RMS Deviation |
644 | 1 | equemene | rmsd=sqrt(max(0.0d0,((x_norm+y_norm)-2.0d0*lambda))/dble(na)) |
645 | 1 | equemene | |
646 | 1 | equemene | if (FRot.OR.FAlign) Call rotation_matrix(EigVec(1,4),U) |
647 | 1 | equemene | IF (FAlign) THEN |
648 | 1 | equemene | DO I=1,na |
649 | 1 | equemene | geom2(1,i)=Coord2(1,i)*U(1,1)+Coord2(2,i)*U(2,1) |
650 | 1 | equemene | & +Coord2(3,i)*U(3,1) +xc1 |
651 | 1 | equemene | geom2(2,i)=Coord2(1,i)*U(1,2)+Coord2(2,i)*U(2,2) |
652 | 1 | equemene | & +Coord2(3,i)*U(3,2) +yc1 |
653 | 1 | equemene | geom2(3,i)=Coord2(1,i)*U(1,3)+Coord2(2,i)*U(2,3) |
654 | 1 | equemene | & +Coord2(3,i)*U(3,3) +zc1 |
655 | 1 | equemene | END DO |
656 | 1 | equemene | END IF |
657 | 1 | equemene | |
658 | 1 | equemene | END |
659 | 1 | equemene | |
660 | 1 | equemene | |
661 | 1 | equemene | !----------------------------------------------------------------------- |
662 | 1 | equemene | subroutine rotation_matrix(q, U) |
663 | 1 | equemene | !----------------------------------------------------------------------- |
664 | 1 | equemene | ! This subroutine constructs rotation matrix U from quaternion q. |
665 | 1 | equemene | !----------------------------------------------------------------------- |
666 | 1 | equemene | ! This subroutine calculates RMSD using quaternions. |
667 | 1 | equemene | ! It is based on the F90 routine bu E. Coutsias |
668 | 1 | equemene | ! http://www.math.unm.edu/~vageli/homepage.html |
669 | 1 | equemene | ! I (PFL) have just translated it, and I have changed the diagonalization |
670 | 1 | equemene | ! subroutine. |
671 | 1 | equemene | ! I also made some changes to make it suitable for Cart package. |
672 | 1 | equemene | !---------------------------------------------------------------------- |
673 | 1 | equemene | !---------------------------------------------------------------------- |
674 | 1 | equemene | ! Copyright (C) 2004, 2005 Chaok Seok, Evangelos Coutsias and Ken Dill |
675 | 1 | equemene | ! UCSF, Univeristy of New Mexico, Seoul National University |
676 | 1 | equemene | ! Witten by Chaok Seok and Evangelos Coutsias 2004. |
677 | 1 | equemene | |
678 | 1 | equemene | ! This library is free software; you can redistribute it and/or |
679 | 1 | equemene | ! modify it under the terms of the GNU Lesser General Public |
680 | 1 | equemene | ! License as published by the Free Software Foundation; either |
681 | 1 | equemene | ! version 2.1 of the License, or (at your option) any later version. |
682 | 1 | equemene | ! |
683 | 1 | equemene | |
684 | 1 | equemene | ! This library is distributed in the hope that it will be useful, |
685 | 1 | equemene | ! but WITHOUT ANY WARRANTY; without even the implied warranty of |
686 | 1 | equemene | ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
687 | 1 | equemene | ! Lesser General Public License for more details. |
688 | 1 | equemene | ! |
689 | 1 | equemene | |
690 | 1 | equemene | ! You should have received a copy of the GNU Lesser General Public |
691 | 1 | equemene | ! License along with this library; if not, write to the Free Software |
692 | 1 | equemene | ! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
693 | 1 | equemene | !---------------------------------------------------------------------------- |
694 | 1 | equemene | |
695 | 1 | equemene | real*8 q(4) |
696 | 1 | equemene | real*8 U(3,3) |
697 | 1 | equemene | real*8 q0,q1,q2,q3,b0,b1,b2,b3,q00,q01,q02,q03 |
698 | 1 | equemene | REAL*8 q11,q12,q13,q22,q23,q33 |
699 | 1 | equemene | |
700 | 1 | equemene | q0 = q(1) |
701 | 1 | equemene | q1 = q(2) |
702 | 1 | equemene | q2 = q(3) |
703 | 1 | equemene | q3 = q(4) |
704 | 1 | equemene | |
705 | 1 | equemene | b0 = 2.0d0*q0 |
706 | 1 | equemene | b1 = 2.0d0*q1 |
707 | 1 | equemene | b2 = 2.0d0*q2 |
708 | 1 | equemene | b3 = 2.0d0*q3 |
709 | 1 | equemene | |
710 | 1 | equemene | q00 = b0*q0-1.0d0 |
711 | 1 | equemene | q01 = b0*q1 |
712 | 1 | equemene | q02 = b0*q2 |
713 | 1 | equemene | q03 = b0*q3 |
714 | 1 | equemene | |
715 | 1 | equemene | q11 = b1*q1 |
716 | 1 | equemene | q12 = b1*q2 |
717 | 1 | equemene | q13 = b1*q3 |
718 | 1 | equemene | |
719 | 1 | equemene | q22 = b2*q2 |
720 | 1 | equemene | q23 = b2*q3 |
721 | 1 | equemene | |
722 | 1 | equemene | q33 = b3*q3 |
723 | 1 | equemene | |
724 | 1 | equemene | U(1,1) = q00+q11 |
725 | 1 | equemene | U(1,2) = q12-q03 |
726 | 1 | equemene | U(1,3) = q13+q02 |
727 | 1 | equemene | |
728 | 1 | equemene | U(2,1) = q12+q03 |
729 | 1 | equemene | U(2,2) = q00+q22 |
730 | 1 | equemene | U(2,3) = q23-q01 |
731 | 1 | equemene | |
732 | 1 | equemene | U(3,1) = q13-q02 |
733 | 1 | equemene | U(3,2) = q23+q01 |
734 | 1 | equemene | U(3,3) = q00+q33 |
735 | 1 | equemene | |
736 | 1 | equemene | end |
737 | 1 | equemene | |
738 | 1 | equemene | c============================================================ |
739 | 1 | equemene | c |
740 | 1 | equemene | c ++ diagonalisation par jacobi |
741 | 1 | equemene | c vecteur propre i : V(i,i) |
742 | 1 | equemene | c valeur propre i : D(i) |
743 | 1 | equemene | c |
744 | 1 | equemene | c============================================================ |
745 | 1 | equemene | c |
746 | 1 | equemene | SUBROUTINE JACOBI(A,N,D,V,max_N) |
747 | 1 | equemene | IMPLICIT REAL*8 (A-H,O-Z) |
748 | 1 | equemene | parameter (max_it=500) |
749 | 1 | equemene | DIMENSION A(max_N,max_N),B(max_N),Z(max_N) |
750 | 1 | equemene | DIMENSION V(max_N,max_N),D(max_N) |
751 | 1 | equemene | |
752 | 1 | equemene | |
753 | 1 | equemene | DO 12 IP=1,N |
754 | 1 | equemene | DO 11 IQ=1,N |
755 | 1 | equemene | V(IP,IQ)=0. |
756 | 1 | equemene | 11 CONTINUE |
757 | 1 | equemene | V(IP,IP)=1. |
758 | 1 | equemene | 12 CONTINUE |
759 | 1 | equemene | DO 13 IP=1,N |
760 | 1 | equemene | B(IP)=A(IP,IP) |
761 | 1 | equemene | D(IP)=B(IP) |
762 | 1 | equemene | Z(IP)=0. |
763 | 1 | equemene | 13 CONTINUE |
764 | 1 | equemene | NROT=0 |
765 | 1 | equemene | DO 24 I=1,max_it |
766 | 1 | equemene | SM=0. |
767 | 1 | equemene | DO 15 IP=1,N-1 |
768 | 1 | equemene | DO 14 IQ=IP+1,N |
769 | 1 | equemene | SM=SM+ABS(A(IP,IQ)) |
770 | 1 | equemene | 14 CONTINUE |
771 | 1 | equemene | 15 CONTINUE |
772 | 1 | equemene | IF(SM.EQ.0.)RETURN |
773 | 1 | equemene | IF(I.LT.4)THEN |
774 | 1 | equemene | TRESH=0.2*SM/N**2 |
775 | 1 | equemene | ELSE |
776 | 1 | equemene | TRESH=0. |
777 | 1 | equemene | ENDIF |
778 | 1 | equemene | DO 22 IP=1,N-1 |
779 | 1 | equemene | DO 21 IQ=IP+1,N |
780 | 1 | equemene | G=100.*ABS(A(IP,IQ)) |
781 | 1 | equemene | IF((I.GT.4).AND.(ABS(D(IP))+G.EQ.ABS(D(IP))) |
782 | 1 | equemene | * .AND.(ABS(D(IQ))+G.EQ.ABS(D(IQ))))THEN |
783 | 1 | equemene | A(IP,IQ)=0. |
784 | 1 | equemene | ELSE IF(ABS(A(IP,IQ)).GT.TRESH)THEN |
785 | 1 | equemene | H=D(IQ)-D(IP) |
786 | 1 | equemene | IF(ABS(H)+G.EQ.ABS(H))THEN |
787 | 1 | equemene | T=A(IP,IQ)/H |
788 | 1 | equemene | ELSE |
789 | 1 | equemene | THETA=0.5*H/A(IP,IQ) |
790 | 1 | equemene | T=1./(ABS(THETA)+SQRT(1.+THETA**2)) |
791 | 1 | equemene | IF(THETA.LT.0.)T=-T |
792 | 1 | equemene | ENDIF |
793 | 1 | equemene | C=1./SQRT(1+T**2) |
794 | 1 | equemene | S=T*C |
795 | 1 | equemene | TAU=S/(1.+C) |
796 | 1 | equemene | H=T*A(IP,IQ) |
797 | 1 | equemene | Z(IP)=Z(IP)-H |
798 | 1 | equemene | Z(IQ)=Z(IQ)+H |
799 | 1 | equemene | D(IP)=D(IP)-H |
800 | 1 | equemene | D(IQ)=D(IQ)+H |
801 | 1 | equemene | A(IP,IQ)=0. |
802 | 1 | equemene | DO 16 J=1,IP-1 |
803 | 1 | equemene | G=A(J,IP) |
804 | 1 | equemene | H=A(J,IQ) |
805 | 1 | equemene | A(J,IP)=G-S*(H+G*TAU) |
806 | 1 | equemene | A(J,IQ)=H+S*(G-H*TAU) |
807 | 1 | equemene | 16 CONTINUE |
808 | 1 | equemene | DO 17 J=IP+1,IQ-1 |
809 | 1 | equemene | G=A(IP,J) |
810 | 1 | equemene | H=A(J,IQ) |
811 | 1 | equemene | A(IP,J)=G-S*(H+G*TAU) |
812 | 1 | equemene | A(J,IQ)=H+S*(G-H*TAU) |
813 | 1 | equemene | 17 CONTINUE |
814 | 1 | equemene | DO 18 J=IQ+1,N |
815 | 1 | equemene | G=A(IP,J) |
816 | 1 | equemene | H=A(IQ,J) |
817 | 1 | equemene | A(IP,J)=G-S*(H+G*TAU) |
818 | 1 | equemene | A(IQ,J)=H+S*(G-H*TAU) |
819 | 1 | equemene | 18 CONTINUE |
820 | 1 | equemene | DO 19 J=1,N |
821 | 1 | equemene | G=V(J,IP) |
822 | 1 | equemene | H=V(J,IQ) |
823 | 1 | equemene | V(J,IP)=G-S*(H+G*TAU) |
824 | 1 | equemene | V(J,IQ)=H+S*(G-H*TAU) |
825 | 1 | equemene | 19 CONTINUE |
826 | 1 | equemene | NROT=NROT+1 |
827 | 1 | equemene | ENDIF |
828 | 1 | equemene | 21 CONTINUE |
829 | 1 | equemene | 22 CONTINUE |
830 | 1 | equemene | DO 23 IP=1,N |
831 | 1 | equemene | B(IP)=B(IP)+Z(IP) |
832 | 1 | equemene | D(IP)=B(IP) |
833 | 1 | equemene | Z(IP)=0. |
834 | 1 | equemene | 23 CONTINUE |
835 | 1 | equemene | 24 CONTINUE |
836 | 1 | equemene | write(6,*) max_it,' iterations should never happen' |
837 | 1 | equemene | STOP |
838 | 1 | equemene | RETURN |
839 | 1 | equemene | END |
840 | 1 | equemene | c |
841 | 1 | equemene | c============================================================ |
842 | 1 | equemene | c |
843 | 1 | equemene | c ++ trie des vecteur dans l'ordre croissant |
844 | 1 | equemene | c |
845 | 1 | equemene | c============================================================ |
846 | 1 | equemene | c |
847 | 1 | equemene | SUBROUTINE trie(nb_niv,ene,psi,max_niv) |
848 | 1 | equemene | integer i,j,k,nb_niv,max_niv |
849 | 1 | equemene | real*8 ene(max_niv),psi(max_niv,max_niv) |
850 | 1 | equemene | real*8 a |
851 | 1 | equemene | |
852 | 1 | equemene | DO i=1,nb_niv |
853 | 1 | equemene | DO j=i+1,nb_niv |
854 | 1 | equemene | IF (ene(i) .GT. ene(j)) THEN |
855 | 1 | equemene | c permutation |
856 | 1 | equemene | a=ene(i) |
857 | 1 | equemene | ene(i)=ene(j) |
858 | 1 | equemene | ene(j)=a |
859 | 1 | equemene | DO k=1,nb_niv |
860 | 1 | equemene | a=psi(k,i) |
861 | 1 | equemene | psi(k,i)=psi(k,j) |
862 | 1 | equemene | psi(k,j)=a |
863 | 1 | equemene | END DO |
864 | 1 | equemene | END IF |
865 | 1 | equemene | END DO |
866 | 1 | equemene | END DO |
867 | 1 | equemene | |
868 | 1 | equemene | END |