# WhenEvent in NDSolve

How come this doesn't work as I intended?

s[{x0_, y0_}, a_, v_] := NDSolveValue[{
x'[t] == vx[t], WhenEvent[x[t] > 0, vx[t] -> -vx[t]],
y'[t] == vy[t] - t, WhenEvent[y[t] < 0, vy[t] -> -vy[t]],
x[0] == x0, vx[0] == v Cos@a,
y[0] == y0, vy[0] == v Sin@a},
{x[t], y[t]}, {t, 0, 10},
DiscreteVariables -> {vx, vy}]


Simulating falling and bouncing of a 2D mass point.

With[{r0 = {-5, 7}},
ParametricPlot[Evaluate@s[r0, -.9, 2],
{t, 0, 10},
PlotRange -> {{-10, 10}, {-10, 10}},
Epilog -> {Point@r0}]]


I can't understand why it doesn't bounce on the x-axis first, and what does happen there anyway? Event x[t]>0 works fine.

Following help I started with lowering the order of equations (and so doubling the number of variables). Here I wrote the equations in a more familiar 2nd order; everything works as expected. I put the function below in a tiny loop which bisected the right initial velocity v0 that returns the ball in its starting position.

Could this be done within NDSolve? I looked Wolfram tutorial for Boundary Value Problems but haven't been able to figure it out.

sstop[{x0_, y0_}, a_, v0_] := NDSolveValue[{
x''[t] == 0, WhenEvent[x[t] > 0, x'[t] -> -x'[t]],
y''[t] == -1, WhenEvent[y[t] < 0, y'[t] -> -y'[t]],
WhenEvent[x[t] < x0, Sow[{t, y[t]}]; "StopIntegration"],
x[0] == x0, x'[0] == v0 Cos[a],
y[0] == y0, y'[0] == v0 Sin[a]},
{x[t], y[t]}, {t, 0, 20}] // Reap

• Have you tried removing the WhenEvent for x[t]>0? Is it the other When Event still ignored? Apr 10, 2013 at 21:13
• Try this WhenEvent[{x[t] > 0, y[t] <0}, If[x[t]>0,vx[t] -> -vx[t],vy[t] -> -vy[t] ]] I think you can have only one WhenEvent included. Apr 10, 2013 at 21:16
• @Spawn1701D Gee, now the same "refraction" occurs at y-axis as well.
– BoLe
Apr 10, 2013 at 21:20
• I read the manual and I thing that if you have more than one WhenEvents you have to put them in a list, e.g { WhenEvent[x[t] > 0, vx[t] -> -vx[t]], WhenEvent[y[t] < 0, vy[t] -> -vy[t]]} Apr 10, 2013 at 21:22

Here you have a bouncing ball simulation using WithEvents[]:

s[{x0_, y0_}, a_, v_] := NDSolveValue[
{
y''[t] == -1,
x'[t] == vx[t],
y[0] == y0,
x[0] == x0,
y'[0] == v Sin@a,
vx[0] == v Cos@a,
vy[0] == v Sin@a,
WhenEvent[y[t] < 0, y'[t] -> - y'[t]],
WhenEvent[x[t] > 0, vx[t] -> -vx[t]]},
{x, y}, {t, 0, 8},
DiscreteVariables -> {vx, vy}] ;

With[{r0 = {-1, 1}},
ParametricPlot[Through[s[r0, 1, 1][u]], {u, 0, 5}, PlotRange -> All,
Epilog -> {Point@r0}]]


• That is weird. If anything, vy picks up, and what does vx[t] -> - 3 vx[t] mean? I'm running a physical system here! :)
– BoLe
Apr 10, 2013 at 22:11
• Thanks. I made a conceptual mistake, I can now understand what was going on above.
– BoLe
Apr 11, 2013 at 19:09