# Every Body Pulls on Every Body

*Task 2 of 5 · [N-Body Gravity](https://gpu.rocks/learn/n-body-gravity-5de47751.md) · GPU.js Learn*

Real gravity has no star at the center — **every body pulls on every
other**. For 64 bodies that's 64 × 63 interactions; for a million, half a trillion.
On the GPU the shape is beautiful: the *outer* loop over bodies becomes 64 parallel
threads, and each thread keeps a small *inner* loop over the other 63. O(n²) work,
O(n) time per thread, all at once.

One wrinkle: pulls are **vectors** now, not strengths. The unit direction
from you to body *j* is `(dx / r, dy / r)`, and the strength is
`mass[j] / r²` — multiply them and the x-component of each contribution is
`mass[j] · dx / r³`. This kernel sums just the x-components; skip yourself, or
you'll divide by zero.

## Figures

- **sixty-three pulls per body, summed in one thread — n² work, n time**

## Goal

**Goal:** complete the inner loop so each thread returns the net
x-acceleration on its body: the sum of `mass[j] · dx / r³` over every other body.

## Requirements

- Loop `j` over all `this.constants.n` bodies
- Skip yourself — the `j !== this.thread.x` guard is already there
- Accumulate `mass[j] * dx / (r² · r)` into `ax`

## Hint 1 — where does r³ come from?

Direction `dx / r` times strength `1 / r²` is
`dx / r³`. With `r2 = dx*dx + dy*dy` in hand, that's
`r2 * Math.sqrt(r2)` — one square root per pair.

## Hint 2 — the loop body

```js
const dx = posX[j] - myX;
const dy = posY[j] - myY;
const r2 = dx * dx + dy * dy;
ax += mass[j] * dx / (r2 * Math.sqrt(r2));
```

## Same idea elsewhere

This loop-inside-a-thread is the canonical O(n²) GPU pattern. Fast CUDA and ROCm
n-body codes keep exactly this loop but *tile* it: a thread block stages a chunk of
bodies in shared memory so all threads reuse the loads — WebGPU's
`var<workgroup>` and Metal's threadgroup memory exist for the same trick.

## Starter code

```js
// Newton, vectorised: this thread's body feels EVERY other body.
// The inner loop is O(n) — but all 64 of them run at once.
const gpu = new GPU({ mode });

const accelX = gpu.createKernel(function (posX, posY, mass) {
  const myX = posX[this.thread.x];
  const myY = posY[this.thread.x];
  let ax = 0;
  for (let j = 0; j < this.constants.n; j++) {
    if (j !== this.thread.x) {
      // TODO: dx, dy → r² → accumulate mass[j] * dx / r³
      // (dx / r is the direction, 1 / r² is the strength.)
      ax += 0;
    }
  }
  return ax;
}, { output: [64], constants: { n: 64 } });

const ax = await accelX(posX, posY, mass);
console.log('net x-pull on body 0:', ax[0]);
```

---

Interactive version: https://gpu.rocks/learn/n-body-gravity-5de47751/2

[Previous task](https://gpu.rocks/learn/n-body-gravity-5de47751/1.md) · [Next task](https://gpu.rocks/learn/n-body-gravity-5de47751/3.md)
