Nbody6
 All Files Functions Variables
higrow.f
Go to the documentation of this file.
1  SUBROUTINE higrow(I,IG,IM,ECC,SEMI,EMAX,EMIN,TG,EDAV,ZI,IQ)
2 *
3 *
4 * Induced change of hierarchical binary.
5 * --------------------------------------
6 *
7  include 'common6.h'
8  common/binary/ cm(4,mmax),yrel(3,mmax),zrel(3,mmax),
9  & hm(mmax),um(4,mmax),umdot(4,mmax),tmdis(mmax),
10  & namem(mmax),nameg(mmax),kstarm(mmax),iflagm(mmax)
11  common/modes/ eb0(ntmax),zj0(ntmax),ecrit(ntmax),ar(ntmax),
12  & br(ntmax),eosc(4,ntmax),edec(ntmax),tosc(ntmax),
13  & rp(ntmax),es(ntmax),zm(2,ntmax),iosc(ntmax),
14  & namec(ntmax)
15  common/slow0/ range,islow(10)
16  common/tidal/ cq(2),ct(2),cgr,dedt
17  common/rksave/ coeff,hohat(3),e0,a0,hh,xmb
18  REAL*8 a1(3),a2(3),xrel(3),vrel(3),ei(3),hi(3),ho(3),bhat(3),
19  & ui(4),v(4),evec(3),xr0(3),vr0(3),ei0(3),ww(6),w(4)
20  REAL*8 bodyi(2),qg(2),wg(2)
21  LOGICAL icoll
22  DATA ww /2.119,3.113,8.175,3.742,4.953,9.413/
23  SAVE icall,itime,itry,namei,dtprev,tcheck,zfac,pmin1
24  DATA icall,itry,namei,tcheck /0,0,0,0.0d0/
25 *
26 *
27 * Copy KS variables to local scalars.
28  DO 1 k = 1,4
29  ui(k) = um(k,im)
30  v(k) = umdot(k,im)
31  1 CONTINUE
32 *
33 * Transform to physical variables and multiply by 4 (momentum formula).
34  CALL ksphys(ui,v,xrel,vrel)
35  DO 2 k = 1,3
36  vrel(k) = 4.0*vrel(k)
37  2 CONTINUE
38 *
39 * Specify index for outer body (second KS component) & pair index.
40  jcomp = i + 1
41  ipair = kvec(i)
42  dtsum = 0.0
43  itime = 0
44  icall = 0
45  ecc0 = ecc
46  semi0 = semi
47  a0 = semi
48  hm0 = hm(im)
49  zm3 = body(jcomp)
50  bodyi(1) = cm(1,im)
51  bodyi(2) = cm(2,im)
52 *
53 * Obtain inner & outer angular momentum by cyclic notation.
54  4 a12 = 0.0
55  a22 = 0.0
56  a1a2 = 0.0
57  ri2 = 0.0
58  vi2 = 0.0
59  rvi = 0.0
60  DO 5 k = 1,3
61  k1 = k + 1
62  IF (k1.GT.3) k1 = 1
63  k2 = k1 + 1
64  IF (k2.GT.3) k2 = 1
65  a1(k) = xrel(k1)*vrel(k2) - xrel(k2)*vrel(k1)
66  a2(k) = (x(k1,jcomp) - x(k1,i))*(xdot(k2,jcomp) - xdot(k2,i))
67  & - (x(k2,jcomp) - x(k2,i))*(xdot(k1,jcomp) - xdot(k1,i))
68  a12 = a12 + a1(k)**2
69  a22 = a22 + a2(k)**2
70  a1a2 = a1a2 + a1(k)*a2(k)
71  ri2 = ri2 + xrel(k)**2
72  vi2 = vi2 + vrel(k)**2
73  rvi = rvi + xrel(k)*vrel(k)
74  5 CONTINUE
75 *
76 * Evaluate orbital parameters for outer orbit from KS elements.
77  zmb = body(i) + body(jcomp)
78  semi1 = -0.5*zmb/h(ipair)
79  ecc2 = (1.0 - r(ipair)/semi1)**2 + tdot2(ipair)**2/(semi1*zmb)
80  ecc1 = sqrt(ecc2)
81 * Determine inclination in radians.
82  fac = a1a2/sqrt(a12*a22)
83  IF(fac.LT.-1.d0.OR.fac.GT.1.d0)THEN
84  IF(fac.LT.-1.05d0.OR.fac.GT.1.05d0)THEN
85  WRITE (6,9) ipair, i, jcomp, ecc1, semi1*su, fac
86  9 FORMAT (' WARNING! HIGROW FAC: IP I J E A FAC ',
87  & 3i6,f7.3,f8.1,f9.5)
88  ENDIF
89  fac = max(fac,-1.d0)
90  fac = min(fac,1.d0)
91  ENDIF
92  zi = acos(fac)
93  cc = (1.0 - ecc**2)*cos(zi)**2
94 *
95 * Construct the Runge-Lenz vector (Heggie & Rasio 1995, Eq.(5)).
96  ei2 = 0.0
97  DO 10 k = 1,3
98  ei(k) = (vi2*xrel(k) - rvi*vrel(k))/body(i) -
99  & xrel(k)/sqrt(ri2)
100  ei2 = ei2 + ei(k)**2
101  evec(k) = ei(k)
102  10 CONTINUE
103  ei2 = min(ei2,0.9999d0)
104 *
105 * Define unit vectors for inner eccentricity and angular momenta.
106  cosj = 0.0
107  sjsg = 0.0
108  DO 15 k = 1,3
109  ei(k) = ei(k)/sqrt(ei2)
110  hi(k) = a1(k)/sqrt(a12)
111  ho(k) = a2(k)/sqrt(a22)
112  cosj = cosj + hi(k)*ho(k)
113  sjsg = sjsg + ei(k)*ho(k)
114  15 CONTINUE
115 *
116 * Form unit vector BHAT and scalars AH & BH (Douglas Heggie, 10/9/96).
117  ah = 0.0
118  bh = 0.0
119  DO 16 k = 1,3
120  k1 = k + 1
121  IF (k1.GT.3) k1 = 1
122  k2 = k1 + 1
123  IF (k2.GT.3) k2 = 1
124  bhat(k) = hi(k1)*ei(k2) - hi(k2)*ei(k1)
125  ah = ah + ei(k)*ho(k)
126  bh = bh + bhat(k)*ho(k)
127  16 CONTINUE
128 *
129 * Evaluate the expressions A & Z.
130  a = cosj*sqrt(1.0 - ei2)
131  z = (1.0 - ei2)*(2.0 - cosj**2) + 5.0*ei2*sjsg**2
132 *
133 * Obtain maximum inner eccentricity (Douglas Heggie, Sept. 1995).
134  z2 = z**2 + 25.0 + 16.0*a**4 - 10.0*z - 20.0*a**2 - 8.0*a**2*z
135  emax = one6*(z + 1.0 - 4.0*a**2 + sqrt(z2))
136  emax = max(emax,0.0001d0)
137  emax = sqrt(emax)
138 *
139 * Form minimum eccentricity (Douglas Heggie, Sept. 1996).
140  az = a**2 + z - 2.0
141  IF (az.GE.0.0) THEN
142  az1 = 1.0 + z - 4.0*a**2
143  emin2 = one6*(az1 - sqrt(az1**2 - 12.0*az))
144  ELSE
145  emin2 = 1.0 - 0.5*(a**2 + z)
146  END IF
147  emin2 = max(emin2,0.0001d0)
148  emin = sqrt(emin2)
149 *
150 * Estimate eccentricity growth time-scale (N-body units).
151  tk = twopi*semi*sqrt(semi/body(i))
152  tk1 = twopi*abs(semi1)*sqrt(abs(semi1)/zmb)
153  tg = tk1**2*zmb*(1.0 - ecc1**2)**1.5/(body(jcomp)*tk)
154 *
155 * Evaluate numerical precession factor (involves elliptic integral).
156  const = pfac(a,z)
157  const = const*4.0/(1.5*twopi*sqrt(6.0))
158 *
159 * Convert growth time to units of 10**6 yrs.
160  tg = const*tg*tstar
161 *
162 * Form doubly averaged eccentricity derivative (Douglas Heggie 9/96).
163  yfac = 15.0*body(jcomp)/(4.0*zmb)*twopi*tk/tk1**2
164  yfac = yfac*ecc*sqrt(1.0 - ecc**2)/(1.0 - ecc1**2)**(1.5)
165  edav = yfac*ah*bh
166 *
167 * Skip small EMAX or large pericentre distance (TMDIS increased).
168  qperi = semi*(1.0 - ecc)
169  pmin = semi*(1.0 - emax)
170  rm = max(radius(i),radius(ig),1.0d-20)
171  IF (kstarm(im).GE.0.AND.emax.LT.0.9) THEN
172  iq = 1
173  go to 40
174  END IF
175 *
176 * Delay Kozai cycle for EMAX > 0.9 and TC > 2000.
177  IF (emax.GE.0.9) THEN
178  CALL hicirc(pmin,emax,i,ig,bodyi,tg,tc,ec,edt,w)
179  IF (tc.GT.2000.OR.(ecc.LT.0.1.AND.emax.LT.0.95)) THEN
180  iq = 2
181  go to 40
182  END IF
183  END IF
184 *
185 * Check termination time for marginal stability criterion.
186  IF (name(i).EQ.namei.AND.(time+toff).GT.tcheck) THEN
187  WRITE (6,17) name(i), ecc, emax, alph, zfac, ecc1, pmin1,
188  & pcrit
189  17 FORMAT (' ECCMOD UNSTAB NM E EX IN YF E1 PM PC ',
190  & i6,2f8.4,f7.1,f6.2,f7.3,1p,2e10.2)
191  iq = -4
192  go to 40
193  END IF
194 *
195 * Ensure evaluation of EDT for large eccentricity and EDAV > 0.
196  IF (ecc.GT.0.9.AND.edav.GT.0.0) THEN
197  CALL hicirc(qperi,ecc,i,ig,bodyi,tg,tc,ec,edt,w)
198  IF (tc.LT.2000.0) THEN
199  icoll = .true.
200  ELSE
201  icoll = .false.
202  edt = edav
203  END IF
204  ELSE
205  icoll = .false.
206  edt = edav
207  END IF
208 *
209 * Activate indicator on small QPERI to prevent collision before EMAX.
210  IF (qperi.LT.2.0*rm) icoll = .true.
211 *
212 * Check circularization time near turning point of normal binary.
213  IF ((kstarm(im).GE.0.AND.edav.GT.0.0.AND.
214  & (dedt.LT.0.0.OR.ecc.GT.abs(emax-0.00005))).OR.icoll) THEN
215  IF (.NOT.icoll) THEN
216  CALL hicirc(qperi,ecc,i,ig,bodyi,tg,tc,ec,edt,w)
217  END IF
218  IF (tc.LT.7.0d+04.AND.qperi.LT.6.0*rm.AND.itry.LT.4.OR.
219  & tc.LT.1.0d+04.AND.qperi.LT.5.0*rm.AND.itry.LT.8) THEN
220  WRITE (6,18) ecc, emax, emin, semi*su, tg, tc, edav,
221  & edt, qperi/rm
222  18 FORMAT (' HICIRC TRY: E EX EM A TG TC EDA EDT QP/R ',
223  & 2f9.5,f7.3,f7.1,1p,5e9.1)
224  itry = itry + 1
225  END IF
226  IF (itry.GT.8) itry = 0
227 *
228 * Check termination for TC < 2000 to be consistent with routine TCIRC.
229  IF (tc.GT.2000.0) go to 25
230 *
231 * Evaluate chaos boundary parameters.
232  eb = -0.5*cm(1,im)*cm(2,im)/a0
233  cj = cm(1,im)*cm(2,im)/body(i)*sqrt(body(i))
234  zj = cj*sqrt(qperi*(1.0 + ecc))
235  ic = nchaos + 1
236  idis = 0
237  itry = 0
238 *
239 * Define oscillation period (dimensionless time).
240  DO 20 k = 1,2
241  IF (k.EQ.1) THEN
242  ik = i
243  ELSE
244  ik = ig
245  END IF
246 * Specify polytropic index for each star (n = 3, 2 or 3/2).
247  IF (kstar(ik).EQ.3.OR.kstar(ik).EQ.5) THEN
248  bodi = cm(k,im)
249  CALL giant3(ik,bodi,wg,qg,xn,ql)
250  w(k) = wg(1)
251  ELSE
252  ip = 3
253  IF (kstar(ik).GE.3) ip = 2
254  IF (kstar(ik).EQ.4.OR.kstar(ik).EQ.6) ip = 3
255  IF (kstar(ik).EQ.0) ip = 1
256  w(k) = ww(ip)
257  END IF
258  20 CONTINUE
259 *
260  CALL chaos0(qperi,ecc,eb,zj,cm(1,im),cm(2,im),radius(i),
261  & radius(ig),w,ecrit(ic),ar(ic),br(ic),idis)
262 *
263 * Begin chaos/spiral stage if chaos boundary has been crossed.
264  IF (idis.EQ.0) THEN
265  WRITE (6,22) ttot, name(i), ic, ecc, emax, semi, qperi,
266  & edav, qperi/rm
267  22 FORMAT (' ECCMOD CHAOS T NAM IC E EX A QP EDAV QP/R ',
268  & f9.2,i6,i4,2f9.5,1p,4e10.2)
269  CALL flush(6)
270  iq = -1
271 * Activate chaos indicator for calling KSTIDE from RESET.
272  kstarm(im) = -1
273  go to 40
274  ELSE IF (idis.EQ.-1) THEN
275  WRITE (6,23) ttot, name(i), ic, ecc, emax, semi, qperi,
276  & edav, qperi/rm
277  23 FORMAT (' ECCMOD SPIRAL T NAM IC E EX A QP EDAV QP/R ',
278  & f9.2,i6,i4,2f9.5,1p,4e10.2)
279  CALL flush(6)
280  iq = -2
281 * Note that KSTARM(IM) = -2 would be treated as existing spiral.
282  kstarm(im) = -1
283  go to 40
284  ELSE IF (idis.EQ.1) THEN
285 * Check collision condition to be sure.
286  IF (qperi.LT.radius(i) + radius(ig)) THEN
287  WRITE (6,24) ttot, name(i), ic, ecc, semi, qperi, edav,
288  & qperi/rm
289  24 FORMAT (' ECCMOD DISRUPT T NAM IC E A QP EDAV QP/R ',
290  & f9.2,i6,i4,f8.4,1p,4e10.2)
291  iq = -3
292  go to 40
293  END IF
294  END IF
295  END IF
296 *
297 * Form quantities for the outer orbit.
298  25 rr = 0.0
299  rv0 = 0.0
300  v20 = 0.0
301  DO 30 k = 1,3
302  xr0(k) = x(k,jcomp) - x(k,i)
303  vr0(k) = xdot(k,jcomp) - xdot(k,i)
304  rv0 = rv0 + xr0(k)*vr0(k)
305  v20 = v20 + vr0(k)**2
306  rr = rr + xr0(k)**2
307  30 CONTINUE
308 *
309 * Construct the outer Runge-Lenz vector.
310  DO 35 k = 1,3
311  ei0(k) = (v20*xr0(k) - rv0*vr0(k))/zmb - xr0(k)/sqrt(rr)
312  35 CONTINUE
313 *
314 * Specify total time interval (unperturbed or perturbed case).
315  IF (list(1,i).EQ.0) THEN
316  dt0 = time - t0(i)
317 * DT = MIN(DT0,0.1*(1.0 - ECC)/(ABS(EDAV) + 1.0D-15))
318  ELSE
319 * Ensure that interval extends to next apocentre (including slow-down).
320  imod = kslow(ipair)
321  dt0 = 0.98*float(islow(imod))*tk1
322 * DT = MIN(DT0,0.1*(1.0 - ECC)*TG/TSTAR)
323  END IF
324 *
325 * Set partial interval and check remaining time.
326  dt1 = min(dt0,0.1*tg*sqrt(1.0 - ecc**2)/tstar)
327  IF (dtsum + dt1.GT.dt0) dt1 = dt0 - dtsum + 1.0d-12
328 *
329 * Obtain quadrupole and tidal constants for each new binary.
330  dtm = time - max(tev0(i),tev0(ig))
331  IF (name(i).NE.namei.OR.dtm.LE.dt0) THEN
332  CALL qtides(i,ig,im,semi,ecc)
333  namei = name(i)
334  dedt = 0.0
335  dtprev = 1.0
336  nst = nstab(semi,semi1,ecc,ecc1,zi,bodyi(1),bodyi(2),zm3)
337  IF (nst.EQ.0) THEN
338  pcrit = 0.98*qperi*(1.0 - pert)
339  pcr = stability(bodyi(1),bodyi(2),zm3,ecc,ecc1,zi)
340  pcr = pcr*semi
341 * Specify reduced peri if old criterion < PCRIT/2 (avoids switching).
342  IF (pcr.LT.0.5*pcrit) THEN
343  pcrit = 0.75*pcrit
344  END IF
345  IF (pcrit.LT.pcr.AND.pert.LT.0.01.AND.
346  & itime.LT.20) THEN
347  alph = 360.0*zi/twopi
348  fail = qperi*(1-pert) - pcr
349  WRITE (6,42) ttot, alph, ecc, ecc1, qperi, fail, pert
350  42 FORMAT (' NEWSTAB T INC EI EO QP FAIL PERT ',
351  & f7.1,f7.2,2f8.4,1p,3e10.2)
352  END IF
353  ELSE
354  pcrit = 1.01*qperi
355  END IF
356  pmin1 = semi1*(1.0 - ecc1)
357  IF (pmin1.LT.pcrit) THEN
358  nk = 1 + 10.0*ecc1/(1.0 - ecc1)
359  tcheck = time + toff + nk*tk1
360  ELSE
361  tcheck = 1.0d+10
362  END IF
363  END IF
364 *
365 * Determine time-step for integration from several criteria.
366  ge=30*ecc+45*ecc**3+3.75*ecc**5
367 * Apply factor of 2 correction for agreement with classical result.
368  ge = 0.5*ge
369  slr=semi*(1.0 - ecc**2)
370  zq=ge/(slr**5*semi*sqrt(semi))
371 * Correct for wrong eccentricity dependence.
372  zq = zq*(1.0 - ecc**2)
373  edq = zq*(cq(1) + cq(2))
374  tq = ecc/edq
375  zgr = cgr/(slr*semi*sqrt(semi))
376 * Note cgr is angular velocity (hence multiply by 2*pi; 12/03).
377  tgr = twopi*ecc/zgr
378 *
379 * Delay first time if apsidal motion or GR are important (ECC < 0.9).
380  IF (ecc.LT.0.90.AND.itime.EQ.0) THEN
381  IF (min(tq,tgr)*tstar.LT.tg) THEN
382  iq = 2
383  go to 40
384  END IF
385  END IF
386 *
387 * Include check on tidal dissipation for large eccentricity.
388  IF (kstarm(im).GE.0.AND.ecc.GT.0.9) THEN
389  tt = ecc/abs(edt)
390  tq = min(tt,tq)
391 * Note that EDT from HICIRC agrees well with actual value from RKINT.
392  END IF
393 *
394 * Adopt harmonic mean of inner period and growth/quadrupole time.
395  dt = 0.5*sqrt(tk*min(tg/tstar,tq))
396  IF (ecc.GT.0.98) dt = 0.1*dt
397  dt = min(dt,0.001/(abs(edav) + 1.0d-20))
398 * Ensure conservative step first time and limit increase to factor 2.
399  IF (itime.EQ.0) THEN
400  dt = min(dt,1.0d-03*tg/tstar)
401  ELSE
402  dt = min(dt,2.0d0*dtprev)
403  END IF
404 *
405 * Include safety check to avoid problems.
406  etry = ecc + edav*dt1
407  IF (ecc.GT.0.96.AND.etry.GT.0.98) THEN
408  etry = min(etry,emax)
409  qptry = semi*(1.0 - etry)
410  CALL hicirc(qptry,etry,i,ig,bodyi,tg,tc,ec,edt,w)
411  IF (tc.LT.10.0) THEN
412  dt1 = 0.5*dt1
413  dt = 0.5*dt
414  END IF
415  END IF
416 *
417 * Ensure frequent termination check inside 5*RM to avoid overshooting.
418  IF (qperi.LT.5.0*rm.AND.edav.GT.0.0.AND.kstarm(im).GE.0) THEN
419 * Restrict HIMOD interval so E + EDAV*DT1 gives new peri outside 4*RM.
420  dtt = (qperi - 4.0*rm)/(semi*edav)
421  dt1 = min(dtt,dt1)
422  dt1 = max(dt,dt1)
423  END IF
424 *
425 * Modify the inner orbit using averaging of de/dt & dh/dt.
426  dtprev = dt
427  CALL himod(evec,a1,zm3,zmb,ei0,a2,icall,dt1,dt,ecc,xrel,vrel)
428 *
429  IF (e0.ge.1.0) THEN
430  iq = 1
431  go to 40
432  END IF
433  semi = a0
434  ecc = e0
435  itime = itime + 1
436  dtsum = dtsum + dt1
437  IF (dtsum.LT.dt0) go to 4
438 *
439 * Update step counter and next time for checking.
440  neint = neint + itime
441  tmdis(im) = time + dtsum
442 *
443 * Transform back to KS variables after integration.
444  40 IF (itime.GT.0) THEN
445  CALL physks(xrel,vrel,ui,v)
446  DO 45 k = 1,4
447  um(k,im) = ui(k)
448  umdot(k,im) = 0.25*v(k)
449  IF (k.LT.4) THEN
450  yrel(k,im) = xrel(k)
451  zrel(k,im) = vrel(k)
452  END IF
453  45 CONTINUE
454  hm(im) = -0.5d0*body(i)/a0
455  CALL hirect(im)
456  zmu = cm(1,im)*cm(2,im)/body(i)
457  decorr = zmu*(hm0 - hm(im))
458  emerge = emerge - decorr
459  ecoll = ecoll + decorr
460  egrav = egrav + decorr
461 * Define circularization if e0 < 0.002 (end of Kozai cycle).
462  IF (e0.LT.0.002) THEN
463  km = kstarm(im)
464  kstarm(im) = 10
465  IF (km.LT.0) ncirc = ncirc + 1
466  tmdis(im) = 1.0d+10
467  tev(n+ipair) = min(tev(i),tev(ig)) - 2.0*stepx
468  tb = days*semi*sqrt(semi/body(i))
469  alph = zi*360.0/twopi
470  WRITE (6,48) name(i), name(ig), km, e0, a0*su, tb, alph
471  48 FORMAT (' END KOZAI NM K* E A P INC ',
472  & 2i6,i4,f7.3,f6.1,2f7.1)
473  END IF
474 * Include rectification of active SPIRAL (suppressed).
475  ic = 0
476  DO 50 k = 1,nchaos
477  IF (namec(k).EQ.nzero - namem(im)) ic = k
478 * IF (NAMEC(K).EQ.NZERO + NAME(I)) IC = K
479  50 CONTINUE
480  IF (ic.EQ.-3) THEN
481  rp(ic) = a0*(1.0 - ecc)
482  es(ic) = ecc
483  tosc(ic) = time
484  dh = hm0 - hm(im)
485  WRITE (6,60) ttot, tmdis(im), ecc, rp(ic), dh
486  60 FORMAT (' UPDATE: T TMD E RP DH ',
487  & 2f10.2,f8.4,1p,2e10.2)
488  END IF
489  END IF
490 *
491  RETURN
492 *
493  END