EXTERN_ENV #define global extern #include "stdinc.h" /* * HACKGRAV: evaluate grav field at a given particle. */ void hackgrav(bodyptr p, long ProcessId) { Local[ProcessId].pskip = p; SETV(Local[ProcessId].pos0, Pos(p)); Local[ProcessId].phi0 = 0.0; CLRV(Local[ProcessId].acc0); Local[ProcessId].myn2bterm = 0; Local[ProcessId].mynbcterm = 0; Local[ProcessId].skipself = FALSE; hackwalk(ProcessId); Phi(p) = Local[ProcessId].phi0; SETV(Acc(p), Local[ProcessId].acc0); #ifdef QUADPOLE Cost(p) = Local[ProcessId].myn2bterm + NDIM * Local[ProcessId].mynbcterm; #else Cost(p) = Local[ProcessId].myn2bterm + Local[ProcessId].mynbcterm; #endif }
nemo_main() { stream instr, quadstr, outstr; Body *btab = NULL, *bp; int nbody, bits; real eps_r, eps_t, tsnap = 0.0; if (!hasvalue("out")) warning("No output supplied (out=)"); quadstr = stropen(getparam("quad"), "r"); get_history(quadstr); instr = stropen(getparam("in"), "r"); get_history(instr); get_quadfield(quadstr, &eps_r, &eps_t); get_snap(instr, &btab, &nbody, &tsnap, &bits); if (bits & PhaseSpaceBit == 0) error("not enuf info: bits = %o", bits); for (bp = btab; bp < btab+nbody; bp++) { CLRV(Acc(bp)); Phi(bp) = 0.0; } quadinter(btab, nbody, eps_r, eps_t); if (hasvalue("out")) { outstr = stropen(getparam("out"), "w"); put_history(outstr); bits = bits | PotentialBit | AccelerationBit; put_snap(outstr, &btab, &nbody, &tsnap, &bits); } }
local void sumforces(bodyptr btab, int nbody, bodyptr gtab, int ngrav, real eps2) { bodyptr bp, gp; double phi0, acc0[NDIM]; vector pos0, dr; real dr2, dr2i, dr1i, mdr1i, mdr3i; for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) { phi0 = 0.0; CLRV(acc0); SETV(pos0, Pos(bp)); for (gp = gtab; gp < NthBody(gtab, ngrav); gp = NextBody(gp)) { DOTPSUBV(dr2, dr, Pos(gp), pos0); dr2i = ((real) 1.0) / (dr2 + eps2); dr1i = rsqrt(dr2i); mdr1i = Mass(gp) * dr1i; mdr3i = mdr1i * dr2i; phi0 -= mdr1i; ADDMULVS(acc0, dr, mdr3i); } Phi(bp) = phi0; SETV(Acc(bp), acc0); } }
void calculateCenterOfMass(cellptr cell) { /* Center of mass position */ vector cmPos; vector tempV; nodeptr q; int i; /* Init the cell's total mass */ Mass(cell) = 0.0; /* Init the cell's center of mass position */ CLRV(cmPos); /* Loop over the subnodes */ for (i = 0; i < NCHILD; i++) { /* Skipping empty child nodes */ if ((q = Child(cell)[i]) != NULL) { /* If node is a cell */ if (Type(q) == CELL) /* Recursively do the same */ calculateCenterOfMass((cellptr) q); /* Accumulate total mass */ Mass(cell) = Mass(q); /* Accumulate center of mass */ ADDMULVS(cmPos, Pos(q), Mass(q)); } } /* Usually, cell has mass */ if (Mass(cell) > 0.0) { /* Find center of mass position */ DIVVS(cmPos, cmPos, Mass(cell)); } else { /* If no mass inside */ SETV(cmPos, Pos(cell)); } SETV(Pos(cell), cmPos); }
void calculateForce(cellptr root, double eps, real rootSize) { /* List of nodes to be calculate */ nodeptr * activeList; /* List of interacting nodes */ cellptr interactionList; /* Maximum number of active nodes */ int activeMaxCount; /* Center of root */ vector rMid; /* */ /* Estimate list length */ activeMaxCount = 216 * (treeDepth(root) + 1); activeList = (nodeptr*) malloc(activeMaxCount * sizeof(nodeptr)); interactionList = (cellptr) malloc(activeMaxCount * sizeof(cell)); /* Initialize active list */ activeList[0] = (nodeptr) root; /* Initialize center of root */ CLRV(rMid) /* Start walking the tree */ walkTree(activeList, activeList + 1, interactionList, interactionList + activeMaxCount, (nodeptr) root, rootSize, rMid, eps); /* Cleaning up */ free(activeList); free(interactionList); }
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); }
local void sum1force(bodyptr btab, int nbody, int i0, real eps2) { bodyptr bp0, bp; double phi0, acc0[NDIM]; vector pos0, dr; real dr2, drab, mri, mr3i; int j; bp0 = NthBody(btab, i0); phi0 = 0.0; CLRV(acc0); SETV(pos0, Pos(bp0)); for (j = 0; j < nbody; j++) if (j != i0) { bp = NthBody(btab, j); DOTPSUBV(dr2, dr, Pos(bp), pos0); dr2 += eps2; drab = rsqrt(dr2); mri = Mass(bp) / drab; phi0 -= mri; mr3i = mri / dr2; ADDMULVS(acc0, dr, mr3i); } Phi(bp0) = phi0; SETV(Acc(bp0), acc0); }
makering(int n, real m, real r, real p) { int i; real theta, v = 0; if (r>0) v = r*pow(r*r,-0.75); /* some fake keplerian vel */ for (i = 0; i < n; i++) { pmass[i] = m; theta = TWO_PI * ( ((real) i) / n + p/360.0 + 0.25); CLRV(pphase[i][0]); pphase[i][0][0] = r * cos(theta); pphase[i][0][1] = r * sin(theta); CLRV(pphase[i][1]); pphase[i][1][0] = -v * sin(theta) * sign_L; pphase[i][1][1] = v * cos(theta) * sign_L; } }
local void diagnostics() { bodyptr p; real velsq, phi0; vector tmpv; matrix tmpt; int ndim=NDIM; mtot = 0.0; /* zero total mass */ etot[1] = etot[2] = 0.0; /* zero total KE and PE */ CLRM(keten); /* zero ke tensor */ CLRM(peten); /* zero pe tensor */ CLRM(amten); /* zero am tensor */ CLRV(cmphase[0]); /* zero c. of m. position */ CLRV(cmphase[1]); /* zero c. of m. velocity */ for (p = bodytab; p < bodytab+nbody; p++) { /* loop over all particles */ mtot += Mass(p); /* sum particle masses */ DOTVP(velsq, Vel(p), Vel(p)); /* square vel vector */ if (extpot) { /* external potential corr. */ (*extpot)(&ndim,Pos(p),tmpv,&phi0,&tnow); phi0 = Phi(p) + phi0; /* extre correction */ } else phi0 = Phi(p); etot[1] += 0.5 * Mass(p) * velsq; /* sum current KE */ etot[2] += 0.5 * Mass(p) * phi0; /* and current PE */ MULVS(tmpv, Vel(p), 0.5 * Mass(p)); /* sum 0.5 m v_i v_j */ OUTVP(tmpt, tmpv, Vel(p)); ADDM(keten, keten, tmpt); MULVS(tmpv, Pos(p), Mass(p)); /* sum m r_i a_j */ OUTVP(tmpt, tmpv, Acc(p)); ADDM(peten, peten, tmpt); OUTVP(tmpt, tmpv, Vel(p)); /* sum m r_i v_j */ ADDM(amten, amten, tmpt); MULVS(tmpv, Pos(p), Mass(p)); /* sum cm position */ ADDV(cmphase[0], cmphase[0], tmpv); MULVS(tmpv, Vel(p), Mass(p)); /* sum cm momentum */ ADDV(cmphase[1], cmphase[1], tmpv); } etot[0] = etot[1] + etot[2]; /* sum KE and PE */ TRANM(tmpt, amten); /* anti-sym. AM tensor */ SUBM(amten, amten, tmpt); DIVVS(cmphase[0], cmphase[0], mtot); /* normalize cm coords */ DIVVS(cmphase[1], cmphase[1], mtot); }
local void diagnostics(void) { bodyptr p1, p2, p; real mp, velsq; vector tmpv; matrix tmpt; mtot = 0.0; // zero total mass etot[1] = etot[2] = 0.0; // zero total KE and PE CLRM(keten); // zero ke tensor CLRM(peten); // zero pe tensor CLRV(amvec); // zero am vector CLRV(cmpos); // zero c. of m. position CLRV(cmvel); // zero c. of m. velocity p1 = bodytab + MAX(nstatic, 0); // set dynamic body range p2 = bodytab + nbody + MIN(nstatic, 0); for (p = p1; p < p2; p++) { // loop over body range mp = (testcalc ? 1.0 / (nbody - ABS(nstatic)) : Mass(p)); // use eq. mass in testcalc mtot += mp; // sum particle masses DOTVP(velsq, Vel(p), Vel(p)); // square vel vector etot[1] += 0.5 * mp * velsq; // sum current KE etot[2] += (testcalc ? 1.0 : 0.5) * mp * Phi(p); // and PE, weighted right MULVS(tmpv, Vel(p), 0.5 * mp); // sum 0.5 m v_i v_j OUTVP(tmpt, tmpv, Vel(p)); ADDM(keten, keten, tmpt); MULVS(tmpv, Pos(p), mp); // sum m r_i a_j OUTVP(tmpt, tmpv, Acc(p)); ADDM(peten, peten, tmpt); CROSSVP(tmpv, Vel(p), Pos(p)); // sum angular momentum MULVS(tmpv, tmpv, mp); ADDV(amvec, amvec, tmpv); MULVS(tmpv, Pos(p), mp); // sum cm position ADDV(cmpos, cmpos, tmpv); MULVS(tmpv, Vel(p), mp); // sum cm momentum ADDV(cmvel, cmvel, tmpv); } etot[0] = etot[1] + etot[2]; // sum KE and PE DIVVS(cmpos, cmpos, mtot); // normalize cm coords DIVVS(cmvel, cmvel, mtot); }
void snapcmacc(vector cmacc, bodyptr btab, int nbody, int woff) { double wtot, cmtmp[NDIM]; bodyptr bp; wtot = 0.0; CLRV(cmtmp); for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) { wtot = wtot + Weight(bp, woff); ADDMULVS(cmtmp, Acc(bp), Weight(bp, woff)); } DIVVS(cmacc, cmtmp, wtot); }
void snaptrak(void) { bodyptr bp, gp; int nzero; if (traktab == NULL) { ntrak = 0; for (bp = bodytab; bp < NthBody(bodytab, nbody); bp = NextBody(bp)) ntrak = MAX(ntrak, Group(bp)); eprintf("[%s: allocating %d groups]\n", getprog(), ntrak); traktab = (bodyptr) allocate(ntrak * SizeofBody); } for (gp = traktab; gp < NthBody(traktab, ntrak); gp = NextBody(gp)) { Mass(gp) = 0.0; CLRV(Pos(gp)); CLRV(Vel(gp)); Key(gp) = 0; } for (bp = bodytab; bp < NthBody(bodytab, nbody); bp = NextBody(bp)) { if (Group(bp) > ntrak) error("snaptrak: cant expand group array\n"); if (Group(bp) > 0) { gp = NthBody(traktab, Group(bp) - 1); Mass(gp) += Mass(bp); ADDMULVS(Pos(gp), Pos(bp), Mass(bp)); ADDMULVS(Vel(gp), Vel(bp), Mass(bp)); Key(gp)++; } } nzero = 0; for (gp = traktab; gp < NthBody(traktab, ntrak); gp = NextBody(gp)) if (Mass(gp) != 0.0) { DIVVS(Pos(gp), Pos(gp), Mass(gp)); DIVVS(Vel(gp), Vel(gp), Mass(gp)); } else nzero++; if (nzero > 0) eprintf("[%s: %d groups have zero mass]\n", getprog(), nzero); }
local void diagnostics() { int i; Body *p; real velsq; vector tmpv; matrix tmpt; mtot = 0.0; /* zero total mass */ etot[1] = etot[2] = 0.0; /* zero total KE and PE */ CLRM(keten); /* zero KE tensor */ CLRM(peten); /* zero PE tensor */ CLRM(amten); /* zero AM tensor */ CLRV(cmphase[0]); /* zero c. of m. position */ CLRV(cmphase[1]); /* zero c. of m. velocity */ for (p = bodytab; p < bodytab+nbody; p++) { /* loop over all bodies */ mtot += Mass(p); /* sum body masses */ DOTVP(velsq, Vel(p), Vel(p)); /* square vel vector */ etot[1] += 0.5 * Mass(p) * velsq; /* sum current KE */ etot[2] += 0.5 * Mass(p) * Phi(p); /* and current PE */ MULVS(tmpv, Vel(p), 0.5 * Mass(p)); /* sum 0.5 m v_i v_j */ OUTVP(tmpt, tmpv, Vel(p)); ADDM(keten, keten, tmpt); MULVS(tmpv, Pos(p), Mass(p)); /* sum m r_i a_j */ OUTVP(tmpt, tmpv, Acc(p)); ADDM(peten, peten, tmpt); OUTVP(tmpt, tmpv, Vel(p)); /* sum m r_i v_j */ ADDM(amten, amten, tmpt); MULVS(tmpv, Pos(p), Mass(p)); /* sum cm position */ ADDV(cmphase[0], cmphase[0], tmpv); MULVS(tmpv, Vel(p), Mass(p)); /* sum cm momentum */ ADDV(cmphase[1], cmphase[1], tmpv); } etot[0] = etot[1] + etot[2]; /* sum KE and PE */ TRANM(tmpt, amten); /* antisymmetrize AM tensor */ SUBM(amten, amten, tmpt); DIVVS(cmphase[0], cmphase[0], mtot); /* normalize cm coords */ DIVVS(cmphase[1], cmphase[1], mtot); }
local void centersnap(Body *btab, int nb) { real mtot; vector cmphase[2], tmp; Body *bp; mtot = 0.0; CLRV(cmphase[0]); CLRV(cmphase[1]); for (bp = btab; bp < btab + nb; bp++) { mtot = mtot + Mass(bp); MULVS(tmp, Phase(bp)[0], Mass(bp)); ADDV(cmphase[0], cmphase[0], tmp); MULVS(tmp, Phase(bp)[1], Mass(bp)); ADDV(cmphase[1], cmphase[1], tmp); } MULVS(cmphase[0], cmphase[0], 1.0/mtot); MULVS(cmphase[1], cmphase[1], 1.0/mtot); for (bp = btab; bp < btab + nb; bp++) { SUBV(Phase(bp)[0], Phase(bp)[0], cmphase[0]); SUBV(Phase(bp)[1], Phase(bp)[1], cmphase[1]); } }
void hackgrav(bodyptr p, bool intree) { pskip = p; /* exclude p from f.c. */ SETV(pos0, PosB(p)); /* set field point */ phi0 = 0.0; /* init total potential */ CLRV(acc0); /* and total acceleration */ n2bterm = nbcterm = 0; /* count body & cell terms */ skipself = FALSE; /* watch for tree-incest */ treescan((nodeptr) &root->cellnode); /* scan tree from root */ if (intree && ! skipself) { /* did tree-incest occur? */ if (! scanopt(options, "allow-incest")) /* treat as catastrophic? */ error("hackgrav: tree-incest detected\n"); if (! treeincest) /* for the first time? */ eprintf("\n[hackgrav: tree-incest detected]\n"); treeincest = TRUE; /* don't repeat warning */ } Phi(p) = phi0; /* store total potential */ SETV(Acc(p), acc0); /* and acceleration */ }
void gravforce(void) { double cpustart; vector rmid; actlen = FACTIVE * 216 * tdepth; /* estimate list length */ actlen = actlen * rpow(theta, -2.5); /* allow for opening angle */ active = (nodeptr *) allocate(actlen * sizeof(nodeptr)); interact = (cellptr) allocate(actlen * sizeof(cell)); cpustart = cputime(); /* record time, less alloc */ actmax = nfcalc = nbbcalc = nbccalc = 0; /* zero cumulative counters */ active[0] = (nodeptr) root; /* initialize active list */ CLRV(rmid); /* set center of root cell */ walkgrav(active, active + 1, interact, interact + actlen, (nodeptr) root, rsize, rmid); /* scan tree, update forces */ cpuforce = cputime() - cpustart; /* store CPU time w/o alloc */ free(active); /* free up temp storage */ free(interact); }
local void gravsum(bodyptr p0, cellptr cptr, cellptr bptr) { vector pos0, acc0; real phi0; SETV(pos0, Pos(p0)); // copy position of body phi0 = 0.0; // init total potential CLRV(acc0); // and total acceleration if (usequad) // if using quad moments sumcell(interact, cptr, pos0, &phi0, acc0); // sum cell forces w quads else // not using quad moments sumnode(interact, cptr, pos0, &phi0, acc0); // sum cell forces wo quads sumnode(bptr, interact + actmax, pos0, &phi0, acc0); // sum forces from bodies Phi(p0) = phi0; // store total potential SETV(Acc(p0), acc0); // and total acceleration nfcalc++; // update counters nbbcalc += interact + actmax - bptr; nbccalc += cptr - interact; }
local void gravsum(bodyptr p0, cellptr cptr, cellptr bptr) { vector pos0, acc0; real phi0; SETV(pos0, Pos(p0)); /* copy position of body */ phi0 = 0.0; /* init total potential */ CLRV(acc0); /* and total acceleration */ if (usequad) /* if using quad moments */ sumcell(interact, cptr, pos0, &phi0, acc0); /* sum cell forces w quads */ else /* not using quad moments */ sumnode(interact, cptr, pos0, &phi0, acc0); /* sum cell forces wo quads */ sumnode(bptr, interact + actlen, pos0, &phi0, acc0); /* sum forces from bodies */ Phi(p0) = phi0; /* store total potential */ SETV(Acc(p0), acc0); /* and total acceleration */ nfcalc++; /* update counters */ nbbcalc += interact + actlen - bptr; nbccalc += cptr - interact; }
/* THIS NEEDS TO BE IMPLEMENTED: see new snapplot code */ var_plot_path() { int i, key, vis; real *pos, *vel, *acc, avec[NDIM], pot, mass, aux; real psz, col, x, y; CLRV(avec); mass = aux = 0.0; key = 0; for (i = 0; i < nobj; i++) { pos = phase[i][0]; vel = phase[i][1]; acc = avec; pot = (phi != NULL ? *(phi + i) : 0.0); vis = (*vfunc)(pos,vel,acc,pot,mass,aux,key,t,i); if (vis != 0) { x = xtrans((*xfunc)(pos,vel,acc,pot,mass,aux,key,t,i)); y = ytrans((*yfunc)(pos,vel,acc,pot,mass,aux,key,t,i)); psz = (*pfunc)(pos,vel,acc,pot,mass,aux,key,t,i); #ifdef COLOR col = (*cfunc)(pos,vel,acc,pot,mass,aux,key,t,i); plcolor(vis == 1 ? col : 2.0); /* highlight if vis > 1 */ #endif if (2.0 < x && x < 18.0 && 2.0 < y && y < 18.0) { if (psz == 0.0) plpoint(x, y); else if (psz > 0.0) plcircle(x, y, psz); else if (psz < 0.0) plcross(x, y, psz); } } } #ifdef COLOR plcolor(2.0); /* reset to white */ #endif }
void gravcalc(void) { double cpustart; vector rmid; if (active == NULL) { // if this is the 1st call actmax = FACTIVE * 216 * (tdepth + 1); // estimate list length #if !defined(QUICKSCAN) if (theta > 0.1) actmax = actmax * rpow(theta,-2.5); // allow for opening angle else actmax = 5.0 * ncell; // guess total node count #endif active = (nodeptr *) allocate(actmax * sizeof(nodeptr)); interact = (cellptr) allocate(actmax * sizeof(cell)); } cpustart = cputime(); // record time, less alloc acttot = nfcalc = nbbcalc = nbccalc = 0; // zero cumulative counters active[0] = (nodeptr) root; // initialize active list CLRV(rmid); // set center of root cell walktree(active, active + 1, interact, interact + actmax, (nodeptr) root, rsize, rmid); // scan tree, update forces cpuforce = cputime() - cpustart; // store CPU time w/o alloc }
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(); }
void nemo_main() { int i, dir, nrad, npots=0, ltype, ndim = NDIM, nx, ny, ns, ndat, nret; int cols[4], n, idx, idx_max; real pmax, symsize, rr, omk_max = 0.0, omk_rmax; real rad[MAXPT], *vel, *vel1, *vel2, *vel3, *vel4, *curve; real *ome, *kap, *opk, *omk, r0l[MAXPT+2], omega, *f; real inrad[MAXPT], invel[MAXPT], inrade[MAXPT], invele[MAXPT]; double pos[3], acc[3], pot, time = 0.0; /* char *fmt, s[20], pfmt[256]; */ char headline[256], fmt1[80]; string axis, mode, infile, plotlabel; stream instr; bool Qtab, Qplot, Qome, Qvel, Qlv, Qin, QoILR; mode = getparam("mode"); n = getiparam("n"); plotlabel = getparam("headline"); sprintf(fmt1,"%s ",getparam("format")); Qome = (*mode == 'o'); /* options are: velocity|omega|lv */ Qlv = (*mode == 'l'); Qvel = (*mode == 'v'); Qtab = getbparam("tab"); Qplot = getbparam("plot"); infile = getparam("in"); Qin = (*infile != 0); if (Qin) { nret = nemoinpi(getparam("cols"),cols,4); if (nret<0 || nret > 4) error("cols= requires 4 numbers"); for (i=nret; i<4; i++) cols[i] = 0; instr = stropen(infile,"r"); ndat = read_table(instr,MAXPT,inrad,invel,inrade,invele,cols); strclose(instr); } mypot1 = get_potential(getparam("name1"),getparam("pars1"),getparam("file1")); omega = get_pattern(); dprintf(0,"Pattern speed: %f\n",omega); mypot2 = get_potential(getparam("name2"),getparam("pars2"),getparam("file2")); mypot3 = get_potential(getparam("name3"),getparam("pars3"),getparam("file3")); mypot4 = get_potential(getparam("name4"),getparam("pars4"),getparam("file4")); headline[0] = '\0'; /* accumulate headline */ if (mypot1) { strcat(headline,getparam("name1")); strcat(headline,"("); strcat(headline,getparam("pars1")); strcat(headline,")"); npots++; } if (mypot2) { strcat(headline,getparam("name2")); strcat(headline,"("); strcat(headline,getparam("pars2")); strcat(headline,") "); npots++; } if (mypot3) { strcat(headline,getparam("name3")); strcat(headline,"("); strcat(headline,getparam("pars3")); strcat(headline,") "); npots++; } if (mypot4) { strcat(headline,getparam("name4")); strcat(headline,"("); strcat(headline,getparam("pars4")); strcat(headline,")"); npots++; } nrad = nemoinpr(getparam("radii"),rad,MAXPT); /* get radii */ if (nrad <= 0) warning("Using %d radii is not very productive",nrad); vel = (real *) allocate(sizeof(real) * nrad); /* allocate stuff */ vel1 = (real *) allocate(sizeof(real) * nrad); vel2 = (real *) allocate(sizeof(real) * nrad); vel3 = (real *) allocate(sizeof(real) * nrad); vel4 = (real *) allocate(sizeof(real) * nrad); if (Qome) { ome = (real *) allocate(4 * sizeof(real) * nrad); /* plus spline */ kap = (real *) allocate(sizeof(real) * nrad); opk = (real *) allocate(sizeof(real) * nrad); omk = (real *) allocate(sizeof(real) * nrad); } axis = getparam("axis"); dir = 0; if (*axis == 'x') dir=0; if (*axis == 'y') dir=1; if (*axis == 'z') dir=2; if (dir>NDIM) error("Axis %s not supported in NDIM=%d",axis,NDIM); pmax = 0.0; for (i=0; i<nrad; i++) { /* loop to compute */ CLRV(pos); /* clear positions */ pos[dir] = rad[i]; /* set the right axis */ vel[i] = 0.0; if (mypot1) { CLRV(acc); (*mypot1) (&ndim,pos,acc,&pot,&time); vel1[i] = -rad[i] * acc[dir]; vel[i] += vel1[i]; vel1[i] = sqrt(vel1[i]); } if (mypot2) { CLRV(acc); (*mypot2) (&ndim,pos,acc,&pot,&time); vel2[i] = -rad[i] * acc[dir]; vel[i] += vel2[i]; vel2[i] = sqrt(vel2[i]); } if (mypot3) { CLRV(acc); (*mypot3) (&ndim,pos,acc,&pot,&time); vel3[i] = -rad[i] * acc[dir]; vel[i] += vel3[i]; vel3[i] = sqrt(vel3[i]); } if (mypot4) { CLRV(acc); (*mypot4) (&ndim,pos,acc,&pot,&time); vel4[i] = -rad[i] * acc[dir]; vel[i] += vel4[i]; vel4[i] = sqrt(vel4[i]); } vel[i] = sqrt(vel[i]); } if (Qome) { lindblad(nrad,rad,vel,ome,kap,opk,omk,n); if (omega> 0.0) { /* compute resonances */ f = opk; idx = nrad-1; if (omega < f[idx]) { warning("Radii not far enough out for OLR: %g",f[idx]); f = ome; if (omega < f[idx]) { warning("Radii not far enough out for CR: %g",f[idx]); f = omk; } } QoILR = FALSE; for(; idx>0; idx--) { if (omk[idx] > omk_max) { idx_max = idx; omk_max = omk[idx]; } if (f==omk) { if (QoILR) { if (omega < f[idx]) continue; } else { if (omega > f[idx]) continue; } } else { if (omega > f[idx]) continue; } /* found a resonance: */ rr = rad[idx] + (rad[idx+1]-rad[idx])* (omega-f[idx])/(f[idx+1]-f[idx]); if (f == omk) { #if 0 if (QoILR) { dprintf(0,"iILR: %g\n",rr); break; } else { dprintf(0,"oILR: %g\n",rr); QoILR = TRUE; } #endif } else if (f == ome) { dprintf(0,"CR: %g\n",rr); f = omk; } else if (f == opk) { dprintf(0,"OLR: %g\n",rr); f = ome; } else error("impossble resonance"); } peak(nrad,rad,omk,idx_max,1, &omk_rmax, &omk_max); dprintf(0,"OMK_max: %g\n",omk_max); dprintf(0,"OMK_rmax: %g\n",omk_rmax); if (omega < omk_max) { /* search for ILR */ for (idx=idx_max; idx<nrad; idx++) { if (omega > omk[idx]) { rr = rad[idx-1] + (rad[idx]-rad[idx-1])* (omega-f[idx-1])/(f[idx]-f[idx-1]); dprintf(0,"oILR: %g\n",rr); break; } } for (idx=idx_max; idx>0; idx--) { if (omega > omk[idx]) { rr = rad[idx] + (rad[idx+1]-rad[idx])* (omega-f[idx])/(f[idx+1]-f[idx]); dprintf(0,"iILR: %g\n",rr); break; } } } } } for (i=0; i<nrad; i++) { /* loop to print */ if (Qtab) { printf(fmt1,rad[i]); printf(fmt1,vel[i]); } if (Qtab && npots>1 && !Qome) { if (mypot1) printf(fmt1,vel1[i]); if (mypot2) printf(fmt1,vel2[i]); if (mypot3) printf(fmt1,vel3[i]); if (mypot4) printf(fmt1,vel4[i]); } if (Qtab && Qome) { printf(fmt1,ome[i]); printf(fmt1,kap[i]); printf(fmt1,opk[i]); printf(fmt1,omk[i]); } if (Qtab) printf("\n"); if (Qome) pmax = MAX(pmax,opk[i]); else pmax = MAX(pmax,vel[i]); } if (Qin && Qvel) goodness(nrad,rad,vel,ndat,inrad,invel,(cols[3]>0?invele:NULL)); if (Qplot) { plinit("***",0.0,20.0,0.0,20.0); /* open device */ nx = nemoinpr(getparam("xrange"),xplot,2); /* get xrange in plot */ switch(nx) { case 0: xplot[0] = rad[0]; case 1: xplot[1] = rad[nrad-1]; break; case 2: break; default: warning("xrange= only accepts two values"); break; } ny = nemoinpr(getparam("yrange"),yplot,2); /* get yrange in plot */ switch(ny) { case 0: yplot[0] = 0.0; yplot[1] = 1.1 * pmax; /* extra 10% for egde */ break; case 1: yplot[1] = 1.1 * pmax; /* extra 10% for egde */ break; case 2: break; default: warning("yrange= only accepts two values"); break; } xaxis ( 2.0, 2.0, 16.0, xplot, -7, xtrans, "R"); /* plot axes */ xaxis ( 2.0,18.0, 16.0, xplot, -7, xtrans, NULL); if (Qome) yaxis ( 2.0, 2.0, 16.0, yplot, -7, ytrans, "[V/R]"); else yaxis ( 2.0, 2.0, 16.0, yplot, -7, ytrans, "V"); yaxis (18.0, 2.0, 16.0, yplot, -7, ytrans, NULL); if (*plotlabel) pltext(plotlabel,2.0,18.5,0.5,0.0); else pltext(headline,2.0,18.5,0.35,0.0); if (*plotmsg) pltext(plotmsg,8.0,2.5,0.25,0.0); curve = (Qome ? ome : vel); /* assign first curve */ plltype(3,1); /* thick solid line */ plmove(xtrans(rad[0]),ytrans(curve[0])); for (i=1; i<nrad; i++) plline(xtrans(rad[i]),ytrans(curve[i])); if (Qome) { /* if Lindblad - plot omk, opk */ plltype(1,1); /* all regular solid lines */ plmove(xtrans(rad[0]), ytrans(omk[0])); for (i=1; i<nrad; i++) plline(xtrans(rad[i]),ytrans(omk[i])); plmove(xtrans(rad[0]), ytrans(opk[0])); for (i=1; i<nrad; i++) plline(xtrans(rad[i]),ytrans(opk[i])); } else if (npots>1) { /* if velocity and > 1 component */ ltype = 1; if (mypot1) { plltype(1,++ltype); plmove(xtrans(rad[0]),ytrans(vel1[0])); for (i=1; i<nrad; i++) plline(xtrans(rad[i]),ytrans(vel1[i])); } if (mypot2) { plltype(1,++ltype); plmove(xtrans(rad[0]),ytrans(vel2[0])); for (i=1; i<nrad; i++) plline(xtrans(rad[i]),ytrans(vel2[i])); } if (mypot3) { plltype(1,++ltype); plmove(xtrans(rad[0]),ytrans(vel2[0])); for (i=1; i<nrad; i++) plline(xtrans(rad[i]),ytrans(vel3[i])); } if (mypot4) { plltype(1,++ltype); plmove(xtrans(rad[0]),ytrans(vel2[0])); for (i=1; i<nrad; i++) plline(xtrans(rad[i]),ytrans(vel4[i])); } } plltype(1,1); symsize = 0.1; if (Qin && Qvel) { /* if input file with velocities */ for (i=0; i<ndat; i++) plbox(xtrans(inrad[i]),ytrans(invel[i]),symsize); if (cols[3]>0) { /* if error bars in radius */ for (i=0; i<ndat; i++) { plmove(xtrans(inrad[i]-inrade[i]),ytrans(invel[i])); plline(xtrans(inrad[i]+inrade[i]),ytrans(invel[i])); } } if (cols[4]>0) { /* if error bars in velocity */ for (i=0; i<ndat; i++) { plmove(xtrans(inrad[i]),ytrans(invel[i]-invele[i])); plline(xtrans(inrad[i]),ytrans(invel[i]+invele[i])); } } } else if (Qin && Qome) { /* if input file with omega */ for (i=0; i<ndat; i++) plbox(xtrans(inrad[i]),ytrans(invel[i]/inrad[i]),symsize); } plstop(); } /* if plot vel/ome */ if (Qlv) { ns = nemoinpr(getparam("r0l"),r0l,MAXPT+2) - 2; if (ns < 0) error("r0l= needs at least two values: r0 and l"); else if (ns==0) warning("r0l= no lv-radii array supplied"); lv(nrad,rad,vel,r0l[0],r0l[1],ns,&r0l[2]); } }
plotsnap() { real t, *mp, *psp, *pp, *ap, *acp; int vismax, visnow, i, vis, icol; real psz, col, x, y, z; Body b; bool Qall = FALSE; t = (timeptr != NULL ? *timeptr : 0.0); /* get current time value */ CLRV(Acc(&b)); /* zero unsupported fields */ Key(&b) = 0; visnow = vismax = 0; do { /* loop painting layers */ visnow++; /* make next layer visib. */ mp = massptr; /* (re)set data pointers */ psp = phaseptr; pp = phiptr; ap = auxptr; acp = accptr; npnt = 0; for (i = 0; i < nbody; i++) { /* loop over all bodies */ Mass(&b) = (mp != NULL ? *mp++ : 0.0); /* set mass if supplied */ SETV(Pos(&b), psp); /* always set position */ psp += NDIM; /* and advance p.s. ptr */ SETV(Vel(&b), psp); /* always set velocity */ psp += NDIM; /* and advance ptr */ Phi(&b) = (pp != NULL ? *pp++ : 0.0); Aux(&b) = (ap != NULL ? *ap++ : 0.0); if (acp) { SETV(Acc(&b),acp); /* set accel's */ acp += NDIM; /* and advance ptr */ } /* set phi,aux if given */ vis = (*vfunc)(&b, t, i); /* evaluate visibility */ vismax = MAX(vismax, vis); /* remember how hi to go*/ if (vis == visnow) { /* if body is visible */ x = (*xfunc)(&b, t, i); /* evaluate x,y,z coords*/ y = (*yfunc)(&b, t, i); z = (*zfunc)(&b, t, i); psz = (*pfunc)(&b, t, i); #define MAXCOLOR 16 #ifdef COLOR col = (*cfunc)(&b, t, i); col = (col - crange[0])/(crange[1] - crange[0]); icol = 1 + (MAXCOLOR - 2) * MAX(0.0, MIN(1.0, col)); s2sci(icol); #endif xpnt[npnt] = x; ypnt[npnt] = y; zpnt[npnt] = z; if (!Qall) { s2pt1(xpnt[npnt],ypnt[npnt],zpnt[npnt], visnow); } npnt++; } } /* i<nbody */ if (Qall) s2pt(npnt, xpnt, ypnt, zpnt, visnow); } while (visnow < vismax); /* until final layer done */ }