Created
March 1, 2019 00:42
-
-
Save gavr123456789/968cd3485cfdc1e784422660506999ba to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* The Computer Language Benchmarks Game | |
https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ | |
contributed by Isaac Gouy | |
*/ | |
// using System; | |
[Compact] | |
class NBody { | |
public static void main(string[] args) { | |
int n = 10000; | |
print(@"sas $(args[1])\n"); | |
if (args.length > 0) n = int.parse(args[1]); | |
print("get arg %d\n",n); | |
NBodySystem bodies = new NBodySystem(); | |
print(@"$(bodies.Energy())\n"); | |
ulong microseconds; | |
double seconds; | |
Timer timer = new Timer (); | |
for (int i=0; i<n; i++) | |
bodies.Advance(0.01); | |
timer.stop (); | |
seconds = timer.elapsed (out microseconds); | |
print (@"sec = $seconds mcsec = $microseconds"); | |
print(@"$(bodies.Energy())\n"); | |
} | |
} | |
class NBodySystem { | |
public Body[] bodies; | |
public NBodySystem() { | |
bodies = new Body[]{ | |
Body.Sun(), | |
Body.Jupiter(), | |
Body.Saturn(), | |
Body.Uranus(), | |
Body.Neptune() | |
}; | |
double px = 0.0; | |
double py = 0.0; | |
double pz = 0.0; | |
foreach (Body body in bodies) { | |
px += body.vx * body.mass; | |
py += body.vy * body.mass; | |
pz += body.vz * body.mass; | |
} | |
bodies[0].OffsetMomentum(px,py,pz); | |
} | |
public void Advance(double dt) { | |
double dx, dy, dz, distance, mag; | |
for (int i=0; i < bodies.length; i++) { | |
Body bodyi = bodies[i]; | |
for (int j=i+1; j < bodies.length; j++) { | |
Body bodyj = bodies[j]; | |
dx = bodyi.x - bodyj.x; | |
dy = bodyi.y - bodyj.y; | |
dz = bodyi.z - bodyj.z; | |
distance = Math.sqrt(dx*dx + dy*dy + dz*dz); | |
mag = dt / (distance * distance * distance); | |
bodyi.vx -= dx * bodyj.mass * mag; | |
bodyi.vy -= dy * bodyj.mass * mag; | |
bodyi.vz -= dz * bodyj.mass * mag; | |
bodyj.vx += dx * bodyi.mass * mag; | |
bodyj.vy += dy * bodyi.mass * mag; | |
bodyj.vz += dz * bodyi.mass * mag; | |
} | |
} | |
foreach (Body body in bodies) { | |
body.x += dt * body.vx; | |
body.y += dt * body.vy; | |
body.z += dt * body.vz; | |
} | |
} | |
public double Energy() { | |
double dx, dy, dz, distance; | |
double e = 0.0; | |
for (int i=0; i < bodies.length; i++) { | |
Body bodyi = bodies[i]; | |
e += 0.5 * bodyi.mass * | |
( bodyi.vx * bodyi.vx | |
+ bodyi.vy * bodyi.vy | |
+ bodyi.vz * bodyi.vz ); | |
for (int j=i+1; j < bodies.length; j++) { | |
Body bodyj = bodies[j]; | |
dx = bodyi.x - bodyj.x; | |
dy = bodyi.y - bodyj.y; | |
dz = bodyi.z - bodyj.z; | |
distance = Math.sqrt(dx*dx + dy*dy + dz*dz); | |
e -= (bodyi.mass * bodyj.mass) / distance; | |
} | |
} | |
return e; | |
} | |
} | |
class Body { | |
const double PI = 3.141592653589793; | |
const double SOLAR_MASS = 4 * PI * PI; | |
const double DAYS_PER_YEAR = 365.24; | |
public double x; | |
public double y; | |
public double z; | |
public double vx; | |
public double vy; | |
public double vz; | |
public double mass; | |
public Body(){} | |
internal static Body Jupiter() { | |
Body p = new Body(); | |
p.x = 4.84143144246472090e+00; | |
p.y = -1.16032004402742839e+00; | |
p.z = -1.03622044471123109e-01; | |
p.vx = 1.66007664274403694e-03 * DAYS_PER_YEAR; | |
p.vy = 7.69901118419740425e-03 * DAYS_PER_YEAR; | |
p.vz = -6.90460016972063023e-05 * DAYS_PER_YEAR; | |
p.mass = 9.54791938424326609e-04 * SOLAR_MASS; | |
return p; | |
} | |
internal static Body Saturn() { | |
Body p = new Body(); | |
p.x = 8.34336671824457987e+00; | |
p.y = 4.12479856412430479e+00; | |
p.z = -4.03523417114321381e-01; | |
p.vx = -2.76742510726862411e-03 * DAYS_PER_YEAR; | |
p.vy = 4.99852801234917238e-03 * DAYS_PER_YEAR; | |
p.vz = 2.30417297573763929e-05 * DAYS_PER_YEAR; | |
p.mass = 2.85885980666130812e-04 * SOLAR_MASS; | |
return p; | |
} | |
internal static Body Uranus() { | |
Body p = new Body(); | |
p.x = 1.28943695621391310e+01; | |
p.y = -1.51111514016986312e+01; | |
p.z = -2.23307578892655734e-01; | |
p.vx = 2.96460137564761618e-03 * DAYS_PER_YEAR; | |
p.vy = 2.37847173959480950e-03 * DAYS_PER_YEAR; | |
p.vz = -2.96589568540237556e-05 * DAYS_PER_YEAR; | |
p.mass = 4.36624404335156298e-05 * SOLAR_MASS; | |
return p; | |
} | |
internal static Body Neptune() { | |
Body p = new Body(); | |
p.x = 1.53796971148509165e+01; | |
p.y = -2.59193146099879641e+01; | |
p.z = 1.79258772950371181e-01; | |
p.vx = 2.68067772490389322e-03 * DAYS_PER_YEAR; | |
p.vy = 1.62824170038242295e-03 * DAYS_PER_YEAR; | |
p.vz = -9.51592254519715870e-05 * DAYS_PER_YEAR; | |
p.mass = 5.15138902046611451e-05 * SOLAR_MASS; | |
return p; | |
} | |
internal static Body Sun() { | |
Body p = new Body(); | |
p.mass = SOLAR_MASS; | |
return p; | |
} | |
internal Body OffsetMomentum(double px, double py, double pz) { | |
vx = -px / SOLAR_MASS; | |
vy = -py / SOLAR_MASS; | |
vz = -pz / SOLAR_MASS; | |
return this; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment