void listdisk(int nlist) { int i; real r, phi, vcir, omega, Adisk, kappa, sigma1, sigma2, mu_eff, sig_r, sig_p, sig_z, vrad, vorb2, vorb; printf("#%5s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s\n", "r", "vcir", "omega", "kappa", "sig_z", "sig_r", "sig_p", "vorb", "Q", "rhomid", "fmax"); for (i = 1; i <= nlist; i++) { /* loop over radii */ r = (i * rcut) / ((real) nlist); vcir = seval(r, &rdtab[0], &vctab[0], &vctab[NTAB], NTAB); omega = vcir / r; Adisk = (omega - spldif(r, &rdtab[0], &vctab[0], &vctab[NTAB], NTAB)) / 2; if (omega - Adisk < 0.0) error("%s: kappa undefined (omega - Adisk < 0)\n" " r, omega, Adisk = %f %f %f\n", getargv0(), r, omega, Adisk); kappa = 2 * rsqrt(rsqr(omega) - Adisk * omega); sigma1 = rsqr(alpha1) * mdisk1 * rexp(- alpha1 * r) / TWO_PI; sigma2 = rsqr(alpha2) * mdisk2 * rexp(- alpha2 * r) / TWO_PI; mu_eff = (r_mu>0 ? 1 + (mu - 1) * (r / (r + r_mu)) : mu); sig_z = rsqrt(PI * (sigma1 + sigma2) * zdisk); sig_r = mu_eff * sig_z; sig_p = (0.5 * kappa / omega) * sig_r; vorb2 = rsqr(vcir) + rsqr(sig_r) * (1 - 2 * alpha1 * r) - rsqr(sig_p) + (r_mu>0 ? rsqr(sig_z) * r * mu_eff*(2*mu-2)*r_mu/rsqr(r+r_mu) : 0); vorb = rsqrt(MAX(vorb2, 0.0)); printf("%6.4f %6.4f %6.2f %6.2f %6.4f %6.4f %6.4f %6.4f " "%6.3f %6.1f %6.1f\n", r, vcir, omega, kappa, sig_z, sig_r, sig_p, vorb, kappa * sig_r / (3.358*(sigma1+sigma2)), sigma1/(2*zdisk), sigma1 / (2*zdisk * rsqrt(rqbe(2*PI)) * sig_z*sig_r*sig_p)); } }
real drho_gsp(gsprof *gsp, real r) { int n = gsp->npoint - 1; if (r < 0) error("%s.drho_gsp: undefined for r = %g\n", getargv0(), r); if (r < gsp->radius[0]) return (gsp->density[0] * rpow(r / gsp->radius[0], gsp->alpha) * gsp->alpha / r); else if (r > gsp->radius[n]) /* less glitches at large r */ return (gsp->density[n] * rpow(r / gsp->radius[n], gsp->beta) * gsp->beta / r); if (gsp->dr_coef == NULL) { gsp->dr_coef = (real *) allocate(3 * (n + 1) * sizeof(real)); spline(gsp->dr_coef, gsp->radius, gsp->density, n + 1); } return (spldif(r, gsp->radius, gsp->density, gsp->dr_coef, n + 1)); }
void makedisk(void) { real m, r, phi, vcir, omega, Adisk, kappa, sigma1, sigma2, mu_eff, sig_r, sig_p, sig_z, vrad, vorb2, vorb, vphi; double Trr = 0.0, Tpp = 0.0, Tzz = 0.0; int i; bodyptr dp; for (i = 0; i < ndisk; i++) { /* loop initializing bodies */ m = mdtab[NTAB-1] * ((real) i + 0.5) / ndisk; r = seval(m, &mdtab[0], &rdtab[0], &rdtab[NTAB], NTAB); vcir = seval(r, &rdtab[0], &vctab[0], &vctab[NTAB], NTAB); omega = vcir / r; Adisk = (omega - spldif(r, &rdtab[0], &vctab[0], &vctab[NTAB], NTAB)) / 2; if (omega - Adisk < 0.0) error("%s: kappa undefined (omega - Adisk < 0)\n" " r, omega, Adisk = %f %f %f\n", getargv0(), r, omega, Adisk); kappa = 2 * rsqrt(rsqr(omega) - Adisk * omega); sigma1 = rsqr(alpha1) * mdisk1 * rexp(- alpha1 * r) / TWO_PI; sigma2 = rsqr(alpha2) * mdisk2 * rexp(- alpha2 * r) / TWO_PI; mu_eff = (r_mu>0 ? 1 + (mu - 1) * (r / (r + r_mu)) : mu); sig_z = rsqrt(PI * (sigma1 + sigma2) * zdisk); sig_r = mu_eff * sig_z; sig_p = (0.5 * kappa / omega) * sig_r; vorb2 = rsqr(vcir) + rsqr(sig_r) * (1 - 2 * alpha1 * r) - rsqr(sig_p) + (r_mu>0 ? rsqr(sig_z) * r * mu_eff*(2*mu-2)*r_mu/rsqr(r+r_mu) : 0); vorb = rsqrt(MAX(vorb2, 0.0)); dp = NthBody(disk, i); /* set up ptr to disk body */ Mass(dp) = mdisk1 / ndisk; phi = xrandom(0.0, TWO_PI); Pos(dp)[0] = r * rsin(phi); Pos(dp)[1] = r * rcos(phi); Pos(dp)[2] = zdisk * ratanh(xrandom(-1.0, 1.0)); vrad = (eta > 0 ? pickdist(eta, sig_r) : grandom(0.0, sig_r)); vphi = (eta > 0 ? pickdist(eta, sig_p) : grandom(0.0, sig_p)) + vorb; Vel(dp)[0] = vrad * rsin(phi) + vphi * rcos(phi); Vel(dp)[1] = vrad * rcos(phi) - vphi * rsin(phi); Vel(dp)[2] = grandom(0.0, sig_z); Trr += Mass(dp) * rsqr(sig_r) / 2; Tpp += Mass(dp) * (rsqr(vorb) + rsqr(sig_p)) / 2; Tzz += Mass(dp) * rsqr(sig_z) / 2; } eprintf("[%s: Trr = %f Tpp = %f Tzz = %f]\n", getargv0(), Trr, Tpp, Tzz); }
void lindblad(int nrad, real *rad, real *vel, real *ome, real *kap, real *opk, real *omk, int n) { int i, nbad=0; real fac; fac = 1.0/(real)n; for (i=0; i<nrad; i++) { /* get ome */ if (rad[i]==0.0) continue; ome[i] = vel[i]/rad[i]; if (i>0 && rad[i] <= rad[i-1]) error("lindblad: Need sorted data for spline fit"); } for (i=0; i<nrad; i++) { /* fix up when rad=0 && set ome^2 */ if (rad[i]==0.0) if (i==0) ome[0] = ome[1]; else error("Cannot handle zero radius here"); else ome[i] = sqr(ome[i]); } spline (&ome[nrad], rad, ome, nrad); /* spline through ome^2 */ for (i=0; i<nrad; i++) { kap[i] = rad[i] * spldif(rad[i],rad,ome,&ome[nrad],nrad) + 4*ome[i]; if (kap[i] < 0) { nbad++; dprintf(1,"r=%f v=%f kappa^2 = %f\n",rad[i],vel[i],kap[i]); kap[i] = -sqrt(-kap[i]); } kap[i] = sqrt(kap[i]); } for (i=0; i<nrad; i++) { ome[i] = sqrt(ome[i]); opk[i] = ome[i] + fac * kap[i]; omk[i] = ome[i] - fac * kap[i]; } if (nbad>0) warning("There were %d radii with badly formed kappa",nbad); }
gsprof *snapgsp(bodyptr btab, int nbody, int npoint, real alpha, real beta) { gsprof *gsp; real *rtab, *dtab, *mtab, *coef, mtot; int nsamp, i, j; if (nbody % npoint != 0) error("%s: npoint must divide nbody\n", getargv0()); gsp = (gsprof *) allocate(sizeof(gsprof)); rtab = (real *) allocate(npoint * sizeof(real)); dtab = (real *) allocate(npoint * sizeof(real)); mtab = (real *) allocate(npoint * sizeof(real)); coef = (real *) allocate(3 * npoint * sizeof(real)); qsort(btab, nbody, SizeofBody, radrank); nsamp = nbody / npoint; mtot = 0.0; j = 0; for (i = 0; i < nbody; i++) { mtot += Mass(NthBody(btab, i)); if (i % nsamp == nsamp - 1) { rtab[j] = absv(Pos(NthBody(btab, i))); mtab[j] = mtot; j++; } } spline(coef, rtab, mtab, npoint); for (j = 0; j < npoint; j++) dtab[j] = spldif(rtab[j], rtab, mtab, coef, npoint) / (FOUR_PI * rsqr(rtab[j])); gsp->npoint = npoint; gsp->radius = rtab; gsp->density = dtab; gsp->alpha = alpha; gsp->beta = beta; gsp->mass = mtab; gsp->mtot = mtot; return (gsp); }
local void makedisk() { Body *bp; int i, nzero=0; real mdsk_i, rad_i, theta_i, vcir_i, omega, Aoort, kappa; real mu, sig_r, sig_t, sig_z, vrad_i, veff_i, vorb_i; real z1; static bool first = TRUE; disktab = (Body *) allocate(ndisk * sizeof(Body)); for (bp = disktab, i = 0; i < ndisk; bp++, i++) { Mass(bp) = mdsk[NTAB-1] / ndisk; mdsk_i = mdsk[NTAB-1] * ((real) i + 1.0) / ndisk; rad_i = seval(mdsk_i, &mdsk[0], &rdsk[0], &rdsk[NTAB], NTAB); theta_i = xrandom(0.0, TWO_PI); Pos(bp)[0] = rad_i * sin(theta_i); /* assign positions */ Pos(bp)[1] = rad_i * cos(theta_i); if (zmode==0) Pos(bp)[2] = grandom(0.0, 0.5 * z0); /* gauss */ else if (zmode==1) { z1 = xrandom(-1.0,1.0); Pos(bp)[2] = log(1-ABS(z1)) * z0; /* exp */ if (z1<0) Pos(bp)[2] = -Pos(bp)[2]; } else if (zmode==2) { z1 = frandom(0.0,10.0,mysech2) * z0; /* sech^2 */ if (xrandom(-1.0,1.0) < 0) z1 = -z1; Pos(bp)[2] = z1; } else if (zmode==3) { z1 = frandom(0.0,10.0,myexp) * z0; /* exp */ if (xrandom(-1.0,1.0) < 0) z1 = -z1; Pos(bp)[2] = z1; } else error("zmode=%d not supported yet",zmode); vcir_i = seval(rad_i, &rcir[0], &vcir[0], &vcir[NTAB], NTAB); omega = vcir_i / rad_i; Aoort = - 0.5 * (spldif(rad_i, &rcir[0], &vcir[0], &vcir[NTAB], NTAB) - omega); if (omega - Aoort < 0.0) printf("rad_i, omega, Aoort = %f %f %f\n", rad_i, omega, Aoort); kappa = 2 * sqrt(omega*omega - Aoort * omega); mu = alpha*alpha * mdisk * exp(- alpha * rad_i) / TWO_PI; if (cmode==1) { /* Straight from Josh - mkbaredisk*/ sig_r = 3.358 * Qtoomre * mu / kappa; sig_t = 0.5 * sig_r * kappa / omega; sig_z = 0.5 * sig_r; } else if (cmode==2) { sig_z = sqrt(PI * mu * z0); /* isothermal sech sheet */ sig_r = 2.0 * sig_z; /* with constant scaleheight */ Qtoomre = sig_r * kappa / (3.358 * mu); /* See vdKruit/Searle */ sig_t = 0.5 * sig_r * kappa / omega; } else error("illegal mode=%d",cmode); vrad_i = grandom(0.0, sig_r); if (gammas > 0.0) /* Josh' method: averaged */ veff_i = (vcir_i*vcir_i + (gammas - 3*alpha*rad_i) * sig_r*sig_r); else /* a little more accurate ? */ veff_i = sqr(vcir_i) - sqr(sig_r) * (sqr(sig_t/sig_r) - 1.5 + 0.5*sqr(sig_z/sig_r) + 2*alpha*rad_i); if (veff_i < 0.0) { nzero++; veff_i = 0.0; } else veff_i = sqrt(veff_i); vorb_i = veff_i + grandom(0.0, sig_t); Vel(bp)[0] = /* assign velocities */ (vrad_i * Pos(bp)[0] + vorb_i * Pos(bp)[1]) / rad_i; Vel(bp)[1] = (vrad_i * Pos(bp)[1] - vorb_i * Pos(bp)[0]) / rad_i; Vel(bp)[2] = grandom(0.0, sig_z); if (Qtab) { if (first) { first = FALSE; printf ("# R M V_circ Ome Kap Aoort mu sig_r sig_t sig_z v_eff Qtoomre sig_t/sig_r sig_z/sig_r fac\n"); } printf ("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g\n", rad_i,mdsk_i,vcir_i,omega,kappa,Aoort,mu,sig_r,sig_t,sig_z,veff_i, Qtoomre, sig_t/sig_r,sig_z/sig_r, 1.5-(sqr(sig_t) + 0.5*sqr(sig_z))/sqr(sig_r) ); } } if (nzero) dprintf(0,"Warning: %d stars with too little orbital motion\n",nzero); if (getbparam("zerocm")) centersnap(disktab, ndisk); }