# WhenEvent ignores some actions

I've got a problem where WhenEvent successfully detects an event, but then performs only some of the actions.

In this minimal example, x[t] can not exceed 1 (driven by If). If x[t] equals 1 in the time window from 0.1 to 0.9, it should be reduced to 0.2, toggle a DiscreteVariable, and print the time.

sol = NDSolve[{x'[t] == If[x[t] < 1, 4 x[t], 0],
WhenEvent[0.1 < t < 0.9 && x[t] >= 1,
{Print[t], x[t] -> 0.2, dv[t] -> 1 - dv[t]}],
x == 0.9, dv == 0}, {x, dv}, {t, 0, 1},
DiscreteVariables -> {dv}][];
(* 0.1 *)
(* 0.502359 *)


The two printed times show that the WhenEvent was correctly triggered twice -- once when the time window opens at t == 0.1 and another time later. But plotting x[t] shows that it was not correctly reduced to 0.2 at the second event at t = 0.502359.

Plot[Evaluate[x[t] /. sol], {t, 0, 1}] However the DiscreteVariable dv[t] was successfully toggled twice:

Plot[Evaluate[dv[t] /. sol], {t, 0, 1}] This seems to be an unfortunate interaction with the If statement, because changing x'[t] == 4 x[t] causes it to work fine.

Bug or just my improper use of WhenEvent? Any ideas for a workaround?

A slightly change of the dgl makes your program working:

{X, DV} =
NDSolveValue[{x'[t] == Boole[x[t] < 1.01] 10 x[t] ,
WhenEvent[0.1 < t < 0.9 && x[t] >= 1, {Print[t], x[t] -> 0.2, dv[t] -> 1 - dv[t]}], x == 0.9, dv == 0}, {x, dv} , {t, 0, 1}, DiscreteVariables -> {dv}] ;
Plot[{X[t], DV[t]} , {t, 0, 1}, GridLines -> {None, {1}}] • Thanks! Seems like the secret sauce in your answer is the 1.01, not the Boole, because changing my original code to If[x[t] < 1.01 works the same way. So does x[t] < 1.00000000001 which is an easy fix and close enough. May 29 '19 at 19:16

I don't know enough about WhenEvent to say whether the behavior is a bug or not. As a workaround, you can introduce an auxiliary function, and modify the WhenEvent condition:

f[t_] = Piecewise[{{1, .1<t<.9}}, 2];
sol = NDSolveValue[
{
x'[t] == If[x[t] < 1, 4 x[t], 0], x == .9,
h[t] == x[t], h == x,
dv == 0,
WhenEvent[x[t]>=f[t], {Print[t], h[t] -> .2, dv[t] -> 1 - dv[t]}]
},
{x, dv},
{t, 0, 1},
DiscreteVariables -> {dv}
];


0.1

0.502359

Visualization:

Plot[First @ Through @ sol[t], {t, 0, 1}] • Interesting approach! I wonder if this forces NDSolve to use a DAE solver. May 29 '19 at 19:26