I'm trying to solve a many bodies problem with NDSolve and I want to integrate just untill one particle has moved beyond a certain point, say the circle of radius 10 in 2D.
ClearAll[force, r, numbodies, pos0]
numbodies = 10;
pos0 = .5 RandomReal[{-10, 10}, {numbodies, 2}];
force[j_] :=
Sum[(Normalize[r[j][t] - r[i][t]])/
EuclideanDistance[r[j][t], r[i][t]]^2 +
1/EuclideanDistance[r[j][t], r[i][t]]^12, {i,
Delete[Range[numbodies], j]}];
odesys = Table[{r[j]'[t] == force[j], r[j][0] == pos0[[j]](*,
WhenEvent[Norm[r[j][t]]>10//Evaluate,"StopIntegration"]*)}, {j, numbodies}];
depvars = Flatten[Table[{r[j]}, {j, numbodies}]];
tfin = 550;
sol = NDSolve[odesys, depvars, {t, 0, tfin}, AccuracyGoal -> 2][[1]];
pos = Array[r, {numbodies}] /. sol;
Show[ListLinePlot[
Transpose@Table[#[t] & /@ pos, {t, 0, tfin, tfin/100}],
Axes -> False, AspectRatio -> 1, Background -> Hue[.5],
PlotStyle -> Table[Hue[.5 + i/(2 numbodies)], {i, numbodies}],
ImageSize -> Large], Graphics[Circle[{0, 0}, 10]]]
The problem is when I uncomment the WhenEvent, and depending if I add an Evaluate
to it, as in this answer it will give either do nothing or break the integration. I guess my problem is that Evaluate
should act only on j
and not on t
but I don't know how to acomplish that.
So, what is the correct way to stop integrating my system when one particle crosses the circle?