int nemo_main() { int i, n, nbody, bits, ndata, count, ngrid[3]; real scale, dt, dtout, dtlog, tstop, tsnap, mass; string exefile = getparam("exe"); string rundir = getparam("outdir"); string fmt = getparam("format"); stream datstr, instr, outstr; char dname[256]; char command[256]; char fmt6[256]; float *gdata, *gd; Body *bp, *btab = NULL; if (hasvalue("header")) unfsize(getiparam("header")); n = nemoinpi(getparam("grid"),ngrid,3); if (n>0 && n<=3) { for (i=n; i<3; i++) ngrid[i] = ngrid[i-1]; } else error("%d Syntax error: %s (need 1,2 or 3 integers)", n,getparam("grid")); scale = getdparam("scale"); dt = getdparam("dt"); dtout = getdparam("dtout"); dtlog = getdparam("dtlog"); tstop = getdparam("tstop"); sprintf(fmt6,"%s %s %s %s %s %s\n",fmt,fmt,fmt,fmt,fmt,fmt); make_rundir(rundir); /* prepare the parameter file for galaxy */ sprintf(dname,"%s/%s",rundir,"galaxy.dat"); datstr = stropen(dname,"w"); fprintf(datstr,"%d %d %d\n",ngrid[0],ngrid[1],ngrid[2]); fprintf(datstr,"%g\n",scale); fprintf(datstr,"%g\n",dt); fprintf(datstr,"%g\n",dtout); fprintf(datstr,"%g\n",dtlog); fprintf(datstr,"%g\n",tstop); strclose(datstr); /* read snapshot and output it in something galaxy understands */ instr = stropen(getparam("in"),"r"); get_history(instr); if (!get_tag_ok(instr, SnapShotTag)) error("no snapshot"); get_snap(instr, &btab, &nbody, &tsnap, &bits); strclose(instr); if ( (bits & PhaseSpaceBit) == 0) error("no phasespace"); for (bp=btab;bp<btab+nbody; bp++) mass += Mass(bp); sprintf(dname,"%s/%s",rundir,"galaxy.ini"); datstr = stropen(dname,"w"); fprintf(datstr,"%g %g %d\n",tsnap,mass,nbody); for (bp=btab;bp<btab+nbody; bp++) fprintf(datstr,fmt6, Pos(bp)[0],Pos(bp)[1],Pos(bp)[2], Vel(bp)[0],Vel(bp)[1],Vel(bp)[2]); strclose(datstr); /* run the fortran program */ goto_rundir(rundir); if (run_program(exefile)) error("Problem executing %s",exefile); /* Output data from native galaxy (.res) format to snapshot */ sprintf(dname,"%s","galaxy.res"); instr = stropen(dname,"r"); sprintf(dname,"%s","galaxy.snap"); outstr = stropen(dname,"w"); put_history(outstr); ndata = 7*sizeof(float)*nbody; gdata = (float *) allocate(ndata); bits = (TimeBit | PhaseSpaceBit | PotentialBit); while (1) { count = unfread(instr,gdata,ndata); if (count <= 0) break; printf("Time=%g\n",gdata[0]); tsnap = gdata[0]; count = unfread(instr,gdata,ndata); if (count <= 0) error("Problem reading posvelphi from galaxy.res"); for (bp=btab, gd=gdata;bp<btab+nbody; bp++) { Pos(bp)[0] = *gd++; Pos(bp)[1] = *gd++; Pos(bp)[2] = *gd++; Vel(bp)[0] = *gd++; Vel(bp)[1] = *gd++; Vel(bp)[2] = *gd++; Phi(bp) = *gd++; } put_snap(outstr, &btab, &nbody, &tsnap, &bits); } }
void Main::inputdata () { std::ifstream instr; char headbuf[128]; int ndim,counter=0; bodyptr p; int i; fprintf(stdout,"reading input file : %s\n",infile.c_str()); fflush(stdout); //instr = fopen(infile, "r"); instr.open(infile.c_str()); /* if (instr == NULL) error("inputdata: cannot find file %s\n", infile); */ //in_int(instr, &nbody); instr >> nbody; if (nbody < 1){ CkPrintf("inputdata: nbody = %d is absurd\n", nbody); CkAbort(""); } //in_int(instr, &ndim); instr >> ndim; if (ndim != NDIM){ CkPrintf("inputdata: NDIM = %d ndim = %d is absurd\n", NDIM,ndim); CkAbort(""); } //in_real(instr, &tnow); instr >> tnow; CkPrintf("read tnow: %f\n", tnow); /* for (i = 0; i < MAX_PROC; i++) { Local[i].tnow = tnow; } */ bodytab = new body [nbody]; //bodytab = (bodyptr) malloc(nbody * sizeof(body)); //bodytab = (bodyptr) our_malloc(nbody * sizeof(body),__FILE__,__LINE__); if (bodytab == NULL){ CkPrintf("inputdata: not enuf memory\n"); CkAbort(""); } for (p = bodytab; p < bodytab+nbody; p++) { Type(p) = BODY; Cost(p) = 1; Phi(p) = 0.0; CLRV(Acc(p)); } #ifdef OUTPUT_ACC int seq = 0; #endif for (p = bodytab; p < bodytab+nbody; p++){ instr >> Mass(p); #ifdef OUTPUT_ACC p->num = seq; seq++; #endif } for (p = bodytab; p < bodytab+nbody; p++){ instr >> Pos(p)[0]; instr >> Pos(p)[1]; instr >> Pos(p)[2]; } for (p = bodytab; p < bodytab+nbody; p++){ instr >> Vel(p)[0]; instr >> Vel(p)[1]; instr >> Vel(p)[2]; } instr.close(); }
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); }
void nemo_main() { stream instr, outstr; real mscale, pscale, xscale, tsnap, escale, dscale; vector rscale, vscale, ascale; string times; int i, nbody, bits, nrscale, nvscale, nascale, kscale; Body *btab = NULL, *bp; bool Qmass, Qphase, Qacc, Qpot, Qkey, Qaux, Qeps, Qdens; nrscale = nemoinpr(getparam("rscale"),rscale,NDIM); /* RSCALE */ if (nrscale==1) for (i=1; i<NDIM; i++) rscale[i] = rscale[0]; else if (nrscale!=NDIM) error("keyword rscale needs either 1 or %d numbers", NDIM); nvscale = nemoinpr(getparam("vscale"),vscale,NDIM); /* VSCALE */ if (nvscale==1) for (i=1; i<NDIM; i++) vscale[i] = vscale[0]; else if (nvscale!=NDIM) error("keyword vscale needs either 1 or %d numbers", NDIM); nascale = nemoinpr(getparam("ascale"),ascale,NDIM); /* ASCALE */ if (nascale==1) for (i=1; i<NDIM; i++) ascale[i] = ascale[0]; else if (nascale!=NDIM) error("keyword ascale needs either 1 or %d numbers", NDIM); mscale = getdparam("mscale"); pscale = getdparam("pscale"); xscale = getdparam("xscale"); dscale = getdparam("dscale"); escale = getdparam("escale"); kscale = getiparam("kscale"); times = getparam("times"); instr = stropen(getparam("in"), "r"); /* open files */ outstr = stropen(getparam("out"), "w"); get_history(instr); put_history(outstr); for (;;) { get_history(instr); /* skip over stuff we can forget */ if (!get_tag_ok(instr, SnapShotTag)) break; /* done with work in loop */ get_snap(instr, &btab, &nbody, &tsnap, &bits); if ((bits & MassBit) == 0 && (bits & PhaseSpaceBit) == 0) { continue; /* just skip it's probably a diagnostics */ } if ((bits & TimeBit) == 0) tsnap = 0.0; else if (!streq(times,"all") && !within(tsnap, times, TIMEFUZZ)) continue; dprintf (1,"Scaling snapshot at time= %f bits=0x%x\n",tsnap,bits); Qmass = MassBit & bits && !uscalar(mscale); Qphase = PhaseSpaceBit & bits &&(!uvector(rscale) || !uvector(vscale)); Qacc = AccelerationBit & bits&& !uvector(ascale); Qpot = PotentialBit & bits && !uscalar(pscale); Qaux = AuxBit & bits && !uscalar(xscale); Qkey = KeyBit & bits && (kscale!=1); Qdens = DensBit & bits && !uscalar(dscale); Qeps = EpsBit & bits && !uscalar(escale); dprintf(1,"Scaling: "); if (Qmass) dprintf(1," mass"); if (Qphase) dprintf(1," phase"); if (Qacc) dprintf(1," acc"); if (Qpot) dprintf(1," pot"); if (Qaux) dprintf(1," aux"); if (Qkey) dprintf(1," key"); if (Qdens) dprintf(1," dens"); if (Qeps) dprintf(1," eps"); dprintf(1,"\n"); if (Qmass || Qphase || Qacc || Qpot || Qaux || Qkey || Qdens || Qeps) { for (bp = btab; bp < btab+nbody; bp++) { if(Qmass) Mass(bp) *= mscale; if(Qphase) { SMULVV(Pos(bp),rscale); SMULVV(Vel(bp),vscale); } if(Qpot) Phi(bp) *= pscale; if(Qacc) { SMULVV(Acc(bp),ascale); } if(Qaux) Aux(bp) *= xscale; if(Qkey) Key(bp) *= kscale; if(Qdens) Dens(bp) *= dscale; if(Qeps) Eps(bp) *= escale; } } else { warning("No scaling applied to snapshot"); } put_snap(outstr, &btab, &nbody, &tsnap, &bits); } }
/* * nbodyGravity: Walk the tree starting at the root to do force * calculations. * * * Random notes: * - Not inlined without inline from multiple calls in * mapForceBody(). Measurably better with the inline, but only * slightly. */ static inline mwvector nbGravity(const NBodyCtx* ctx, NBodyState* st, const Body* p) { mwbool skipSelf = FALSE; mwvector pos0 = Pos(p); mwvector acc0 = ZERO_VECTOR; const NBodyNode* q = (const NBodyNode*) st->tree.root; /* Start at the root */ while (q != NULL) /* while not at end of scan */ { mwvector dr = mw_subv(Pos(q), pos0); /* Then compute distance */ real drSq = mw_sqrv(dr); /* and distance squared */ if (isBody(q) || (drSq >= Rcrit2(q))) /* If is a body or far enough away to approximate */ { if (mw_likely((const Body*) q != p)) /* self-interaction? */ { real drab, phii, mor3; /* Compute gravity */ drSq += ctx->eps2; /* use standard softening */ drab = mw_sqrt(drSq); phii = Mass(q) / drab; mor3 = phii / drSq; acc0.x += mor3 * dr.x; acc0.y += mor3 * dr.y; acc0.z += mor3 * dr.z; if (ctx->useQuad && isCell(q)) /* if cell, add quad term */ { real dr5inv, drQdr, phiQ; mwvector Qdr; /* form Q * dr */ Qdr.x = Quad(q).xx * dr.x + Quad(q).xy * dr.y + Quad(q).xz * dr.z; Qdr.y = Quad(q).xy * dr.x + Quad(q).yy * dr.y + Quad(q).yz * dr.z; Qdr.z = Quad(q).xz * dr.x + Quad(q).yz * dr.y + Quad(q).zz * dr.z; /* form dr * Q * dr */ drQdr = Qdr.x * dr.x + Qdr.y * dr.y + Qdr.z * dr.z; dr5inv = 1.0 / (sqr(drSq) * drab); /* form dr^-5 */ /* get quad. part of phi */ phiQ = 2.5 * (dr5inv * drQdr) / drSq; acc0.x += phiQ * dr.x; acc0.y += phiQ * dr.y; acc0.z += phiQ * dr.z; /* acceleration */ acc0.x -= dr5inv * Qdr.x; acc0.y -= dr5inv * Qdr.y; acc0.z -= dr5inv * Qdr.z; } } else { skipSelf = TRUE; /* Encountered self */ } q = Next(q); /* Follow next link */ } else { q = More(q); /* Follow to the next level if need to go deeper */ } } if (!skipSelf) { /* If a body does not encounter itself in its traversal of the * tree, it is "tree incest" */ nbReportTreeIncest(ctx, st); } return acc0; }