The Computer Language
Benchmarks Game

n-body Swift #6 program

source code

/* The Computer Language Benchmarks Game
   http://benchmarksgame.alioth.debian.org/
   contributed by Ralph Ganszky
*/

import Glibc

let SOLAR_MASS = 4 * M_PI * M_PI
let DAYS_PER_YEAR = 365.24

var sun     = ( (0.0, 0.0, 0.0), (0.0, 0.0, 0.0), SOLAR_MASS )
var jupiter = ( (4.8414314424647209,
		-1.16032004402742839,
	        -0.103622044471123109),
                (1.66007664274403694e-03 * DAYS_PER_YEAR,
                 7.69901118419740425e-03 * DAYS_PER_YEAR,
                -6.90460016972063023e-05 * DAYS_PER_YEAR),
                 9.54791938424326609e-04 * SOLAR_MASS )
var saturn  = ( (8.34336671824457987,
		 4.12479856412430479,
		-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 )
var 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)
var 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)

var bodies = [sun, jupiter, saturn, uranus, neptune]

func advance(_ bodies: inout [((Double,Double,Double),
			     (Double,Double,Double),
			    Double)], dt: Double) {
    for i in 0..<bodies.count {
        for j in i+1..<bodies.count {
            let (dx, dy, dz) = (bodies[i].0.0 - bodies[j].0.0,
                                bodies[i].0.1 - bodies[j].0.1,
                                bodies[i].0.2 - bodies[j].0.2)
            
            let dSquared = dx*dx + dy*dy + dz*dz
            let distance = sqrt(dSquared)
            let mag = dt / (dSquared * distance)
            
            bodies[i].1 = (bodies[i].1.0 - dx * bodies[j].2 * mag,
                           bodies[i].1.1 - dy * bodies[j].2 * mag,
                           bodies[i].1.2 - dz * bodies[j].2 * mag)
            bodies[j].1 = (bodies[j].1.0 + dx * bodies[i].2 * mag,
                           bodies[j].1.1 + dy * bodies[i].2 * mag,
                           bodies[j].1.2 + dz * bodies[i].2 * mag)
        }
    }
    for i in 0..<bodies.count {
        bodies[i].0 = (bodies[i].0.0 + dt * bodies[i].1.0,
                       bodies[i].0.1 + dt * bodies[i].1.1,
                       bodies[i].0.2 + dt * bodies[i].1.2)
    }
}

func energy(_ bodies: [((Double,Double,Double),
		      (Double,Double,Double),
		      Double)]) -> Double {
    var energy = 0.0
    for (i, body) in bodies.enumerated() {
        energy += 0.5 * body.2 * ( body.1.0*body.1.0
				 + body.1.1*body.1.1
				 + body.1.2*body.1.2)
        for jbody in bodies[i+1..<bodies.count] {
            let dx = body.0.0 - jbody.0.0
            let dy = body.0.1 - jbody.0.1
            let dz = body.0.2 - jbody.0.2
            let distance = sqrt(dx*dx + dy*dy + dz*dz)
            energy -= (body.2 * jbody.2) / distance
        }
    }
    
    return energy
}

let n: Int
if CommandLine.argc > 1 {
    n = Int(CommandLine.arguments[1]) ?? 1000
} else {
    n = 1000
}

// Adjust momentum of the sun
var p = (0.0, 0.0, 0.0)
for body in bodies {
    p.0 += body.1.0 * body.2
    p.1 += body.1.1 * body.2
    p.2 += body.1.2 * body.2
}
bodies[0].1 = (-p.0 / SOLAR_MASS, -p.1 / SOLAR_MASS, -p.2 / SOLAR_MASS)

print("\(energy(bodies))")
for i in 0..<n {
    advance(&bodies, dt: 0.01)
}
print("\(energy(bodies))")
    

notes, command-line, and program output

NOTES:
64-bit Ubuntu quad core
Swift version 3.1-dev (LLVM 90ddc086b8, Clang 38e310f953, Swift 66d9533723)
Target: x86_64-unknown-linux-gnu




Fri, 14 Apr 2017 19:55:55 GMT

MAKE:
/usr/local/src/swift-2017-04-13-a-ubuntu16.10/usr/bin/swiftc nbody.swift-6.swift -Ounchecked -whole-module-optimization  -o nbody.swift-6.swift_run
nbody.swift-6.swift:8:22: warning: 'M_PI' is deprecated: Please use 'Double.pi' or '.pi' to get the value of correct type and avoid casting.
let SOLAR_MASS = 4 * M_PI * M_PI
                     ^
nbody.swift-6.swift:8:29: warning: 'M_PI' is deprecated: Please use 'Double.pi' or '.pi' to get the value of correct type and avoid casting.
let SOLAR_MASS = 4 * M_PI * M_PI
                            ^
nbody.swift-6.swift:108:5: warning: immutable value 'i' was never used; consider replacing with '_' or removing it
for i in 0..<n {
    ^
    _
1.56s to complete and log all make actions

COMMAND LINE:
./nbody.swift-6.swift_run 50000000

PROGRAM OUTPUT:
-0.169075163828524
-0.169059906816626