# WhenEvent how to handle events at the same time and detection order

I need to use WhenEvent inside NDSolve in which events happen simultaneously.
I show simple code to better explain my question:

eqTime = {time'[t] == 1, time[0] == 0};
update1 = WhenEvent[Mod[t , 0.2], {a[t] -> a[t] + 0.1, Sow@a[t]}];
update2 = WhenEvent[Mod[t , 0.3], {a[t] -> a[t] + 1, Sow@a[t]}];
update3 = WhenEvent[Mod[t , 0.6], {a[t] -> a[t] + 2, Sow@a[t]}];
update = {update1, update2, update3};
ic = a[0] == 0;
{sol, data} =
NDSolveValue[{eqTime, update, ic}, a[t], {t, 0, 0.7},
DiscreteVariables -> a[t]] // Reap;
data
(*{{0.1, 1.1, 1.2, 2.2, 4.2, 4.3}}*)


What I'd like to obtain is  {{0.1, 1.1, 1.2, 3.2}} in such a way that when the events happen at the same time only one wins, update3 in this case.
Another question, why data is not {{.1, 1.1, 1.2, 1.3, 2.3, 4.3}} ? Which is the order of detection ?

An approach could be to make the event in this form Mod[t,ST1] && !Mod[t, ST2]. I've already read the documentation and previous questions about how WhenEvent manages the event trigger thereby I know it has no Mathematica meaning but is just to show one road to approach the problem.

Here is a simple code to represent the issue:

eqTime = {time'[t] == 1, time[0] == 0};
update = WhenEvent[Mod[t, 0.1] && !Mod[t,0.2], { a[t] -> a[t] + 0.1, Sow@a[t]}]; (*Not Working*)
ic = a[0] == 0;
{sol, data} =
NDSolveValue[{eqTime, update, ic}, a[t], {t, 0, 1},
DiscreteVariables -> a[t]] // Reap;

Plot[sol, {t, 0, 1}]


The output should be a step function that increases at {0.1, 0.3, 0.5, 0.7, 0.9}.

• @Bill Thanks for the answer. I know Mod[t, ST] is like a special function for WhenEvent and it doesn't return either True or False. It was just to show the behave I'd like to obtain. Commented May 3, 2021 at 9:47
• @Bill Thanks, I've modified the answer because I wasn't explaining myself as I wanted. Your solution work for the last part of the question but it just translates in the time Mod[t, 0.2]. Commented May 3, 2021 at 13:36
• @Bill Thanks for the answer, I understand your work around. The fact is that in my original problem I need to do other more complex actions and this solution doesn't fit Commented May 4, 2021 at 6:11
• @Bill There is no need to be sorry, you have been very useful, my question was ill posed and thanks to you I caught it. Commented May 4, 2021 at 8:21
• @Bill I made it ! I'm gonna post it as an answer hoping it will help someone else in the future Commented May 5, 2021 at 12:40

The best solution I've found is quite simple despite of the struggle in making everything works.

t0 = 0;
tfin = 300;
TS1 = 0.2 // Rationalize;
TS2 = 0.3 // Rationalize;
TS3 = 0.6 // Rationalize;
eqTime = {time'[t] == 1, time[0] == t0};
ac1 = {a[t] -> a[t] + 0.1, Hold@Sow@"a"};
ac2 = {a[t] -> a[t] + 1, Hold@Sow@"b"};
ac3 = {a[t] -> a[t] + 2, Hold@Sow@"c"};
update1 =
WhenEvent[Mod[t, TS1] && Mod[Rationalize@t, TS3] != 0, Evaluate@ac1];
update2 =
WhenEvent[Mod[t, TS2] && Mod[Rationalize@t, TS3] != 0,
Evaluate@ac2];
update3 = WhenEvent[Mod[t, TS3], Evaluate@ac3];
update = {update1, update2, update3};
ic = a[0] == 0;
{tempo, {sol, data}} =
NDSolveValue[{eqTime, update, ic}, {a[t], n[t]}, {t, t0, 0.65},
DiscreteVariables -> a[t]] // Reap // AbsoluteTiming;
Plot[sol[[1]], {t, t0, 0.65}, PlotRange -> All]


data
{{"a", "b", "a", "c"}}