source code
/* The Computer Language Benchmarks Game
https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
Naive transliteration from Michael Ferguson's Chapel program
contributed by Isaac Gouy
*/
import math
SOLAR-MASS ::= 4 * math.PI * math.PI
DAYS-PER-YEAR ::= 365.24
class Body:
x /float := ?
y /float := ?
z /float := ?
vx /float := ?
vy /float := ?
vz /float := ?
mass /float := ?
constructor .x .y .z .vx .vy .vz .mass:
offset-momentum bodies/List:
px := 0.0
py := 0.0
pz := 0.0
bodies.do:
px += it.vx * it.mass
py += it.vy * it.mass
pz += it.vz * it.mass
b := bodies[0]
b.vx = -px / SOLAR-MASS
b.vy = -py / SOLAR-MASS
b.vz = -pz / SOLAR-MASS
energy bodies/List -> float:
e := 0.0
num-bodies := bodies.size
num-bodies.repeat:
b := bodies[it]
sq := b.vx * b.vx + b.vy * b.vy + b.vz * b.vz
e += 0.5 * bodies[it].mass * sq
for j := it + 1; j < num-bodies; ++j:
dx := b.x - bodies[j].x
dy := b.y - bodies[j].y
dz := b.z - bodies[j].z
sq = dx * dx + dy * dy + dz * dz
e -= (b.mass * bodies[j].mass) / (math.sqrt sq)
return e
advance bodies/List dt/float:
num-bodies := bodies.size
num-bodies.repeat:
for j := it + 1; j < num-bodies; ++j:
dx := bodies[it].x - bodies[j].x
dy := bodies[it].y - bodies[j].y
dz := bodies[it].z - bodies[j].z
dpos_norm_sq := dx*dx + dy*dy + dz*dz
mag := dt / (dpos_norm_sq * (math.sqrt dpos_norm_sq))
mj := bodies[j].mass * mag
bodies[it].vx -= dx * mj
bodies[it].vy -= dy * mj
bodies[it].vz -= dz * mj
mi := bodies[it].mass * mag
bodies[j].vx += dx * mi
bodies[j].vy += dy * mi
bodies[j].vz += dz * mi
bodies.do:
it.x += it.vx * dt
it.y += it.vy * dt
it.z += it.vz * dt
nbody n/int:
bodies := [
// Sun
Body 0.0 0.0 0.0 0.0 0.0 0.0 SOLAR-MASS,
Body
// Jupiter
4.84143144246472090e+00
-1.16032004402742839e+00
-1.03622044471123109e-01
1.66007664274403694e-03 * DAYS-PER-YEAR
7.69901118419740425e-03 * DAYS-PER-YEAR
-6.90460016972063023e-05 * DAYS-PER-YEAR
9.54791938424326609e-04 * SOLAR-MASS,
Body
// Saturn
8.34336671824457987e+00
4.12479856412430479e+00
-4.03523417114321381e-01
-2.76742510726862411e-03 * DAYS_PER-YEAR
4.99852801234917238e-03 * DAYS-PER-YEAR
2.30417297573763929e-05 * DAYS-PER-YEAR
2.85885980666130812e-04 * SOLAR-MASS,
Body
// Uranus
1.28943695621391310e+01
-1.51111514016986312e+01
-2.23307578892655734e-01
2.96460137564761618e-03 * DAYS-PER-YEAR
2.37847173959480950e-03 * DAYS-PER-YEAR
-2.96589568540237556e-05 * DAYS-PER-YEAR
4.36624404335156298e-05 * SOLAR-MASS,
Body
// Neptune
1.53796971148509165e+01
-2.59193146099879641e+01
1.79258772950371181e-01
2.68067772490389322e-03 * DAYS-PER-YEAR
1.62824170038242295e-03 * DAYS-PER-YEAR
-9.51592254519715870e-05 * DAYS-PER-YEAR
5.15138902046611451e-05 * SOLAR-MASS,
]
offset-momentum bodies
print "$(%.9f energy bodies)"
n.repeat:
advance bodies 0.01
print "$(%.9f energy bodies)"
main args:
n := args.size == 1 ? int.parse args[0] : 0
nbody n
notes, command-line, and program output
NOTES:
64-bit Ubuntu quad core
v2.0.0-alpha.163
Tue, 08 Oct 2024 01:01:56 GMT
MAKE:
cp -r Include/toit/.packages .
cp -r Include/toit/package.lock .
cp -r Include/toit/package.yaml .
/opt/src/toit/bin/toit.compile -O2 --strip -o nbody.toit-8.toit_run nbody.toit-8.toit
1.15s to complete and log all make actions
COMMAND LINE:
./nbody.toit-8.toit_run 50000000
PROGRAM OUTPUT:
-0.169075164
-0.169059907