root / src / Calc_zmat.f90 @ 4
Historique | Voir | Annoter | Télécharger (32,19 ko)
1 | 1 | equemene | SUBROUTINE Calc_Zmat(na,atome,ind_zmat,val_zmat,x,y,z, & |
---|---|---|---|
2 | 1 | equemene | r_cov, fact) |
3 | 1 | equemene | |
4 | 1 | equemene | use Path_module, only : Pi,max_Z, NMaxL, Nom, KINT, KREAL |
5 | 1 | equemene | use Io_module, only : IoIn, IoOut |
6 | 1 | equemene | |
7 | 1 | equemene | IMPLICIT NONE |
8 | 1 | equemene | |
9 | 1 | equemene | ! Number of atoms |
10 | 1 | equemene | integer(KINT), INTENT(IN) :: na |
11 | 1 | equemene | ! Mass number of atoms |
12 | 1 | equemene | INTEGER(KINT), INTENT(IN) :: atome(na) |
13 | 1 | equemene | ! Coordinates |
14 | 1 | equemene | real(KREAL), INTENT(IN) :: x(na),y(na),z(na) |
15 | 1 | equemene | ! Covalent radii |
16 | 1 | equemene | REAL(KREAL), INTENT(IN) :: R_cov(Max_Z) |
17 | 1 | equemene | ! Factor to determine connectivity |
18 | 1 | equemene | REAL(KREAL) :: Fact |
19 | 1 | equemene | ! Zmat index and values |
20 | 1 | equemene | integer(KINT), INTENT(OUT) :: ind_zmat(na,5) |
21 | 1 | equemene | real(KREAL),INTENT(OUT) :: val_zmat(na,3) |
22 | 1 | equemene | |
23 | 1 | equemene | character(2) :: ATOM |
24 | 1 | equemene | integer(KINT) :: at,long |
25 | 1 | equemene | |
26 | 1 | equemene | real(KREAL) :: vx,vy,vz,dist |
27 | 1 | equemene | INTEGER(KINT), ALLOCATABLE :: LIAISONS(:,:) !(na,0:NMaxL |
28 | 1 | equemene | INTEGER(KINT), ALLOCATABLE :: LiaisonsBis(:,:) ! na,0:NMaxL |
29 | 1 | equemene | INTEGER(KINT), ALLOCATABLE :: LieS_CP(:,:),LieS_CF(:,:) ! (na,0:NMaxL) |
30 | 1 | equemene | INTEGER(KINT), ALLOCATABLE :: NbAt3(:,:) !(Na,2) |
31 | 1 | equemene | INTEGER(KINT), ALLOCATABLE :: CycleAt(:) !(Na) |
32 | 1 | equemene | INTEGER(KINT) :: Nbli,Nblj |
33 | 1 | equemene | INTEGER(KINT), ALLOCATABLE :: CAFaire(:) ! Na |
34 | 1 | equemene | |
35 | 1 | equemene | Integer(KINT) :: AtTypCycl(Max_Z) |
36 | 1 | equemene | Integer(KINT) :: NbCycle |
37 | 1 | equemene | real(KREAL) :: vx1,vy1,vz1,norm1 |
38 | 1 | equemene | real(KREAL) :: vx2,vy2,vz2,norm2 |
39 | 1 | equemene | real(KREAL) :: vx3,vy3,vz3,norm3 |
40 | 1 | equemene | real(KREAL) :: vx4,vy4,vz4,norm4 |
41 | 1 | equemene | real(KREAL) :: vx5,vy5,vz5,norm5 |
42 | 1 | equemene | real(KREAL) :: val,val_d |
43 | 1 | equemene | Logical PasFini,AtTerm,Debug,Bicycle,FLie3,FirstCycle |
44 | 1 | equemene | LOGICAL, ALLOCATABLE :: Former3(:), DejaFait(:) ! Na |
45 | 1 | equemene | Logical FTmp |
46 | 1 | equemene | LOGICAL F1213, F1223,F1323 |
47 | 1 | equemene | |
48 | 1 | equemene | INTEGER(KINT) :: I,J,K, IZM, N1,n2, N3, IL, JL |
49 | 1 | equemene | INTEGER(KINT) :: IdAt0, I3, IAt3, Idx3, I1, I0, IAf |
50 | 1 | equemene | INTEGER(KINT) :: Izm1,Izm2, IZm3,IZm4, VCF, ICat |
51 | 1 | equemene | INTEGER(KINT) :: IOld, IndFin, IdAtL, IndAFaire |
52 | 1 | equemene | INTEGER(KINT) :: IAti, IAtD, IAtv, IIAtDh, IAtDh |
53 | 1 | equemene | INTEGER(KINT) :: IAt0, IAta, IAt, Jat,Idx |
54 | 1 | equemene | INTEGER(KINT) :: ITmp, IAtTmp, NbAt0 |
55 | 1 | equemene | INTEGER(KINT) :: NbLies, ICycle, IMax |
56 | 1 | equemene | REAL(KREAL) :: d,d12, d13,d32 |
57 | 1 | equemene | |
58 | 1 | equemene | INTERFACE |
59 | 1 | equemene | function valid(string) result (isValid) |
60 | 1 | equemene | CHARACTER(*), intent(in) :: string |
61 | 1 | equemene | logical :: isValid |
62 | 1 | equemene | END function VALID |
63 | 1 | equemene | |
64 | 1 | equemene | FUNCTION angle(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2) |
65 | 1 | equemene | use Path_module, only : Pi,KINT, KREAL |
66 | 1 | equemene | real(KREAL) :: v1x,v1y,v1z,norm1 |
67 | 1 | equemene | real(KREAL) :: v2x,v2y,v2z,norm2 |
68 | 1 | equemene | real(KREAL) :: angle |
69 | 1 | equemene | END FUNCTION ANGLE |
70 | 1 | equemene | |
71 | 1 | equemene | |
72 | 1 | equemene | END INTERFACE |
73 | 1 | equemene | |
74 | 1 | equemene | |
75 | 1 | equemene | |
76 | 1 | equemene | debug=valid("Calc_zmat") |
77 | 1 | equemene | if (debug) WRITE(*,*) "========== Entering Calc_zmat ==========" |
78 | 1 | equemene | |
79 | 1 | equemene | FirstCycle=.TRUE. |
80 | 1 | equemene | FTmp=.FALSE. |
81 | 1 | equemene | NbCycle=0 |
82 | 1 | equemene | DO i=1,na |
83 | 1 | equemene | DO J=1,5 |
84 | 1 | equemene | Ind_Zmat(i,J)=0 |
85 | 1 | equemene | END DO |
86 | 1 | equemene | END DO |
87 | 1 | equemene | ALLOCATE(Former3(Na), DejaFait(Na)) |
88 | 1 | equemene | ALLOCATE(CaFaire(Na), CycleAt(Na)) |
89 | 1 | equemene | ALLOCATE(NbAt3(Na,2)) |
90 | 1 | equemene | ALLOCATE(Liaisons(na,0:NMaxL),LiaisonsBis(na,0:NMaxL)) |
91 | 1 | equemene | ALLOCATE(Lies_CP(na,0:NMaxL), Lies_CF(na,0:NMaxL)) |
92 | 1 | equemene | |
93 | 1 | equemene | |
94 | 1 | equemene | WRITE(IOOUT,*) Na |
95 | 1 | equemene | WRITE(IOOUT,*) 'Calc_zmat' |
96 | 1 | equemene | DO I=1,na |
97 | 1 | equemene | WRITE(IOOUT,*) NOM(Atome(I)),X(i),y(i),z(i) |
98 | 1 | equemene | END DO |
99 | 1 | equemene | |
100 | 1 | equemene | if (na.le.2) THEN |
101 | 1 | equemene | WRITE(*,*) "I do not work for less than 2 atoms :-p" |
102 | 1 | equemene | RETURN |
103 | 1 | equemene | END IF |
104 | 1 | equemene | |
105 | 1 | equemene | ! Cas particulier: 3 atomes ou moins... |
106 | 1 | equemene | if (Na.eq.3) THEN |
107 | 1 | equemene | d12=sqrt((x(1)-x(2))**2+(y(1)-y(2))**2+(z(1)-z(2))**2) |
108 | 1 | equemene | d13=sqrt((x(1)-x(3))**2+(y(1)-y(3))**2+(z(1)-z(3))**2) |
109 | 1 | equemene | d32=sqrt((x(3)-x(2))**2+(y(3)-y(2))**2+(z(3)-z(2))**2) |
110 | 1 | equemene | F1213=(d12<=d13) |
111 | 1 | equemene | F1323=(d13<=d32) |
112 | 1 | equemene | F1223=(d12<=d32) |
113 | 1 | equemene | if (debug) THEN |
114 | 1 | equemene | WRITE(*,*) "DEBUG Calc_Zmat 3 atoms" |
115 | 1 | equemene | WRITE(*,*) "d12,d13,d32:",d12,d13,d32 |
116 | 1 | equemene | WRITE(*,*) "F1213,F1323,F1223:",F1213,F1323,F1223 |
117 | 1 | equemene | END IF |
118 | 1 | equemene | if (F1213) THEN |
119 | 1 | equemene | if (F1323) THEN |
120 | 1 | equemene | ind_zmat(1,1)=3 |
121 | 1 | equemene | ind_zmat(2,1)=1 |
122 | 1 | equemene | ind_zmat(2,2)=3 |
123 | 1 | equemene | ind_zmat(3,1)=2 |
124 | 1 | equemene | ind_zmat(3,2)=1 |
125 | 1 | equemene | ind_zmat(3,3)=3 |
126 | 1 | equemene | ELSE |
127 | 1 | equemene | ind_zmat(1,1)=1 |
128 | 1 | equemene | ind_zmat(2,1)=2 |
129 | 1 | equemene | ind_zmat(2,2)=1 |
130 | 1 | equemene | ind_zmat(3,1)=3 |
131 | 1 | equemene | ind_zmat(3,2)=2 |
132 | 1 | equemene | ind_zmat(3,3)=1 |
133 | 1 | equemene | END IF |
134 | 1 | equemene | ELSE |
135 | 1 | equemene | IF (F1223) THEN |
136 | 1 | equemene | ind_zmat(1,1)=2 |
137 | 1 | equemene | ind_zmat(2,1)=1 |
138 | 1 | equemene | ind_zmat(2,2)=2 |
139 | 1 | equemene | ind_zmat(3,1)=3 |
140 | 1 | equemene | ind_zmat(3,2)=1 |
141 | 1 | equemene | ind_zmat(3,3)=2 |
142 | 1 | equemene | ELSE |
143 | 1 | equemene | ind_zmat(1,1)=2 |
144 | 1 | equemene | ind_zmat(2,1)=3 |
145 | 1 | equemene | ind_zmat(2,2)=2 |
146 | 1 | equemene | ind_zmat(3,1)=1 |
147 | 1 | equemene | ind_zmat(3,2)=3 |
148 | 1 | equemene | ind_zmat(3,3)=2 |
149 | 1 | equemene | END IF |
150 | 1 | equemene | END IF |
151 | 1 | equemene | IF (debug) THEN |
152 | 1 | equemene | DO i=1,na |
153 | 1 | equemene | WRITE(*,*) (ind_zmat(i,j),j=1,5) |
154 | 1 | equemene | END DO |
155 | 1 | equemene | END IF |
156 | 1 | equemene | |
157 | 1 | equemene | ! We have ind_zmat, we fill val_zmat |
158 | 1 | equemene | val_zmat(1,1)=0. |
159 | 1 | equemene | val_zmat(1,2)=0. |
160 | 1 | equemene | val_zmat(1,3)=0. |
161 | 1 | equemene | n2=ind_zmat(2,1) |
162 | 1 | equemene | n1=ind_zmat(2,2) |
163 | 1 | equemene | d=sqrt((x(n1)-x(n2))**2+(y(n1)-y(n2))**2+ & |
164 | 1 | equemene | (z(n1)-z(n2))**2) |
165 | 1 | equemene | val_zmat(2,1)=d |
166 | 1 | equemene | val_zmat(2,2)=0. |
167 | 1 | equemene | val_zmat(2,3)=0. |
168 | 1 | equemene | n1=ind_zmat(3,1) |
169 | 1 | equemene | n2=ind_zmat(3,2) |
170 | 1 | equemene | n3=ind_zmat(3,3) |
171 | 1 | equemene | CALL vecteur(n2,n1,x,y,z,vx1,vy1,vz1,norm1) |
172 | 1 | equemene | if (debug) write(*,*) n1,n2,norm1 |
173 | 1 | equemene | val_zmat(3,1)=norm1 |
174 | 1 | equemene | |
175 | 1 | equemene | CALL vecteur(n2,n3,x,y,z,vx2,vy2,vz2,norm2) |
176 | 1 | equemene | val=angle(vx1,vy1,vz1,norm1,vx2,vy2,vz2,norm2) |
177 | 1 | equemene | if (debug) write(*,*) n2,n3,norm2,val |
178 | 1 | equemene | val_zmat(3,2)=val |
179 | 1 | equemene | val_zmat(3,3)=0. |
180 | 1 | equemene | |
181 | 1 | equemene | RETURN |
182 | 1 | equemene | END IF |
183 | 1 | equemene | |
184 | 1 | equemene | |
185 | 1 | equemene | 1036 FORMAT(I2) |
186 | 1 | equemene | |
187 | 1 | equemene | ! Premiere etape : calcul des connectivites |
188 | 1 | equemene | DO I=1,na |
189 | 1 | equemene | DejaFait(I)=.FALSE. |
190 | 1 | equemene | Former3(I)=.False. |
191 | 1 | equemene | Do J=0,NMaxL |
192 | 1 | equemene | Liaisons(I,j)=0. |
193 | 1 | equemene | LiaisonsBis(I,j)=0. |
194 | 1 | equemene | END DO |
195 | 1 | equemene | DO J=1,5 |
196 | 1 | equemene | ind_zmat(I,J)=0 |
197 | 1 | equemene | END DO |
198 | 1 | equemene | END DO |
199 | 1 | equemene | |
200 | 1 | equemene | if (debug) WRITE(IOOUT,*) "Liaisons initialiazed" |
201 | 1 | equemene | ! DO IL=1,na |
202 | 1 | equemene | ! WRITE(IOOUT,1003) Il,(LIAISONS(IL,JL),JL=0,NMaxL) |
203 | 1 | equemene | ! WRITE(IOOUT,1003) Il,(LIAISONSBis(IL,JL),JL=0,NMaxL) |
204 | 1 | equemene | ! END DO |
205 | 1 | equemene | |
206 | 1 | equemene | Call CalcCnct(na,atome,x,y,z,LIAISONS,r_cov,fact) |
207 | 1 | equemene | |
208 | 1 | equemene | if (debug) THEN |
209 | 1 | equemene | WRITE(IOOUT,*) "Connections calculated" |
210 | 1 | equemene | DO IL=1,na |
211 | 1 | equemene | WRITE(IOOUT,1003) Il,(LIAISONS(IL,JL),JL=0,NMaxL) |
212 | 1 | equemene | END DO |
213 | 1 | equemene | END IF |
214 | 1 | equemene | |
215 | 1 | equemene | |
216 | 1 | equemene | ! on va maintenant trier ces connectivites en 2 : |
217 | 1 | equemene | ! Lies_CF : vers l'exterieur de la molecule |
218 | 1 | equemene | ! Lies_CP : vers l'interieur de la molecule |
219 | 1 | equemene | ! Pour cela, on procede 'a l'envers' : on regarde les atomes |
220 | 1 | equemene | ! auxquels sont lies les atomes attaches -> on remplit Lies_CF/P |
221 | 1 | equemene | ! et on supprime ces atomes... |
222 | 1 | equemene | |
223 | 1 | equemene | ! v2.0 on copie Liaison dans LiaisonBis. On analyse LiaisonBis |
224 | 1 | equemene | ! tout en modifiant Liaison. Cela evite de fausser l'analyse: un atome |
225 | 1 | equemene | ! qui est lie initialement a 2 atomes (et qui n'est donc pas terminal) |
226 | 1 | equemene | ! peut devenir terminal en milieu de traitement si on annule la liaison |
227 | 1 | equemene | ! qui le liait a un atome terminal situ? avant lui... |
228 | 1 | equemene | ! ex: H2O code dans l'ordre H,O,H. |
229 | 1 | equemene | PasFini=.True. |
230 | 1 | equemene | AtTerm=.True. |
231 | 1 | equemene | DO WHILE (PasFini.AND.AtTerm) |
232 | 1 | equemene | PasFini=.False. |
233 | 1 | equemene | AtTerm=.False. |
234 | 1 | equemene | DO I=1,na |
235 | 1 | equemene | DO J=0,NMaxL |
236 | 1 | equemene | LiaisonsBis(I,J)=Liaisons(I,J) |
237 | 1 | equemene | END DO |
238 | 1 | equemene | END DO |
239 | 1 | equemene | ! DO IL=1,na |
240 | 1 | equemene | ! WRITE(IOOUT,1003) Il,(LIAISONS(IL,JL),JL=0,NMaxL) |
241 | 1 | equemene | ! WRITE(IOOUT,1003) Il,(LIAISONSBis(IL,JL),JL=0,NMaxL) |
242 | 1 | equemene | ! END DO |
243 | 1 | equemene | ! WRITE(IOOUT,*) "==================================" |
244 | 1 | equemene | |
245 | 1 | equemene | |
246 | 1 | equemene | DO I=1,na |
247 | 1 | equemene | if ((LiaisonsBis(I,0).eq.1).AND.Liaisons(I,0).ne.0) THEN |
248 | 1 | equemene | AtTerm=.True. |
249 | 1 | equemene | ! On enleve cet atome |
250 | 1 | equemene | Liaisons(I,0)=0 |
251 | 1 | equemene | NbLies=Lies_CP(I,0)+1 |
252 | 1 | equemene | Lies_CP(I,NbLies)=Liaisons(I,1) |
253 | 1 | equemene | Lies_CP(I,0)=NbLies |
254 | 1 | equemene | Liaisons(Liaisons(I,1),0)=Liaisons(Liaisons(I,1),0)-1 |
255 | 1 | equemene | |
256 | 1 | equemene | NbLies=Lies_CF(Liaisons(I,1),0)+1 |
257 | 1 | equemene | Lies_CF(Liaisons(I,1),NbLies)=I |
258 | 1 | equemene | Lies_CF(Liaisons(I,1),0)=NbLies |
259 | 1 | equemene | |
260 | 1 | equemene | Call Annul(Liaisons,Liaisons(I,1),I) |
261 | 1 | equemene | |
262 | 1 | equemene | END IF |
263 | 1 | equemene | |
264 | 1 | equemene | if (Liaisons(I,0).ge.1) THEN |
265 | 1 | equemene | PasFini=.TRUE. |
266 | 1 | equemene | END IF |
267 | 1 | equemene | |
268 | 1 | equemene | END DO |
269 | 1 | equemene | if (debug) WRITE(*,*) 'PasFini, AtTerm',PasFini,AtTerm |
270 | 1 | equemene | If (PasFini.AND.(.Not.AtTerm)) THEN |
271 | 1 | equemene | ! Pas d'atomes terminaux lors de l'exploration precedente. |
272 | 1 | equemene | ! On a soit une erreur, soit un cycle. Je ne sais pas encore gerer |
273 | 1 | equemene | ! tous les cas : on affiche un warning |
274 | 1 | equemene | WRITE(*,*) "Je ne trouve pas d'atomes terminaux" |
275 | 1 | equemene | WRITE(*,*) "Possibilite de molecule cyclique" |
276 | 1 | equemene | WRITE(*,*) "Cas en cours de traitement: verifier l'output" |
277 | 1 | equemene | ! On va d'abord voir si on a des atomes li?s a plus de 2 centres. |
278 | 1 | equemene | AtTerm=.TRUE. |
279 | 1 | equemene | Bicycle=.False. |
280 | 1 | equemene | ICycle=0 |
281 | 1 | equemene | IMax=0 |
282 | 1 | equemene | DO I=1,na |
283 | 1 | equemene | if (Liaisons(I,0).gt.2) THEN |
284 | 1 | equemene | ICycle=ICycle+1 |
285 | 1 | equemene | BiCycle=.True. |
286 | 1 | equemene | If (Liaisons(I,0).gt.IMax) Imax=Liaisons(I,0) |
287 | 1 | equemene | Former3(I)=.True. |
288 | 1 | equemene | END IF |
289 | 1 | equemene | END DO |
290 | 1 | equemene | IF (BiCycle) THEN |
291 | 1 | equemene | ! On a des atomes lies a 3 ou plus d'atomes... |
292 | 1 | equemene | ! donc soit des bicycles, soit plusieurs |
293 | 1 | equemene | ! cycles attaches par un sommet... |
294 | 1 | equemene | WRITE(*,*) "On dirait un bicyle... on essaie" |
295 | 1 | equemene | WRITE(*,*) ICycle, "atomes lies a plus de 2 atomes" |
296 | 1 | equemene | WRITe(*,*) "Nb Attaches max:",IMax |
297 | 1 | equemene | ! Plusieurs cas possibles pour un bicycle: |
298 | 1 | equemene | ! 1) 2 cycles relies par un sommet, ICycle=2, IMax=3 |
299 | 1 | equemene | ! 2) 2 cycles relies par une arrete, ICycle=2, Imax=3 |
300 | 1 | equemene | If (Imax.Eq.3) THEN |
301 | 1 | equemene | ! on doit pouvoir traiter celui la... |
302 | 1 | equemene | ! On classe les atomes li?s a trois atomes, par le nombre d'atomes |
303 | 1 | equemene | ! lies a trois atomes |
304 | 1 | equemene | ! auxquels ils sont li?s ... interessant pour les composes asterisques. |
305 | 1 | equemene | I3=0 |
306 | 1 | equemene | FLie3=.False. |
307 | 1 | equemene | DO I=1,Na |
308 | 1 | equemene | If (Liaisons(I,0).EQ.3) THEN |
309 | 1 | equemene | I3=I3+1 |
310 | 1 | equemene | K=0 |
311 | 1 | equemene | DO J=1,Liaisons(I,0) |
312 | 1 | equemene | If (Liaisons(Liaisons(I,J),0).Eq.3) THEN |
313 | 1 | equemene | k=k+1 |
314 | 1 | equemene | FLie3=.True. |
315 | 1 | equemene | END IF |
316 | 1 | equemene | END DO |
317 | 1 | equemene | NbAt3(I3,2)=k |
318 | 1 | equemene | NbAt3(I3,1)=I |
319 | 1 | equemene | END IF |
320 | 1 | equemene | END DO |
321 | 1 | equemene | ! A-t-on deux atomes a 3 lies ensemble ? |
322 | 1 | equemene | IF (FLie3) THEN |
323 | 1 | equemene | ! on les classe pas nb at lies a 3 |
324 | 1 | equemene | IAt3=0 |
325 | 1 | equemene | Idx3=0 |
326 | 1 | equemene | DO I=1,I3 |
327 | 1 | equemene | IF (NbAt3(I,2).ge.Iat3) THEN |
328 | 1 | equemene | IAt3=NbAt3(I,2) |
329 | 1 | equemene | Idx3=NbAt3(I,1) |
330 | 1 | equemene | END IF |
331 | 1 | equemene | END DO |
332 | 1 | equemene | ! On va enlever ces liaisons entre atomes a 3, en les mettant |
333 | 1 | equemene | ! en CF de l'atome 'central' |
334 | 1 | equemene | if (debug) WRITE(*,*) "Atome ",Idx3, & |
335 | 1 | equemene | " retenu, li? a",IAt3," atomes 3" |
336 | 1 | equemene | DO I=1,Liaisons(Idx3,0) |
337 | 1 | equemene | I1=Liaisons(Idx3,I) |
338 | 1 | equemene | If (Liaisons(I1,0).EQ.3) THEN |
339 | 1 | equemene | if (debug) WRITE(*,*) "Traitement ",I1,Idx3 |
340 | 1 | equemene | NbLies=Lies_CF(Idx3,0)+1 |
341 | 1 | equemene | Lies_CF(Idx3,NbLies)=I1 |
342 | 1 | equemene | Lies_CF(Idx3,0)=NbLies |
343 | 1 | equemene | NbLies=Lies_CP(I1,0)+1 |
344 | 1 | equemene | Lies_CP(I1,NbLies)=Idx3 |
345 | 1 | equemene | Call Annul(Liaisons,I1,Idx3) |
346 | 1 | equemene | Call Annul(Liaisons,Idx3,I1) |
347 | 1 | equemene | Liaisons(Idx3,0)=Liaisons(Idx3,0)-1 |
348 | 1 | equemene | Liaisons(I1,0)=Liaisons(I1,0)-1 |
349 | 1 | equemene | END IF |
350 | 1 | equemene | END DO |
351 | 1 | equemene | ELSE |
352 | 1 | equemene | WRITE(*,*) "Aucune liaisons entre deux atomes li?s" |
353 | 1 | equemene | WRITE(*,*) "Pas encore trait?" |
354 | 1 | equemene | STOP |
355 | 1 | equemene | END IF !FLie3=T ? |
356 | 1 | equemene | END IF !Imax=3 ? |
357 | 1 | equemene | ELSE ! BiCyle ? |
358 | 1 | equemene | ! Un seul cycle. Facile :-) |
359 | 1 | equemene | WRITE(*,*) "Un cycle identifie..." |
360 | 1 | equemene | NbCycle=NbCycle+1 |
361 | 1 | equemene | if (debug) WRITE(*,*) 'Considering cycle ',NbCycle |
362 | 1 | equemene | If (NbCycle.ge.2) THEN |
363 | 1 | equemene | ! si ce n'est pas le premier cycle que l'on met, on regarde si parmi les |
364 | 1 | equemene | ! atomes du cycle, l'un d'eux etait avant attache a 3 atomes... |
365 | 1 | equemene | I=1 |
366 | 1 | equemene | DO WHILE (Liaisons(I,0).ne.2) |
367 | 1 | equemene | I=I+1 |
368 | 1 | equemene | END DO |
369 | 1 | equemene | if (debug) WRITE(*,*) "I>2:",I,Former3(I) |
370 | 1 | equemene | FTmp=Former3(I) |
371 | 1 | equemene | I0=I |
372 | 1 | equemene | IOld=I |
373 | 1 | equemene | I1=I |
374 | 1 | equemene | I=Liaisons(I,1) |
375 | 1 | equemene | DO WHILE (.NOT.FTmp) |
376 | 1 | equemene | I1=Liaisons(I,1) |
377 | 1 | equemene | If (I1.Eq.IOld) I1=Liaisons(I,2) |
378 | 1 | equemene | FTmp=Former3(I1) |
379 | 1 | equemene | if (debug) WRITE(*,*) "I,I1,I0,IOld",I,I1,I0, & |
380 | 1 | equemene | IOld,FTmp |
381 | 1 | equemene | IF (I1.eq.I0) FTmp=.TRUE. |
382 | 1 | equemene | if (debug) WRITE(*,*) "I,I1,I0,IOld",I,I1,I0, & |
383 | 1 | equemene | IOld,FTmp |
384 | 1 | equemene | IOld=I |
385 | 1 | equemene | I=I1 |
386 | 1 | equemene | END DO |
387 | 1 | equemene | if (debug) WRITE(*,*) "I,I1,I0,IOld",I,I1,I0, & |
388 | 1 | equemene | IOld,FTmp |
389 | 1 | equemene | IF (Former3(I1)) THEN |
390 | 1 | equemene | ! On a notre atome particulier ... cool :-) |
391 | 1 | equemene | if (debug) WRITE(*,*) "Atome former3",I1 |
392 | 1 | equemene | ITmp=I1 |
393 | 1 | equemene | END IF |
394 | 1 | equemene | END IF ! NbCycle >=2 |
395 | 1 | equemene | IF (.NOT.Ftmp) THEN |
396 | 1 | equemene | if (debug) WRITE(*,*) "Pas trouve de former3" |
397 | 1 | equemene | ! on regarde si il y a un atome particulier.. ie un heteroatome ou autre. |
398 | 1 | equemene | DO I=1,Max_Z |
399 | 1 | equemene | AtTypCycl(I)=0 |
400 | 1 | equemene | END DO |
401 | 1 | equemene | DO I=1,na |
402 | 1 | equemene | if (Liaisons(I,0).eq.2) & |
403 | 1 | equemene | AtTypCycl(Atome(I))=AtTypCycl(Atome(I))+1 |
404 | 1 | equemene | if (debug) WRITE(*,*) I,Atome(I), & |
405 | 1 | equemene | AtTypCycl(Atome(I)), & |
406 | 1 | equemene | Liaisons(I,0) |
407 | 1 | equemene | END DO |
408 | 1 | equemene | Itmp=NmaxL+1 |
409 | 1 | equemene | IAtTmp=0 |
410 | 1 | equemene | DO I=1,Max_Z |
411 | 1 | equemene | If ((AtTypCycl(I).gt.0).and.(AtTypCycl(I).le.Itmp)) & |
412 | 1 | equemene | THEN |
413 | 1 | equemene | Itmp=AtTypCycl(I) |
414 | 1 | equemene | IAtTmp=I |
415 | 1 | equemene | END IF |
416 | 1 | equemene | END DO |
417 | 1 | equemene | if (debug) WRITE(*,*) 'Itmp,IAtTmp:',Itmp,IAtTmp |
418 | 1 | equemene | ! On a le type de l'atome particulier... on va prendre le premier venu |
419 | 1 | equemene | DO I=na,1,-1 |
420 | 1 | equemene | If ((Atome(I).eq.IAtTmp).AND.(Liaisons(I,0).Eq.2)) & |
421 | 1 | equemene | Itmp=I |
422 | 1 | equemene | END DO |
423 | 1 | equemene | END IF |
424 | 1 | equemene | if (debug) WRITE(*,*) 'Atome ',Itmp,'(',IAtTmp,') retenu' |
425 | 1 | equemene | ! On va tricher en enlevant les liaisons de cet atome a la main... |
426 | 1 | equemene | I0=Itmp |
427 | 1 | equemene | I1=Liaisons(I0,1) |
428 | 1 | equemene | DO WHILE (I1.Ne.ITmp) |
429 | 1 | equemene | if (debug) WRITE(*,*) "Going from",I0,"to ",I1 |
430 | 1 | equemene | ! On rajoute ces deux liaisons en CF de Itmp |
431 | 1 | equemene | NbLies=Lies_CF(I0,0)+1 |
432 | 1 | equemene | Lies_CF(I0,NbLies)=Liaisons(I0,1) |
433 | 1 | equemene | Lies_CF(I0,0)=NbLies |
434 | 1 | equemene | ! et les liaisons vers Itmp deviennent des CP pour les autres atomes |
435 | 1 | equemene | NbLies=Lies_CP(I1,0)+1 |
436 | 1 | equemene | Lies_CP(I1,NbLies)=I0 |
437 | 1 | equemene | Lies_CP(I1,0)=NbLies |
438 | 1 | equemene | |
439 | 1 | equemene | Call Annul(Liaisons,I1,I0) |
440 | 1 | equemene | Liaisons(I1,0)=Liaisons(I1,0)-1 |
441 | 1 | equemene | Liaisons(I0,0)=Liaisons(I0,0)-1 |
442 | 1 | equemene | |
443 | 1 | equemene | DO IL=1,na |
444 | 1 | equemene | WRITE(IOOUT,1003) Il,(LIAISONS(IL,JL),JL=0,NMaxL) |
445 | 1 | equemene | END DO |
446 | 1 | equemene | I0=I1 |
447 | 1 | equemene | I1=Liaisons(I0,1) |
448 | 1 | equemene | |
449 | 1 | equemene | end do |
450 | 1 | equemene | Call Annul(Liaisons,I1,I0) |
451 | 1 | equemene | Liaisons(I1,0)=Liaisons(I1,0)-1 |
452 | 1 | equemene | Liaisons(I0,0)=Liaisons(I0,0)-1 |
453 | 1 | equemene | END IF |
454 | 1 | equemene | END IF |
455 | 1 | equemene | DO IL=1,na |
456 | 1 | equemene | WRITE(IOOUT,1003) Il,(LIAISONS(IL,JL),JL=0,NMaxL) |
457 | 1 | equemene | END DO |
458 | 1 | equemene | ! WRITE(IOOUT,*) "==================================" |
459 | 1 | equemene | ! WRITE(IOOUT,*) "==================================" |
460 | 1 | equemene | END DO |
461 | 1 | equemene | |
462 | 1 | equemene | ! WRITE(IOOUT,*) "==================================" |
463 | 1 | equemene | ! Il ne reste plus que des atomes lies a rien... |
464 | 1 | equemene | ! ce sont les 'centres' de la molecule. On repart |
465 | 1 | equemene | ! d'eux pour construire le reste de la molecule. |
466 | 1 | equemene | |
467 | 1 | equemene | 1003 FORMAT(1X,I4,' - ',15(I5)) |
468 | 1 | equemene | ! Avant de partir, on va classer, pour chaque atome, les atomes CF par |
469 | 1 | equemene | ! nombre de masse decroissant. |
470 | 1 | equemene | DO I=1,na |
471 | 1 | equemene | ! WRITE(*,*) I,Lies_CF(I,0),(Atome(Lies_CF(I,J)),j=1,Lies_CF(I,0)) |
472 | 1 | equemene | DO J=1,Lies_CF(I,0)-1 |
473 | 1 | equemene | DO K=J+1,Lies_CF(I,0) |
474 | 1 | equemene | if (atome(Lies_CF(I,K))>atome(Lies_CF(I,J))) THEN |
475 | 1 | equemene | Itmp=Lies_CF(I,K) |
476 | 1 | equemene | Lies_CF(I,K)=Lies_CF(I,J) |
477 | 1 | equemene | Lies_CF(I,J)=Itmp |
478 | 1 | equemene | END IF |
479 | 1 | equemene | END DO |
480 | 1 | equemene | END DO |
481 | 1 | equemene | ! WRITE(*,*) I,Lies_CF(I,0),(Atome(Lies_CF(I,J)),j=1,Lies_CF(I,0)) |
482 | 1 | equemene | END DO |
483 | 1 | equemene | |
484 | 1 | equemene | IF (Debug) THEN |
485 | 1 | equemene | WRITE(IOOUT,*) 'LIAISONS' |
486 | 1 | equemene | DO I=1,na |
487 | 1 | equemene | WRITE(IOOUT,1003) i,(LIAISONS(I,J),J=0,NMaxL) |
488 | 1 | equemene | END DO |
489 | 1 | equemene | |
490 | 1 | equemene | WRITE(IOOUT,*) 'LIes_CF' |
491 | 1 | equemene | DO I=1,na |
492 | 1 | equemene | WRITE(IOOUT,1003) i,(LIeS_CF(I,J),J=0,NMaxL) |
493 | 1 | equemene | END DO |
494 | 1 | equemene | |
495 | 1 | equemene | WRITE(IOOUT,*) 'LIes_CP' |
496 | 1 | equemene | DO I=1,na |
497 | 1 | equemene | WRITE(IOOUT,1003) i,(LIeS_CP(I,J),J=0,NMaxL) |
498 | 1 | equemene | END DO |
499 | 1 | equemene | END IF |
500 | 1 | equemene | |
501 | 1 | equemene | |
502 | 1 | equemene | ! On compte le nb d'atomes sans atomes CP (centripetes) |
503 | 1 | equemene | NbAt0=0 |
504 | 1 | equemene | DO I=1,na |
505 | 1 | equemene | IF (Lies_CP(I,0).eq.0) THEN |
506 | 1 | equemene | NbAt0=NbAt0+1 |
507 | 1 | equemene | IF (DEBUG) WRITE(*,*) "Center atom",NbAt0,I,Atome(I) |
508 | 1 | equemene | END IF |
509 | 1 | equemene | END DO |
510 | 1 | equemene | |
511 | 1 | equemene | ! On va les traiter tous en construisant les molecules en partant d'eux |
512 | 1 | equemene | ! Le premier atome sans CP est different des autres car il fixe |
513 | 1 | equemene | ! l'origine |
514 | 1 | equemene | |
515 | 1 | equemene | IZm=1 |
516 | 1 | equemene | ! Boucle pour trouver celui qui a le plus d'atomes CF |
517 | 1 | equemene | IdAt0=0 |
518 | 1 | equemene | VCF=0 |
519 | 1 | equemene | DO ICAt=1,na |
520 | 1 | equemene | if ((Lies_CP(ICaT,0).eq.0).AND.(Lies_CF(ICAt,0).gt.VCF)) THEN |
521 | 1 | equemene | IdAt0=ICat |
522 | 1 | equemene | VCF=Lies_CF(ICAt,0) |
523 | 1 | equemene | END IF |
524 | 1 | equemene | END DO |
525 | 1 | equemene | Lies_CP(IdAt0,0)=-1 |
526 | 1 | equemene | |
527 | 1 | equemene | ! WRITE(IOOUT,*) 'Atome 1', IdAt0, Nom(Atome(IdAt0)) |
528 | 1 | equemene | Izm1=IdAt0 |
529 | 1 | equemene | ind_zmat(izm,1)=Izm1 |
530 | 1 | equemene | ind_zmat(izm,2)=0 |
531 | 1 | equemene | ind_zmat(izm,3)=0 |
532 | 1 | equemene | ind_zmat(izm,4)=0 |
533 | 1 | equemene | ind_zmat(izm,5)=0 |
534 | 1 | equemene | val_zmat(izm,1)=0.0 |
535 | 1 | equemene | val_zmat(izm,2)=0.0 |
536 | 1 | equemene | val_zmat(izm,3)=0.0 |
537 | 1 | equemene | DejaFait(Izm1)=.True. |
538 | 1 | equemene | |
539 | 1 | equemene | ! Les atomes CF lies a IdAt0 sont mis en attente pour |
540 | 1 | equemene | ! etre traites |
541 | 1 | equemene | |
542 | 1 | equemene | IndFin=1 |
543 | 1 | equemene | Do iaf=1,Lies_CF(IdAt0,0) |
544 | 1 | equemene | CAfaire(IndFin)=Lies_CF(IdAt0,Iaf) |
545 | 1 | equemene | IndFin=IndFin+1 |
546 | 1 | equemene | END DO |
547 | 1 | equemene | CAfaire(IndFin)=0 |
548 | 1 | equemene | |
549 | 1 | equemene | ! On construit la premiere couche qui est speciale car elle fixe les |
550 | 1 | equemene | ! axes. |
551 | 1 | equemene | ! Plusieurs cas sont possibles suivant le nb d'atomes CF |
552 | 1 | equemene | |
553 | 1 | equemene | IF (Lies_CF(IdAt0,0).ge.3) THEN |
554 | 1 | equemene | if (debug) WRITE(*,*) 'Cas tres simple,',IdAt0, & |
555 | 1 | equemene | ' li? a plus de 3 atomes' |
556 | 1 | equemene | IZm2=Lies_CF(IdAt0,1) |
557 | 1 | equemene | IZm3=Lies_CF(IdAt0,2) |
558 | 1 | equemene | ! WRITE(IOOUT,*) 'Atome 2' , Izm2, Nom(Atome(Izm2)) |
559 | 1 | equemene | ! WRITE(IOOUT,*) 'Atome 3' ,Izm3, Nom(Atome(izm3)) |
560 | 1 | equemene | |
561 | 1 | equemene | Izm=2 |
562 | 1 | equemene | CALL vecteur(IZm1,IZm2,x,y,z,vx1,vy1,vz1,norm1) |
563 | 1 | equemene | ! write(*,11) n1,n2,norm1 |
564 | 1 | equemene | |
565 | 1 | equemene | ind_zmat(izm,1)=izm2 |
566 | 1 | equemene | ind_zmat(izm,2)=izm1 |
567 | 1 | equemene | ind_zmat(izm,3)=0 |
568 | 1 | equemene | ind_zmat(izm,4)=0 |
569 | 1 | equemene | ind_zmat(izm,5)=0 |
570 | 1 | equemene | val_zmat(izm,1)=norm1 |
571 | 1 | equemene | val_zmat(izm,2)=0.0 |
572 | 1 | equemene | val_zmat(izm,3)=0.0 |
573 | 1 | equemene | DejaFait(Izm2)=.TRUE. |
574 | 1 | equemene | |
575 | 1 | equemene | Izm=3 |
576 | 1 | equemene | CALL vecteur(izm1,izm3,x,y,z,vx2,vy2,vz2,norm2) |
577 | 1 | equemene | val=angle(vx1,vy1,vz1,norm1,vx2,vy2,vz2,norm2) |
578 | 1 | equemene | |
579 | 1 | equemene | ! write(*,11) n1,n2,norm1,n3,val |
580 | 1 | equemene | |
581 | 1 | equemene | ind_zmat(izm,1)=izm3 |
582 | 1 | equemene | ind_zmat(izm,2)=izm1 |
583 | 1 | equemene | ind_zmat(izm,3)=izm2 |
584 | 1 | equemene | ind_zmat(izm,4)=0 |
585 | 1 | equemene | ind_zmat(izm,5)=0 |
586 | 1 | equemene | val_zmat(izm,1)=norm2 |
587 | 1 | equemene | val_zmat(izm,2)=val |
588 | 1 | equemene | val_zmat(izm,3)=0.0 |
589 | 1 | equemene | DejaFait(Izm3)=.TRUE. |
590 | 1 | equemene | |
591 | 1 | equemene | DO IdAtl=3,Lies_CF(IdAt0,0) |
592 | 1 | equemene | Izm4= Lies_CF(IdAt0,IdAtl) |
593 | 1 | equemene | ! WRITE(IOOUT,*) 'Atome ',Izm+1,Izm4,Nom(Atome(Izm4)),Izm1, |
594 | 1 | equemene | ! $Izm2,Izm3 |
595 | 1 | equemene | Izm=Izm+1 |
596 | 1 | equemene | Call AddLigne(Izm,Izm4,Izm1,Izm2,Izm3,ind_zmat,val_zmat, & |
597 | 1 | equemene | x,y,z) |
598 | 1 | equemene | DejaFait(Izm4)=.TRUE. |
599 | 1 | equemene | END DO |
600 | 1 | equemene | END IF |
601 | 1 | equemene | |
602 | 1 | equemene | IF (Lies_CF(Izm1,0).eq.2) THEN |
603 | 1 | equemene | if (debug) WRITE(*,*) 'Cas simple,',IdAt0, & |
604 | 1 | equemene | ' li? a 2 atomes' |
605 | 1 | equemene | |
606 | 1 | equemene | IZm2=Lies_CF(IdAt0,1) |
607 | 1 | equemene | IZm3=Lies_CF(IdAt0,2) |
608 | 1 | equemene | Izm=2 |
609 | 1 | equemene | CALL vecteur(IZm1,IZm2,x,y,z,vx1,vy1,vz1,norm1) |
610 | 1 | equemene | ! write(*,11) n1,n2,norm1 |
611 | 1 | equemene | |
612 | 1 | equemene | ind_zmat(izm,1)=izm2 |
613 | 1 | equemene | ind_zmat(izm,2)=izm1 |
614 | 1 | equemene | ind_zmat(izm,3)=0 |
615 | 1 | equemene | ind_zmat(izm,4)=0 |
616 | 1 | equemene | ind_zmat(izm,5)=0 |
617 | 1 | equemene | val_zmat(izm,1)=norm1 |
618 | 1 | equemene | val_zmat(izm,2)=0.0 |
619 | 1 | equemene | val_zmat(izm,3)=0.0 |
620 | 1 | equemene | DejaFait(Izm2)=.TRUE. |
621 | 1 | equemene | |
622 | 1 | equemene | Izm=3 |
623 | 1 | equemene | |
624 | 1 | equemene | CALL vecteur(izm1,izm3,x,y,z,vx2,vy2,vz2,norm2) |
625 | 1 | equemene | val=angle(vx1,vy1,vz1,norm1, & |
626 | 1 | equemene | vx2,vy2,vz2,norm2) |
627 | 1 | equemene | |
628 | 1 | equemene | ! write(*,11) n1,n2,norm1,n3,val |
629 | 1 | equemene | |
630 | 1 | equemene | ind_zmat(izm,1)=izm3 |
631 | 1 | equemene | ind_zmat(izm,2)=izm1 |
632 | 1 | equemene | ind_zmat(izm,3)=izm2 |
633 | 1 | equemene | ind_zmat(izm,4)=0 |
634 | 1 | equemene | ind_zmat(izm,5)=0 |
635 | 1 | equemene | val_zmat(izm,1)=norm2 |
636 | 1 | equemene | val_zmat(izm,2)=val |
637 | 1 | equemene | val_zmat(izm,3)=0.0 |
638 | 1 | equemene | DejaFait(Izm3)=.TRUE. |
639 | 1 | equemene | |
640 | 1 | equemene | END IF |
641 | 1 | equemene | |
642 | 1 | equemene | IF (Lies_CF(Izm1,0).eq.1) THEN |
643 | 1 | equemene | if (debug) WRITE(*,*) 'Cas merdouille,',IdAt0, & |
644 | 1 | equemene | ' li? a 1 atome' |
645 | 1 | equemene | |
646 | 1 | equemene | IZm2=Lies_CF(IdAt0,1) |
647 | 1 | equemene | Izm=2 |
648 | 1 | equemene | CALL vecteur(IZm1,IZm2,x,y,z,vx1,vy1,vz1,norm1) |
649 | 1 | equemene | ! write(*,11) n1,n2,norm1 |
650 | 1 | equemene | |
651 | 1 | equemene | ind_zmat(izm,1)=izm2 |
652 | 1 | equemene | ind_zmat(izm,2)=izm1 |
653 | 1 | equemene | ind_zmat(izm,3)=0 |
654 | 1 | equemene | ind_zmat(izm,4)=0 |
655 | 1 | equemene | ind_zmat(izm,5)=0 |
656 | 1 | equemene | val_zmat(izm,1)=norm1 |
657 | 1 | equemene | val_zmat(izm,2)=0.0 |
658 | 1 | equemene | val_zmat(izm,3)=0.0 |
659 | 1 | equemene | DejaFait(Izm2)=.TRUE. |
660 | 1 | equemene | |
661 | 1 | equemene | ! Pour les autres atomes, on prend les atomes |
662 | 1 | equemene | ! CF lie a l'tome CF lie a At0... en esperant |
663 | 1 | equemene | ! qu'il en a !!! |
664 | 1 | equemene | ! => il faudra voir le cas ou il n'en a pas !!! |
665 | 1 | equemene | ! en attendant on rajoute le test... |
666 | 1 | equemene | IF (Lies_CF(Izm2,0).Eq.0) THEN |
667 | 1 | equemene | WRITE(*,*) "Je n'arrive pas a trouver les premiers" |
668 | 1 | equemene | WRITE(*,*) "atomes pour construire la molecule" |
669 | 1 | equemene | WRITE(*,*) "Atome central li? au plus a 1 atome",Izm1,izm2 |
670 | 1 | equemene | WRITE(*,*) "Et atome 2 li? a rien... moi perdu" |
671 | 1 | equemene | STOP |
672 | 1 | equemene | END IF |
673 | 1 | equemene | |
674 | 1 | equemene | ! On ajoute les atomes lies a cet atome dans la liste a faire |
675 | 1 | equemene | Do iaf=1,Lies_CF(Izm2,0) |
676 | 1 | equemene | CAfaire(IndFin)=Lies_CF(Izm2,Iaf) |
677 | 1 | equemene | IndFin=IndFin+1 |
678 | 1 | equemene | END DO |
679 | 1 | equemene | CAfaire(IndFin)=0 |
680 | 1 | equemene | Izm3= Lies_CF(Izm2,1) |
681 | 1 | equemene | Izm=3 |
682 | 1 | equemene | CALL vecteur(izm2,izm1,x,y,z,vx1,vy1,vz1,norm1) |
683 | 1 | equemene | |
684 | 1 | equemene | CALL vecteur(izm2,izm3,x,y,z,vx2,vy2,vz2,norm2) |
685 | 1 | equemene | val=angle(vx1,vy1,vz1,norm1, & |
686 | 1 | equemene | vx2,vy2,vz2,norm2) |
687 | 1 | equemene | |
688 | 1 | equemene | ! write(*,11) n1,n2,norm1,n3,val |
689 | 1 | equemene | |
690 | 1 | equemene | ind_zmat(izm,1)=izm3 |
691 | 1 | equemene | ind_zmat(izm,2)=izm2 |
692 | 1 | equemene | ind_zmat(izm,3)=izm1 |
693 | 1 | equemene | ind_zmat(izm,4)=0 |
694 | 1 | equemene | ind_zmat(izm,5)=0 |
695 | 1 | equemene | val_zmat(izm,1)=norm1 |
696 | 1 | equemene | val_zmat(izm,2)=val |
697 | 1 | equemene | val_zmat(izm,3)=0.0 |
698 | 1 | equemene | DejaFait(Izm3)=.TRUE. |
699 | 1 | equemene | |
700 | 1 | equemene | ! je pense que ce qui suit est totalement inutile |
701 | 1 | equemene | ! C DO IdAtl=3,Lies_CF(IdAt0,0) |
702 | 1 | equemene | ! C Izm4= Lies_CF(IdAt0,IdAtl) |
703 | 1 | equemene | ! C Izm=Izm+1 |
704 | 1 | equemene | ! C Call AddLigne(Izm,Izm4,Izm1,Izm2,Izm3,ind_zmat,val_zmat |
705 | 1 | equemene | ! C $,x,y,z) |
706 | 1 | equemene | ! C DejaFait(Izm4)=.TRUE. |
707 | 1 | equemene | ! C END DO |
708 | 1 | equemene | END IF |
709 | 1 | equemene | |
710 | 1 | equemene | ! on a cree la premiere couche autour du premier centre |
711 | 1 | equemene | ! reste a finir les autres couches |
712 | 1 | equemene | IndAFaire=1 |
713 | 1 | equemene | if (debug) WRITE(IOOUT,*) "CaFaire:",CaFaire |
714 | 1 | equemene | Do WHILE (Cafaire(IndAFaire).ne.0) |
715 | 1 | equemene | IAt0=Cafaire(IndAfaire) |
716 | 1 | equemene | if (debug) WRITE(*,*) "IndAFaire,IAt0,Lies_CF(IAt0,0)", & |
717 | 1 | equemene | IndAFaire,IAt0,Lies_CF(IAt0,0) |
718 | 1 | equemene | if (Lies_CF(IAt0,0).ge.1) THEN |
719 | 1 | equemene | ! IAt0 est l'atome pour lequel on construit la couche suivante |
720 | 1 | equemene | ! le premier atome lie est particulier car il definit l'orientation |
721 | 1 | equemene | ! de ce fragment |
722 | 1 | equemene | IAti=Lies_CF(IAt0,1) |
723 | 1 | equemene | ! WRITE(IOOUT,*) 'IAti:',IAti |
724 | 1 | equemene | IAtd=IAt0 |
725 | 1 | equemene | ! WRITE(IOOUT,*) 'IAtd:',IAtd |
726 | 1 | equemene | IAtv=Lies_CP(IAt0,1) |
727 | 1 | equemene | ! WRITE(IOOUT,*) 'IAtv:',IAtv |
728 | 1 | equemene | IIAtdh=1 |
729 | 1 | equemene | IAtdh=Lies_CF(IAtv,IIatdh) |
730 | 1 | equemene | DO WHILE (Iatdh.eq.IAt0) |
731 | 1 | equemene | IIatdh=IIatdh+1 |
732 | 1 | equemene | IAtdh=Lies_CF(IAtv,IIatdh) |
733 | 1 | equemene | END DO |
734 | 1 | equemene | IF (IAtdh.eq.0) IAtdh=Lies_CP(IAtv,1) |
735 | 1 | equemene | ! WRITE(IOOUT,*) 'IAtdh:',IAtdh |
736 | 1 | equemene | IF (.NOT.DejaFait(IAti)) THEN |
737 | 1 | equemene | Izm=Izm+1 |
738 | 1 | equemene | if (debug) WRITE(*,*) 'izm,IAti,IAtd,IAtv,IAtdh', & |
739 | 1 | equemene | izm,IAti,IAtd,IAtv,IAtdh |
740 | 1 | equemene | Call AddLigne(Izm,IAti,IAtd,IAtv,IAtdh,ind_zmat,val_zmat & |
741 | 1 | equemene | ,x,y,z) |
742 | 1 | equemene | DejaFait(IAti)=.TRUE. |
743 | 1 | equemene | END IF |
744 | 1 | equemene | |
745 | 1 | equemene | CAfaire(IndFin)=Lies_CF(IAt0,1) |
746 | 1 | equemene | IndFin=IndFin+1 |
747 | 1 | equemene | ! Le traitement des autres est plus facile |
748 | 1 | equemene | IAtdh=Lies_CF(IAt0,1) |
749 | 1 | equemene | DO IAta=2,Lies_CF(IAt0,0) |
750 | 1 | equemene | IAtI=Lies_CF(IAt0,IAta) |
751 | 1 | equemene | if (debug) WRITE(*,*) " Problem is here; IndFin:",I |
752 | 1 | equemene | CAfaire(IndFin)=IAtI |
753 | 1 | equemene | IndFin=IndFin+1 |
754 | 1 | equemene | |
755 | 1 | equemene | IF (.NOT.DejaFait(IAti)) THEN |
756 | 1 | equemene | Izm=Izm+1 |
757 | 1 | equemene | Call AddLigne(Izm,IAti,IAtd,IAtv,IAtdh,ind_zmat & |
758 | 1 | equemene | ,val_zmat,x,y,z) |
759 | 1 | equemene | DejaFait(IAti)=.TRUE. |
760 | 1 | equemene | END IF |
761 | 1 | equemene | END DO |
762 | 1 | equemene | |
763 | 1 | equemene | CAfaire(IndFin)=0 |
764 | 1 | equemene | END IF |
765 | 1 | equemene | IndAFaire=IndAFaire+1 |
766 | 1 | equemene | END DO |
767 | 1 | equemene | |
768 | 1 | equemene | |
769 | 1 | equemene | ! On a fini de creer la molecule autour du premier atome 'centre' |
770 | 1 | equemene | ! Pour les autres c'est presque id... sauf que les axes sont deja fixes |
771 | 1 | equemene | ! On pourrait imaginer de mettre des atomes fictifs pour redefinir des axes |
772 | 1 | equemene | ! locaux... dans une autre version |
773 | 1 | equemene | ! V2.0 |
774 | 1 | equemene | NbAt0=NbAt0-1 |
775 | 1 | equemene | DO I=1,NbAt0 |
776 | 1 | equemene | ! Boucle pour trouver celui qui a le plus d'atomes CF |
777 | 1 | equemene | |
778 | 1 | equemene | IdAt0=0 |
779 | 1 | equemene | VCF=0 |
780 | 1 | equemene | |
781 | 1 | equemene | DO ICAt=1,na |
782 | 1 | equemene | if ((Lies_CP(ICaT,0).eq.0).AND.(Lies_CF(ICAt,0).gt.VCF)) & |
783 | 1 | equemene | THEN |
784 | 1 | equemene | IdAt0=ICat |
785 | 1 | equemene | VCF=Lies_CF(ICAt,0) |
786 | 1 | equemene | END IF |
787 | 1 | equemene | END DO |
788 | 1 | equemene | Lies_CP(IdAt0,0)=-1 |
789 | 1 | equemene | |
790 | 1 | equemene | IF (debug) WRITE(*,*) 'Adding fragment centered on ',IdAt0, & |
791 | 1 | equemene | LIAISONS(IdAt0,0) |
792 | 1 | equemene | IF (debug) WRITE(*,*) 'Center linked to ',Lies_CF(IdAt0,0), & |
793 | 1 | equemene | ' atoms' |
794 | 1 | equemene | ! if (LIAISONS(IdAt0,0).EQ.0) goto 12345 |
795 | 1 | equemene | |
796 | 1 | equemene | if (debug) THEN |
797 | 1 | equemene | WRITE(IOOUT,*) 'LIAISONS tralala',nbcycle |
798 | 1 | equemene | DO IAt=1,na |
799 | 1 | equemene | WRITE(IOOUT,1003) iat,(LIAISONS(Iat,Jat),Jat=0,NMaxL) |
800 | 1 | equemene | END DO |
801 | 1 | equemene | END IF |
802 | 1 | equemene | |
803 | 1 | equemene | ! Boucle pour voir quel est l'atome du fragment precedent qui est le plus |
804 | 1 | equemene | ! proche de celui ci |
805 | 1 | equemene | ! Rq: si ce sont des cycles lies, il pourrait etre malin de rechercher |
806 | 1 | equemene | ! a quoi il etait lie. |
807 | 1 | equemene | norm2=1.e6 |
808 | 1 | equemene | Idx=0 |
809 | 1 | equemene | DO ICAt=1,Izm |
810 | 1 | equemene | CALL vecteur(Idat0,ind_zmat(icat,1),x,y,z,vx1,vy1,vz1,norm1) |
811 | 1 | equemene | if (norm2.ge.norm1) THEN |
812 | 1 | equemene | norm2=norm1 |
813 | 1 | equemene | Idx=Icat |
814 | 1 | equemene | END IF |
815 | 1 | equemene | END DO |
816 | 1 | equemene | IF (debug) WRITE(*,*) 'Link between fragments ',IdAt0, & |
817 | 1 | equemene | ind_zmat(Idx,1), ' -- Idx=',Idx |
818 | 1 | equemene | |
819 | 1 | equemene | ! on a l'indice... on va rajouter cet atome a la liste ! |
820 | 1 | equemene | izm=izm+1 |
821 | 1 | equemene | n1=ind_zmat(Idx,1) |
822 | 1 | equemene | ! Petit probleme si Idx<=2 |
823 | 1 | equemene | IF (Idx.EQ.1) THEN |
824 | 1 | equemene | ! Pb non negligeable ... |
825 | 1 | equemene | IF (izm.ge.2) THEN |
826 | 1 | equemene | IAtv=ind_zmat(2,1) |
827 | 1 | equemene | IAtdh=ind_zmat(3,1) |
828 | 1 | equemene | ELSE |
829 | 1 | equemene | WRITE(*,*) '2 fragments, le 1er a moins de 2 atomes...' |
830 | 1 | equemene | WRITE(*,*) "J'ai merde... " |
831 | 1 | equemene | STOP |
832 | 1 | equemene | END IF |
833 | 1 | equemene | ELSEIF (Idx.EQ.2) THEN |
834 | 1 | equemene | IAtv=1 |
835 | 1 | equemene | IF (izm.ge.2) THEN |
836 | 1 | equemene | IAtdh=ind_zmat(3,1) |
837 | 1 | equemene | ELSE |
838 | 1 | equemene | WRITE(*,*) '2 fragments, le 1er a moins de 2 atomes...' |
839 | 1 | equemene | WRITE(*,*) "J'ai merde... " |
840 | 1 | equemene | STOP |
841 | 1 | equemene | END IF |
842 | 1 | equemene | ELSE |
843 | 1 | equemene | IAtv=ind_zmat(Idx,2) |
844 | 1 | equemene | IAtdh=ind_zmat(Idx,3) |
845 | 1 | equemene | END IF |
846 | 1 | equemene | |
847 | 1 | equemene | ! WRITE(*,*) "Outchilou IAtv, IAtdh", IAtv, IAtdh,n1 |
848 | 1 | equemene | CALL vecteur(n1,IdAt0,x,y,z,vx1,vy1,vz1,norm1) |
849 | 1 | equemene | CALL vecteur(n1,IAtv,x,y,z,vx2,vy2,vz2,norm2) |
850 | 1 | equemene | val=angle(vx1,vy1,vz1,norm1, & |
851 | 1 | equemene | vx2,vy2,vz2,norm2) |
852 | 1 | equemene | if (debug) WRITE(*,*) 'Angle val:1',IdAt0,n1,IAtv,val |
853 | 1 | equemene | if ((abs(val).LE.10.).OR.(abs(pi-val).le.10.)) THEN |
854 | 1 | equemene | IAtv=IAtdh |
855 | 1 | equemene | ! Ceci pose pb si Idx<=3... a traiter plus tard |
856 | 1 | equemene | IF (Idx.ge.3) THEN |
857 | 1 | equemene | IAtdh=ind_zmat(Idx,4) |
858 | 1 | equemene | ELSE |
859 | 1 | equemene | if (izm.ge.4) THEN |
860 | 1 | equemene | IAtdh=4 |
861 | 1 | equemene | ELSE |
862 | 1 | equemene | WRITE(*,*) 'Pb Angle Val+idx=3+izm<=4' |
863 | 1 | equemene | STOP |
864 | 1 | equemene | END IF |
865 | 1 | equemene | END IF |
866 | 1 | equemene | END IF |
867 | 1 | equemene | Call AddLigne(Izm,IdAt0,ind_zmat(Idx,1),IAtv,IAtdh, & |
868 | 1 | equemene | ind_zmat,val_zmat,x,y,z) |
869 | 1 | equemene | |
870 | 1 | equemene | |
871 | 1 | equemene | IndFin=1 |
872 | 1 | equemene | IAtd=IdAt0 |
873 | 1 | equemene | n1=IAtdh |
874 | 1 | equemene | IAtdh=IAtv |
875 | 1 | equemene | IAtv=ind_zmat(Idx,1) |
876 | 1 | equemene | ! On ajoute les atomes lies a cet atome dans la liste a faire |
877 | 1 | equemene | Do iaf=1,Lies_CF(IdAt0,0) |
878 | 1 | equemene | IatI=Lies_CF(IdAt0,Iaf) |
879 | 1 | equemene | ! We check that this atom is not the one that is the closest to |
880 | 1 | equemene | ! the center atom |
881 | 1 | equemene | if (IAtv.Ne.IAtI) THEN |
882 | 1 | equemene | IF (debug) WRITE(*,*) 'Adding atom',IAtI, & |
883 | 1 | equemene | 'to CAFaire in pos',iaf |
884 | 1 | equemene | CAfaire(IndFin)=IAtI |
885 | 1 | equemene | IndFin=IndFin+1 |
886 | 1 | equemene | ! On les ajoute aussi dans la zmat |
887 | 1 | equemene | If (.NOT.DejaFait(IatI)) THEN |
888 | 1 | equemene | izm=izm+1 |
889 | 1 | equemene | ! WRITE(*,*) "Outchili IAtv, IAtdh,IAtI", IAtv, IAtdh,IAtI |
890 | 1 | equemene | CALL vecteur(IAtI,IAtD,x,y,z,vx1,vy1,vz1,norm1) |
891 | 1 | equemene | CALL vecteur(IAtI,IAtv,x,y,z,vx2,vy2,vz2,norm2) |
892 | 1 | equemene | val=angle(vx1,vy1,vz1,norm1, vx2,vy2,vz2,norm2) |
893 | 1 | equemene | if (debug) WRITE(*,*) 'Angle val:2',IAtI,IAtD,IAtv,val |
894 | 1 | equemene | if ((abs(val).LE.10.).OR.(abs(180.-abs(val)).le.10.)) & |
895 | 1 | equemene | THEN |
896 | 1 | equemene | Call AddLigne(Izm,IAtI,IAtv,IAtdh,n1, & |
897 | 1 | equemene | ind_zmat,val_zmat,x,y,z) |
898 | 1 | equemene | ELSE |
899 | 1 | equemene | |
900 | 1 | equemene | Call AddLigne(Izm,IAtI,IAtD,IAtv,IAtdh, & |
901 | 1 | equemene | ind_zmat,val_zmat,x,y,z) |
902 | 1 | equemene | END IF |
903 | 1 | equemene | END IF |
904 | 1 | equemene | END IF |
905 | 1 | equemene | END DO |
906 | 1 | equemene | CAfaire(IndFin)=0 |
907 | 1 | equemene | |
908 | 1 | equemene | ! On traite le reste de ce fragment !! |
909 | 1 | equemene | IndAFaire=1 |
910 | 1 | equemene | WRITE(IOOUT,*) CaFaire |
911 | 1 | equemene | Do WHILE (Cafaire(IndAFaire).ne.0) |
912 | 1 | equemene | IAt0=Cafaire(IndAfaire) |
913 | 1 | equemene | if (Lies_CF(IAt0,0).ge.1) THEN |
914 | 1 | equemene | ! IAt0 est l'atome pour lequel on construit la couche suivante |
915 | 1 | equemene | ! le premier atome lie est particulier car il definit l'orientation |
916 | 1 | equemene | ! de ce fragment |
917 | 1 | equemene | Itmp=1 |
918 | 1 | equemene | IAti=Lies_CF(IAt0,Itmp) |
919 | 1 | equemene | DO WHILE (DejaFait(IAti).AND.(Itmp.Le.Lies_CF(IAt0,0))) |
920 | 1 | equemene | Itmp=Itmp+1 |
921 | 1 | equemene | IAti=Lies_CF(IAt0,ITmp) |
922 | 1 | equemene | END DO |
923 | 1 | equemene | If (.NOT.DejaFait(Iati)) THEN |
924 | 1 | equemene | IF (debug) WRITE(IOOUT,*) 'IAti:',IAti |
925 | 1 | equemene | IAtd=IAt0 |
926 | 1 | equemene | IF (debug) WRITE(IOOUT,*) 'IAtd:',IAtd |
927 | 1 | equemene | IAtv=Lies_CP(IAt0,1) |
928 | 1 | equemene | IF (debug) WRITE(IOOUT,*) 'IAtv:',IAtv |
929 | 1 | equemene | IIAtdh=1 |
930 | 1 | equemene | IAtdh=Lies_CF(IAtv,IIatdh) |
931 | 1 | equemene | DO WHILE (Iatdh.eq.IAt0) |
932 | 1 | equemene | IIatdh=IIatdh+1 |
933 | 1 | equemene | IAtdh=Lies_CF(IAtv,IIatdh) |
934 | 1 | equemene | END DO |
935 | 1 | equemene | IF (IAtdh.eq.0) IAtdh=Lies_CP(IAtv,1) |
936 | 1 | equemene | IF (debug) WRITE(IOOUT,*) 'IAtdh:',IAtdh |
937 | 1 | equemene | Izm=Izm+1 |
938 | 1 | equemene | Call AddLigne(Izm,IAti,IAtd,IAtv,IAtdh, & |
939 | 1 | equemene | ind_zmat,val_zmat,x,y,z) |
940 | 1 | equemene | ! Le traitement des autres est plus facile |
941 | 1 | equemene | IAtdh=Lies_CF(IAt0,ITmp) |
942 | 1 | equemene | DO IAta=ITmp+1,Lies_CF(IAt0,0) |
943 | 1 | equemene | IAtI=Lies_CF(IAt0,IAta) |
944 | 1 | equemene | If (.NOT.DejaFait(IAtI)) THEN |
945 | 1 | equemene | Izm=Izm+1 |
946 | 1 | equemene | Call AddLigne(Izm,IAti,IAtd,IAtv,IAtdh, & |
947 | 1 | equemene | ind_zmat,val_zmat,x,y,z) |
948 | 1 | equemene | END IF |
949 | 1 | equemene | END DO |
950 | 1 | equemene | END IF |
951 | 1 | equemene | |
952 | 1 | equemene | ! On ajoute les atomes lies a cet atome dans la liste a faire |
953 | 1 | equemene | Do iaf=1,Lies_CF(IAt0,0) |
954 | 1 | equemene | CAfaire(IndFin)=Lies_CF(IAt0,Iaf) |
955 | 1 | equemene | IndFin=IndFin+1 |
956 | 1 | equemene | END DO |
957 | 1 | equemene | CAfaire(IndFin)=0 |
958 | 1 | equemene | END IF |
959 | 1 | equemene | IndAFaire=IndAFaire+1 |
960 | 1 | equemene | END DO |
961 | 1 | equemene | 12345 CONTINUE |
962 | 1 | equemene | END DO |
963 | 1 | equemene | |
964 | 1 | equemene | if (debug) THEN |
965 | 1 | equemene | WRITE(*,*) 'ind_zmat' |
966 | 1 | equemene | DO I=1,na |
967 | 1 | equemene | WRITE(*,'(1X,5I5)') (ind_zmat(i,j),j=1,5) |
968 | 1 | equemene | END DO |
969 | 1 | equemene | END IF |
970 | 1 | equemene | |
971 | 1 | equemene | |
972 | 1 | equemene | |
973 | 1 | equemene | if (debug) WRITE(*,*) "====================== Exiting Calc_zmat ===================" |
974 | 1 | equemene | |
975 | 1 | equemene | END SUBROUTINE Calc_Zmat |