# Using NDsolve with WhenEvent is not working

I am trying to use WhenEventin this No-linear equation system:

$$\ddot r-\dot\phi^2r+9.8(sin\phi-0.7cos\phi)=0$$

$$1.2(1+20(r^2+2^2+4rsin\phi)^2)\ddot\phi+\dot\phi+\phi=Sin4t$$

I want that When $$r(t)>1 \Rightarrow r(t)=1$$ and When $$r(t)<-1 \Rightarrow r(t)=-1$$ so I was using the code below:

sol = NDSolve[{r''[t] - phi'[t]^2 r[t] +
9.8 (Sin[phi[t]] - 0.7*Cos[phi[t]]) == 0,
1.2 (1 + 20*(r[t]^2 + 2^2 + 4 r[t] Sin[phi[t]])^2) phi''[t] +
phi'[t] + phi[t] == Sin[4 t],
phi[0] == phi'[0] == r[0] == r'[0] == 0,
WhenEvent[r[t] > 1, r[t] -> 1],
WhenEvent[r[t] < -1, r[t] -> -1]}, {r, phi}, {t, 0, 20}]

Plot[r[t] /. sol, {t, 0, 20}]


But when i run the code and i plot $$r$$ i take values bigger than 1... What am i doing wrong?

Thanks!

• You can "fix" this by setting WhenEvent[r[t]>1,r[t]->0.9998]. This is necessary due to how WhenEvent triggers. However, DO NOT DO THIS. Since your DE is of the second order, it will still tend towards the one anyway since its "velocity" keeps unchanged. Thus you'd just create a very fine sawtooth pattern. So you'd have to set the first derivative as well to get something stable. Something like WhenEvent[r[t]>1,{r[t]->0.99999,r'[t]->0}] or even the reflection. (Add PlotRange->All to your plot here) Oct 13 at 11:46
• Thank you so much, i will try what you have said!!! Oct 13 at 20:20

We have a misunderstanding here. r[t]>1 means: the time when r[t] crosses 1 from below and NOT when r[t] is larger than 1. Look it up in the help.

To achieve what you want, that r[t] stays constant after hitting 1, you may define a piecewise function:

sol = NDSolve[{1.2 (562500 +
1.2*(r[t]^2 + 40^2 + 2*r[t]*40*Sin[phi[t]])) phi''[t] +
1030400*phi'[t] + 0.41*phi[t] == 2*Sin [4 t],
r''[t] - 0.7*9.8*Cos[phi[t]] + 9.8 Sin[phi[t]] == 0,
phi[0] == r[0] == phi'[0] == r'[0] == 0,
WhenEvent[r[t] < -1, r[t] -> -1],
WhenEvent[r[t] > 1, {r[t] -> 1, tend = t, "StopIntegration"}]
}, {r[t], phi[t]}, {t, 0, 20}]
fun[t_] =
Piecewise[{{Evaluate[r[t] /. sol[[1, 1]]], t < tend}, {1, True}}]


This gives the following interpolating function:

Plot[fun[t], {t, 0, 20}]


• Thank you so much for the info!! Oct 13 at 20:20