I have programmed a 3 body problem, that can in theory work for more than 3 bodies. I apologize in advance for the length of the code that I posted, I don't really know how much one would need to help.
My problem in a nutshell is that when I switched the program from 2D to 3D by adding a component to my initial vectors and making my ListPlot 3D, it didn't work any more and I couldn't see what was even happening. (I just want a way for me to see the path each of my particles takes in 3D)
On a side note... how do I create my Orbit1, Orbit2 and Orbit3 in a loop? so that I don't have to just keep adding terms when I add a particle.
Clear["Global`"];
Off[General::spell, General::spell1, General::infy];
dt = 0.01;
bodies = 3;
rnum := RandomReal[{-1.00, 1.00}];
rnum2 := RandomReal[{-0.07, 0.07}];
PosVel = Table[0, {0}, {j, 2}];
Do[{
Pos = {rnum, rnum, rnum},
Vel = {rnum2, rnum2, rnum2},
AppendTo[PosVel, {Pos, Vel}]
}, {j, 1, bodies}];
r = Table[0, {i, bodies}, {j, bodies}];
rmag = Table[0, {i, bodies}, {j, bodies}];
rsq = Table[0, {i, bodies}, {j, bodies}];
Do[{
r[[i, j]] = (PosVel[[i, 1]] - PosVel[[j, 1]]),
rmag[[i, j]] = Norm[(PosVel[[i, 1]] - PosVel[[j, 1]])],
rsq[[i, j]] = (Norm[(PosVel[[i, 1]] - PosVel[[j, 1]])])^2
}, {j, 1, bodies}, {i, 1, bodies}]
f = -1/rmag^3;
Do[{
f[[i, i]] = 0
}, {i, 1, bodies}]
Force = Table[0, {i, bodies}];
Do[{
Force[[i]] = Sum[f[[i, j]]*r[[i, j]], {j, 1, bodies}]
}, {i, 1, bodies}]
n = 3000;
Clear[Orbit];
Orbit = Table[0, {i, n}, {j, bodies}];
Do[{
PosVel[[i, 2]] = PosVel[[i, 2]] + Force[[i]]*dt,
PosVel[[i, 1]] = PosVel[[i, 1]] + PosVel[[i, 2]]*dt,
Do[{
r[[i, j]] = (PosVel[[i, 1]] - PosVel[[j, 1]]),
rmag[[i, j]] = Norm[(PosVel[[i, 1]] - PosVel[[j, 1]])],
rsq[[i, j]] = (Norm[(PosVel[[i, 1]] - PosVel[[j, 1]])])^2
}, {j, 1, bodies}, {i, 1, bodies}],
f = -1/rmag^3,
Do[{
f[[i, i]] = 0
}, {i, 1, bodies}],
Do[{
Force[[i]] = Sum[f[[i, j]]*r[[i, j]], {j, 1, bodies}]
}, {i, 1, bodies}],
Orbit[[j, i]] = PosVel[[i, 1]]
}, {i, 1, bodies}, {j, 1, n}]
Orbit1 = Table[Orbit[[i, 1]], {i, 1, n}];
Orbit2 = Table[Orbit[[i, 2]], {i, 1, n}];
Orbit3 = Table[Orbit[[i, 3]], {i, 1, n}];
Animate[
ListPlot3D[{Orbit1[[1 ;; j]], Orbit2[[1 ;; j]], Orbit3[[1 ;; j]]},
Mesh -> None,
Epilog -> {PointSize -> 0.05, Blue,
Point[{Orbit1[[j]], Orbit2[[j]], Orbit3[[j]]}]}], {j, 1, n, 1}]
orbit[x_] := Table[Orbit[[i, x]], {i, 1, n}];
And then do it for every body using map:
Map[Orbit[#] &, Range[bodies]]
I think in general you could speed and clean up your code by using constructs like Map instead of Do loops. I'd write this as an actual answer if I were more confident. But I happen to have recently written some NBody code of my own, if you would like to see it to get some ideas or inspiration feel free to send me a message.
– Jason Houtekamer Oct 19 '14 at 22:52Also the ListPointPlot3D works, thank you.
– Karl Oct 20 '14 at 13:15I am curious though about how to use Map instead of Do? Do you think you could give an example with regards to my code?
Lastly, how do I make animate and ListPlot work in this new case? Should I just use Plot since I now have a function? Or do I need to use one inside the other?
– Karl Oct 24 '14 at 15:09