The Computer Language
24.11 Benchmarks Game

n-body Toit program

source code

/* The Computer Language Benchmarks game
   https://salsa.debian.org/benchmarksgame-team/benchmarksgame/

   transliterated from Mark C. Lewis's Java program by Isaac Gouy   
*/

import math

main args:
  n := args.size == 1 ? int.parse args[0] : 0
  bodies := NBodySystem
  print "$(%.9f bodies.energy)" 
  n.repeat:
    bodies.advance 0.01
  print "$(%.9f bodies.energy)" 
  
    
class NBodySystem:
  bodies /List ::= ?
    
  constructor:
    bodies = [
      Body.Sun, 
      Body.Jupiter, 
      Body.Saturn, 
      Body.Uranus, 
      Body.Neptune,
      ]
      
    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  
      
    bodies[0].offsetMomentum px py pz
        
    
  advance dt/float:  
    dx := 0.0
    dy := 0.0
    dz := 0.0  
    distance := 0.0      
    mag := 0.0     
    bodies.size.repeat: 
      for j := it + 1; j < bodies.size; ++j:      
        dx = bodies[it].x - bodies[j].x 
        dy = bodies[it].y - bodies[j].y 
        dz = bodies[it].z - bodies[j].z 
        
        distance = math.sqrt dx*dx + dy*dy + dz*dz        
        mag = dt / (distance * distance * distance)
        
        bodies[it].vx -= dx * bodies[j].mass * mag
        bodies[it].vy -= dy * bodies[j].mass * mag
        bodies[it].vz -= dz * bodies[j].mass * mag
            
        bodies[j].vx += dx * bodies[it].mass * mag
        bodies[j].vy += dy * bodies[it].mass * mag
        bodies[j].vz += dz * bodies[it].mass * mag 
        
    bodies.do:       
      it.x += dt * it.vx
      it.y += dt * it.vy    
      it.z += dt * it.vz         
     

  energy -> float:
    dx := 0.0
    dy := 0.0
    dz := 0.0  
    distance := 0.0      
    e := 0.0
    bodies.size.repeat:   
      e += 0.5 * bodies[it].mass 
         *   (bodies[it].vx * bodies[it].vx 
            + bodies[it].vy * bodies[it].vy 
            + bodies[it].vz * bodies[it].vz)
            
      for j := it + 1; j < bodies.size; ++j:   
        dx = bodies[it].x - bodies[j].x 
        dy = bodies[it].y - bodies[j].y 
        dz = bodies[it].z - bodies[j].z         
        
        distance = math.sqrt dx*dx + dy*dy + dz*dz
        e -= (bodies[it].mass * bodies[j].mass) / distance  
        
    return e          
                     
         
class Body:
  static PI ::= 3.141592653589793
  static SOLAR-MASS ::= 4 * PI * PI
  static DAYS-PER-YEAR ::= 365.24
  
  x /float := ?
  y /float := ?
  z /float := ?
  vx /float := ?
  vy /float := ?
  vz /float := ?
  mass /float := ?
  
  constructor .x .y .z .vx .vy .vz .mass:
  
  static Sun -> Body: 
    return Body
      0.0
      0.0
      0.0
      0.0
      0.0
      0.0
      SOLAR_MASS    

  static Jupiter -> Body:
    return Body  
      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             

  static Saturn -> Body:
    return Body   
      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  
    
  static Uranus -> Body:
    return Body 
      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 
    
  static Neptune -> Body:
    return Body   
      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      
   
  offsetMomentum px/float py/float pz/float:
    vx = -px / SOLAR_MASS
    vy = -py / SOLAR_MASS
    vz = -pz / SOLAR_MASS      
    
    

notes, command-line, and program output

NOTES:
64-bit Ubuntu quad core
v2.0.0-alpha.163



 Tue, 08 Oct 2024 01:12:14 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_run nbody.toit 

1.24s to complete and log all make actions

COMMAND LINE:
 ./nbody.toit_run 50000000

PROGRAM OUTPUT:
-0.169075164
-0.169059907