N-body problem: Difference between revisions

(Added Wren)
Line 3,367:
Body 3 : -1.006089 -4.103186 -3.122591 | -0.359686 -1.177995 -0.875924
</pre>
 
=={{header|Nim}}==
{{trans|Go}}
<lang Nim>import math, os, strformat, strscans, strutils
 
type Vector = tuple[x, y, z: float]
 
func`+`(v1, v2: Vector): Vector = (v1.x + v2.x, v1.y + v2.y, v1.z + v2.z)
 
func `+=`(v1: var Vector; v2: Vector) =
v1.x += v2.x
v1.y += v2.y
v1.z += v2.z
 
func`-`(v1, v2: Vector): Vector = (v1.x - v2.x, v1.y - v2.y, v1.z - v2.z)
 
func `*`(v: Vector; m: float): Vector = (v.x * m, v.y * m, v.z * m)
 
func abs(v: Vector): float = sqrt(v.x * v.x + v.y * v.y + v.z * v.z)
 
 
type Simulation = object
bodies: int
timeSteps: int
masses: seq[float]
gc: float
positions: seq[Vector]
velocities: seq[Vector]
accelerations: seq[Vector]
 
proc emitError(linenum: Positive) =
raise newException(ValueError, "wrong data at line $#.".format(linenum))
 
proc initSimulation(fileName: string): Simulation =
let infile = fileName.open()
var line = infile.readLine()
if not line.scanf("$f $i $i", result.gc, result.bodies, result.timeSteps):
emitError(1)
result.masses.setlen(result.bodies)
result.positions.setLen(result.bodies)
result.velocities.setLen(result.bodies)
result.accelerations.setLen(result.bodies)
var linenum = 1
for i in 0..<result.bodies:
inc linenum
line = infile.readLine()
if not line.scanf("$f", result.masses[i]):
emitError(linenum)
inc linenum
line = infile.readLine()
if not line.scanf("$f $f $f", result.positions[i].x, result.positions[i].y, result.positions[i].z):
emitError(linenum)
inc linenum
line = infile.readLine()
if not line.scanf("$f $f $f", result.velocities[i].x, result.velocities[i].y, result.velocities[i].z):
emitError(linenum)
 
 
func resolveCollisions(sim: var Simulation) =
for i in 0..sim.bodies-2:
for j in i+1..sim.bodies-1:
if sim.positions[i] == sim.positions[j]:
swap sim.velocities[i], sim.velocities[j]
 
 
func computeAccelerations(sim: var Simulation) =
for i in 0..<sim.bodies:
sim.accelerations[i] = (0.0, 0.0, 0.0)
for j in 0..<sim.bodies:
if i != j:
let m = sim.gc * sim.masses[j] / abs(sim.positions[i] - sim.positions[j])^3
sim.accelerations[i] += (sim.positions[j] - sim.positions[i]) * m
 
 
func computeVelocities(sim: var Simulation) =
for i in 0..<sim.bodies:
sim.velocities[i] += sim.accelerations[i]
 
 
func computePositions(sim: var Simulation) =
for i in 0..<sim.bodies:
sim.positions[i] += sim.velocities[i] + sim.accelerations[i] * 0.5
 
 
func step(sim: var Simulation) =
sim.computeAccelerations()
sim.computePositions()
sim.computeVelocities()
sim.resolveCollisions()
 
 
proc printResults(sim: Simulation) =
for i in 0..<sim.bodies:
echo &"Body {i + 1}: ",
&"{sim.positions[i].x: 8.6f} {sim.positions[i].y: 8.6f} {sim.positions[i].z: 8.6f} | ",
&"{sim.velocities[i].x: 8.6f} {sim.velocities[i].y: 8.6f} {sim.velocities[i].z: 8.6f}"
 
if paramCount() != 1:
echo "Usage: $# <file name containing system configuration data>" % getAppFilename().lastPathPart
else:
var sim = initSimulation(paramStr(1))
echo "Body x y z | vx vy vz"
for step in 1..sim.timeSteps:
echo "\nCycle ", step
sim.step()
sim.printResults()</lang>
 
{{out}}
Using same data as Go.
<pre>Body x y z | vx vy vz
 
Cycle 1
Body 1: 0.010177 0.000179 0.000002 | 0.010354 0.000357 0.000004
Body 2: 0.998230 0.998232 0.020002 | -0.003539 -0.003536 0.020004
Body 3: 0.010177 0.988232 0.988055 | 0.010354 -0.013536 -0.013889
 
Cycle 2
Body 1: 0.020709 0.000718 0.000011 | 0.010710 0.000721 0.000014
Body 2: 0.992907 0.992896 0.039971 | -0.007109 -0.007138 0.019935
Body 3: 0.020717 0.972888 0.972173 | 0.010727 -0.017153 -0.017876
 
Cycle 3
Body 1: 0.031600 0.001625 0.000034 | 0.011072 0.001094 0.000033
Body 2: 0.983985 0.983910 0.059834 | -0.010735 -0.010835 0.019790
Body 3: 0.031643 0.953868 0.952235 | 0.011125 -0.020886 -0.021999
 
Cycle 4
Body 1: 0.042858 0.002913 0.000081 | 0.011443 0.001481 0.000060
Body 2: 0.971393 0.971163 0.079509 | -0.014448 -0.014659 0.019561
Body 3: 0.042981 0.931039 0.928087 | 0.011552 -0.024772 -0.026299
 
Cycle 5
Body 1: 0.054492 0.004595 0.000160 | 0.011826 0.001884 0.000097
Body 2: 0.955030 0.954509 0.098909 | -0.018278 -0.018649 0.019238
Body 3: 0.054766 0.904225 0.899522 | 0.012018 -0.028857 -0.030829
 
Cycle 6
Body 1: 0.066517 0.006691 0.000281 | 0.012224 0.002308 0.000145
Body 2: 0.934759 0.933760 0.117931 | -0.022265 -0.022849 0.018806
Body 3: 0.067040 0.873197 0.866280 | 0.012530 -0.033199 -0.035655
 
Cycle 7
Body 1: 0.078950 0.009225 0.000456 | 0.012642 0.002759 0.000206
Body 2: 0.910400 0.908677 0.136456 | -0.026454 -0.027316 0.018244
Body 3: 0.079856 0.837662 0.828023 | 0.013101 -0.037871 -0.040861
 
Cycle 8
Body 1: 0.091815 0.012227 0.000702 | 0.013086 0.003245 0.000284
Body 2: 0.881722 0.878958 0.154340 | -0.030902 -0.032122 0.017523
Body 3: 0.093281 0.797239 0.784313 | 0.013749 -0.042975 -0.046559
 
Cycle 9
Body 1: 0.105140 0.015737 0.001035 | 0.013564 0.003775 0.000383
Body 2: 0.848429 0.844216 0.171401 | -0.035684 -0.037362 0.016600
Body 3: 0.107405 0.751427 0.734579 | 0.014498 -0.048649 -0.052908
 
Cycle 10
Body 1: 0.118964 0.019805 0.001481 | 0.014085 0.004362 0.000509
Body 2: 0.810137 0.803953 0.187408 | -0.040900 -0.043166 0.015414
Body 3: 0.122346 0.699554 0.678056 | 0.015384 -0.055097 -0.060138
 
Cycle 11
Body 1: 0.133337 0.024498 0.002071 | 0.014662 0.005025 0.000672
Body 2: 0.766343 0.757509 0.202050 | -0.046687 -0.049720 0.013868
Body 3: 0.138268 0.640690 0.613685 | 0.016460 -0.062633 -0.068603
 
Cycle 12
Body 1: 0.148327 0.029907 0.002851 | 0.015317 0.005792 0.000888
Body 2: 0.716377 0.703998 0.214889 | -0.053246 -0.057302 0.011810
Body 3: 0.155406 0.573482 0.539941 | 0.017816 -0.071782 -0.078886
 
Cycle 13
Body 1: 0.164025 0.036157 0.003887 | 0.016079 0.006709 0.001184
Body 2: 0.659310 0.642172 0.225282 | -0.060887 -0.066351 0.008976
Body 3: 0.174112 0.495836 0.454475 | 0.019596 -0.083511 -0.092045
 
Cycle 14
Body 1: 0.180564 0.043437 0.005286 | 0.017000 0.007852 0.001613
Body 2: 0.593807 0.570186 0.232208 | -0.070119 -0.077621 0.004875
Body 3: 0.194929 0.404136 0.353320 | 0.022038 -0.099890 -0.110265
 
Cycle 15
Body 1: 0.198150 0.052049 0.007234 | 0.018171 0.009372 0.002283
Body 2: 0.517817 0.485100 0.233878 | -0.081861 -0.092550 -0.001535
Body 3: 0.218605 0.290860 0.228583 | 0.025314 -0.126661 -0.139210
 
Cycle 16
Body 1: 0.217126 0.062542 0.010117 | 0.019781 0.011614 0.003484
Body 2: 0.427899 0.381659 0.226654 | -0.097974 -0.114332 -0.012913
Body 3: 0.244268 0.131956 0.057562 | 0.026013 -0.191148 -0.202831
 
Cycle 17
Body 1: 0.238346 0.076539 0.015221 | 0.022658 0.016380 0.006723
Body 2: 0.317489 0.248502 0.200967 | -0.122846 -0.151982 -0.038461
Body 3: 0.075592 -0.559591 -0.487315 | -0.363366 -1.191945 -0.886924
 
Cycle 18
Body 1: 0.263123 0.097523 0.026918 | 0.026898 0.025587 0.016672
Body 2: 0.173428 0.050424 0.112716 | -0.165275 -0.244174 -0.138041
Body 3: -0.286241 -1.745597 -1.369528 | -0.360299 -1.180066 -0.877501
 
Cycle 19
Body 1: 0.270854 0.113045 0.061923 | -0.011436 0.005457 0.053339
Body 2: 0.199821 -0.093105 -0.208666 | 0.218061 -0.042882 -0.504723
Body 3: -0.646318 -2.924909 -2.246453 | -0.359856 -1.178559 -0.876350
 
Cycle 20
Body 1: 0.258572 0.116046 0.112038 | -0.013129 0.000544 0.046890
Body 2: 0.426346 -0.111425 -0.681150 | 0.234987 0.006241 -0.440245
Body 3: -1.006089 -4.103186 -3.122591 | -0.359686 -1.177995 -0.875924</pre>
 
=={{header|Octave}}==
Anonymous user