void polymodel(void) { gsl_interp_accel *pmsplacc = gsl_interp_accel_alloc(); bodyptr p; real rad, phi, vel, psi, vr, vp, a, E, J; vector rhat, vtmp, vper; for (p = btab; p < NthBody(btab, nbody); p = NextBody(p)) { rad = rad_m(xrandom(0.0, mtot)); phi = gsl_spline_eval(pmspline, (double) rad, pmsplacc); vel = pick_v(phi); psi = pick_psi(); vr = vel * rcos(psi); vp = vel * rsin(psi); Mass(p) = mtot / nbody; pickshell(rhat, NDIM, 1.0); MULVS(Pos(p), rhat, rad); pickshell(vtmp, NDIM, 1.0); a = dotvp(vtmp, rhat); MULVS(vper, rhat, - a); ADDV(vper, vper, vtmp); a = absv(vper); MULVS(vper, vper, vp / a); MULVS(Vel(p), rhat, vr); ADDV(Vel(p), Vel(p), vper); Phi(p) = phi; E = phi + 0.5 * rsqr(vel); J = rad * ABS(vp); Aux(p) = Kprime * rpow(phi1 - E, npol - 1.5) * rpow(J, 2 * mpol); } gsl_interp_accel_free(pmsplacc); }
local void testdata(void) { real rsc, vsc, r, v, x, y; bodyptr p; float scale = 1.0f; float vscale = 1.0f; float mscale = 1.0f; if (nbody < 1) // check for silly values error("%s: absurd value for nbody\n", getargv0()); bodytab = (bodyptr) allocate(nbody * sizeof(body)); // alloc space for bodies rsc = (3 * PI) / 16; // set length scale factor vsc = rsqrt(1.0 / rsc); // find speed scale factor for (p = bodytab; p < bodytab+nbody; p++) { // loop over particles Type(p) = BODY; // tag as a body //Mass(p) = 1.0 / nbody; // set masses equal // Set mass randomly, like in brute Mass(p) = (rand() / (float) RAND_MAX) * mscale; x = xrandom(0.0, MFRAC); // pick enclosed mass r = 1.0 / rsqrt(rpow(x, -2.0/3.0) - 1); // find enclosing radius pickshell(Pos(p), NDIM, rsc * r); // pick position vector do { // select from fn g(x) x = xrandom(0.0, 1.0); // for x in range 0:1 y = xrandom(0.0, 0.1); // max of g(x) is 0.092 } while (y > x*x * rpow(1 - x*x, 3.5)); // using von Neumann tech v = x * rsqrt(2.0 / rsqrt(1 + r*r)); // find resulting speed pickshell(Vel(p), NDIM, vsc * v); // pick velocity vector } tnow = 0.0; // set elapsed model time }
void picktriad(vector x, vector y, vector z) { real a; pickshell(x, NDIM, 1.0); pickshell(z, NDIM, 1.0); CROSSVP(y, x, z); a = absv(y); DIVVS(y, y, a); CROSSVP(z, x, y); }
void makedisk(bool randspin) { int i; bodyptr bp; double m, r, v, phi; matrix xmat, zmat; vector tmpv; for (i = 0; i < ndisk; i++) { // loop initializing bodies bp = NthBody(disk, i); // set ptr to body number i m = mdtab[NTAB-1] * ((double) i + 0.5) / ndisk; r = gsl_interp_eval(rm_spline, mdtab, rdtab, m, NULL); v = gsl_interp_eval(vr_spline, rdtab, vctab, r, NULL); phi = xrandom(0.0, 2 * M_PI); Pos(bp)[0] = r * sin(phi); Pos(bp)[1] = r * cos(phi); Pos(bp)[2] = 0.0; Vel(bp)[0] = v * cos(phi); Vel(bp)[1] = - v * sin(phi); Vel(bp)[2] = 0.0; pickshell(AuxVec(bp), NDIM, 1.0); if (randspin) { xmatrix(xmat, acos(AuxVec(bp)[2])); zmatrix(zmat, atan2(AuxVec(bp)[0], AuxVec(bp)[1])); MULMV(tmpv, xmat, Pos(bp)); MULMV(Pos(bp), zmat, tmpv); MULMV(tmpv, xmat, Vel(bp)); MULMV(Vel(bp), zmat, tmpv); } } }
void gspsphere(void) { real gamma0, mcut, r, sig2, eint = 0.0; static real *sig2tab = NULL; bodyptr bp; nbody = getiparam("nbody"); assert(nbody > 0); gamma0 = getdparam("gamma"); mcut = getdparam("mcut"); assert(0.0 < mcut && mcut <= 1.0); if (sig2tab == NULL) sig2tab = calc_sig2_gsp(gsp, ggsp, 0.0); if (btab == NULL) btab = (bodyptr) allocate(nbody * SizeofBody); for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) { Mass(bp) = gsp->mtot / nbody; r = r_mass_gsp(gsp, xrandom(0.0, mcut * gsp->mtot)); pickshell(Pos(bp), NDIM, r); CLRV(Vel(bp)); Rho(bp) = rho_gsp(gsp, r); sig2 = sig2_gsp(gsp, ggsp, 0.0, sig2tab, r); EntFunc(bp) = sig2 / rpow(Rho(bp), gamma0 - 1); Uintern(bp) = sig2 / (gamma0 - 1); eint += Mass(bp) * Uintern(bp); } eprintf("[%s: thermal energy = %f]\n", getargv0(), eint); }
void pickvec(vector x, bool cf) { dprintf(1,"pickvec: cf = %d\t", cf); if (cf) /* cent. concentrated? */ pickshell(x, NDIM, xrandom(0.0, 1.0)); /* pick from M(r) = r */ else pickball(x, NDIM, 1.0); /* use uniform distr. */ dprintf(1,"x = [%8.4f,%8.4f,%8.4f]\n", x[0], x[1], x[2]); }
void plummodel(real mfrac) { real rsc, vsc, r, v, x, y; bodyptr p; if (mfrac < 0 || mfrac > 1) // check for silly values error("%s: absurd value for mfrac\n", getprog()); rsc = (3 * PI) / 16; // set length scale factor vsc = rsqrt(1.0 / rsc); // and speed scale factor for (p = btab; p < NthBody(btab,nbody); p = NextBody(p)) { // loop over particles Mass(p) = 1.0 / nbody; // set masses equal x = xrandom(0.0, mfrac); // pick enclosed mass r = 1.0 / rsqrt(rpow(x, -2.0/3.0) - 1); // find enclosing radius pickshell(Pos(p), NDIM, rsc * r); // pick position vector do { // use von Neumann rejection x = xrandom(0.0, 1.0); // for x in range 0:1 y = xrandom(0.0, 0.1); // max of g(x) is 0.092 } while (y > x*x * rpow(1 - x*x, 3.5)); // select from g(x) v = x * rsqrt(2.0 / rsqrt(1 + r*r)); // find resulting speed pickshell(Vel(p), NDIM, vsc * v); // pick velocity vector Phi(p) = -1.0 / (rsc * rsqrt(rsqr(r) + 1)); // compute model potential } }
void polymodel1(void) { bodyptr p; real r, x, v; for (p = btab; p < NthBody(btab, nbody); p = NextBody(p)) { Mass(p) = 1.0 / nbody; r = xrandom(0.0, 2.0); pickshell(Pos(p), 3, r); x = SQRT2 * rcos(PI * (2.0 - xrandom(0.0, 1.0)) / 4.0); v = (xrandom(-1.0, 1.0) < 0.0 ? -1.0 : 1.0) * (1 - x*x) * rsqrt(rlog(2 / r)); MULVS(Vel(p), Pos(p), v/r); Phi(p) = 0.5 * rlog(r / 2.0) - 0.5; } bodyfields[4] = NULL; // don't output Aux data }