2
$\begingroup$

Can a time-based WhenEvent be triggered at the initial time within NDSolve? As a minimal example, a pulse is to be applied every integer time t, but NDSolve skips the initial pulse at t=0:

sol = NDSolve[{x'[t] == -x[t], x[0] == 0, WhenEvent[Mod[t, 1], x[t] -> x[t] + 1]},
  x, {t, 0, 1}][[1]];
Plot[x[t] /. sol, {t, 0, 1}]

enter image description here

One possible solution is to give the initial values just before t=0:

sol = NDSolve[{x'[t] == -x[t], x[-$MachineEpsilon] == 0,
  WhenEvent[Mod[t, 1], x[t] -> x[t] + 1]}, x, {t, 0, 1}][[1]];
Plot[x[t] /. sol, {t, 0, 1}]

enter image description here

but this leaves me slightly uneasy, because in general, the system will vary in the small time between t=-$MachineEpsilon and t=0. Also x[0]/.sol yields 0. instead of 1. even with this hack.

Is there a better way for such a time-based WhenEvent to be triggered at the initial time?

$\endgroup$
  • 1
    $\begingroup$ Similar to your approach you can create a separate WhenEvent : WhenEvent[ t == $MachineEpsilon , .. ] Obviously for this example you could just set initial condition x[0]=1, you might want to come up with a not-so-trivial example. $\endgroup$ – george2079 Aug 9 '16 at 21:45
  • $\begingroup$ I don't think so. Unless you consider an initial condition an "event." :) $\endgroup$ – Michael E2 Aug 9 '16 at 21:45
2
$\begingroup$

You could back up the initial condition so that t == 0 becomes an event, or you could effectively have a discrete variable be a switch to "turn on" the ODE at t == 0:

{sol} = NDSolve[{x'[t] == -x[t], x[-0.5] == 0, 
    WhenEvent[Mod[t, 1], x[t] -> x[t] + 1]}, x, {t, 0, 10}];
Plot[x[t] /. sol, {t, 0, 10}]

Mathematica graphics

A switch is a better way to keep the derivative x'[t] equal to zero until the first event:

{sol} = NDSolve[{x'[t] == a[t] (1 + 2 x[t] - x[t]^2), x[-1/2] == 0, 
    a[-1/2] == 0, WhenEvent[Mod[t, 1], x[t] -> x[t] + 1], 
    WhenEvent[t == 0, a[t] -> 1]},
   x, {t, 0, 10}, 
   DiscreteVariables -> {a}];
Plot[x[t] /. sol, {t, 0, 10}, PlotRange -> All]

Mathematica graphics

$\endgroup$
  • $\begingroup$ BTW, the simpler NDSolve[{x'[t] == UnitStep[t] (1 + 2 x[t] - x[t]^2), x[-1/2] == 0, WhenEvent[Mod[t, 1], x[t] -> x[t] + 1]}, x, {t, 0, 10}] fails to integrate, but I don't know why.... $\endgroup$ – Michael E2 Aug 9 '16 at 22:10
2
$\begingroup$

I have a simple mind, so I wonder why you can't just code the initial impulse into the initial condition.

sol =
  NDSolve[{x'[t] == -x[t], x[0] == 1, WhenEvent[Mod[t, 1], x[t] -> 1]},
    x, {t, 0, 3}][[1]];
Plot[x[t] /. sol, {t, 0, 3}]

plot

$\endgroup$
  • $\begingroup$ That's the obvious solution, but my real problem algorithmically generates the arguments for NDSolve within a function, so I'd have to parse out the user-supplied WhenEvents and then apply them to the user-supplied initial conditions. That's why I'm looking for a simpler solution that applies the WhenEvents at the initial time. $\endgroup$ – Chris K Aug 10 '16 at 13:45

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.