Nbody6
 All Files Functions Variables
binpop.f
Go to the documentation of this file.
1  SUBROUTINE binpop
2 *
3 *
4 * Initial binary population.
5 * --------------------------
6 *
7  include 'common6.h'
8  REAL*8 xorb(2),vorb(2),xrel(3),vrel(3),px(3),qx(3),bs(nmax)
9  REAL*8 ran2
10  DATA eta1,eta2 /2.5,45.0/
11 *
12 *
13  READ (5,*) semi0, ecc0, ratio, range, nskip, idorm, icirc
14  nbin = nbin0
15  nbin1 = nbin + 1
16  WRITE (6,1) nbin, semi0, ecc0, ratio, range, nskip, idorm, icirc
17  1 FORMAT (/,12x,'BINARIES: NBIN =',i5,' A =',f9.6,' E =',f6.2,
18  & ' RATIO =',f4.1,' RANGE =',f6.1,' NSKIP =',i3,
19  & ' IDORM =',i2,' ICIRC =',i2,/)
20 *
21 * Check type of binary mass distribution (NSKIP, IMF2 or split c.m.).
22  IF (nskip.EQ.0.OR.kz(20).GE.2) go to 10
23  IF (ratio.EQ.1.0) go to 20
24 *
25 * Select binaries from the most massive bodies (frequency NSKIP).
26  ilast = (1 + nskip)*nbin
27  jskip = 0
28  js = 0
29  jb = 1
30 *
31 * Transfer binary masses to first NBIN locations.
32  DO 6 i = 2,ilast
33  jskip = jskip + 1
34 * Copy binary mass of body #I to new global location.
35  IF (jskip.GT.nskip) THEN
36  jskip = 0
37  jb = jb + 1
38  body(jb) = body(i)
39  ELSE
40 * Save next NSKIP masses of single bodies.
41  js = js + 1
42  bs(js) = body(i)
43  END IF
44  6 CONTINUE
45 *
46 * Restore the single bodies in subsequent locations.
47  js = 0
48  DO 8 i = nbin1,ilast
49  js = js + 1
50  body(i) = bs(js)
51  8 CONTINUE
52 *
53 * Move main variables of all single bodies.
54  10 DO 15 i = n,nbin1,-1
55  j = i + nbin
56  body(j) = body(i)
57  DO 12 k = 1,3
58  x(k,j) = x(k,i)
59  xdot(k,j) = xdot(k,i)
60  12 CONTINUE
61  15 CONTINUE
62 *
63 * Create space for each binary component next to primary.
64  20 DO 30 i = nbin,2,-1
65  j = 2*i - 1
66  body(j) = body(i)
67  DO 25 k = 1,3
68  x(k,j) = x(k,i)
69  xdot(k,j) = xdot(k,i)
70  25 CONTINUE
71  30 CONTINUE
72 *
73 * Introduce binary components from relative motion.
74  DO 60 i = 1,nbin
75 *
76 * Randomize perihelion, node & inclination (ZI = 0.25 before 3/99).
77  pi = twopi*ran2(idum1)
78  omega = twopi*ran2(idum1)
79  zi = 0.5*twopi*ran2(idum1)
80 *
81 * Set transformation elements (Brouwer & Clemence p. 35).
82  px(1) = cos(pi)*cos(omega) - sin(pi)*sin(omega)*cos(zi)
83  qx(1) =-sin(pi)*cos(omega) - cos(pi)*sin(omega)*cos(zi)
84  px(2) = cos(pi)*sin(omega) + sin(pi)*cos(omega)*cos(zi)
85  qx(2) =-sin(pi)*sin(omega) + cos(pi)*cos(omega)*cos(zi)
86  px(3) = sin(pi)*sin(zi)
87  qx(3) = cos(pi)*sin(zi)
88 *
89 * Specify component masses (copy BODY0 from IMF2 or use RATIO).
90  i1 = 2*i - 1
91  i2 = 2*i
92  IF (kz(20).GE.2) THEN
93  body(i1) = body0(i1)
94  body(i2) = body0(i2)
95  ELSE IF (ratio.EQ.1.0) THEN
96  body(i2) = body(i1)
97  ELSE
98  body(i1) = ratio*body(i1)
99  body(i2) = body(i1)*(1.0 - ratio)/ratio
100  END IF
101 *
102 * Choose random (thermalized; < 0.9 for triples) or fixed eccentricity.
103  IF (ecc0.LT.0.0) THEN
104  ecc2 = ran2(idum1)
105  ecc = sqrt(ecc2)
106  IF (kz(18).GT.1) ecc = min(ecc,0.9d0)
107  ELSE
108  ecc = ecc0
109  END IF
110 *
111 * Generate semi-major axis (new option added 4/8/05, modified 27/7/10).
112  IF (kz(8).EQ.4) THEN
113 * Adopt Pavel Kroupa (1995, Eq.11b) distribution for semi-major axis.
114  exp1 = exp(2.d0*ran2(idum1)/2.5d0) - 1.d0
115  exp1 = sqrt(exp1*45.d0) + 1.d0
116 * Specify period in yrs.
117  exp1 = 10**exp1 /365.25d0
118 * Transform to semi-major axis in model units by Kepler's Law.
119  semi = (body(i1)+body(i2))*zmbar*exp1*exp1
120  semi = semi**(1.d0/3.d0)
121 * Set semi in pc and then in model units.
122  semi = semi/206259.591d0
123  semi = semi/rbar
124 * Select semi-major axis from uniform distribution in log(A) or SEMI0.
125  ELSE IF (range.GT.0.0) THEN
126  exp1 = ran2(idum1)*log10(range)
127  semi = semi0/10.0**exp1
128  ELSE
129  semi = semi0
130  END IF
131 *
132 * Check for eigen-evolution (Pavel Kroupa & Rosemary Mardling).
133  IF (icirc.EQ.1) THEN
134  icoll = 0
135  ic0 = 0
136  ic1 = 0
137  ic2 = 0
138  ic3 = 0
139  zmb = (body(i1) + body(i2))*zmbar
140 * Include minimum period (copy RANGE; at least 1 day).
141  pmin = max(range,1.0d0)
142  it = 0
143  35 xr = ran2(idum1)
144 * Generate period distribution (Pavel Kroupa: MN 277, 1491, eq.11b).
145  p0 = log10(pmin) + sqrt(eta2*(exp(2.0*xr/eta1) - 1.0))
146  tk = 10.0**p0
147 * Invert eccentricity from thermal distribution (XR = E**2).
148  xr = ran2(idum1)
149  es0 = sqrt(xr)
150 * Set pericentre distance in AU with period in days & mass in SU.
151  rp0 = (1.0 - es0)*((tk/365.0)**2*zmb)**0.3333
152 * Convert to N-body units.
153  rp0 = rp0/rau
154  a0 = rp0/(1.0 - es0)
155  e0 = es0
156 * Limit the maximum semi-major axis to 1000 AU (Oct 2004).
157  IF (a0*rau.GT.1000.0) go to 35
158 * Define K* = 0/1 and enhanced radii for pre-main sequence.
159  kstar(i1) = 1
160  kstar(i2) = 1
161  IF (body(i1)*zmbar.LT.0.7) kstar(i1) = 0
162  IF (body(i2)*zmbar.LT.0.7) kstar(i2) = 0
163  radius(i1) = 5.0*sqrt(body(i1)*zmbar)/su
164  radius(i2) = 5.0*sqrt(body(i2)*zmbar)/su
165  IF (rp0.LT.max(radius(i1),radius(i2))) THEN
166  WRITE (6,38) i1, zmb, es0, a0, rp0
167  38 FORMAT (12x,'COLLISION: I1 MB E A RP ',
168  & i6,f6.1,f7.3,1p,2e10.2)
169  icoll = icoll + 1
170  go to 35
171  END IF
172 * Perform eigen-evolution of pericentre & eccentricity for 10^6 yrs.
173  tc = -1.0/tscale
174  CALL tcirc(rp0,es0,i1,i2,icirc,tc)
175 * Copy modified eccentricity and re-evaluate the semi-major axis.
176  ecc = es0
177  semi = rp0/(1.0 - ecc)
178  it = it + 1
179  IF (semi.GT.semi0.AND.it.LT.25) go to 35
180  tk = 365.0*sqrt((semi*rau)**3/zmb)
181  IF (ecc.LE.0.002) ic0 = ic0 + 1
182  IF (tk.LT.pmin) ic1 = ic1 + 1
183  IF (tk.LT.2.0*pmin) ic2 = ic2 + 1
184  IF (tk.LT.5.0*pmin) ic3 = ic3 + 1
185  WRITE (23,40) it, i1, zmb, e0, ecc, a0, semi, tk
186  40 FORMAT (12x,'BINARY: IT I1 MB E0 E A0 A P ',
187  & i2,i5,f5.1,2f7.3,1p,3e10.2)
188  CALL flush(23)
189  ELSE IF (kz(27).EQ.1.OR.kz(19).GE.3) THEN
190 * Obtain tidal encounter distance (4*RADIUS) from square root relation.
191  rsun = 1.0/su
192  zm = max(body(i1),body(i2))*zmbar
193  rt = 4.0*rsun*sqrt(zm)
194  IF (kstar(i1).GT.1.OR.kstar(i2).GT.1) rt = 0.d0
195 * Modify orbital elements to avoid tidal interaction or collision.
196  42 IF (semi*(1.0 - ecc).LT.2.0*rt) THEN
197 * Increase semi-major axis or reduce eccentricity until peri > 2*RT.
198  44 IF (semi.LT.2.0*rt) THEN
199  semi = 2.0*semi
200  go to 44
201  ELSE
202  ecc = 0.9*ecc
203  END IF
204  WRITE (51,46) i1, i2, ecc, semi, semi*(1.0-ecc), rt
205  46 FORMAT (12x,'REDUCE ECC: I1 I2 E A PM RT ',
206  & 2i5,f7.3,1p,3e10.2)
207  CALL flush(51)
208  go to 42
209  END IF
210  END IF
211 *
212 * Evolve ECC and SEMI via circularization and feeding (Kroupa 1995).
213  IF (icirc.EQ.2) THEN
214  CALL proto_star(zmbar,rbar,body(i1),body(i2),ecc,semi)
215  END IF
216 *
217 * Specify relative motion at apocentre.
218  xorb(1) = semi*(1.0 + ecc)
219 * Specify relative motion at apocentre and sum binding energy.
220  xorb(1) = semi*(1.0 + ecc)
221  xorb(2) = 0.0
222  vorb(1) = 0.0
223  zmbin = body(i1) + body(i2)
224  vorb(2) = sqrt(zmbin*(1.0d0 - ecc)/(semi*(1.0d0 + ecc)))
225  ebin0 = ebin0 - 0.5*body(i1)*body(i2)/semi
226 *
227 * Transform to relative variables.
228  DO 50 k = 1,3
229  xrel(k) = px(k)*xorb(1) + qx(k)*xorb(2)
230  vrel(k) = px(k)*vorb(1) + qx(k)*vorb(2)
231  50 CONTINUE
232 *
233 * Set global variables for each component.
234  DO 55 k = 1,3
235  x(k,i1) = x(k,i1) + body(i2)*xrel(k)/zmbin
236  x(k,i2) = x(k,i1) - xrel(k)
237  xdot(k,i1) = xdot(k,i1) + body(i2)*vrel(k)/zmbin
238  xdot(k,i2) = xdot(k,i1) - vrel(k)
239  55 CONTINUE
240  60 CONTINUE
241 *
242 * Update the total particle number after primary splitting or IMF2.
243  IF (ratio.LT.1.0.OR.kz(20).GE.2) THEN
244  n = n + nbin
245  nzero = n
246  ntot = n
247  bodym = zmass/float(n)
248  IF (nskip.GT.0) THEN
249  WRITE (6,62) (body(j),j=1,10)
250  WRITE (6,64) (body(j),j=2*nbin+1,2*nbin+10)
251  62 FORMAT (/,12x,'BINARY MASSES (1-10): ',10f9.5)
252  64 FORMAT (/,12x,'SINGLE MASSES (1-10): ',10f9.5,/)
253  END IF
254  END IF
255 *
256 * Include procedure for introducing dormant binaries.
257  IF (idorm.GT.0) THEN
258  DO 66 i = 1,nbin
259  i1 = 2*i - 1
260  i2 = i1 + 1
261  zmbin = body(i1) + body(i2)
262  DO 65 k = 1,3
263  x(k,i) = (body(i1)*x(k,i1) + body(i2)*x(k,i2))/zmbin
264  xdot(k,i) = (body(i1)*xdot(k,i1) +
265  & body(i2)*xdot(k,i2))/zmbin
266  65 CONTINUE
267  body(i) = zmbin
268  66 CONTINUE
269 *
270 * Move the original single particles up to form compact array.
271  i1 = 2*nbin + 1
272  i2 = nbin
273  DO 68 i = i1,n
274  i2 = i2 + 1
275  body(i2) = body(i)
276  DO 67 k = 1,3
277  x(k,i2) = x(k,i)
278  xdot(k,i2) = xdot(k,i)
279  67 CONTINUE
280  68 CONTINUE
281 *
282 * Reset particle membership and turn off binary output option (if = 1).
283  n = n - nbin
284  nzero = n
285  ntot = n
286  nbin0 = 0
287  ebin0 = 0.0
288  IF (kz(8).EQ.1) kz(8) = 0
289  END IF
290 *
291 * Set coordinates & velocities in c.m. rest frame.
292  DO 70 k = 1,3
293  cmr(k) = 0.0d0
294  cmrdot(k) = 0.0d0
295  70 CONTINUE
296 *
297  DO 80 i = 1,n
298  DO 75 k = 1,3
299  cmr(k) = cmr(k) + body(i)*x(k,i)
300  cmrdot(k) = cmrdot(k) + body(i)*xdot(k,i)
301  75 CONTINUE
302  80 CONTINUE
303 *
304  DO 90 i = 1,n
305  DO 85 k = 1,3
306  x(k,i) = x(k,i) - cmr(k)/zmass
307  xdot(k,i) = xdot(k,i) - cmrdot(k)/zmass
308  85 CONTINUE
309  90 CONTINUE
310 *
311  RETURN
312 *
313  END