n-body F# .NET Core program
source code
// The Computer Language Benchmarks Game
// https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
//
// contributed by Valentin Kraevskiy
// modified by Peter Kese
// rewritten to be less "advanced" and similar to the OCAML implementation by Phillip Carter
open System
let solar_mass = 4. * Math.PI * Math.PI
let days_per_year = 365.24
type Planet =
{ mutable X: float
mutable Y: float
mutable Z: float
mutable VX: float
mutable VY: float
mutable VZ: float
Mass: float }
let advance bodies dt =
let n = Array.length bodies - 1
for i = 0 to n do
let b = bodies.[i]
for j = i+1 to n do
let b' = bodies.[j]
let dx = b.X - b'.X
let dy = b.Y - b'.Y
let dz = b.Z - b'.Z
let dist2 = dx * dx + dy * dy + dz * dz
let mag = dt / (dist2 * sqrt(dist2))
b.VX <- b.VX - dx * b'.Mass * mag
b.VY <- b.VY - dy * b'.Mass * mag
b.VZ <- b.VZ - dz * b'.Mass * mag
b'.VX <- b'.VX + dx * b.Mass * mag
b'.VY <- b'.VY + dy * b.Mass * mag
b'.VZ <- b'.VZ + dz * b.Mass * mag
for i = 0 to n do
let b = bodies.[i]
b.X <- b.X + dt * b.VX
b.Y <- b.Y + dt * b.VY
b.Z <- b.Z + dt * b.VZ
let energy bodies =
let mutable e = 0.0
let n = Array.length bodies - 1
for i = 0 to n do
let b = bodies.[i]
e <- e + 0.5 * b.Mass * (b.VX * b.VX + b.VY * b.VY + b.VZ * b.VZ)
for j = i+1 to n do
let b' = bodies.[j]
let dx = b.X - b'.X
let dy = b.Y - b'.Y
let dz = b.Z - b'.Z
let distance = sqrt(dx * dx + dy * dy + dz * dz)
e <- e - (b.Mass * b'.Mass) / distance
e
let offset_momentum bodies =
let mutable px = 0.0
let mutable py = 0.0
let mutable pz = 0.0
for i = 0 to Array.length bodies - 1 do
px <- px + bodies.[i].VX * bodies.[i].Mass
py <- py + bodies.[i].VY * bodies.[i].Mass
pz <- pz + bodies.[i].VZ * bodies.[i].Mass
bodies.[0].VX <- -px / solar_mass
bodies.[0].VY <- -py / solar_mass
bodies.[0].VZ <- -pz / solar_mass
let jupiter =
{ X = 4.84143144246472090e+00
Y = -1.16032004402742839e+00
Z = -1.03622044471123109e-01
VX = 1.66007664274403694e-03 * days_per_year
VY = 7.69901118419740425e-03 * days_per_year
VZ = -6.90460016972063023e-05 * days_per_year
Mass = 9.54791938424326609e-04 * solar_mass }
let saturn =
{ X = 8.34336671824457987e+00
Y = 4.12479856412430479e+00
Z = -4.03523417114321381e-01
VX = -2.76742510726862411e-03 * days_per_year
VY = 4.99852801234917238e-03 * days_per_year
VZ = 2.30417297573763929e-05 * days_per_year
Mass = 2.85885980666130812e-04 * solar_mass }
let uranus =
{ X = 1.28943695621391310e+01
Y = -1.51111514016986312e+01
Z = -2.23307578892655734e-01
VX = 2.96460137564761618e-03 * days_per_year
VY = 2.37847173959480950e-03 * days_per_year
VZ = -2.96589568540237556e-05 * days_per_year
Mass = 4.36624404335156298e-05 * solar_mass }
let neptune =
{ X = 1.53796971148509165e+01
Y = -2.59193146099879641e+01
Z = 1.79258772950371181e-01
VX = 2.68067772490389322e-03 * days_per_year
VY = 1.62824170038242295e-03 * days_per_year
VZ = -9.51592254519715870e-05 * days_per_year
Mass = 5.15138902046611451e-05 * solar_mass }
let sun =
{ X = 0.0
Y = 0.0
Z = 0.0
VX = 0.0
VY = 0.0
VZ = 0.0
Mass = solar_mass }
let bodies = [| sun; jupiter; saturn; uranus; neptune |]
[<EntryPoint>]
let main args =
let n = if Array.isEmpty args then 20_000_000 else int args.[0]
let e0 = energy bodies
offset_momentum bodies
for _ = 1 to n do
advance bodies 0.01
let e1 = energy bodies
printf "%.9f\n%.9f\n" e0 e1
0
notes, command-line, and program output
NOTES:
64-bit Ubuntu quad core
.NET Core SDK 3.1.201
Host Version: 3.1.3; Commit: 4a9f85e9f8
<ServerGarbageCollection>true
<ConcurrentGarbageCollection>true
Thu, 18 Jun 2020 19:58:09 GMT
MAKE:
cp nbody.fsharpcore Program.fs
cp Include/fsharpcore/tmp.fsproj .
mkdir obj
cp Include/fsharpcore/project.assets.json ./obj
/usr/bin/dotnet build -c Release --no-restore
Microsoft (R) Build Engine version 16.5.0+d4cbfca49 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.
tmp -> /home/dunham/benchmarksgame_quadcore/nbody/tmp/bin/Release/netcoreapp3.1/tmp.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:11.80
17.30s to complete and log all make actions
COMMAND LINE:
/usr/bin/dotnet ./bin/Release/netcoreapp3.1/tmp.dll 500000
UNEXPECTED OUTPUT
1c1
< -0.169289903
--- field 1 absolute error 2.15e-04
> -0.169075164
PROGRAM OUTPUT:
-0.169289903
-0.169096567