Statistiques
| Révision :

root / src / Calc_zmat_frag.f90 @ 12

Historique | Voir | Annoter | Télécharger (39,81 ko)

1 1 pfleura2
SUBROUTINE Calc_Zmat_frag(na,atome,ind_zmat,val_zmat,x,y,z,r_cov,fact)
2 1 pfleura2
3 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4 1 pfleura2
!
5 1 pfleura2
!   Goal: to compute a viable Z-Matrix starting from the
6 1 pfleura2
!         cartesian coordinates of the atoms
7 1 pfleura2
!
8 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
9 1 pfleura2
!
10 1 pfleura2
! Input:
11 1 pfleura2
!  na    : Number or atoms
12 1 pfleura2
! atome  : Mass number of the atoms (H=1, He=2,...)
13 1 pfleura2
! x,y,z  : cartesian coordinates of the atoms
14 1 pfleura2
! r_cov  : array containing the covalent radii of the atoms
15 1 pfleura2
!  fact  : multiplicative factor used to determine if two atoms are linked.
16 1 pfleura2
!          see CalcCnct for more details.
17 1 pfleura2
!
18 1 pfleura2
! Output:
19 1 pfleura2
! ind_zmat : INTEGER(na,5) contains the indices of the Z-matrix
20 1 pfleura2
! val_zmat : REAL(na,3)    contains the values of the Z-matrix
21 1 pfleura2
!
22 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
23 1 pfleura2
! History
24 1 pfleura2
!
25 1 pfleura2
! v1.0 written for Cart a long time ago. Does not use fragment analysis, but was quite good !
26 1 pfleura2
!
27 1 pfleura2
! v2.0 12/2007
28 1 pfleura2
! Comes from Calc_zmat_constr_frag, based on a fragment analysis of the
29 1 pfleura2
! system under study.
30 1 pfleura2
! It should be more flexible and robust.
31 1 pfleura2
!
32 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
33 1 pfleura2
34 12 pfleura2
!----------------------------------------------------------------------
35 12 pfleura2
!  Copyright 2003-2014 Ecole Normale Sup?rieure de Lyon,
36 12 pfleura2
!  Centre National de la Recherche Scientifique,
37 12 pfleura2
!  Universit? Claude Bernard Lyon 1. All rights reserved.
38 12 pfleura2
!
39 12 pfleura2
!  This work is registered with the Agency for the Protection of Programs
40 12 pfleura2
!  as IDDN.FR.001.100009.000.S.P.2014.000.30625
41 12 pfleura2
!
42 12 pfleura2
!  Authors: P. Fleurat-Lessard, P. Dayal
43 12 pfleura2
!  Contact: optnpath@gmail.com
44 12 pfleura2
!
45 12 pfleura2
! This file is part of "Opt'n Path".
46 12 pfleura2
!
47 12 pfleura2
!  "Opt'n Path" is free software: you can redistribute it and/or modify
48 12 pfleura2
!  it under the terms of the GNU Affero General Public License as
49 12 pfleura2
!  published by the Free Software Foundation, either version 3 of the License,
50 12 pfleura2
!  or (at your option) any later version.
51 12 pfleura2
!
52 12 pfleura2
!  "Opt'n Path" is distributed in the hope that it will be useful,
53 12 pfleura2
!  but WITHOUT ANY WARRANTY; without even the implied warranty of
54 12 pfleura2
!
55 12 pfleura2
!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
56 12 pfleura2
!  GNU Affero General Public License for more details.
57 12 pfleura2
!
58 12 pfleura2
!  You should have received a copy of the GNU Affero General Public License
59 12 pfleura2
!  along with "Opt'n Path". If not, see <http://www.gnu.org/licenses/>.
60 12 pfleura2
!
61 12 pfleura2
! Contact The Office of Technology Licensing, valorisation@ens-lyon.fr,
62 12 pfleura2
! for commercial licensing opportunities.
63 12 pfleura2
!----------------------------------------------------------------------
64 12 pfleura2
65 8 pfleura2
  Use Path_module, only : max_Z, NMaxL, Nom, Pi
66 1 pfleura2
  Use Io_module
67 1 pfleura2
68 1 pfleura2
  IMPLICIT NONE
69 1 pfleura2
70 1 pfleura2
  integer(KINT), INTENT(IN) ::  na,atome(na)
71 1 pfleura2
  real(KREAL), INTENT(IN)   ::  x(Na),y(Na),z(Na),fact
72 1 pfleura2
  real(KREAL), INTENT(IN)   ::  r_cov(0:Max_Z)
73 1 pfleura2
74 1 pfleura2
  INTEGER(KINT), INTENT(OUT) :: ind_zmat(Na,5)
75 1 pfleura2
  real(KREAL), INTENT(OUT)   :: val_zmat(Na,3)
76 1 pfleura2
77 1 pfleura2
  INTEGER(KINT) :: idx_zmat(NA)
78 1 pfleura2
! Frozen contains the indices of frozen atoms
79 1 pfleura2
! INTEGER(KINT) Frozen(*),NFroz
80 1 pfleura2
! Number of fragment, Index of the current fragment for loops
81 2 pfleura2
  INTEGER(KINT) :: NbFrag
82 1 pfleura2
! Fragment(I) contains the fragment index to which I belongs
83 1 pfleura2
! NbAtFrag(j) contains the number of atoms of fragment j
84 1 pfleura2
  INTEGER(KINT), ALLOCATABLE :: Fragment(:),NbAtFrag(:) !na
85 1 pfleura2
! FragAt(i,:) lists the atoms of fragment i
86 1 pfleura2
  INTEGER(KINT), ALLOCATABLE :: FragAt(:,:) !na,na
87 1 pfleura2
! MaxLFrag(i,1) contains the maximum of links for an atom for fragment i
88 1 pfleura2
! MaxLFrag(i,2) is the atom that has this number of linked atoms
89 1 pfleura2
  INTEGER(KINT), ALLOCATABLE :: MaxLFrag(:,:) !na,2
90 1 pfleura2
! INTEGER(KINT), ALLOCATABLE :: IdxFragAt(:) !na
91 1 pfleura2
! INTEGER(KINT), ALLOCATABLE :: FrozBlock(:,:) !(na,0:na)
92 1 pfleura2
! DistFrag contains the distance between a given atom and some other atoms
93 1 pfleura2
  REAL(KREAL), ALLOCATABLE :: DistFrag(:) !na
94 1 pfleura2
! FragDist(I) contains the index of the atoms corresponding to DistFrag(I)
95 1 pfleura2
  INTEGER(KINT), ALLOCATABLE :: FragDist(:) ! na
96 1 pfleura2
97 1 pfleura2
  INTEGER(KINT) :: IdxCaFaire, IAfaire
98 1 pfleura2
  INTEGER(KINT), ALLOCATABLE ::  LIAISONS(:,:) ! (Na,0:NMaxL)
99 1 pfleura2
! INTEGER(KINT), ALLOCATABLE ::  LiaisonsIni(:,:) ! (Na,0:NMaxL)
100 1 pfleura2
  INTEGER(KINT), ALLOCATABLE :: CAFaire(:) ! (Na)
101 1 pfleura2
102 1 pfleura2
  real(KREAL) ::  vx1,vy1,vz1,norm1
103 1 pfleura2
  real(KREAL) ::  vx2,vy2,vz2,norm2
104 1 pfleura2
  real(KREAL) ::  vx3,vy3,vz3,norm3
105 1 pfleura2
  real(KREAL) ::  vx4,vy4,vz4,norm4
106 1 pfleura2
  real(KREAL) ::  vx5,vy5,vz5,norm5
107 1 pfleura2
  real(KREAL) ::  val,val_d, d12, d13,d23,d
108 2 pfleura2
  Logical Debug, FirstAt, DebugGaussian
109 1 pfleura2
  LOGICAL, ALLOCATABLE :: DejaFait(:), FCaf(:) !(na)
110 1 pfleura2
!  Logical, ALLOCATABLE ::  FrozAt(:)    !T if this atom is frozen
111 1 pfleura2
  LOGICAL F1213, F1223,F1323
112 1 pfleura2
113 1 pfleura2
  INTEGER(KINT) :: I,J,n0,n1,n2,n3,n4,IAt,IL,JL,IFrag,ITmp, K, KMax
114 2 pfleura2
  INTEGER(KINT) :: I3, I1, Ip
115 2 pfleura2
  INTEGER(KINT) :: I0, Izm, JAt
116 1 pfleura2
  INTEGER(KINT) :: OrderZmat
117 1 pfleura2
118 1 pfleura2
  REAL(KREAL) :: sDihe
119 12 pfleura2
  REAL(KREAL), PARAMETER :: LocalNCart=0.d0
120 1 pfleura2
121 1 pfleura2
  INTERFACE
122 1 pfleura2
     function valid(string) result (isValid)
123 1 pfleura2
       CHARACTER(*), intent(in) :: string
124 1 pfleura2
       logical                  :: isValid
125 1 pfleura2
     END function VALID
126 1 pfleura2
127 1 pfleura2
     FUNCTION angle(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2)
128 1 pfleura2
       INTEGER, PARAMETER :: KREAL=KIND(1.0D0)
129 1 pfleura2
       real(KREAL) ::  v1x,v1y,v1z,norm1
130 1 pfleura2
       real(KREAL) ::  v2x,v2y,v2z,norm2
131 1 pfleura2
       real(KREAL) ::  angle
132 1 pfleura2
     END FUNCTION ANGLE
133 1 pfleura2
134 1 pfleura2
     FUNCTION SinAngle(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2)
135 1 pfleura2
       INTEGER, PARAMETER :: KREAL=KIND(1.0D0)
136 1 pfleura2
       real(KREAL) ::  v1x,v1y,v1z,norm1
137 1 pfleura2
       real(KREAL) ::  v2x,v2y,v2z,norm2
138 1 pfleura2
       real(KREAL) ::  SinAngle
139 1 pfleura2
     END FUNCTION SINANGLE
140 1 pfleura2
141 1 pfleura2
     FUNCTION angle_d(v1x,v1y,v1z,norm1,v2x,v2y,v2z,norm2,v3x,v3y,v3z,norm3)
142 1 pfleura2
       INTEGER, PARAMETER :: KREAL=KIND(1.0D0)
143 1 pfleura2
       real(KREAL) ::  v1x,v1y,v1z,norm1
144 1 pfleura2
       real(KREAL) ::  v2x,v2y,v2z,norm2
145 1 pfleura2
       real(KREAL) ::  v3x,v3y,v3z,norm3
146 1 pfleura2
       real(KREAL) ::  angle_d,ca,sa
147 1 pfleura2
     END FUNCTION ANGLE_D
148 1 pfleura2
  END INTERFACE
149 1 pfleura2
150 1 pfleura2
  debug=valid("calc_zmat").OR.valid("calc_zmat_frag")
151 1 pfleura2
  debugGaussian=valid("zmat_gaussian")
152 1 pfleura2
153 1 pfleura2
  if (debug) WRITE(*,*) "=============================== Entering Calc_zmat_frag ========================"
154 1 pfleura2
  if (na.le.2) THEN
155 1 pfleura2
     WRITE(*,*) "I do not work for less than 2 atoms :-p"
156 1 pfleura2
     RETURN
157 1 pfleura2
  END IF
158 1 pfleura2
159 1 pfleura2
  ALLOCATE(FragDist(Na),Fragment(na), NbAtFrag(na),FragAt(na,na))
160 1 pfleura2
! ALLOCATE(FrozFrag(na,3), IdxFragAt(na), FrozBlock(na,0:na))
161 1 pfleura2
! ALLOCATE(FrozFrag(na,3))
162 1 pfleura2
  ALLOCATE(DistFrag(na),Liaisons(na,0:NMaxL))
163 1 pfleura2
! ALLOCATE(Liaisons(na,0:NMaxL),LiaisonsIni(na,0:NMaxL))
164 1 pfleura2
! ALLOCATE(CaFaire(na),DejaFait(Na),FCaf(na),FrozAt(na))
165 1 pfleura2
  ALLOCATE(CaFaire(na+1),DejaFait(Na),FCaf(na))
166 1 pfleura2
167 1 pfleura2
  if (debug) THEN
168 1 pfleura2
     WRITE(*,*) "DBG Calc_zmat_frag - Cartesian coordinates"
169 1 pfleura2
     DO I=1,na
170 1 pfleura2
        WRITE(*,'(1X,A3,3(1X,F15.8))') Nom(atome(i)),x(i),y(i),z(i)
171 1 pfleura2
     END DO
172 1 pfleura2
  END if
173 1 pfleura2
174 1 pfleura2
  DO I=1,na
175 1 pfleura2
     DO J=1,5
176 1 pfleura2
        Ind_Zmat(I,J)=0
177 1 pfleura2
     END DO
178 1 pfleura2
  END DO
179 1 pfleura2
180 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
181 1 pfleura2
!
182 1 pfleura2
!     Easy case : 3 or less atoms
183 1 pfleura2
!
184 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
185 1 pfleura2
  if (Na.eq.3) THEN
186 1 pfleura2
     d12=sqrt((x(1)-x(2))**2+(y(1)-y(2))**2+(z(1)-z(2))**2)
187 1 pfleura2
     d13=sqrt((x(1)-x(3))**2+(y(1)-y(3))**2+(z(1)-z(3))**2)
188 1 pfleura2
     d23=sqrt((x(3)-x(2))**2+(y(3)-y(2))**2+(z(3)-z(2))**2)
189 1 pfleura2
     F1213=(d12<=d13)
190 1 pfleura2
     F1323=(d13<=d23)
191 1 pfleura2
     F1223=(d12<=d23)
192 1 pfleura2
     if (debug) THEN
193 1 pfleura2
        WRITE(*,*) "DEBUG Calc_Zmat 3 atoms"
194 1 pfleura2
        WRITE(*,*) "d12,d13,d23:",d12,d13,d23
195 1 pfleura2
        WRITE(*,*) "F1213,F1323,F1223:",F1213,F1323,F1223
196 1 pfleura2
     END IF
197 1 pfleura2
     OrderZmat=0
198 1 pfleura2
     if (F1213) orderZmat=OrderZmat+4
199 1 pfleura2
     if (F1323) orderZmat=OrderZmat+2
200 1 pfleura2
     if (F1223) orderZmat=OrderZmat+1
201 1 pfleura2
     if (debug) WRITE(*,*) 'OrderZmat=',OrderZmat
202 1 pfleura2
     SELECT CASE (OrderZmat)
203 1 pfleura2
        CASE (0)
204 1 pfleura2
! F F F ordre 2-3----1
205 1 pfleura2
           ind_zmat(1,1)=3
206 1 pfleura2
           ind_zmat(2,1)=2
207 1 pfleura2
           ind_zmat(2,2)=3
208 1 pfleura2
           ind_zmat(3,1)=1
209 1 pfleura2
           ind_zmat(3,2)=3
210 1 pfleura2
           ind_zmat(3,3)=2
211 1 pfleura2
        CASE (2)
212 1 pfleura2
! F T F ordre 1-3----2
213 1 pfleura2
           ind_zmat(1,1)=3
214 1 pfleura2
           ind_zmat(2,1)=1
215 1 pfleura2
           ind_zmat(2,2)=3
216 1 pfleura2
           ind_zmat(3,1)=2
217 1 pfleura2
           ind_zmat(3,2)=3
218 1 pfleura2
           ind_zmat(3,3)=1
219 1 pfleura2
        CASE (3)
220 1 pfleura2
! F T T ordre 2---1-3
221 1 pfleura2
           ind_zmat(1,1)=1
222 1 pfleura2
           ind_zmat(2,1)=3
223 1 pfleura2
           ind_zmat(2,2)=1
224 1 pfleura2
           ind_zmat(3,1)=2
225 1 pfleura2
           ind_zmat(3,2)=1
226 1 pfleura2
           ind_zmat(3,3)=3
227 1 pfleura2
        CASE (5)
228 1 pfleura2
! T F T  ordre 1-2----3
229 1 pfleura2
           ind_zmat(1,1)=2
230 1 pfleura2
           ind_zmat(2,1)=1
231 1 pfleura2
           ind_zmat(2,2)=2
232 1 pfleura2
           ind_zmat(3,1)=3
233 1 pfleura2
           ind_zmat(3,2)=2
234 1 pfleura2
           ind_zmat(3,3)=1
235 1 pfleura2
        CASE (7)
236 1 pfleura2
! T T T ordre 3----1-2
237 1 pfleura2
           ind_zmat(1,1)=1
238 1 pfleura2
           ind_zmat(2,1)=2
239 1 pfleura2
           ind_zmat(2,2)=1
240 1 pfleura2
           ind_zmat(3,1)=3
241 1 pfleura2
           ind_zmat(3,2)=1
242 1 pfleura2
           ind_zmat(3,3)=2
243 1 pfleura2
        END SELECT
244 1 pfleura2
245 1 pfleura2
     IF (debug) THEN
246 1 pfleura2
        WRITE(*,*) "DBG Calc_zmat_frag - Nat=3 -"
247 1 pfleura2
        DO i=1,na
248 1 pfleura2
           WRITE(*,'(1X,A3,5(1X,I5))') Nom(Atome(ind_zmat(i,1))),(ind_zmat(i,j),j=1,5)
249 1 pfleura2
        END DO
250 1 pfleura2
     END IF
251 1 pfleura2
252 1 pfleura2
     ! We have ind_zmat, we fill val_zmat
253 1 pfleura2
     val_zmat=0.d0
254 1 pfleura2
     n2=ind_zmat(2,1)
255 1 pfleura2
     n1=ind_zmat(2,2)
256 1 pfleura2
     d=sqrt((x(n1)-x(n2))**2+(y(n1)-y(n2))**2+(z(n1)-z(n2))**2)
257 1 pfleura2
     val_zmat(2,1)=d
258 1 pfleura2
     n1=ind_zmat(3,1)
259 1 pfleura2
     n2=ind_zmat(3,2)
260 1 pfleura2
     n3=ind_zmat(3,3)
261 1 pfleura2
     CALL vecteur(n2,n1,x,y,z,vx1,vy1,vz1,norm1)
262 1 pfleura2
     if (debug) write(*,*) n1,n2,norm1
263 1 pfleura2
     val_zmat(3,1)=norm1
264 1 pfleura2
265 1 pfleura2
     CALL vecteur(n2,n3,x,y,z,vx2,vy2,vz2,norm2)
266 1 pfleura2
     val=angle(vx1,vy1,vz1,norm1,vx2,vy2,vz2,norm2)
267 1 pfleura2
     if (debug) write(*,*) n2,n3,norm2,val
268 1 pfleura2
     val_zmat(3,2)=val
269 1 pfleura2
270 1 pfleura2
     RETURN
271 1 pfleura2
  END IF !matches if (Na.eq.3) THEN
272 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
273 1 pfleura2
!
274 1 pfleura2
!  End of Easy case : 3 or less atoms
275 1 pfleura2
!
276 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
277 1 pfleura2
!
278 1 pfleura2
! General Case
279 1 pfleura2
!
280 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
281 1 pfleura2
!
282 1 pfleura2
283 1 pfleura2
! Initialization
284 1 pfleura2
  DejaFait=.False.
285 1 pfleura2
  Liaisons=0
286 1 pfleura2
  ind_zmat=0
287 1 pfleura2
  val_zmat=0.d0
288 1 pfleura2
289 1 pfleura2
  if (debug) WRITE(*,*) "Coucou from Calc_zmat_frag.f90; L240"
290 1 pfleura2
291 1 pfleura2
  if (debug) THEN
292 1 pfleura2
     WRITE(*,*) "Bonds initialized"
293 1 pfleura2
     WRITE(*,*) 'Covalent radii used'
294 1 pfleura2
     DO iat=1,na
295 1 pfleura2
        i=atome(iat)
296 1 pfleura2
        WRITE(*,*) Nom(I),Iat,r_cov(i),r_cov(i)*fact
297 1 pfleura2
     END DO
298 1 pfleura2
  END IF
299 1 pfleura2
300 1 pfleura2
1003 FORMAT(1X,I4,' - ',25(I5))
301 1 pfleura2
302 1 pfleura2
!   First step : connectivity  are calculated
303 1 pfleura2
304 1 pfleura2
  Call CalcCnct(na,atome,x,y,z,LIAISONS,r_cov,fact)
305 1 pfleura2
306 1 pfleura2
  if (debug) THEN
307 1 pfleura2
     WRITE(*,*) "Connections calculated"
308 1 pfleura2
     DO IL=1,na
309 1 pfleura2
        WRITE(IOOUT,1003) Il,(LIAISONS(IL,JL),JL=0,NMaxL)
310 1 pfleura2
     END DO
311 1 pfleura2
  END IF
312 1 pfleura2
313 1 pfleura2
  FCaf=.TRUE.
314 1 pfleura2
  Call Decomp_frag(na,liaisons,FCaf,nbfrag,Fragment,NbAtFrag,FragAt)
315 1 pfleura2
316 1 pfleura2
  IF (debug) THEN
317 1 pfleura2
     WRITE(*,*) 'I found ',NbFrag, 'fragments'
318 1 pfleura2
     WRITE(*,*) (NbAtFrag(I),I=1,NbFrag)
319 1 pfleura2
     DO I=1,NbFrag
320 1 pfleura2
        WRITE(*,*) NbAtFrag(I)
321 1 pfleura2
        WRITE(*,*) 'Fragment ', i
322 1 pfleura2
        DO J=1,Na
323 1 pfleura2
           IF (Fragment(J).EQ.I) WRITE(*,'(1X,I3,1X,A5,3(1X,F10.6))') J,Nom(Atome(J)) &
324 1 pfleura2
                ,X(J),Y(J),Z(J)
325 1 pfleura2
        END DO
326 1 pfleura2
        WRITE(*,*) "FragAt:",(FragAt(I,j),j=1,NbAtFrag(I))
327 1 pfleura2
     END DO
328 1 pfleura2
  END IF
329 1 pfleura2
330 1 pfleura2
 ALLOCATE(MaxLFrag(NbFrag,2))
331 1 pfleura2
332 1 pfleura2
 MaxLFrag=0
333 1 pfleura2
334 1 pfleura2
  DO I=1,NbFrag
335 1 pfleura2
     MaxLFrag(I,1)=Liaisons(FragAt(I,1),0)
336 1 pfleura2
     MaxLFrag(I,2)=FragAt(I,1)
337 1 pfleura2
338 1 pfleura2
     DO J=1,NbAtFrag(I)
339 1 pfleura2
      Iat=FragAt(I,J)
340 1 pfleura2
        IF (Liaisons(IAt,0).GT.MaxLFrag(I,1)) THEN
341 1 pfleura2
       MaxLFrag(I,1)=Liaisons(Iat,0)
342 1 pfleura2
       MaxLFrag(I,2)=Iat
343 1 pfleura2
    END IF
344 1 pfleura2
     END DO
345 1 pfleura2
     IF (debug) WRITE(*,*) 'Frag :',I,', atom ',MaxLFrag(I,2), ' has ',MaxLFrag(I,2),' links'
346 1 pfleura2
  END DO
347 1 pfleura2
348 1 pfleura2
  !     We will now build the molecule fragment by fragment
349 1 pfleura2
  !     We choose the starting fragment with two criteria:
350 1 pfleura2
  !     1- Number of linked atoms:
351 1 pfleura2
  !       * >=3 is good as it fully defines the coordinate space
352 1 pfleura2
  !       * 2 is ok as we can either use a 3rd atom from the same fragment
353 1 pfleura2
  !       or add a X atom somewhere but this complicates quite a lot the way
354 1 pfleura2
  !       to treat the conversion from cartesian to zmat latter
355 1 pfleura2
  !       * 1 is bad...
356 1 pfleura2
  !     2- Size of the fragment
357 1 pfleura2
  !     this allows us to deal more easily with cases 1- when number of
358 1 pfleura2
  !     directly linked atoms is less than 3
359 1 pfleura2
360 1 pfleura2
  IFrag=0
361 1 pfleura2
! I0 is the number of connections of the best fragment
362 1 pfleura2
  I0=0
363 1 pfleura2
! I1 is the number of atoms of the best fragment
364 1 pfleura2
  I1=0
365 1 pfleura2
  IAt=0
366 1 pfleura2
  DO I=1,NbFrag
367 1 pfleura2
    SELECT CASE(MaxLFrag(I,1)-I0)
368 1 pfleura2
     CASE (1:)
369 1 pfleura2
        IFrag=I
370 1 pfleura2
        I0=MaxLFrag(I,1)
371 1 pfleura2
        I1=NbAtFrag(I)
372 1 pfleura2
        IAt=MaxLFrag(I,2)
373 1 pfleura2
     CASE (0)
374 1 pfleura2
        if (NbAtFrag(I).GT.I1) THEN
375 1 pfleura2
           IFrag=I
376 1 pfleura2
           I0=MaxLFrag(I,1)
377 1 pfleura2
           I1=NbAtFrag(I)
378 1 pfleura2
           IAt=MaxLFrag(I,2)
379 1 pfleura2
        END IF
380 1 pfleura2
     END SELECT
381 1 pfleura2
  END DO
382 1 pfleura2
383 1 pfleura2
  if (debug) WRITE(*,'(1X,A,I5,A,I5,A,I5,A,I5)') 'Starting with fragment:',IFrag,' with ',I0   &
384 1 pfleura2
      ,' max links for atom',IAt,' fragment size',NbAtFrag(IFrag)
385 1 pfleura2
386 1 pfleura2
  !     We will build the first fragment in a special way, as it will
387 1 pfleura2
  !     set the coordinates system
388 1 pfleura2
389 1 pfleura2
  if (debug) WRITE(*,*) 'Fragment 1, starting with atom:',IAt, &
390 1 pfleura2
    'with ',I0,' connections'
391 1 pfleura2
392 1 pfleura2
  DejaFait=.FALSE.
393 1 pfleura2
  FCaf=.FALSE.
394 1 pfleura2
395 1 pfleura2
  izm=0
396 1 pfleura2
  SELECT CASE (I0)
397 1 pfleura2
  CASE(3:)
398 1 pfleura2
     if (debug) WRITE(*,*) 'DBG select case I0 3'
399 1 pfleura2
     n0=Iat
400 1 pfleura2
401 1 pfleura2
     ITmp=2
402 1 pfleura2
     sDihe=0.
403 1 pfleura2
     n2=IAt
404 1 pfleura2
     n3=Liaisons(Iat,1)
405 1 pfleura2
     ! We search for the third atom while making sure that it is not aligned with first two !
406 1 pfleura2
     DO While ((ITmp.LE.Liaisons(Iat,0)).AND.(sDihe.LE.0.09d0))
407 1 pfleura2
        n4=Liaisons(Iat,Itmp)
408 1 pfleura2
        CALL vecteur(n2,n3,x,y,z,vx2,vy2,vz2,norm2)
409 1 pfleura2
        CALL vecteur(n3,n4,x,y,z,vx3,vy3,vz3,norm3)
410 1 pfleura2
        val_d=angle(vx3,vy3,vz3,norm3,vx2,vy2,vz2,norm2)
411 1 pfleura2
        sDiHe=abs(sin(val_d*pi/180.d0))
412 1 pfleura2
        if (debug) Write(*,*) 'Trying n2,n3,n4,sdihe,val_d',n2,n3,n4,sdihe,val_d
413 1 pfleura2
        Itmp=Itmp+1
414 1 pfleura2
     END DO
415 1 pfleura2
     If (debug) WRITE(*,*) 'Itmp,Liaisons',Itmp,Liaisons(Iat,1:NMaxL)
416 1 pfleura2
     Liaisons(Iat,Itmp-1)=Liaisons(iat,2)
417 1 pfleura2
     Liaisons(Iat,2)=n4
418 1 pfleura2
     If (debug) WRITE(*,*) 'Itmp,Liaisons',Itmp,Liaisons(Iat,1:NMaxL)
419 1 pfleura2
420 1 pfleura2
     if (sDihe.LE.0.09d0) THEN
421 1 pfleura2
        WRITE(*,*) "PROBLEM !!! All atoms linked to ",n0," are aligned..."
422 1 pfleura2
    WRITE(*,*) "Surprising as this atom has at least three bonds... For NOW STOP"
423 1 pfleura2
    STOP
424 1 pfleura2
     END IF
425 1 pfleura2
426 2 pfleura2
     CALL produit_vect(vx3,vy3,vz3,vx2,vy2,vz2,  vx5,vy5,vz5,norm5)
427 1 pfleura2
428 1 pfleura2
429 1 pfleura2
! We search for the fourth atom while checking that it is not aligned with 1st and 2nd atoms.
430 1 pfleura2
     Itmp=3
431 1 pfleura2
     sDiHe=0.
432 1 pfleura2
! PFL 28 Dec 2007 ->
433 1 pfleura2
! I had a test on the dihedral angle, but I cannot see why it is important to have
434 1 pfleura2
! a non planar fragment at the begining... ethylene works and is fully planar
435 1 pfleura2
! I thus suppress this test
436 1 pfleura2
!
437 1 pfleura2
!     DO While ((ITmp.LE.Liaisons(Iat,0)).AND.(sDihe.LE.0.09d0))
438 1 pfleura2
!        ITmp=ITmp+1
439 1 pfleura2
        n1=Liaisons(Iat,Itmp)
440 1 pfleura2
        if (debug) WRITe(*,*) 'trying n1,n2,n3,n4',n1,n2,n3,n4
441 1 pfleura2
        CALL vecteur(n2,n1,x,y,z,vx1,vy1,vz1,norm1)
442 1 pfleura2
        ! Is this atom aligned with n2-n3 ?
443 1 pfleura2
        val_d=angle(vx1,vy1,vz1,norm1,vx2,vy2,vz2,norm2)
444 1 pfleura2
        sDiHe=abs(sin(val_d*pi/180.d0))
445 1 pfleura2
        if (debug) Write(*,*) 'Angle n3-n2-n1',val_d
446 1 pfleura2
        if (sDiHe.le.0.09d0) THEN
447 1 pfleura2
           ! As atoms n2,n3 and n4 are not aligned, we interchange n3 and n4 so that n1,n2 and n3 are not aligned
448 1 pfleura2
           if (debug) WRITE(*,*) "n3-n2-n1 aligned, we interchange n3 and n4"
449 1 pfleura2
           n1=n3
450 1 pfleura2
           n3=n4
451 1 pfleura2
           n4=n1
452 1 pfleura2
           n1=Liaisons(Iat,ITmp)
453 1 pfleura2
           CALL vecteur(n2,n3,x,y,z,vx2,vy2,vz2,norm2)
454 1 pfleura2
           CALL vecteur(n2,n4,x,y,z,vx3,vy3,vz3,norm3)
455 1 pfleura2
           val_d=angle(vx1,vy1,vz1,norm1,vx2,vy2,vz2,norm2)
456 1 pfleura2
           if (debug) Write(*,*) 'NEW Angle n3-n2-n1',val_d
457 1 pfleura2
        END IF
458 1 pfleura2
459 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
460 1 pfleura2
        ! avant de tester l'angle diedre, il faut verifier que ce 4e atome n'est pas
461 1 pfleura2
        ! aligne avec les 2 premiers.
462 1 pfleura2
        ! comme on a deja test? que les 3 premiers ne sont pas alignes,
463 1 pfleura2
        ! s'il est align? avec les 2 premiers, on peut inverser le role de 2 et 3.
464 1 pfleura2
        ! On pourrait tout simplier en faisant une bete recherche parmi tous les atomes geles
465 1 pfleura2
        ! de ce bloc (au moins 4 ?) avec le critere 1) on les range par distance croissante
466 1 pfleura2
        ! 2) on les scanne tant que l'angle valence n'est pas bon, puis tant que diehedre pas bon
467 1 pfleura2
        ! puis les atomes des autres fragment par distance croissante.
468 1 pfleura2
        ! les autres fragments ne seraient additonn?s que si l'on ne trouve pas notre bonheur dans le premier bloc
469 1 pfleura2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
470 1 pfleura2
471 2 pfleura2
        CALL produit_vect(vx1,vy1,vz1,vx2,vy2,vz2, vx4,vy4,vz4,norm4)
472 1 pfleura2
        val_d=angle_d(vx4,vy4,vz4,norm4,vx5,vy5,vz5,norm5, &
473 1 pfleura2
             vx2,vy2,vz2,norm2)
474 1 pfleura2
        sDihe=abs(sin(val_d*pi/180.d0))
475 1 pfleura2
        if (debug) WRITE(*,*) 'n2,n3,n4,n1, angle_d',n2,n3,n4,n1,val_d
476 1 pfleura2
!     END DO
477 1 pfleura2
478 1 pfleura2
     DejaFait(n2)=.TRUE.
479 1 pfleura2
     DejaFait(n3)=.TRUE.
480 1 pfleura2
     DejaFait(n4)=.TRUE.
481 1 pfleura2
482 1 pfleura2
!     if (sDihe.LE.0.09d0) THEN
483 1 pfleura2
!        !     None of the atoms linked to IAt are good to define the third
484 1 pfleura2
!        !     direction in space...
485 1 pfleura2
!        !     We will look at the other atoms
486 1 pfleura2
!        !     we might improve the search so as to take the atom closest to IAt
487 1 pfleura2
!        if (debug) WRITE(*,*) "All atoms linked to ",Iat," are in a plane. Looking for other atoms"
488 1 pfleura2
!        ITmp=0
489 1 pfleura2
!        DO I=1,NbAtFrag(IFrag)
490 1 pfleura2
!           JAt=FragAt(IFrag,I)
491 1 pfleura2
!           if (FrozAt(Jat).AND.(.NOT.DejaFait(JAt))) THEN
492 1 pfleura2
!              n1=JAt
493 1 pfleura2
!              CALL vecteur(n2,n1,x,y,z,vx1,vy1,vz1,norm1)
494 2 pfleura2
!              CALL produit_vect(vx1,vy1,vz1,vx2,vy2,vz2,vx4,vy4,vz4,norm4)
495 1 pfleura2
!              val_d=angle_d(vx4,vy4,vz4,norm4, &
496 1 pfleura2
!                   vx5,vy5,vz5,norm5, &
497 1 pfleura2
!                   vx2,vy2,vz2,norm2)
498 1 pfleura2
!              if (abs(sin(val_d)).GE.0.09D0) THEN
499 1 pfleura2
!                 ITmp=ITmp+1
500 1 pfleura2
!                 DistFrag(ITmp)=Norm1
501 1 pfleura2
!                 FragDist(ITmp)=JAt
502 1 pfleura2
!              END IF
503 1 pfleura2
!           END IF
504 1 pfleura2
!        END DO
505 1 pfleura2
506 1 pfleura2
!        IF (ITmp.EQ.0) THEN
507 1 pfleura2
!           !     All dihedral angles between frozen atoms are less than 5?
508 1 pfleura2
!           !     (or more than 175?). We have to look at other fragments :-(
509 1 pfleura2
!           DO I=1,NFroz
510 1 pfleura2
!              Jat=Frozen(I)
511 1 pfleura2
!              if (.NOT.DejaFait(JAt)) THEN
512 1 pfleura2
!                 n1=JAt
513 1 pfleura2
!                 CALL vecteur(n2,n1,x,y,z,vx1,vy1,vz1,norm1)
514 2 pfleura2
!                 CALL produit_vect(vx1,vy1,vz1,vx2,vy2,vz2,vx4,vy4,vz4,norm4)
515 1 pfleura2
!                 val_d=angle_d(vx4,vy4,vz4,norm4, &
516 1 pfleura2
!                      vx5,vy5,vz5,norm5, &
517 1 pfleura2
!                      vx2,vy2,vz2,norm2)
518 1 pfleura2
!                 if (abs(sin(val_d)).GE.0.09D0) THEN
519 1 pfleura2
!                    ITmp=ITmp+1
520 1 pfleura2
!                    DistFrag(ITmp)=Norm1
521 1 pfleura2
!                    FragDist(ITmp)=JAt
522 1 pfleura2
!                 END IF
523 1 pfleura2
!              END IF
524 1 pfleura2
!           END DO
525 1 pfleura2
!           IF (ITmp.EQ.0) THEN
526 1 pfleura2
!              !     All frozen atoms are in a plane... too bad
527 1 pfleura2
!              WRITE(*,*) 'ERROR: It seems that all frozen atoms are in a plane'
528 1 pfleura2
!              WRITE(*,*) 'For now, I do not treat this case'
529 1 pfleura2
!              STOP
530 1 pfleura2
!           END IF
531 1 pfleura2
!        END IF
532 1 pfleura2
!        I1=0
533 1 pfleura2
!        d=1e9
534 1 pfleura2
!        DO I=1,ITmp
535 1 pfleura2
!           IF (DistFrag(I).LE.d) THEN
536 1 pfleura2
!              d=DistFrag(I)
537 1 pfleura2
!              I1=FragDist(I)
538 1 pfleura2
!           END IF
539 1 pfleura2
!        END DO
540 1 pfleura2
!     ELSE                !(sDihe.LE.0.09d0)
541 1 pfleura2
!        I1=FrozBlock(IAt,ITmp)
542 1 pfleura2
!        if (debug) WRITE(*,*) 'I1,n1:',I1,n1
543 1 pfleura2
!     END IF                 !(sDihe.LE.0.09d0)
544 1 pfleura2
!     !     we now have the atom that is closer to the first one and that
545 1 pfleura2
!     !     forms a non 0/Pi dihedral angle
546 1 pfleura2
!
547 1 pfleura2
!  <- PFL 28 Dec 2007
548 1 pfleura2
549 1 pfleura2
! We construct the begining of the Z-Matrix
550 1 pfleura2
551 1 pfleura2
     ind_zmat(1,1)=n2
552 1 pfleura2
     ind_zmat(2,1)=n3
553 1 pfleura2
     ind_zmat(2,2)=n2
554 1 pfleura2
     ind_zmat(3,1)=n4
555 1 pfleura2
     ind_zmat(3,2)=n2
556 1 pfleura2
     ind_zmat(3,3)=n3
557 1 pfleura2
     DejaFait(n2)=.TRUE.
558 1 pfleura2
     DejaFait(n3)=.TRUE.
559 1 pfleura2
     DejaFait(n4)=.TRUE.
560 1 pfleura2
     CaFaire(1)=n3
561 1 pfleura2
     CaFaire(2)=n4
562 1 pfleura2
563 1 pfleura2
! PFL 28 Dec 2007
564 1 pfleura2
! We have not selected a fourth atom, so that the following is not needed
565 1 pfleura2
!     ind_zmat(4,1)=I1
566 1 pfleura2
!     ind_zmat(4,2)=n2
567 1 pfleura2
!     ind_zmat(4,3)=n3
568 1 pfleura2
!     ind_zmat(4,4)=n4
569 1 pfleura2
!     DejaFait(I1)=.TRUE.
570 1 pfleura2
!     CaFaire(3)=I1
571 1 pfleura2
!     CaFaire(4)=0
572 1 pfleura2
!     IdxCaFaire=4
573 1 pfleura2
!     izm=4
574 1 pfleura2
!     FCaf(I1)=.TRUE.
575 1 pfleura2
!!!!!!!
576 1 pfleura2
! and replaced by:
577 1 pfleura2
     CaFaire(3)=0
578 1 pfleura2
   IdxCaFaire=3
579 1 pfleura2
   izm=3
580 1 pfleura2
!
581 1 pfleura2
! <- PFL 28 Dec 2007
582 1 pfleura2
583 1 pfleura2
     FCaf(n2)=.TRUE.
584 1 pfleura2
     FCaf(n3)=.TRUE.
585 1 pfleura2
   FirstAt=.TRUE.
586 1 pfleura2
     DO I=3,Liaisons(Iat,0)
587 1 pfleura2
        IF (.NOT.DejaFait(Liaisons(Iat,I))) THEN
588 1 pfleura2
           izm=izm+1
589 1 pfleura2
           !           ind_zmat(izm,1)=Liaisons(Iat,I)
590 1 pfleura2
           !           ind_zmat(izm,2)=n2
591 1 pfleura2
           !           ind_zmat(izm,3)=n3
592 1 pfleura2
           !           ind_zmat(izm,4)=n4
593 1 pfleura2
           Call add2indzmat(na,izm,Liaisons(Iat,I),n2,n3,n4,ind_zmat,x,y,z)
594 1 pfleura2
           if (FirstAt) THEN
595 1 pfleura2
           n4=Liaisons(Iat,I)
596 1 pfleura2
         FirstAt=.FALSE.
597 1 pfleura2
       END IF
598 1 pfleura2
           IF (.NOT.FCaf(Liaisons(Iat,I))) THEN
599 1 pfleura2
              CaFaire(IdxCaFaire)=Liaisons(Iat,I)
600 1 pfleura2
              IdxCaFaire=IdxCaFaire+1
601 1 pfleura2
              CaFaire(IdxCaFaire)=0
602 1 pfleura2
              FCaf(Liaisons(Iat,I))=.TRUE.
603 1 pfleura2
           END IF
604 1 pfleura2
           DejaFait(Liaisons(Iat,I))=.TRUE.
605 1 pfleura2
        END IF
606 1 pfleura2
     END DO
607 1 pfleura2
608 1 pfleura2
     if (debug) THEN
609 1 pfleura2
        WRITE(*,*) "Ind_zmat 0 - SELECT CASE I0 3: -- izm=",izm
610 1 pfleura2
        WRITE(*,'(1X,4(1X,I5))') ind_zmat(1,1)
611 1 pfleura2
        WRITE(*,'(1X,4(1X,I5))') ind_zmat(2,1), ind_zmat(2,2)
612 1 pfleura2
        WRITE(*,'(1X,4(1X,I5))') ind_zmat(3,1), ind_zmat(3,2), ind_zmat(3,3)
613 1 pfleura2
        DO I=4,izm
614 1 pfleura2
           WRITE(*,'(1X,4(1X,I5))') ind_zmat(I,1), ind_zmat(I,2),  &
615 1 pfleura2
                ind_zmat(I,3), ind_zmat(I,4)
616 1 pfleura2
        END DO
617 1 pfleura2
     END IF
618 1 pfleura2
619 1 pfleura2
620 1 pfleura2
     !     First four atoms (at least) have been put we go on with next parts
621 1 pfleura2
     !     of this fragment... later
622 1 pfleura2
623 1 pfleura2
624 1 pfleura2
  CASE(2)
625 1 pfleura2
     if (debug) WRITE(*,*) 'DBG select case I0 2'
626 1 pfleura2
   WRITE(*,*) "PFL 28 Dec 2007: No test of alignment here :(  TO DO TO DO TO DO"
627 1 pfleura2
     ind_zmat(1,1)=IAt
628 1 pfleura2
     ind_zmat(2,1)=Liaisons(IAt,1)
629 1 pfleura2
     ind_zmat(2,2)=IAt
630 1 pfleura2
     ind_zmat(3,1)=Liaisons(IAt,2)
631 1 pfleura2
     ind_zmat(3,2)=IAt
632 1 pfleura2
     ind_zmat(3,3)=Liaisons(IAt,1)
633 1 pfleura2
     DejaFait(IAt)=.TRUE.
634 1 pfleura2
     DejaFait(Liaisons(Iat,1))=.TRUE.
635 1 pfleura2
     DejaFait(Liaisons(Iat,2))=.TRUE.
636 1 pfleura2
     CaFaire(1)=Liaisons(Iat,1)
637 1 pfleura2
     CaFaire(2)=Liaisons(Iat,2)
638 1 pfleura2
     FCaf(Liaisons(Iat,1))=.TRUE.
639 1 pfleura2
     FCaf(Liaisons(Iat,2))=.TRUE.
640 1 pfleura2
641 1 pfleura2
! PFL 28 Dec 2007 ->
642 1 pfleura2
! We do NOT need a fourth atom !!! The third direction in space is defined by the cross
643 1 pfleura2
! product of the first two directions
644 1 pfleura2
!
645 1 pfleura2
! the following is thus commented
646 1 pfleura2
!
647 1 pfleura2
!     !     We search for a fourth atom, first in the FrozBlock atoms
648 1 pfleura2
!     ITmp=2
649 1 pfleura2
!     sDihe=0.
650 1 pfleura2
!     n2=IAt
651 1 pfleura2
!     n3=Liaisons(Iat,1)
652 1 pfleura2
!     n4=Liaisons(Iat,2)
653 1 pfleura2
!     CALL vecteur(n2,n3,x,y,z,vx2,vy2,vz2,norm2)
654 1 pfleura2
!     CALL vecteur(n3,n4,x,y,z,vx3,vy3,vz3,norm3)
655 2 pfleura2
!     CALL produit_vect(vx3,vy3,vz3, vx2,vy2,vz2, vx5,vy5,vz5,norm5)
656 1 pfleura2
!
657 1 pfleura2
!     DO While ((ITmp.LE.FrozBlock(Iat,0)).AND.(sDihe.LE.0.09d0))
658 1 pfleura2
!        ITmp=ITmp+1
659 1 pfleura2
!        n1=FrozBlock(Iat,Itmp)
660 1 pfleura2
!        CALL vecteur(n2,n1,x,y,z,vx1,vy1,vz1,norm1)
661 2 pfleura2
!        CALL produit_vect(vx1,vy1,vz1,vx2,vy2,vz2, vx4,vy4,vz4,norm4)
662 1 pfleura2
!        val_d=angle_d(vx4,vy4,vz4,norm4,  &
663 1 pfleura2
!             vx5,vy5,vz5,norm5,           &
664 1 pfleura2
!             vx2,vy2,vz2,norm2)
665 1 pfleura2
!        sDihe=abs(sin(val_d))
666 1 pfleura2
!     END DO
667 1 pfleura2
!     IF (debug) WRITE(*,*) 'DBG 4th atom, ITmp, sDihe',ITmp, sDihe
668 1 pfleura2
!     if (sDihe.LE.0.09d0) THEN
669 1 pfleura2
!        !     None of the frozen atoms linked to IAt are good to define the third
670 1 pfleura2
!        !     direction in space...
671 1 pfleura2
!        !     We will look at the other frozen atoms
672 1 pfleura2
!        !     we might improve the search so as to take the atom closest to IAt
673 1 pfleura2
!        ITmp=0
674 1 pfleura2
!        DO I=1,NbAtFrag(IFrag)
675 1 pfleura2
!           JAt=FragAt(IFrag,I)
676 1 pfleura2
!           if (FrozAt(Jat).AND.(.NOT.DejaFait(JAt))) THEN
677 1 pfleura2
!              n1=JAt
678 1 pfleura2
!              CALL vecteur(n2,n1,x,y,z,vx1,vy1,vz1,norm1)
679 2 pfleura2
!              CALL produit_vect(vx1,vy1,vz1, vx2,vy2,vz2, vx4,vy4,vz4,norm4)
680 1 pfleura2
!              val_d=angle_d(vx4,vy4,vz4,norm4,    &
681 1 pfleura2
!                   vx5,vy5,vz5,norm5,              &
682 1 pfleura2
!                   vx2,vy2,vz2,norm2)
683 1 pfleura2
!              if (abs(sin(val_d)).GE.0.09D0) THEN
684 1 pfleura2
!                 ITmp=ITmp+1
685 1 pfleura2
!                 DistFrag(ITmp)=Norm1
686 1 pfleura2
!                 FragDist(ITmp)=JAt
687 1 pfleura2
!              END IF
688 1 pfleura2
!           END IF
689 1 pfleura2
!        END DO
690 1 pfleura2
!        IF (ITmp.EQ.0) THEN
691 1 pfleura2
!           !     All dihedral angles between frozen atoms are less than 5?
692 1 pfleura2
!           !     (or more than 175?). We have to look at other fragments :-(
693 1 pfleura2
!           DO I=1,NFroz
694 1 pfleura2
!              Jat=Frozen(I)
695 1 pfleura2
!              if (.NOT.DejaFait(JAt)) THEN
696 1 pfleura2
!                 n1=JAt
697 1 pfleura2
!                 CALL vecteur(n2,n1,x,y,z,vx1,vy1,vz1,norm1)
698 2 pfleura2
!                 CALL produit_vect(vx1,vy1,vz1, vx2,vy2,vz2, vx4,vy4,vz4,norm4)
699 1 pfleura2
!                 val_d=angle_d(vx4,vy4,vz4,norm4,       &
700 1 pfleura2
!                      vx5,vy5,vz5,norm5,                 &
701 1 pfleura2
!                      vx2,vy2,vz2,norm2)
702 1 pfleura2
!                 if (abs(sin(val_d)).GE.0.09D0) THEN
703 1 pfleura2
!                    ITmp=ITmp+1
704 1 pfleura2
!                    DistFrag(ITmp)=Norm1
705 1 pfleura2
!                    FragDist(ITmp)=JAt
706 1 pfleura2
!                 END IF
707 1 pfleura2
!              END IF
708 1 pfleura2
!           END DO
709 1 pfleura2
!           IF (ITmp.EQ.0) THEN
710 1 pfleura2
!              !     All frozen atoms are in a plane... too bad
711 1 pfleura2
!              WRITE(*,*) 'ERROR: It seems that all frozen atoms are in a plane'
712 1 pfleura2
!              WRITE(*,*) 'For now, I do not treat this case'
713 1 pfleura2
!              STOP
714 1 pfleura2
!           END IF
715 1 pfleura2
!        END IF
716 1 pfleura2
!        I1=0
717 1 pfleura2
!        d=1e9
718 1 pfleura2
!        DO I=1,ITmp
719 1 pfleura2
!           IF (DistFrag(I).LE.d) THEN
720 1 pfleura2
!              d=DistFrag(I)
721 1 pfleura2
!              I1=FragDist(I)
722 1 pfleura2
!           END IF
723 1 pfleura2
!        END DO
724 1 pfleura2
!     ELSE                   !(sDihe.LE.0.09d0)
725 1 pfleura2
!        I1=FrozBlock(IAt,ITmp)
726 1 pfleura2
!     END IF                 !(sDihe.LE.0.09d0)
727 1 pfleura2
!     !     we now have the atom that is closer to the first one and that
728 1 pfleura2
!     !     forms a non 0/Pi dihedral angle
729 1 pfleura2
!     !     ind_zmat(4,1)=I1
730 1 pfleura2
!     !     ind_zmat(4,2)=IAt
731 1 pfleura2
!     !     ind_zmat(4,3)=Liaisons(Iat,1)
732 1 pfleura2
!     !     ind_zmat(4,4)=Liaisons(Iat,2)
733 1 pfleura2
!     n3=Liaisons(Iat,1)
734 1 pfleura2
!     n4=Liaisons(Iat,2)
735 1 pfleura2
!     Call add2indzmat(na,4,I1,Iat,n3,n4,ind_zmat,x,y,z)
736 1 pfleura2
!     Liaisons(Iat,1)=n3
737 1 pfleura2
!     Liaisons(Iat,2)=n4
738 1 pfleura2
!     DejaFait(I1)=.TRUE.
739 1 pfleura2
!     CaFaire(3)=I1
740 1 pfleura2
!     CaFaire(4)=0
741 1 pfleura2
!     IdxCaFaire=4
742 1 pfleura2
!     izm=4
743 1 pfleura2
!     FCaf(I1)=.TRUE.
744 1 pfleura2
!
745 1 pfleura2
!!!!!! <- PFL 28 Dec 2007
746 1 pfleura2
747 1 pfleura2
     CaFaire(3)=0
748 1 pfleura2
     IdxCaFaire=3
749 1 pfleura2
     izm=3
750 1 pfleura2
751 1 pfleura2
  CASE(1)
752 1 pfleura2
     if (debug) WRITE(*,*) 'DBG select case I0 1, NbAtFrag=',NbAtFrag(IFrag)
753 1 pfleura2
     ind_zmat(1,1)=IAt
754 1 pfleura2
     ind_zmat(2,1)=Liaisons(IAt,1)
755 1 pfleura2
     ind_zmat(2,2)=IAt
756 1 pfleura2
     DejaFait(IAt)=.TRUE.
757 1 pfleura2
     DejaFait(Liaisons(Iat,1))=.TRUE.
758 1 pfleura2
     IdxCaFaire=2
759 1 pfleura2
     CaFaire(1)=Liaisons(Iat,1)
760 1 pfleura2
     CaFaire(2)=0
761 1 pfleura2
     FCaf(Liaisons(Iat,1))=.TRUE.
762 1 pfleura2
763 1 pfleura2
! PFL 28 Dec 2007 ->
764 1 pfleura2
! We do NOT need a fourth atom. So we will look only for a third atom
765 1 pfleura2
!
766 1 pfleura2
!!!!
767 1 pfleura2
!
768 1 pfleura2
     !     We search for a third and fourth atoms, first in the FrozBlock atoms
769 1 pfleura2
     !     It should not be possible to have   (FrozBlock(Iat,0).GT.2) and
770 1 pfleura2
     !     iat linked to only one atom !
771 1 pfleura2
772 1 pfleura2
773 1 pfleura2
     !     we calculate the distances between Iat and all other frozen
774 1 pfleura2
     !     atoms of this fragment, and store only those for which
775 1 pfleura2
     !     valence angles are not too close to 0/Pi. (limit:5?)
776 1 pfleura2
777 1 pfleura2
     ITmp=0
778 1 pfleura2
     CALL vecteur(Liaisons(Iat,1),IAt,x,y,z,vx2,vy2,vz2,norm2)
779 1 pfleura2
780 1 pfleura2
! PFL 28 Dec 2007: As MaxL=1 I think that there is at most 2 atoms in this fragment...
781 1 pfleura2
! so that the following loop is useless... this should be tested more carefully
782 1 pfleura2
     DO I=1,NbAtFrag(IFrag)
783 1 pfleura2
        JAt=FragAt(IFrag,I)
784 1 pfleura2
        if (.NOT.DejaFait(JAt)) THEN
785 1 pfleura2
           CALL vecteur(JAt,IAt,x,y,z,vx1,vy1,vz1,norm1)
786 1 pfleura2
           if (abs(cos(angle(vx1,vy1,vz1,norm1,  &
787 1 pfleura2
                vx2,vy2,vz2,norm2))).LE.0.996d0) THEN
788 1 pfleura2
              ITmp=ITmp+1
789 1 pfleura2
              DistFrag(ITmp)=Norm1
790 1 pfleura2
              FragDist(ITmp)=JAt
791 1 pfleura2
           END IF
792 1 pfleura2
        END IF
793 1 pfleura2
     END DO
794 1 pfleura2
795 1 pfleura2
     IF (ITMP.EQ.0) THEN
796 1 pfleura2
        !     We have no atoms correct in this fragment, we use
797 1 pfleura2
        !     atoms from other fragments
798 1 pfleura2
        DO Jat=1,Na
799 1 pfleura2
! DejaFait(Iat)=.TRUE. so that we do not need to test Jat/=Iat
800 1 pfleura2
           if (.NOT.DejaFait(JAt)) THEN
801 1 pfleura2
              CALL vecteur(JAt,IAt,x,y,z,vx1,vy1,vz1,norm1)
802 1 pfleura2
              if (abs(cos(angle(vx1,vy1,vz1,norm1, &
803 1 pfleura2
                   vx2,vy2,vz2,norm2))).LE.0.996d0) THEN
804 1 pfleura2
                 ITmp=ITmp+1
805 1 pfleura2
                 DistFrag(ITmp)=Norm1
806 1 pfleura2
                 FragDist(ITmp)=JAt
807 1 pfleura2
              END IF
808 1 pfleura2
           END IF
809 1 pfleura2
        END DO
810 1 pfleura2
        IF (ITMP.EQ.0) THEN
811 1 pfleura2
           WRITE(*,*) 'It seems all atoms are aligned'
812 1 pfleura2
           WRITE(*,*) 'Case non treated for now :-( '
813 1 pfleura2
           STOP
814 1 pfleura2
        END IF
815 1 pfleura2
     END IF
816 1 pfleura2
817 1 pfleura2
     I1=0
818 1 pfleura2
     d=1e9
819 1 pfleura2
! PFL 28 Dec 2007: There exists some F90 intrinsics to find the smallest element of an array.
820 1 pfleura2
! The following loop should be replaced by it !
821 1 pfleura2
     DO I=1,ITmp
822 1 pfleura2
        IF (DistFrag(I).LE.d) THEN
823 1 pfleura2
           I1=FragDist(I)
824 1 pfleura2
           d=DistFrag(I)
825 1 pfleura2
        END IF
826 1 pfleura2
     END DO
827 1 pfleura2
828 1 pfleura2
     !     we now have the atom that is closer to the first one and that
829 1 pfleura2
     !     forms a non 0/Pi valence angle
830 1 pfleura2
     ind_zmat(3,1)=I1
831 1 pfleura2
     ind_zmat(3,2)=IAt
832 1 pfleura2
     ind_zmat(3,3)=Liaisons(Iat,1)
833 1 pfleura2
     DejaFait(I1)=.TRUE.
834 1 pfleura2
     CaFaire(2)=I1
835 1 pfleura2
     FCaf(I1)=.TRUE.
836 1 pfleura2
837 1 pfleura2
838 1 pfleura2
! PFL 28 Dec 2007 ->
839 1 pfleura2
! We do NOT need a fourth atom so that the following is suppressed
840 1 pfleura2
!
841 1 pfleura2
!     !     we search for a fourth atom !
842 1 pfleura2
!     !     We search for a fourth atom, first in the FrozBlock atoms
843 1 pfleura2
!     ITmp=2
844 1 pfleura2
!     sDihe=0.
845 1 pfleura2
!     n2=IAt
846 1 pfleura2
!     n3=Liaisons(Iat,1)
847 1 pfleura2
!     n4=I1
848 1 pfleura2
!     CALL vecteur(n2,n3,x,y,z,vx2,vy2,vz2,norm2)
849 1 pfleura2
!     CALL vecteur(n3,n4,x,y,z,vx3,vy3,vz3,norm3)
850 2 pfleura2
!     CALL produit_vect(vx3,vy3,vz3, vx2,vy2,vz2,vx5,vy5,vz5,norm5)
851 1 pfleura2
!
852 1 pfleura2
!     !     We will look at the other frozen atoms
853 1 pfleura2
!     !     we might improve the search so as to take the atom closest to IAt
854 1 pfleura2
!     ITmp=0
855 1 pfleura2
!     DO I=1,NbAtFrag(IFrag)
856 1 pfleura2
!        JAt=FragAt(IFrag,I)
857 1 pfleura2
!        if (FrozAt(Jat).AND.(.NOT.DejaFait(JAt))) THEN
858 1 pfleura2
!           n1=JAt
859 1 pfleura2
!           CALL vecteur(n2,n1,x,y,z,vx1,vy1,vz1,norm1)
860 2 pfleura2
!           CALL produit_vect(vx1,vy1,vz1, vx2,vy2,vz2, vx4,vy4,vz4,norm4)
861 1 pfleura2
!           val_d=angle_d(vx4,vy4,vz4,norm4,  &
862 1 pfleura2
!                vx5,vy5,vz5,norm5,   &
863 1 pfleura2
!                vx2,vy2,vz2,norm2)
864 1 pfleura2
!           if (abs(sin(val_d)).GE.0.09D0) THEN
865 1 pfleura2
!              ITmp=ITmp+1
866 1 pfleura2
!              DistFrag(ITmp)=Norm1
867 1 pfleura2
!              FragDist(ITmp)=JAt
868 1 pfleura2
!           END IF
869 1 pfleura2
!        END IF
870 1 pfleura2
!     END DO
871 1 pfleura2
!     IF (ITmp.EQ.0) THEN
872 1 pfleura2
!        !     All dihedral angles between frozen atoms are less than 5?
873 1 pfleura2
!        !     (or more than 175?). We have to look at other fragments :-(
874 1 pfleura2
!        DO I=1,NFroz
875 1 pfleura2
!           Jat=Frozen(I)
876 1 pfleura2
!           if (.NOT.DejaFait(JAt)) THEN
877 1 pfleura2
!              n1=JAt
878 1 pfleura2
!              CALL vecteur(n2,n1,x,y,z,vx1,vy1,vz1,norm1)
879 2 pfleura2
!              CALL produit_vect(vx1,vy1,vz1,vx2,vy2,vz2, vx4,vy4,vz4,norm4)
880 1 pfleura2
!              val_d=angle_d(vx4,vy4,vz4,norm4,   &
881 1 pfleura2
!                   vx5,vy5,vz5,norm5,           &
882 1 pfleura2
!                   vx2,vy2,vz2,norm2)
883 1 pfleura2
!              if (abs(sin(val_d)).GE.0.09D0) THEN
884 1 pfleura2
!                 ITmp=ITmp+1
885 1 pfleura2
!                 DistFrag(ITmp)=Norm1
886 1 pfleura2
!                 FragDist(ITmp)=JAt
887 1 pfleura2
!              END IF
888 1 pfleura2
!           END IF
889 1 pfleura2
!       END DO
890 1 pfleura2
!        IF (ITmp.EQ.0) THEN
891 1 pfleura2
!           !     All frozen atoms are in a plane... too bad
892 1 pfleura2
!           WRITE(*,*) 'ERROR: It seems that all frozen atoms are in a plane'
893 1 pfleura2
!           WRITE(*,*) 'For now, I do not treat this case'
894 1 pfleura2
!           STOP
895 1 pfleura2
!        END IF
896 1 pfleura2
!     END IF                 ! ITmp.EQ.0 after scaning fragment
897 1 pfleura2
!     I1=0
898 1 pfleura2
!     d=1e9
899 1 pfleura2
!     DO I=1,ITmp
900 1 pfleura2
!        IF (DistFrag(I).LE.d) THEN
901 1 pfleura2
!           d=DistFrag(I)
902 1 pfleura2
!           I1=FragDist(I)
903 1 pfleura2
!        END IF
904 1 pfleura2
!     END DO
905 1 pfleura2
!
906 1 pfleura2
!     !     we now have the atom that is closer to the first one and that
907 1 pfleura2
!     !     forms a non 0/Pi dihedral angle
908 1 pfleura2
!     !     ind_zmat(4,1)=I1
909 1 pfleura2
!     !     ind_zmat(4,2)=IAt
910 1 pfleura2
!     !     ind_zmat(4,3)=ind_zmat(2,1)
911 1 pfleura2
!     !     ind_zmat(4,4)=ind_zmat(3,1)
912 1 pfleura2
!     n3=ind_zmat(2,1)
913 1 pfleura2
!     n4=ind_zmat(3,1)
914 1 pfleura2
!     Call add2indzmat(na,4,I1,IAt,n3,n4,ind_zmat,x,y,z)
915 1 pfleura2
!     ind_zmat(2,1)=n3
916 1 pfleura2
!     ind_zmat(3,1)=n4
917 1 pfleura2
!     DejaFait(I1)=.TRUE.
918 1 pfleura2
!     CaFaire(3)=I1
919 1 pfleura2
!     CaFaire(4)=0
920 1 pfleura2
!     IdxCaFaire=4
921 1 pfleura2
!     izm=4
922 1 pfleura2
!     FCaf(I1)=.TRUE.
923 1 pfleura2
!!!!!!!!!!!
924 1 pfleura2
!
925 1 pfleura2
! <- PFL 28 Dec 2007
926 1 pfleura2
927 1 pfleura2
     CaFaire(3)=0
928 1 pfleura2
   IdxCaFaire=3
929 1 pfleura2
930 1 pfleura2
  CASE(0)
931 1 pfleura2
     WRITE(*,*) 'All atoms are separated .. '
932 1 pfleura2
     WRITE(*,*) 'this case should be treated separately !'
933 1 pfleura2
     STOP
934 1 pfleura2
  END SELECT
935 1 pfleura2
936 1 pfleura2
  if (debug) THEN
937 1 pfleura2
     WRITE(*,*) 'ind_zmat 1 izm=',izm
938 1 pfleura2
     WRITE(*,'(1X,4(1X,I5))') ind_zmat(1,1)
939 1 pfleura2
     WRITE(*,'(1X,4(1X,I5))') ind_zmat(2,1), ind_zmat(2,2)
940 1 pfleura2
     WRITE(*,'(1X,4(1X,I5))') ind_zmat(3,1), ind_zmat(3,2), ind_zmat(3,3)
941 1 pfleura2
     DO I=4,izm
942 1 pfleura2
        WRITE(*,'(1X,4(1X,I5))') ind_zmat(I,1), ind_zmat(I,2),  &
943 1 pfleura2
             ind_zmat(I,3), ind_zmat(I,4)
944 1 pfleura2
     END DO
945 1 pfleura2
  END IF
946 1 pfleura2
947 1 pfleura2
  DO I=1,izm
948 1 pfleura2
     Idx_zmat(ind_zmat(I,1))=i
949 1 pfleura2
  END Do
950 1 pfleura2
951 1 pfleura2
  !     at least first three atoms of this fragment done...
952 1 pfleura2
  !     we empty the 'cafaire' array before going on
953 1 pfleura2
  IAFaire=1
954 1 pfleura2
  DO WHILE (CaFaire(IaFaire).NE.0)
955 1 pfleura2
     n1=CaFaire(IaFaire)
956 1 pfleura2
     n2=ind_zmat(idx_zmat(N1),2)
957 1 pfleura2
     if (idx_zmat(N1).EQ.2) THEN
958 1 pfleura2
        !     We have a (small) problem: we have to add atoms linked to the 2nd
959 1 pfleura2
        !     atom of the zmat. This is a pb because we do not know
960 1 pfleura2
        !     which atom to use to define the dihedral angle
961 1 pfleura2
        !     we take the third atom of the zmat
962 1 pfleura2
        n3=ind_zmat(3,1)
963 1 pfleura2
     ELSE
964 1 pfleura2
        n3=ind_zmat(idx_zmat(n1),3)
965 1 pfleura2
     END IF
966 1 pfleura2
967 1 pfleura2
   FirstAt=.TRUE.
968 1 pfleura2
     DO I=1,Liaisons(n1,0)
969 1 pfleura2
        IAt=Liaisons(n1,I)
970 1 pfleura2
! PFL 29.Aug.2008 ->
971 1 pfleura2
! We dissociate the test on 'DejaFait' that indicates that this atom
972 1 pfleura2
! has already been put in the Zmat
973 1 pfleura2
! from the test on FCaf that indicates that this atom has been put in the
974 1 pfleura2
! 'CAFaire' list that deals with identifying its connectivity.
975 1 pfleura2
! Those two test might differ in some cases.
976 1 pfleura2
        IF (.NOT.DejaFait(Iat)) THEN
977 1 pfleura2
           izm=izm+1
978 1 pfleura2
           if (debug) WRITE(*,*) ">1< Adding atom ",Iat,"position izm=",izm
979 1 pfleura2
           !           ind_zmat(izm,1)=iat
980 1 pfleura2
           !           ind_zmat(izm,2)=n1
981 1 pfleura2
           !           ind_zmat(izm,3)=n2
982 1 pfleura2
           !           ind_zmat(izm,4)=n3
983 1 pfleura2
           Call add2indzmat(na,izm,iat,n1,n2,n3,ind_zmat,x,y,z)
984 1 pfleura2
       if (FirstAt) THEN
985 1 pfleura2
          n3=Iat
986 1 pfleura2
        FirstAt=.FALSE.
987 1 pfleura2
           END IF
988 1 pfleura2
           idx_zmat(iat)=izm
989 1 pfleura2
           DejaFait(iat)=.TRUE.
990 1 pfleura2
        END IF
991 1 pfleura2
        IF (.NOT.FCaf(Iat)) THEN
992 1 pfleura2
           CaFaire(IdxCaFaire)=iat
993 1 pfleura2
           IdxCaFaire=IdxCaFaire+1
994 1 pfleura2
           CaFaire(IdxCaFaire)=0
995 1 pfleura2
           FCaf(Iat)=.TRUE.
996 1 pfleura2
        END IF
997 1 pfleura2
! <- PFL 29.Aug.2008
998 1 pfleura2
     END DO
999 1 pfleura2
     IaFaire=IaFaire+1
1000 1 pfleura2
  END Do                    ! DO WHILE CaFaire
1001 1 pfleura2
1002 1 pfleura2
  if (debug) THEN
1003 1 pfleura2
     WRITE(*,*) 'ind_zmat 2, izm=',izm
1004 1 pfleura2
     WRITE(*,'(1X,4(1X,I5))') ind_zmat(1,1)
1005 1 pfleura2
     WRITE(*,'(1X,4(1X,I5))') ind_zmat(2,1), ind_zmat(2,2)
1006 1 pfleura2
     WRITE(*,'(1X,4(1X,I5))') ind_zmat(3,1), ind_zmat(3,2), ind_zmat(3,3)
1007 1 pfleura2
     DO I=4,izm
1008 1 pfleura2
        WRITE(*,'(1X,4(1X,I5))') ind_zmat(I,1), ind_zmat(I,2),  &
1009 1 pfleura2
             ind_zmat(I,3), ind_zmat(I,4)
1010 1 pfleura2
     END DO
1011 1 pfleura2
  END IF
1012 1 pfleura2
1013 1 pfleura2
  !     We have finished putting atoms linked to the first one
1014 1 pfleura2
  ! There should not be any atom left from this fragment. We check:
1015 1 pfleura2
  !     we will add other atoms of this fragment
1016 1 pfleura2
  DO I=1,NbAtFrag(IFrag)
1017 1 pfleura2
     Iat=FragAt(IFrag,I)
1018 1 pfleura2
     if (debug) WRITE(*,*) "DBG: I,Iat,dejafait",I,Iat,DejaFait(Iat)
1019 1 pfleura2
     IF (.NOT.DejaFait(Iat)) THEN
1020 1 pfleura2
           WRITE(*,*) 'Treating atom I,Iat',I,Iat
1021 1 pfleura2
1022 1 pfleura2
     END IF
1023 1 pfleura2
1024 1 pfleura2
  END DO
1025 1 pfleura2
1026 1 pfleura2
  NbAtFrag(Ifrag)=0
1027 1 pfleura2
  MaxLFrag(IFrag,1)=0
1028 1 pfleura2
1029 1 pfleura2
  !     we start again with the rest of the molecule...
1030 1 pfleura2
  ! v 1.01 We add the fragment in the order corresponding to NbAtFrag
1031 1 pfleura2
  KMax=NbFrag-1
1032 1 pfleura2
1033 1 pfleura2
  IF (DEBUG) WRITE(*,*) "Adding the ",Kmax," remaining fragments"
1034 1 pfleura2
  DO K=1, KMax
1035 1 pfleura2
  IFrag=0
1036 1 pfleura2
  I0=0
1037 1 pfleura2
  IAt=0
1038 1 pfleura2
  I1=0
1039 1 pfleura2
  DO I=1,NbFrag
1040 1 pfleura2
    SELECT CASE(MaxLFrag(I,1)-I0)
1041 1 pfleura2
     CASE (1:)
1042 1 pfleura2
        IFrag=I
1043 1 pfleura2
        I0=MaxLFrag(I,1)
1044 1 pfleura2
        IAt=MaxLFrag(I,2)
1045 1 pfleura2
        I1=NbAtFrag(I)
1046 1 pfleura2
     CASE (0)
1047 1 pfleura2
        if (NbAtFrag(I).GT.I1) THEN
1048 1 pfleura2
           IFrag=I
1049 1 pfleura2
           I0=MaxLFrag(I,1)
1050 1 pfleura2
           IAt=MaxLFrag(I,2)
1051 1 pfleura2
           I1=NbAtFrag(I)
1052 1 pfleura2
        END IF
1053 1 pfleura2
     END SELECT
1054 1 pfleura2
1055 1 pfleura2
  END DO
1056 1 pfleura2
1057 1 pfleura2
  if (debug) WRITE(*,'(1X,A,I5,A,I5,A,I5,A,I5)') 'Adding fragment:',IFrag,' with ',I0   &
1058 1 pfleura2
      ,' max links for atom',IAt,' fragment size',NbAtFrag(IFrag)
1059 1 pfleura2
1060 1 pfleura2
     MaxLFrag(IFrag,1)=0
1061 1 pfleura2
1062 1 pfleura2
! We search for the closest atoms of the previous fragments to the atom with max links
1063 1 pfleura2
  d=1e9
1064 1 pfleura2
  DO J=1,izm
1065 1 pfleura2
    Call vecteur(iat,ind_zmat(j,1),x,y,z,vx1,vy1,vz1,norm1)
1066 1 pfleura2
    if (norm1.le.d) THEN
1067 1 pfleura2
      Jat=j
1068 1 pfleura2
      d=norm1
1069 1 pfleura2
    END IF
1070 1 pfleura2
  END DO
1071 1 pfleura2
  n2=ind_zmat(jat,1)
1072 1 pfleura2
  SELECT CASE(jat)
1073 1 pfleura2
        CASE (1)
1074 1 pfleura2
     n3=ind_zmat(2,1)
1075 1 pfleura2
     n4=ind_zmat(3,1)
1076 1 pfleura2
    CASE (2)
1077 1 pfleura2
     n3=ind_zmat(1,1)
1078 1 pfleura2
     n4=ind_zmat(3,1)
1079 1 pfleura2
    CASE DEFAULT
1080 1 pfleura2
     n3=ind_zmat(jAt,2)
1081 1 pfleura2
     n4=ind_zmat(jat,3)
1082 1 pfleura2
  END SELECT
1083 1 pfleura2
  izm=izm+1
1084 1 pfleura2
  Call add2indzmat(na,izm,iat,n2,n3,n4,ind_zmat,x,y,z)
1085 1 pfleura2
    idx_zmat(iat)=izm
1086 1 pfleura2
    DejaFait(iat)=.TRUE.
1087 1 pfleura2
  IdxCaFaire=2
1088 1 pfleura2
    CaFaire(1)=iat
1089 1 pfleura2
              CaFaire(2)=0
1090 1 pfleura2
              FCaf(Iat)=.TRUE.
1091 1 pfleura2
              IaFaire=1
1092 1 pfleura2
              DO WHILE (CaFaire(IaFaire).NE.0)
1093 1 pfleura2
                 n1=CaFaire(IaFaire)
1094 1 pfleura2
                 n2=ind_zmat(idx_zmat(N1),2)
1095 1 pfleura2
                 if (idx_zmat(N1).EQ.2) THEN
1096 1 pfleura2
                    !     We have a (small) problem: we have to add atoms linked to the 2nd
1097 1 pfleura2
                    !     atom of the zmat. This is a pb because we do not know
1098 1 pfleura2
                    !     which atom to use to define the dihedral angle
1099 1 pfleura2
                    !     we take the third atom of the zmat
1100 1 pfleura2
                    n3=ind_zmat(3,1)
1101 1 pfleura2
                 ELSE
1102 1 pfleura2
                    n3=ind_zmat(idx_zmat(n1),3)
1103 1 pfleura2
                 END IF
1104 1 pfleura2
                 DO I3=1,Liaisons(n1,0)
1105 1 pfleura2
                    IAt=Liaisons(n1,I3)
1106 1 pfleura2
! PFL 29.Aug.2008 ->
1107 1 pfleura2
! We dissociate the test on 'DejaFait' that indicates that this atom
1108 1 pfleura2
! has already been put in the Zmat
1109 1 pfleura2
! from the test on FCaf that indicates that this atom has been put in the
1110 1 pfleura2
! 'CAFaire' list that deals with identifying its connectivity.
1111 1 pfleura2
! Those two test might differ for a frozen atom linked to non frozen atoms.
1112 1 pfleura2
                    IF (.NOT.DejaFait(Iat)) THEN
1113 1 pfleura2
                       izm=izm+1
1114 1 pfleura2
                       Call add2indzmat(na,izm,Iat,n1,n2,n3,ind_zmat,x,y,z)
1115 1 pfleura2
                       idx_zmat(iat)=izm
1116 1 pfleura2
                       n3=iat
1117 1 pfleura2
                       DejaFait(Iat)=.TRUE.
1118 1 pfleura2
                    END IF
1119 1 pfleura2
                    IF (.NOT.FCaf(Iat)) THEN
1120 1 pfleura2
                       CaFaire(IdxCaFaire)=iat
1121 1 pfleura2
                       IdxCaFaire=IdxCaFaire+1
1122 1 pfleura2
                       CaFaire(IdxCaFaire)=0
1123 1 pfleura2
                       FCaf(Iat)=.TRUE.
1124 1 pfleura2
                    END IF
1125 1 pfleura2
! <- PFL 29.Aug.2008
1126 1 pfleura2
                 END DO
1127 1 pfleura2
                 IaFaire=IaFaire+1
1128 1 pfleura2
              END Do              ! DO WHILE CaFaire
1129 1 pfleura2
1130 1 pfleura2
        if (debug) THEN
1131 1 pfleura2
           WRITE(*,*) 'ind_zmat 4'
1132 1 pfleura2
           WRITE(*,'(1X,4(1X,I5))') ind_zmat(1,1)
1133 1 pfleura2
           WRITE(*,'(1X,4(1X,I5))') ind_zmat(2,1), ind_zmat(2,2)
1134 1 pfleura2
           WRITE(*,'(1X,4(1X,I5))') ind_zmat(3,1), ind_zmat(3,2), ind_zmat(3,3)
1135 1 pfleura2
           DO Ip=4,izm
1136 1 pfleura2
              WRITE(*,'(1X,4(1X,I5))') ind_zmat(Ip,1), ind_zmat(Ip,2), &
1137 1 pfleura2
                   ind_zmat(Ip,3), ind_zmat(Ip,4)
1138 1 pfleura2
           END DO
1139 1 pfleura2
        END IF
1140 1 pfleura2
1141 1 pfleura2
  END DO                    ! Loop on all fragments
1142 1 pfleura2
1143 1 pfleura2
1144 1 pfleura2
     ! We have ind_zmat. We calculate val_zmat :-)
1145 1 pfleura2
     if (debug) WRITE(*,*) "Calculating val_zmat"
1146 1 pfleura2
1147 1 pfleura2
     val_zmat(1,1)=0.d0
1148 1 pfleura2
     val_zmat(1,2)=0.d0
1149 1 pfleura2
     val_zmat(1,3)=0.d0
1150 1 pfleura2
     val_zmat(2,2)=0.d0
1151 1 pfleura2
     val_zmat(2,3)=0.d0
1152 1 pfleura2
     val_zmat(3,3)=0.d0
1153 1 pfleura2
1154 1 pfleura2
     n1=ind_zmat(2,1)
1155 1 pfleura2
     n2=ind_zmat(2,2)
1156 1 pfleura2
1157 1 pfleura2
     CALL vecteur(n2,n1,x,y,z,vx1,vy1,vz1,norm1)
1158 1 pfleura2
1159 1 pfleura2
     val_zmat(2,1)=norm1
1160 1 pfleura2
1161 1 pfleura2
1162 1 pfleura2
     n1=ind_zmat(3,1)
1163 1 pfleura2
     n2=ind_zmat(3,2)
1164 1 pfleura2
     n3=ind_zmat(3,3)
1165 1 pfleura2
1166 1 pfleura2
     CALL vecteur(n2,n1,x,y,z,vx1,vy1,vz1,norm1)
1167 1 pfleura2
1168 1 pfleura2
     val_zmat(3,1)=norm1
1169 1 pfleura2
1170 1 pfleura2
     CALL vecteur(n2,n3,x,y,z,vx2,vy2,vz2,norm2)
1171 1 pfleura2
     val=angle(vx1,vy1,vz1,norm1,vx2,vy2,vz2,norm2)
1172 1 pfleura2
1173 1 pfleura2
     val_zmat(3,2)=val
1174 1 pfleura2
1175 1 pfleura2
     DO i=4,na
1176 1 pfleura2
1177 1 pfleura2
        n1=ind_zmat(i,1)
1178 1 pfleura2
        n2=ind_zmat(i,2)
1179 1 pfleura2
        n3=ind_zmat(i,3)
1180 1 pfleura2
        n4=ind_zmat(i,4)
1181 1 pfleura2
1182 1 pfleura2
        if (debug) WRITE(*,*) "Doing i,n1,n2,n3,n4",i,n1,n2,n3,n4
1183 1 pfleura2
        CALL vecteur(n2,n1,x,y,z,vx1,vy1,vz1,norm1)
1184 1 pfleura2
1185 1 pfleura2
        CALL vecteur(n2,n3,x,y,z,vx2,vy2,vz2,norm2)
1186 1 pfleura2
        val=angle(vx1,vy1,vz1,norm1,vx2,vy2,vz2,norm2)
1187 1 pfleura2
1188 1 pfleura2
        CALL vecteur(n3,n4,x,y,z,vx3,vy3,vz3,norm3)
1189 2 pfleura2
        CALL produit_vect(vx1,vy1,vz1,vx2,vy2,vz2,vx4,vy4,vz4,norm4)
1190 2 pfleura2
        CALL produit_vect(vx3,vy3,vz3,vx2,vy2,vz2,vx5,vy5,vz5,norm5)
1191 1 pfleura2
1192 1 pfleura2
        val_d=angle_d(vx4,vy4,vz4,norm4, vx5,vy5,vz5,norm5, &
1193 1 pfleura2
             vx2,vy2,vz2,norm2)
1194 1 pfleura2
1195 1 pfleura2
        !     write(*,11) n1,n2,norm1,n3,val,n4,val_d
1196 1 pfleura2
        !11   format (2(1x,i3),1x,f8.4,2(1x,i3,1x,f8.3))
1197 1 pfleura2
1198 1 pfleura2
        val_zmat(i,1)=norm1
1199 1 pfleura2
        val_zmat(i,2)=val
1200 1 pfleura2
        val_zmat(i,3)=val_d
1201 1 pfleura2
1202 1 pfleura2
     END DO
1203 1 pfleura2
1204 1 pfleura2
     if (debug) THEN
1205 1 pfleura2
        WRITE(*,*) 'DBG Cre_Zmat_Frag: ind_zmat'
1206 1 pfleura2
        DO I=1,na
1207 1 pfleura2
           WRITE(*,'(1X,5I5)') (ind_zmat(i,j),j=1,5)
1208 1 pfleura2
        END DO
1209 1 pfleura2
1210 1 pfleura2
        WRITE(*,*) 'DBG Cre_Zmat_Frag: Full zmat'
1211 1 pfleura2
        DO I=1,na
1212 1 pfleura2
           WRITE(*,'(1X,I5,1X,I5,F8.4,2(1X,I5,1X,F7.2))') ind_zmat(i,1),(ind_zmat(i,j+1),val_zmat(i,j),j=1,3)
1213 1 pfleura2
        END DO
1214 1 pfleura2
1215 1 pfleura2
     END IF
1216 1 pfleura2
1217 1 pfleura2
     if (debugGaussian) THEN
1218 1 pfleura2
        WRITE(*,*) 'DBG Cre_Zmat_Frag: Gaussian Zmat - START'
1219 12 pfleura2
        Call WriteMixed_Gaussian(na,atome,LocalNCart,ind_zmat,val_zmat)
1220 1 pfleura2
        WRITE(*,*) 'DBG Cre_Zmat_Frag: Gaussian Zmat - END'
1221 1 pfleura2
     END IF
1222 1 pfleura2
1223 1 pfleura2
1224 1 pfleura2
     if (debug) WRITE(*,*) "Deallocate (FragDist,Fragment, NbAtFrag,FragAt)"
1225 1 pfleura2
     DEALLOCATE(FragDist,Fragment, NbAtFrag,FragAt)
1226 1 pfleura2
     if (debug) WRITE(*,*) "Deallocate (DistFrag,Liaisons)"
1227 1 pfleura2
     DEALLOCATE(DistFrag,Liaisons)
1228 1 pfleura2
     if (debug) WRITE(*,*) "Deallocate(CaFaire,DejaFait)"
1229 1 pfleura2
     DEALLOCATE(CaFaire,DejaFait,FCaf,MaxLFrag)
1230 1 pfleura2
1231 1 pfleura2
1232 1 pfleura2
1233 1 pfleura2
     if (debug) WRITE(*,*) "=============================== Exiting Calc_zmat_frag ========================"
1234 1 pfleura2
1235 1 pfleura2
END SUBROUTINE Calc_Zmat_frag