1
$\begingroup$

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}.

$\endgroup$
5
  • $\begingroup$ @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. $\endgroup$ – PeaceEverybody May 3 at 9:47
  • $\begingroup$ @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]. $\endgroup$ – PeaceEverybody May 3 at 13:36
  • $\begingroup$ @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 $\endgroup$ – PeaceEverybody May 4 at 6:11
  • $\begingroup$ @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. $\endgroup$ – PeaceEverybody May 4 at 8:21
  • $\begingroup$ @Bill I made it ! I'm gonna post it as an answer hoping it will help someone else in the future $\endgroup$ – PeaceEverybody May 5 at 12:40
1
$\begingroup$

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]

enter image description here

data
{{"a", "b", "a", "c"}}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.