0

From the expression we know Mod[t,1]==0 and Sin[2 [Pi] t] > 0 are equivalent in WhenEvent. This can be seen from the results below.

{sol, data} = Reap@NDSolve[{x'[t] == Cos[t], x[0] == 0, WhenEvent[x[t] > 0, Sow[{t, x[t]}]]}, x, {t, 0, 20}]
Plot[x[t] /. sol, {t, 0, 20}, Epilog -> {PointSize[0.01], Red, Apply[Point, data]}]
{sol2, data2} = Reap@NDSolve[{y'[t] == Cos[t], y[0] == 0, WhenEvent[Mod[t, 2 \[Pi]] == 0, Sow[{t, y[t]}]]}, y, {t, 0, 20}]
Plot[y[t] /. sol2, {t, 0, 20}, Epilog -> {PointSize[0.01], Red, Apply[Point, data2]}]

But in my real case, Mod[]==0 does not work correctly.

Clear["Global`*"];
F0 = 14160; FREF = 40; C0 = 40*10^-6; C1 = 360*10^-6; C2 = 20*10^-6; R1 = 14000; R2 = 1000; IP = 60*10^-6; IN = 60*10^-6; KVCO = 300; DELAY = 5;
sol = NDSolve[{R1*C1*VC1'[t] + VC1[t] == VC0[t], R2*C2*VC2'[t] + VC2[t] == VC0[t], C0*VC0'[t] + C1*VC1'[t] + C2*VC2'[t] == ICP[t], \[Phi]'[t] == 2 \[Pi]*(KVCO*VC2[t] + F0)/360, VC0[0] == 0, VC1[0] == 0, VC2[0] == 0, \[Phi][0] == 0, ICP[0] == 0, WhenEvent[Sin[\[Phi][t]] > 0 && ICP[t] == 0, ICP[t] -> -IN], WhenEvent[Sin[\[Phi][t]] > 0 && ICP[t] == IP, ICP[t] -> 0], WhenEvent[Mod[FREF*(t - DELAY), 1] == 0 && ICP[t] == 0 && t >= DELAY, ICP[t] -> IP], WhenEvent[Mod[FREF*(t - DELAY), 1] == 0 && ICP[t] == -IN && t >= DELAY, ICP[t] -> 0]}, {VC0, VC1, VC2, \[Phi]}, {t, 0, 30}, DiscreteVariables -> ICP];
Plot[VC2[t] /. sol, {t, 0, 30}]

Now if I use Sin[]>0, it works pretty fine.

sol2 = NDSolve[{R1*C1*VC1'[t] + VC1[t] == VC0[t], R2*C2*VC2'[t] + VC2[t] == VC0[t], C0*VC0'[t] + C1*VC1'[t] + C2*VC2'[t] == ICP[t], \[Phi]'[t] == 2 \[Pi]*(KVCO*VC2[t] + F0)/360, VC0[0] == 0, VC1[0] == 0, VC2[0] == 0, \[Phi][0] == 0, ICP[0] == 0, WhenEvent[Sin[\[Phi][t]] > 0 && ICP[t] == 0, ICP[t] -> -IN], WhenEvent[Sin[\[Phi][t]] > 0 && ICP[t] == IP, ICP[t] -> 0], WhenEvent[Sin[2 \[Pi]*FREF*(t - DELAY)] > 0 && ICP[t] == 0 && t >= DELAY, ICP[t] -> IP], WhenEvent[Sin[2 \[Pi]*FREF*(t - DELAY)] > 0 && ICP[t] == -IN && t >= DELAY,ICP[t] -> 0]}, {VC0, VC1, VC2, \[Phi]}, {t, 0, 30}, DiscreteVariables -> ICP];
Plot[VC2[t] /. sol2, {t, 0, 30}]
metroidman
  • 545
  • 7
  • Can you boil this all down to a simpler case? For instance, can you at least reproduce the problem with just a single WhenEvent? – MarcoB Dec 21 '23 at 12:24
  • 1
    I suggest reading many posts about the peculiarities of WhenEvent on this site (example 1, example 2). Try reordering the conditions and using a function with even crossing (Mod[..., 2] < 1]) instead of an odd one (Mod[..., 1] == 0]): WhenEvent[t >= DELAY && ICP[t] == 0 && Mod[FREF*(t - DELAY), 1] == 0, ...] – Domen Dec 21 '23 at 15:12
  • NDSolve uses a sequence of steps of the independent variable between its minimum and maximum values; it adaptively determines the step size. For an arbitrary step $x$, Sin[x] > 0 is True for a wide range of values, but Mod[x, 1] == 0 is True only when $x$ is near an integer within a small multiple of $MachineEpsilon. So unless the step size is small enough, Mod[FREF*(t - DELAY), 1] == 0 never encountrers a value that returns True. On the other hand, Sin[2 \[Pi]*FREF*(t - DELAY)] > 0 is True even when the step size is relatively large. – creidhne Dec 21 '23 at 18:43

0 Answers0