Nbody6
 All Files Functions Variables
checkl.f
Go to the documentation of this file.
1  SUBROUTINE checkl(I,NNB,XI,XIDOT,RS2,FIRR,FREG,FD,FDR)
2 *
3 *
4 * Neighbour list modification.
5 * ----------------------------
6 *
7  include 'common6.h'
8  REAL*8 xi(3),xidot(3),dx(3),dv(3),firr(3),freg(3),fd(3),fdr(3)
9 *
10 *
11  icm = 1
12 * Only consider high-velocity particles if KZ(37) = 1.
13  IF (kz(37).EQ.1) go to 350
14 * Omit special treatments of c.m. particles because of force errors.
15  IF (i.GT.n) go to 350
16 *
17 * See whether any neighbour has encounter with body outside sphere.
18  nnb1 = nnb + 1
19  lj = 0
20 * First perform fast test since actual cases are rare.
21  DO 306 l = 2,nnb1
22  j = ilist(l)
23  IF (step(j).LT.smin) lj = l
24  306 CONTINUE
25  IF (lj.EQ.0) go to 320
26 *
27  jcomp = ilist(lj)
28  k = 1
29  308 IF (k.GT.list(1,jcomp)) go to 320
30  k = k + 1
31  j = list(k,jcomp)
32  IF (step(j).GT.smin) go to 308
33 * Skip single regularized particles or body #I itself.
34  IF (j.LT.ifirst.OR.j.EQ.i) go to 308
35  a1 = x(1,j) - x(1,jcomp)
36  a2 = x(2,j) - x(2,jcomp)
37  a3 = x(3,j) - x(3,jcomp)
38  rij2 = a1**2 + a2**2 + a3**2
39 * Only accept body #J as neighbour if distance to JCOMP is < 2*RMIN.
40  IF (rij2.GT.rmin22) go to 308
41 *
42  IF (j.LE.n) go to 309
43 * Also accept pairs satisfying the c.m. force approximation.
44  IF (cmsep2*r(j-n)**2.GT.rs2) go to 308
45 *
46 * Now see whether body #J has already been included as neighbour.
47  309 DO 310 l = 1,nnb
48  IF (j.EQ.ilist(l+1)) go to 308
49  310 CONTINUE
50 * Include body #J in sequential location of neighbour list.
51  l = nnb + 1
52  312 IF (j.GT.ilist(l)) go to 314
53  ilist(l+1) = ilist(l)
54 * Move other members down by one until appropriate location is free.
55  l = l - 1
56  IF (l.GT.1) go to 312
57 *
58  314 ilist(l+1) = j
59  nnb = nnb + 1
60 * Only one close encounter neighbour is allowed without test of NNB.
61  nlsmin = nlsmin + 1
62 *
63 * Finally correct irregular and regular force components.
64  dr2 = 0.0
65  drdv = 0.0
66  DO 315 k = 1,3
67  dx(k) = x(k,j) - xi(k)
68  dv(k) = xdot(k,j) - xidot(k)
69  dr2 = dr2 + dx(k)**2
70  drdv = drdv + dx(k)*dv(k)
71  315 CONTINUE
72 *
73  dr2i = 1.0/dr2
74  dr3i = body(j)*dr2i*sqrt(dr2i)
75  drdv = 3.0*drdv*dr2i
76 *
77  DO 316 k = 1,3
78  firr(k) = firr(k) + dx(k)*dr3i
79  freg(k) = freg(k) - dx(k)*dr3i
80  fd(k) = fd(k) + (dv(k) - dx(k)*drdv)*dr3i
81  fdr(k) = fdr(k) - (dv(k) - dx(k)*drdv)*dr3i
82  316 CONTINUE
83 *
84 * Include the other component of two recently disrupted pairs.
85  320 IF (nnb.GE.nnbmax) go to 330
86 *
87  l = 0
88  321 l = l + 2
89 * Advance list index by two for every identified pair.
90  IF (ilist(l).GT.ifirst + 3.OR.l.GT.nnb + 1) go to 330
91 *
92 * Set appropriate pair index for either component.
93  jl = ilist(l)
94  jpair = kvec(jl)
95  il1 = ilist(l+1)
96  ipair = kvec(il1)
97 * Check whether two consecutive list members belong to same pair.
98  IF (jpair.EQ.ipair) go to 321
99 * The case of index L referring to the last neighbour is permitted.
100  j = 2*jpair
101  IF (j.EQ.ilist(l)) j = j - 1
102 * Index of the missing component, subject to neighbour test.
103  IF (j.EQ.i) go to 323
104  jcomp = ilist(l)
105  a1 = x(1,jcomp) - x(1,j)
106  a2 = x(2,jcomp) - x(2,j)
107  a3 = x(3,jcomp) - x(3,j)
108  rij2 = a1*a1 + a2*a2 + a3*a3
109 * Only accept #J as neighbour if distance to JCOMP is < 2*RMIN.
110  IF (rij2.LT.rmin22) go to 324
111  323 l = l - 1
112 * Increase search index by one only after unsuccessful test.
113  go to 321
114 *
115 * Correct irregular & regular force components.
116  324 dr2 = 0.0
117  drdv = 0.0
118  DO 325 k = 1,3
119  dx(k) = x(k,j) - xi(k)
120  dv(k) = xdot(k,j) - xidot(k)
121  dr2 = dr2 + dx(k)**2
122  drdv = drdv + dx(k)*dv(k)
123  325 CONTINUE
124 *
125  dr2i = 1.0/dr2
126  dr3i = body(j)*dr2i*sqrt(dr2i)
127  drdv = 3.0*drdv*dr2i
128 *
129  DO 326 k = 1,3
130  firr(k) = firr(k) + dx(k)*dr3i
131  freg(k) = freg(k) - dx(k)*dr3i
132  fd(k) = fd(k) + (dv(k) - dx(k)*drdv)*dr3i
133  fdr(k) = fdr(k) - (dv(k) - dx(k)*drdv)*dr3i
134  326 CONTINUE
135 *
136  lj = nnb + 1
137  327 IF (j.GT.ilist(lj)) go to 328
138 * Move other members down by one until relevant location is free.
139  ilist(lj+1) = ilist(lj)
140  lj = lj - 1
141  IF (lj.GT.1) go to 327
142 *
143  328 ilist(lj+1) = j
144  nnb = nnb + 1
145  nbdis = nbdis + 1
146 * Note that next list index is increased by two after including #J.
147  IF (nnb.LT.nnbmax) go to 321
148 *
149 * This part includes the other component of an exchanged pair.
150  330 IF (listr(1).EQ.0.OR.nnb.GE.nnbmax) go to 350
151 *
152 * Do a fast skip if only one disrupted pair in original location.
153  IF (listr(1).EQ.2.AND.listr(2).LE.ifirst + 3) go to 350
154  nnb1 = listr(1)
155  lj = 1 + 0.2*float(nnb)
156  l = 1
157  332 icase = 0
158  lg = 0
159  ktime = 0
160  334 ktime = ktime + 1
161  335 IF (l.GT.nnb1) go to 350
162 *
163  l = l + 1
164  jbody = listr(l)
165  IF (jbody.LE.ifirst + 3) go to 335
166 * The two last disrupted pairs have already been considered.
167  336 lg = lg + lj
168 * First use large increments to speed up the search.
169  IF (lg.GT.nnb + 1) lg = nnb + 1
170  IF (ilist(lg).LT.jbody.AND.lg.LT.nnb + 1) go to 336
171 *
172  lg = lg + 1
173  338 lg = lg - 1
174  IF (ilist(lg).GT.jbody.AND.lg.GT.2) go to 338
175  IF (ilist(lg).EQ.jbody) icase = icase + ktime
176  IF (ktime.EQ.1) go to 334
177 *
178 * See whether any or both of the components have been identified.
179  IF (icase.EQ.0.OR.icase.EQ.3) go to 332
180 *
181  j = listr(l+1-icase)
182 * Index of missing component to be included subject to J = I test.
183  jcomp = listr(l+icase-2)
184 * Arguments for J & JCOMP are L or L - 1 depending on ICASE.
185  a1 = x(1,jcomp) - x(1,j)
186  a2 = x(2,jcomp) - x(2,j)
187  a3 = x(3,jcomp) - x(3,j)
188  rij2 = a1*a1 + a2*a2 + a3*a3
189 * Accept body #J only if distance to JCOMP is < 2*RMIN (skip J = I).
190  IF (rij2.GT.rmin22.OR.j.EQ.i) go to 332
191 *
192 * Carry out force modifications due to addition of neighbour.
193  342 dr2 = 0.0
194  drdv = 0.0
195  DO 343 k = 1,3
196  dx(k) = x(k,j) - xi(k)
197  dv(k) = xdot(k,j) - xidot(k)
198  dr2 = dr2 + dx(k)**2
199  drdv = drdv + dx(k)*dv(k)
200  343 CONTINUE
201 *
202  dr2i = 1.0/dr2
203  dr3i = body(j)*dr2i*sqrt(dr2i)
204  drdv = 3.0*drdv*dr2i
205 *
206  DO 344 k = 1,3
207  firr(k) = firr(k) + dx(k)*dr3i
208  freg(k) = freg(k) - dx(k)*dr3i
209  fd(k) = fd(k) + (dv(k) - dx(k)*drdv)*dr3i
210  fdr(k) = fdr(k) - (dv(k) - dx(k)*drdv)*dr3i
211  344 CONTINUE
212 *
213 * Include body #J in neighbour list and increase NNB.
214  345 k = nnb + 1
215  346 IF (j.GT.ilist(k)) go to 348
216 * Move other members down by one until relevant location is free.
217  ilist(k+1) = ilist(k)
218  k = k - 1
219  IF (k.GT.1) go to 346
220 *
221  348 ilist(k+1) = j
222  nnb = nnb + 1
223  nbdis2 = nbdis2 + 1
224 *
225 * Check list of high velocity intruders for early retention.
226  350 IF (listv(1).EQ.0.OR.icm.EQ.-1) go to 355
227  l = 2
228  351 j = listv(l)
229  IF (j.EQ.i) go to 354
230  a1 = x(1,j) - xi(1)
231  a2 = x(2,j) - xi(2)
232  a3 = x(3,j) - xi(3)
233  rij2 = a1**2 + a2**2 + a3**2
234 * IF (RIJ2.GT.4.0*RS2.OR.RIJ2.LT.RS2) GO TO 354
235 * Simplify to include GPU (standard code needs a few extra searches).
236  IF (rij2.GT.4.0*rs2) go to 354
237  a4 = xdot(1,j) - xdot(1,i)
238  a5 = xdot(2,j) - xdot(2,i)
239  a6 = xdot(3,j) - xdot(3,i)
240  a7 = a1*a4 + a2*a5 + a3*a6
241  IF (a7.GT.0.0) go to 354
242  p2 = rij2 - a7**2/(a4**2 + a5**2 + a6**2)
243 * Accept if impact parameter < RS.
244  IF (p2.GT.rs2) go to 354
245 * See if body #J has been included by other procedures.
246  DO 353 k = 1,nnb
247  IF (j.EQ.ilist(k+1)) go to 354
248  353 CONTINUE
249  icm = -1
250 * Redundant indicator (normally > 0) used for joint procedure.
251  nbdis2 = nbdis2 - 1
252  nbfast = nbfast + 1
253 *
254 * Distinguish betweeen single particle treatment and perturbed case.
255  IF (nnb.LE.nnbmax) THEN
256  IF (i.LE.n) go to 342
257  rij2 = (xi(1) - x(1,j))**2 + (xi(2) - x(2,j))**2 +
258  & (xi(3) - x(3,j))**2
259 * Adopt c.m. approximation if body #J is also single.
260  IF (rij2.GT.cmsep2*r(i-n)**2.AND.j.LE.n) go to 342
261  ELSE
262  go to 355
263  END IF
264 *
265 * Set KS component indices (also body #J if inside c.m. approximation).
266  i1 = 2*(i - n) - 1
267  i2 = i1 + 1
268  j1 = j
269  j2 = 0
270  IF (j.GT.n) THEN
271  IF (rij2.LT.cmsep2*r(j-n)**2) THEN
272  j1 = 2*(j - n) - 1
273  j2 = j1 + 1
274  END IF
275  END IF
276 *
277 * Begin evaluation of all relevant interactions (at most 4 terms).
278  k = j1
279  360 l = i1
280  362 a1 = x(1,k) - x(1,l)
281  a2 = x(2,k) - x(2,l)
282  a3 = x(3,k) - x(3,l)
283  rij2 = a1*a1 + a2*a2 + a3*a3
284  dv(1) = xdot(1,k) - xdot(1,l)
285  dv(2) = xdot(2,k) - xdot(2,l)
286  dv(3) = xdot(3,k) - xdot(3,l)
287 *
288 * Employ the appropriate mass-weighted expression.
289  dr2i = 1.0/rij2
290  dr3i = body(k)*body(l)*dr2i*sqrt(dr2i)/body(i)
291  drdv = 3.0*(a1*dv(1) + a2*dv(2) + a3*dv(3))*dr2i
292 *
293 * Add irregular F & FDOT and subtract regular terms.
294  firr(1) = firr(1) + a1*dr3i
295  firr(2) = firr(2) + a2*dr3i
296  firr(3) = firr(3) + a3*dr3i
297  fd(1) = fd(1) + (dv(1) - a1*drdv)*dr3i
298  fd(2) = fd(2) + (dv(2) - a2*drdv)*dr3i
299  fd(3) = fd(3) + (dv(3) - a3*drdv)*dr3i
300  freg(1) = freg(1) - a1*dr3i
301  freg(2) = freg(2) - a2*dr3i
302  freg(3) = freg(3) - a3*dr3i
303  fdr(1) = fdr(1) - (dv(1) - a1*drdv)*dr3i
304  fdr(2) = fdr(2) - (dv(2) - a2*drdv)*dr3i
305  fdr(3) = fdr(3) - (dv(3) - a3*drdv)*dr3i
306 *
307 * Consider each interaction in turn (body #J may be resolved).
308  l = l + 1
309  IF (l.EQ.i2) go to 362
310  k = k + 1
311  IF (k.EQ.j2) go to 360
312 *
313 * Include body #J in the neighbour list.
314  go to 345
315 *
316  354 l = l + 1
317  IF (l.LE.listv(1) + 1) go to 351
318 *
319  355 RETURN
320 *
321  END