Statistiques
| Révision :

root / src / Calc_zmat.f90 @ 2

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