public unsafe void Step(float timeStep, Vector2 mousePosition, int buttons) { Body *state = (Body *)m_statePtr; for (int i = 0; i < m_count; i++) { var b1 = state + i; for (int j = i + 1; j < m_count; j++) { var b2 = state + j; var vec = b2->pos - b1->pos; var distance = vec.magnitude; vec /= distance; vec *= (5f / (0.1f + distance * 0.01f)) * m_adjust; b1->acc += vec; b2->acc -= vec; } } if (buttons == 1) { state[0].pos = mousePosition; state[0].vel = Vector2.zero; for (int i = 0; i < m_count; i++) { var b = state + i; var vec = mousePosition - b->pos; var distance = vec.magnitude; if (distance > float.Epsilon) { vec /= distance; } vec *= (3f / (0.1f + distance * 0.001f)); b->acc += vec; } } for (int i = 0; i < m_count; i++) { var b = state + i; if (b->vel.sqrMagnitude > 2500f) { b->acc -= b->vel; } b->vel += timeStep * b->acc; b->pos += timeStep * b->vel; b->acc = Vector2.zero; } }
public unsafe void UpdateViews(List <Transform> views) { Body *state = (Body *)m_statePtr; for (int i = 0; i < m_count; i++) { views[i].position = state[i].pos; } }
public void BenchSetup() { bodyPtr = (Body *)Marshal.AllocHGlobal(Marshal.SizeOf <Body>() * 6); rsPtr = (RS *)Marshal.AllocHGlobal(3 * 1024 * sizeof(double)); nBodyPP = Marshal.AllocHGlobal(Marshal.SizeOf <BodyVector>() * 12); nBodyPtr = (BodyVector *)((ulong)nBodyPP - ((ulong)nBodyPP + 16) % 16); rPtr = (R *)Marshal.AllocHGlobal(Marshal.SizeOf <R>() * 1024); magPtr = (double *)Marshal.AllocHGlobal(sizeof(double) * 1024); bodySystem = new NBodySystem(bodyPtr); NBodySystem.Initialize(nBodyPtr); }
public static void AdvanceStaticIntr1(double dt, R *rPtr, double *magPtr, ref NBodySystem bodySystem, int count = 50000000) { Body * items = bodySystem.bodies; const int N = (BodyCount - 1) * BodyCount / 2; R * r = rPtr; double * mag = magPtr; { int k = 0; ref Body iBody = ref items[0]; for (int j = 1; j < 5; ++j, ++k) { ref Body jBody = ref items[j]; ref R rf = ref r[k];
public unsafe void Init(int count) { m_statePtr = Marshal.AllocHGlobal(count * sizeof(Body)); m_count = count; Body *state = (Body *)m_statePtr; for (int i = 0; i < m_count; i++) { state[i] = new Body() { pos = UnityEngine.Random.insideUnitCircle * 10f, vel = UnityEngine.Random.insideUnitCircle, acc = Vector2.zero }; } m_adjust = 1f / count; }
public unsafe void InitializeVerify() { double *bvPtr = stackalloc double[sizeof(BodyVector) / sizeof(double)]; NBodySystem.Initialize((BodyVector *)bvPtr); Body * bodies = stackalloc Body[5]; NBodySystem bodySystem = new NBodySystem(bodies); var result = NBodySystem.DumpBodyVector(5); Assert.NotNull(result); var expected = NBodySystem.DumpBodies(bodies, 5); Assert.NotNull(expected); Assert.Equal(expected, result); }
public unsafe void AdvanceByOne() { double *bvPtr = stackalloc double[sizeof(BodyVector) / sizeof(double)]; NBodySystem.Initialize((BodyVector *)bvPtr); Body * bodies = stackalloc Body[5]; NBodySystem bodySystem = new NBodySystem(bodies); // Other data structures RS * rsaPtr = stackalloc RS[1]; R * rPtr = stackalloc R[1024]; double *magPtr = stackalloc double[1024]; double *mag2Ptr = stackalloc double[1024]; NBodySystem.AdvanceStaticIntrSoa(0.01, rsaPtr, magPtr); var result = NBodySystem.DumpBodyVector(5); NBodySystem.AdvanceStaticIntr2(0.01, rPtr, mag2Ptr, ref bodySystem); var expected = NBodySystem.DumpBodies(bodies, 5); Assert.Equal(expected, result); }
public NBodySystem(Body *ptr) { bodies = ptr; ref Body p = ref bodies[0];
public static void Initialize() { bodies = (Body *)(U8.Base); pairs = (Pair *)(&bodies[BodyCount]); InitBody( 0, // Sun mass: Solarmass ); InitBody( 1, // Jupiter x: 4.84143144246472090e+00, y: -1.16032004402742839e+00, z: -1.03622044471123109e-01, vx: 1.66007664274403694e-03 * DaysPeryear, vy: 7.69901118419740425e-03 * DaysPeryear, vz: -6.90460016972063023e-05 * DaysPeryear, mass: 9.54791938424326609e-04 * Solarmass ); InitBody( 2, // Saturn x: 8.34336671824457987e+00, y: 4.12479856412430479e+00, z: -4.03523417114321381e-01, vx: -2.76742510726862411e-03 * DaysPeryear, vy: 4.99852801234917238e-03 * DaysPeryear, vz: 2.30417297573763929e-05 * DaysPeryear, mass: 2.85885980666130812e-04 * Solarmass ); InitBody( 3, // Uranus x: 1.28943695621391310e+01, y: -1.51111514016986312e+01, z: -2.23307578892655734e-01, vx: 2.96460137564761618e-03 * DaysPeryear, vy: 2.37847173959480950e-03 * DaysPeryear, vz: -2.96589568540237556e-05 * DaysPeryear, mass: 4.36624404335156298e-05 * Solarmass ); InitBody( 4, // Neptune x: 1.53796971148509165e+01, y: -2.59193146099879641e+01, z: 1.79258772950371181e-01, vx: 2.68067772490389322e-03 * DaysPeryear, vy: 1.62824170038242295e-03 * DaysPeryear, vz: -9.51592254519715870e-05 * DaysPeryear, mass: 5.15138902046611451e-05 * Solarmass ); int pi = 0; for (int i = 0; i < BodyCount - 1; i++) { for (int j = i + 1; j < BodyCount; j++) { var p = &pairs[pi++]; p->bi = &bodies[i]; p->bj = &bodies[j]; } } double px = 0.0, py = 0.0, pz = 0.0; for (int i = 0; i < BodyCount; i++) { var b = &(bodies[i]); px += b->vx * b->mass; py += b->vy * b->mass; pz += b->vz * b->mass; } var sol = &bodies[0]; sol->vx = -px / Solarmass; sol->vy = -py / Solarmass; sol->vz = -pz / Solarmass; }
public static void Initialize () { bodies = (Body*)(U8.Base); pairs = (Pair*)(&bodies[BodyCount]); InitBody( 0, // Sun mass: Solarmass ); InitBody( 1, // Jupiter x: 4.84143144246472090e+00, y: -1.16032004402742839e+00, z: -1.03622044471123109e-01, vx: 1.66007664274403694e-03 * DaysPeryear, vy: 7.69901118419740425e-03 * DaysPeryear, vz: -6.90460016972063023e-05 * DaysPeryear, mass: 9.54791938424326609e-04 * Solarmass ); InitBody( 2, // Saturn x: 8.34336671824457987e+00, y: 4.12479856412430479e+00, z: -4.03523417114321381e-01, vx: -2.76742510726862411e-03 * DaysPeryear, vy: 4.99852801234917238e-03 * DaysPeryear, vz: 2.30417297573763929e-05 * DaysPeryear, mass: 2.85885980666130812e-04 * Solarmass ); InitBody( 3, // Uranus x: 1.28943695621391310e+01, y: -1.51111514016986312e+01, z: -2.23307578892655734e-01, vx: 2.96460137564761618e-03 * DaysPeryear, vy: 2.37847173959480950e-03 * DaysPeryear, vz: -2.96589568540237556e-05 * DaysPeryear, mass: 4.36624404335156298e-05 * Solarmass ); InitBody( 4, // Neptune x: 1.53796971148509165e+01, y: -2.59193146099879641e+01, z: 1.79258772950371181e-01, vx: 2.68067772490389322e-03 * DaysPeryear, vy: 1.62824170038242295e-03 * DaysPeryear, vz: -9.51592254519715870e-05 * DaysPeryear, mass: 5.15138902046611451e-05 * Solarmass ); int pi = 0; for (int i = 0; i < BodyCount - 1; i++) { for (int j = i + 1; j < BodyCount; j++) { var p = &pairs[pi++]; p->bi = &bodies[i]; p->bj = &bodies[j]; } } double px = 0.0, py = 0.0, pz = 0.0; for (int i = 0; i < BodyCount; i++) { var b = &(bodies[i]); px += b->vx * b->mass; py += b->vy * b->mass; pz += b->vz * b->mass; } var sol = &bodies[0]; sol->vx = -px / Solarmass; sol->vy = -py / Solarmass; sol->vz = -pz / Solarmass; }