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); }
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); }
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 }
int read_snapshot( bodyptr *btab_ptr, /* gets particle array */ int *nobj_ptr, /* gets number of bodies */ stream instr /* stream to read from */ ) { int nobj, cs, i; real *mbuf, *mp, *pbuf, *pp; bodyptr bp; for(;;) { /* loop until done or proper snapshot */ if (!get_tag_ok(instr,SnapShotTag)) return 0; get_set(instr, SnapShotTag); if (!get_tag_ok(instr,ParametersTag)) { get_tes(instr,SnapShotTag); continue; } get_set(instr, ParametersTag); get_data(instr, NobjTag, IntType, &nobj, 0); if (nobj < 1) error("read_snapshot: %s = %d is absurd", NobjTag, nobj); if (get_tag_ok(instr,TimeTag)) get_data(instr,TimeTag, RealType, &tsnap, 0); else { dprintf(0,"No time tag: time=0.0 assumed\n"); tsnap = 0.0; } get_tes(instr, ParametersTag); if (!get_tag_ok(instr,ParticlesTag)) { get_tes(instr,SnapShotTag); continue; } get_set(instr, ParticlesTag); get_data(instr, CoordSystemTag, IntType, &cs, 0); if (cs != CSCode(Cartesian, NDIM, 2)) error("read_snapshot: cannot handle %s = %d", CoordSystemTag, cs); mbuf = mp = (real *) allocate(nobj * sizeof(real)); pbuf = pp = (real *) allocate(nobj * 2 * NDIM * sizeof(real)); get_data(instr, MassTag, RealType, mbuf, nobj, 0); get_data(instr, PhaseSpaceTag, RealType, pbuf, nobj, 2, NDIM, 0); get_tes(instr, ParticlesTag); get_tes(instr, SnapShotTag); *btab_ptr = bp = (bodyptr) allocate(nobj * sizeof(body)); for (i = 0; i < nobj; i++) { Type(bp) = BODY; Mass(bp) = *mp++; SETV(Pos(bp), pp); pp += NDIM; SETV(Vel(bp), pp); pp += NDIM; bp++; } free(mbuf); free(pbuf); *nobj_ptr = nobj; return 1; } }
local void walktree(nodeptr *aptr, nodeptr *nptr, cellptr cptr, cellptr bptr, nodeptr p, real psize, vector pmid) { nodeptr *np, *ap, q; int actsafe; matrix trQM; if (Update(p)) { // new forces needed in node? np = nptr; // start new active list actsafe = actmax - NSUB; // leave room for NSUB more for (ap = aptr; ap < nptr; ap++) { // loop over active nodes if (Type(*ap) == CELL) { // is this node a cell? if (accept(*ap, psize, pmid)) { // does it pass the test? if (Mass(*ap) > 0.0) { // and contribute to field? Mass(cptr) = Mass(*ap); // copy to interaction list SETV(Pos(cptr), Pos(*ap)); #if defined(SOFTCORR) TRACEM(Trace(cptr), Quad(*ap)); // save trace in copy SETMI(trQM); MULMS(trQM, trQM, Trace(cptr)/3); SUBM(Quad(cptr), Quad(*ap), trQM); // store traceless moment #else SETM(Quad(cptr), Quad(*ap)); // copy traceless moment #endif cptr++; // and bump cell array ptr } } else { // this cell fails the test if (np - active >= actsafe) // make sure list has room fatal("%s.walktree: active list overflow\n", getprog()); for (q = More(*ap); q != Next(*ap); q = Next(q)) // loop over all subcells *np++= q; // put them on active list } } else // else this node is a body if (*ap != p && Mass(*ap) > 0.0) { // not self-interaction? --bptr; // bump body array ptr Mass(bptr) = Mass(*ap); // and copy data to array SETV(Pos(bptr), Pos(*ap)); } } acttot = MAX(acttot, np - active); // keep track of max active if (np != nptr) { // if new actives were added walksub(nptr, np, cptr, bptr, p, psize, pmid); // then visit next level } else { // else no actives left if (Type(p) != BODY) // make sure we got a body fatal("%s.walktree: recursion terminated with cell\n" " p = 0x%x psize = %.8f Mass(p) = %g\n" " pmid = (%.8f,%.8f,%.8f)\n Pos(p) = (%.8f,%.8f,%.8f)\n", getprog(), (int) p, psize, Mass(p), pmid[0], pmid[1], pmid[2], Pos(p)[0], Pos(p)[1], Pos(p)[2]); gravsum((bodyptr) p, cptr, bptr); // sum force on this body } } }
void snaprect(bodyptr btab, int nbody) { matrix qmat, tmpm; bodyptr bp; vector frame[3], tmpv; static vector oldframe[3] = { { 1.0, 0.0, 0.0, }, { 0.0, 1.0, 0.0, }, { 0.0, 0.0, 1.0, }, }; int i; snapcenter(btab, nbody, WeightField.offset); CLRM(qmat); for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) { OUTVP(tmpm, Pos(bp), Pos(bp)); MULMS(tmpm, tmpm, Weight(bp)); ADDM(qmat, qmat, tmpm); } eigenvect(frame[0], frame[1], frame[2], qmat); if (dotvp(oldframe[0], frame[0]) < 0.0) MULVS(frame[0], frame[0], -1.0); if (dotvp(oldframe[2], frame[2]) < 0.0) MULVS(frame[2], frame[2], -1.0); CROSSVP(frame[1], frame[2], frame[0]); printvect("e_x:", frame[0]); printvect("e_y:", frame[1]); printvect("e_z:", frame[2]); for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) { if (PosField.offset != BadOffset) { for (i = 0; i < NDIM; i++) tmpv[i] = dotvp(Pos(bp), frame[i]); SETV(Pos(bp), tmpv); } if (VelField.offset != BadOffset) { for (i = 0; i < NDIM; i++) tmpv[i] = dotvp(Vel(bp), frame[i]); SETV(Vel(bp), tmpv); } if (AccField.offset != BadOffset) { for (i = 0; i < NDIM; i++) tmpv[i] = dotvp(Acc(bp), frame[i]); SETV(Acc(bp), tmpv); } if (AuxVecField.offset != BadOffset) { for (i = 0; i < NDIM; i++) tmpv[i] = dotvp(AuxVec(bp), frame[i]); SETV(AuxVec(bp), tmpv); } } for (i = 0; i < NDIM; i++) SETV(oldframe[i], frame[i]); }
void disconnect(bool async, bool cleanup) { if(curpeer) { if(!discmillis) { enet_peer_disconnect(curpeer, DISC_NONE); enet_host_flush(clienthost); discmillis = totalmillis; } if(curpeer->state!=ENET_PEER_STATE_DISCONNECTED) { if(async) return; enet_peer_reset(curpeer); } curpeer = NULL; discmillis = 0; conoutf("disconnected"); game::gamedisconnect(cleanup); SETV(mainmenu, 1); } if(!connpeer && clienthost) { enet_host_destroy(clienthost); clienthost = NULL; } }
void rotatevec(vector vec, matrix mat) { vector tmp; MULMV(tmp, mat, vec); SETV(vec, tmp); }
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 write_snapshot(void) { real *mbuf, *mp, *pspbuf, *pspp; bodyptr bp; int cs = CSCode(Cartesian, NDIM, 2); string options = getparam("options"); mbuf = mp = (real *) allocate(ntest * sizeof(real)); pspbuf = pspp = (real *) allocate(ntest * 2 * NDIM * sizeof(real)); for (bp = testdata; bp < testdata+ntest; bp++) { *mp++ = Mass(bp); SETV(pspp, Pos(bp)); pspp += NDIM; SETV(pspp, Vel(bp)); pspp += NDIM; } put_set(outstr, SnapShotTag); put_set(outstr, ParametersTag); put_data(outstr, NobjTag, IntType, &ntest, 0); put_data(outstr, TimeTag, RealType, &tsnap, 0); put_data(outstr, "tol", RealType, &tol, 0); put_data(outstr, "eps", RealType, &eps, 0); put_tes(outstr, ParametersTag); put_set(outstr, ParticlesTag); put_data(outstr, CoordSystemTag, IntType, &cs, 0); if (scanopt(options, "mass")) put_data(outstr, MassTag, RealType, mbuf, ntest, 0); if (scanopt(options, "phase")) put_data(outstr, PhaseSpaceTag, RealType, pspbuf, ntest, 2, NDIM, 0); put_data(outstr, PotentialTag, RealType, phidata, ntest, 0); put_data(outstr, AccelerationTag, RealType, accdata, ntest, NDIM, 0); put_tes(outstr, ParticlesTag); put_set(outstr, DiagnosticsTag); put_data(outstr, "n2btot", IntType, &n2btot, 0); put_data(outstr, "nbctot", IntType, &nbctot, 0); put_data(outstr, "cputree", RealType, &cputree, 0); put_data(outstr, "cpufcal", RealType, &cpufcal, 0); put_tes(outstr, DiagnosticsTag); put_tes(outstr, SnapShotTag); free(mbuf); free(pspbuf); }
void walkTree(nodeptr * aPtr, nodeptr *nPtr, cellptr cPtr, cellptr bPtr, nodeptr p, real pSize, vector pMid, double eps) { nodeptr *np, *ap, q; int activeSafe; /* Are new forces needed? */ if (Update(p)) { /* Start new active list */ np = nPtr; /* Loop over active nodes */ for (ap = aPtr; ap < nPtr; ap++) { /* Is this node a cell? */ if (Type(*ap) == CELL) { /* If the node pass the test */ if (acceptNode(*ap, pSize, pMid)) { /* If the node contribute to the field */ if (Mass(*ap) > 0.0) { /* Copy to interaction list */ Mass(cPtr) = Mass(*ap); SETV(Pos(cPtr), Pos(*ap)); /* Next interaction element */ cPtr++; } } else { /* If not accepted */ for (q = More(*ap); q != Next(*ap); q = Next(q)) *np++ = q; } } else {/* If this node is a body */ /* If it's not self-interaction */ if (*ap != p && Mass(*ap) > 0.0) { /* Build interaction element */ --bPtr; /* Copy data to array */ Mass(bptr) = Mass(*ap); SETV(Pos(bPtr), Pos(*ap)); } } } } }
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 walkgrav(nodeptr *aptr, nodeptr *nptr, cellptr cptr, cellptr bptr, nodeptr p, real psize, vector pmid) { nodeptr *np, *ap, q; int actsafe; if (Update(p)) { /* are new forces needed? */ np = nptr; /* start new active list */ actsafe = actlen - NSUB; /* leave room for NSUB more */ for (ap = aptr; ap < nptr; ap++) /* loop over active nodes */ if (Cell(*ap)) { /* is this node a cell? */ if (accept(*ap, psize, pmid)) { /* does it pass the test? */ Mass(cptr) = Mass(*ap); /* copy to interaction list */ SETV(Pos(cptr), Pos(*ap)); SETM(Quad(cptr), Quad(*ap)); cptr++; /* and bump cell array ptr */ } else { /* else it fails the test */ if (np - active >= actsafe) /* check list has room */ error("walkgrav: active list overflow\n"); for (q = More(*ap); q != Next(*ap); q = Next(q)) /* loop over all subcells */ *np++= q; /* put on new active list */ } } else /* else this node is a body */ if (*ap != p) { /* if not self-interaction */ --bptr; /* bump body array ptr */ Mass(bptr) = Mass(*ap); /* and copy data to array */ SETV(Pos(bptr), Pos(*ap)); } actmax = MAX(actmax, np - active); /* keep track of max active */ if (np != nptr) /* if new actives listed */ walksub(nptr, np, cptr, bptr, p, psize, pmid); /* then visit next level */ else { /* else no actives left, so */ if (! Body(p)) /* must have found a body */ error("walkgrav: recursion terminated with cell\n"); gravsum((bodyptr) p, cptr, bptr); /* sum force on the body */ } } }
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; }
void force_calc(void) { real *pp, *ap; double cpubase; string *rminxstr; int i; bodyptr bp; tol = getdparam("tol"); eps = getdparam("eps"); rsize = getdparam("rsize"); rminxstr = burststring(getparam("rmin"), ", "); if (xstrlen(rminxstr, sizeof(string)) < NDIM) { SETVS(rmin, - rsize / 2.0); } else for (i = 0; i < NDIM; i++) rmin[i] = atof(rminxstr[i]); dprintf(0,"initial rsize: %8f rmin: %8f %8f %8f\n", rsize, rmin[0], rmin[1], rmin[2]); fcells = getdparam("fcells"); phidata = pp = (real *) allocate(ntest * sizeof(real)); accdata = ap = (real *) allocate(ntest * NDIM * sizeof(real)); cpubase = cputime(); maketree(massdata, nmass); cputree = cputime() - cpubase; dprintf(0," final rsize: %8f rmin: %8f %8f %8f\n", rsize, rmin[0], rmin[1], rmin[2]); cpubase = cputime(); n2btot = nbctot = 0; for (bp = testdata; bp < testdata+ntest; bp++) { hackgrav(bp); *pp++ = Phi(bp); SETV(ap, Acc(bp)); ap += NDIM; n2btot += n2bterm; nbctot += nbcterm; } cpufcal = cputime() - cpubase; }
void TargetingControl::determineMouseTarget(bool forceEntityCheck) { TargetingControl::worldPosition = worldpos; if (Logging::shouldShow(Logging::INFO)) particle_splash(0, 50, 100, TargetingControl::worldPosition); // Kripken: Show some sparkles where the mouse points - for debug if (!useMouseTargeting && !editmode && !forceEntityCheck) { TargetingControl::targetLogicEntity = placeholderLogicEntity; TargetingControl::targetPosition = TargetingControl::worldPosition; SETV(has_mouse_target, 0); } else { static long lastEntityCheck = -1; // Use this to not run an actual entity check more than 1/frame if (lastEntityCheck != lastmillis) { float dist; TargetingControl::intersectClosest(camera1->o, worldpos, camera1, dist, TargetingControl::targetLogicEntity); // If not edit mode, ignore the player itself if (!editmode && TargetingControl::targetLogicEntity.get() && !TargetingControl::targetLogicEntity->isNone() && TargetingControl::targetLogicEntity->getUniqueId() == ClientSystem::uniqueId) { // Try to see if the player was the sole cause of collision - move it away, test, then move it back vec save = ClientSystem::playerLogicEntity->dynamicEntity->o; ClientSystem::playerLogicEntity->dynamicEntity->o.add(10000.0); TargetingControl::intersectClosest(camera1->o, worldpos, camera1, dist, TargetingControl::targetLogicEntity); ClientSystem::playerLogicEntity->dynamicEntity->o = save; } SETV(has_mouse_target, int(TargetingControl::targetLogicEntity.get() && !TargetingControl::targetLogicEntity->isNone())); if (GETIV(has_mouse_target)) { vec temp(worldpos); temp.sub(camera1->o); temp.normalize(); temp.mul(dist); temp.add(camera1->o); TargetingControl::targetPosition = temp; } else TargetingControl::targetPosition = TargetingControl::worldPosition; lastEntityCheck = lastmillis; } } // if (!placeholderLogicEntity.get()->isNone()) // TargetingControl::targetLogicEntity = LogicSystem::getLogicEntity(placeholderLogicEntity.get()->getUniqueId()); // else // TargetingControl::targetLogicEntity = placeholderLogicEntity; }
void showscores(bool on) { SETV(scoreboard, on ? 1 : 0); scoreboard.show(on); }
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 */ }