Nbody6
 All Files Functions Variables
ksinit.f
Go to the documentation of this file.
1  SUBROUTINE ksinit
2 *
3 *
4 * Initialization of KS regularization.
5 * ------------------------------------
6 *
7  include 'common6.h'
8  REAL*8 q(3),rdot(3),ui(4),vi(4),a1(3,4)
9  INTEGER ipipe(9)
10  SAVE ipipe
11  DATA ipipe /9*0/
12 *
13 *
14 * Set new global indices of the components and current pair index.
15  icomp = 2*npairs - 1
16  jcomp = icomp + 1
17  ipair = npairs
18 *
19 * Add body #N in case the only neighbour was removed in KSREG.
20  IF (list(1,icomp).EQ.0) THEN
21  list(2,icomp) = n
22  list(2,jcomp) = n
23  list(1,icomp) = 1
24  list(1,jcomp) = 1
25  END IF
26 *
27 * Specify mass, neighbour radius, name, radius & type for new c.m.
28  body(ntot) = body(icomp) + body(jcomp)
29  rs(ntot) = rs(icomp)
30  name(ntot) = nzero + name(icomp)
31  radius(ntot) = 0.0
32  tev(ntot) = 1.0e+10
33  tev0(ntot) = 1.0e+10
34  body0(ntot) = body(ntot)
35  epoch(ntot) = time*tstar
36  kstar(ntot) = 0
37  imod = 1
38 *
39 * Define c.m. coordinates & velocities and set XDOT for components.
40  DO 10 k = 1,3
41  x(k,ntot) = (body(icomp)*x(k,icomp) + body(jcomp)*x(k,jcomp))/
42  & body(ntot)
43  x0dot(k,ntot) = (body(icomp)*x0dot(k,icomp) + body(jcomp)*
44  & x0dot(k,jcomp))/body(ntot)
45  xdot(k,ntot) = x0dot(k,ntot)
46  xdot(k,icomp) = x0dot(k,icomp)
47  xdot(k,jcomp) = x0dot(k,jcomp)
48  10 CONTINUE
49 *
50 * Obtain force polynomial for c.m. with components ICOMP & JCOMP.
51  nnb = list(1,icomp)
52 *
53 * Predict current coordinates & velocities for the neighbours.
54  CALL xvpred(icomp,nnb)
55 *
56 * Obtain new polynomials & steps (first F & FDOT, then F2DOT & F3DOT).
57  CALL fpoly1(icomp,jcomp,1)
58  CALL fpoly2(ntot,ntot,1)
59 *
60 * Skip KS initialization at merger termination (H, U & UDOT in RESET).
61  IF (iphase.EQ.7) THEN
62  eb = 2.0*ebh
63  go to 50
64  END IF
65 *
66 * Define relative coordinates and velocities in physical scaled units.
67  DO 20 k = 1,3
68  q(k) = x(k,icomp) - x(k,jcomp)
69  rdot(k) = x0dot(k,icomp) - x0dot(k,jcomp)
70  20 CONTINUE
71 *
72 * Introduce regularized variables using definition of Book.
73  r(ipair) = sqrt(q(1)**2 + q(2)**2 + q(3)**2)
74 *
75 * Initialize the regularized coordinates according to sign of Q(1).
76  IF (q(1).LE.0.0d0) THEN
77  ui(3) = 0.0d0
78  ui(2) = sqrt(0.5d0*(r(ipair) - q(1)))
79  ui(1) = 0.5d0*q(2)/ui(2)
80  ui(4) = 0.5d0*q(3)/ui(2)
81  ELSE
82  ui(4) = 0.0d0
83  ui(1) = sqrt(0.5d0*(r(ipair) + q(1)))
84  ui(2) = 0.5d0*q(2)/ui(1)
85  ui(3) = 0.5d0*q(3)/ui(1)
86  END IF
87 *
88 * Set current transformation matrix.
89  CALL matrix(ui,a1)
90 *
91 * Form regularized velocity and set initial KS coordinates.
92  tdot2(ipair) = 0.0
93  DO 30 k = 1,4
94  udot(k,ipair) = 0.50d0*(a1(1,k)*rdot(1) + a1(2,k)*rdot(2) +
95  & a1(3,k)*rdot(3))
96 * Note that A1(J,K) is the transpose of A1(K,J).
97  u(k,ipair) = ui(k)
98  u0(k,ipair) = u(k,ipair)
99  tdot2(ipair) = tdot2(ipair) + 2.0d0*ui(k)*udot(k,ipair)
100  30 CONTINUE
101 *
102 * Evaluate initial binding energy per unit mass (singular form).
103  h(ipair) = (2.0d0*(udot(1,ipair)**2 + udot(2,ipair)**2 +
104  & udot(3,ipair)**2 + udot(4,ipair)**2) -
105  & body(ntot))/r(ipair)
106  eb = h(ipair)*body(icomp)*body(jcomp)/body(ntot)
107 *
108 * Form perturber list.
109  50 CALL kslist(ipair)
110 *
111 * Transform any unperturbed hard binary to apocentre and set time-step.
112  semi = -0.5*body(ntot)/h(ipair)
113  IF (list(1,icomp).EQ.0.AND.eb.LT.ebh.AND.semi.LT.rmin) THEN
114  tk = twopi*semi*sqrt(semi/body(ntot))
115 * Note TIME is not commensurate after KSPERI (cf. CHTERM & STEPS).
116  IF (iphase.NE.7.AND.iphase.NE.8) THEN
117  DO 55 k = 1,4
118  vi(k) = udot(k,ipair)
119  55 CONTINUE
120 * Determine pericentre time (TP < 0 if TDOT2 < 0) and add TK/2.
121  CALL tperi(semi,ui,vi,body(ntot),tp)
122 * Note: apocentre to apocentre gives almost zero step.
123  step(icomp) = 0.5*min(tk,step(ntot)) - tp
124 * Transform KS variables to peri and by pi/2 to apocentre (skip apo).
125  IF (abs(tdot2(ipair)).GT.1.0e-12.OR.r(ipair).LT.semi) THEN
126  time0 = time
127  CALL ksperi(ipair)
128  CALL ksapo(ipair)
129 * Reset TIME to quantized value (small > 0 or < 0 possible initially).
130  time = time0
131  time = max(time,0.0d0)
132  ELSE IF (tdot2(ipair).GT.0.0) THEN
133  tdot2(ipair) = -1.0e-20
134  END IF
135  END IF
136  END IF
137 *
138 * Estimate an appropriate KS slow-down index for G < GMIN.
139  IF (list(1,icomp).EQ.0.AND.semi.GT.0.0) THEN
140  tk = twopi*semi*sqrt(semi/body(ntot))
141  IF (kz(26).GT.0.AND.step(ntot).GT.tk) THEN
142  imod = 1 + log(step(ntot)/tk)/0.69
143  imod = min(imod,5)
144  END IF
145  END IF
146 *
147 * Specify zero membership and set large steps for second component.
148  list(1,jcomp) = 0
149 * Set large step for second component to avoid detection.
150  step(jcomp) = 1.0e+06
151  stepr(jcomp) = 1.0e+06
152 *
153 * Obtain polynomials for perturbed KS motion (standard case & merger).
154  CALL kspoly(ipair,imod)
155 *
156 * Obtain apocentre distance.
157  semi = -0.5*body(ntot)/h(ipair)
158  ecc2 = (1.0-r(ipair)/semi)**2 + tdot2(ipair)**2/(body(ntot)*semi)
159  rap = semi*(1.0 + sqrt(ecc2))
160 *
161 * Include suggestion for monitoring hyperbolic encounters (suppressed).
162 * IF (SEMI.LT.0.0) THEN
163 * PMIN = SEMI*(1.0 - SQRT(ECC2))
164 * WRITE (31,56) TIME+TOFF, NAME(ICOMP), NAME(JCOMP), PMIN
165 * 56 FORMAT (' HYPERBOLIC T NAM PMIN ',F8.2,2I6,1P,E10.2)
166 * END IF
167 *
168 * Set 2*SEMI as termination scale for hard binary if 2*SEMI < RS/20.
169  IF (eb.LT.ebh.AND.rap.LT.0.05*rs(ntot)) THEN
170  r0(ipair) = max(rmin,-body(ntot)/h(ipair))
171  r0(ipair) = min(r0(ipair),5.0*rmin)
172  ELSE
173  r0(ipair) = r(ipair)
174  END IF
175 *
176 * Increase regularization counters (#9 & NKSHYP for hyperbolic orbits).
177  nksreg = nksreg + 1
178  IF (h(ipair).GT.0.0) nkshyp = nkshyp + 1
179 *
180 * Check optional output for new KS.
181  IF (kz(10).GT.0) THEN
182  ri = sqrt((x(1,ntot) - rdens(1))**2 +
183  & (x(2,ntot) - rdens(2))**2 +
184  & (x(3,ntot) - rdens(3))**2)
185  WRITE (6,60) time+toff, name(icomp), name(jcomp),dtau(ipair),
186  & r(ipair), ri, h(ipair), ipair, gamma(ipair),
187  & step(ntot), list(1,icomp), list(1,ntot)
188  60 FORMAT (/,' NEW KSREG TIME =',f8.2,2i6,f12.3,1p,e10.1,
189  & 0p,f7.2,f9.2,i5,f8.3,1p,e10.1,2i5)
190  END IF
191 *
192 * Include limited diagnostics for NS or BH hard binary formation.
193  IF (max(kstar(icomp),kstar(jcomp)).GE.13.AND.eb.LT.ebh.AND.
194  & iphase.NE.7) THEN
195  id = 0
196  np = ipipe(1)
197 * See whether at least one component was recorded in previous pair.
198  DO 62 j = 2,np+1
199  IF (ipipe(j).EQ.name(icomp).OR.
200  & ipipe(j).EQ.name(jcomp)) id = id + 1
201  62 CONTINUE
202 * Print diagnostics if NS/BH binary not listed among four last pairs.
203  IF (id.LE.1) THEN
204  pd = days*semi*sqrt(abs(semi)/body(ntot))
205  WRITE (6,65) time+toff, name(icomp), name(jcomp),
206  & kstar(icomp), kstar(jcomp), kstar(ntot),
207  & sqrt(ecc2), pd, eb
208  65 FORMAT (' NS/BH BINARY T NM K* E P EB ',
209  & f8.1,2i6,3i4,f7.3,1p,e9.1,e11.2)
210  END IF
211 * Update table and membership by removing first two.
212  IF (np.GE.8) THEN
213 * Note there are at most 4 pairs with entries in IPIPE(2:9).
214  DO 66 j = 2,6
215  ipipe(j) = ipipe(j+2)
216  ipipe(j+1) = ipipe(j+3)
217  66 CONTINUE
218  np = np - 2
219  END IF
220 * Add NAME of each component in NP+2/3 and increase membership by 2.
221  ipipe(np+2) = name(icomp)
222  ipipe(np+3) = name(jcomp)
223  ipipe(1) = np + 2
224  END IF
225 *
226 * Modify the termination criterion according to value of NPAIRS.
227  IF (npairs.GT.kmax - 3) gmax = 0.8*gmax
228  IF (npairs.LT.kmax - 5.AND.gmax.LT.0.001) gmax = 1.2*gmax
229  IF (npairs.EQ.kmax) WRITE (6,70) npairs, time+toff
230  70 FORMAT (5x,'WARNING! MAXIMUM KS PAIRS NPAIRS TIME',i5,f9.2)
231 *
232 * Initialize prediction variables to avoid skipping KS components.
233  DO 75 kcomp = 1,2
234  jdum = 2*npairs - 2 + kcomp
235  DO 72 k = 1,3
236  x0(k,jdum) = x(k,jdum)
237  x0dot(k,jdum) = 0.0d0
238  f(k,jdum) = 0.0d0
239  fdot(k,jdum) = 0.0d0
240  d2(k,jdum) = 0.0d0
241  d3(k,jdum) = 0.0d0
242  d2r(k,jdum) = 0.0d0
243  d3r(k,jdum) = 0.0d0
244  72 CONTINUE
245  75 CONTINUE
246 *
247 * See whether either component has been regularized recently.
248  nnb = listd(1) + 1
249  k = 0
250 * Check case of initial binary and loop over disrupted pairs.
251  IF (iabs(name(icomp) - name(jcomp)).EQ.1) THEN
252  IF (name(icomp).LE.2*nbin0) k = -1
253  END IF
254  DO 80 l = 2,nnb
255  IF (name(icomp).EQ.listd(l).OR.name(jcomp).EQ.listd(l)) k = -1
256  80 CONTINUE
257  IF (h(ipair).GT.0.0) k = 0
258 *
259 * Treat mergers as new binaries and ensure chain/hard KS as standard.
260  IF (iphase.EQ.6) THEN
261  k = 0
262  ELSE IF (k.EQ.0) THEN
263  IF (iphase.EQ.8.OR.eb.LT.ebh) k = -1
264  END IF
265 * Set flag to distinguish between existing and new binaries (K = -1/0).
266  list(2,jcomp) = k
267 *
268 * Check diagnostic output of new hard binary.
269  IF (kz(8).GT.0.AND.k.EQ.0) THEN
270  IF (eb.GT.ebh) go to 100
271  semi = -0.5*body(ntot)/h(ipair)
272  ri = sqrt((x(1,ntot) - rdens(1))**2 +
273  & (x(2,ntot) - rdens(2))**2 +
274  & (x(3,ntot) - rdens(3))**2)
275  WRITE (8,90) time+toff, name(icomp), name(jcomp), k,
276  & body(icomp),body(jcomp), eb, semi, r(ipair),
277  & gamma(ipair), ri
278  90 FORMAT (' NEW BINARY T =',f7.1,' NAME = ',2i6,i3,
279  & ' M =',1p,2e9.1,' EB =',e9.1,
280  & ' A =',e9.1,' R =',e9.1,' G =',e9.1,
281  & ' RI =',e9.1)
282  CALL flush(8)
283  END IF
284 *
285  100 RETURN
286 *
287  END