# Problem with WhenEvent

I am trying to add a time dependent fraction to a parameter in NDSolve, i.e. when 10 < t< 20, add s to k1...

Manipulate[ sol = NDSolve[{A'[t] == k1*A[t], A == 10,
WhenEvent[ 10 < t < 20, k1 -> (k1 + s)]},
A, {t, 0, 100}],
{k1, 0.0, 1.0}, {s, 0.0, 1.0}]


But I cannot get the code to work, and get the following error message. Does anyone have any suggestions, or can find the error in the code?

NDSolve::wenset: Warning: the rule FEk1$$16->FEk1$$16+FEs16 will not
directly set the state because the left-hand side is not a list of state variables. >>


I don't think you can use WhenEvent to do what you want. The value of k1 is passed in the DE in NDSolve, not the symbol. WhenEvent has the attribute HoldAll, so that it deals with k1 and s as Symbols. Perhaps you could use ParametricNDSolve (see below).

Perhaps you want something like this?

kparam[t_?NumericQ, k1_, s_] := If[10 < t < 20, k1 + s, k1];
Manipulate[
sol = NDSolve[{A'[t] == kparam[t, k1, s]*A[t], A == 10}, A, {t, 0, 100}],
{k1, 0.0, 1.0}, {s, 0.0, 1.0}]


The solution (for k1 == 0.1, s == 0.2) looks like this:

Plot[Evaluate[A[t] /. sol], {t, 0, 30}] This accomplishes the same thing with ParametricNDSolve (if you have v9.0.1):

psol = ParametricNDSolve[{A'[t] == k1*A[t], A == 10,
WhenEvent[t < 10, k1 -> (k1 + s)],
WhenEvent[t < 20, k1 -> (k1 - s)]},
A, {t, 0, 100}, {k1 \[Element] Reals, s \[Element] Reals}];

Plot[Evaluate[A[0.1, 0.2][t] /. psol], {t, 0, 30}]
(* output same as above *)

• Thanks, all solutions are great! Apr 29, 2013 at 2:04

I'd like to extend the solution offered by Michael E2:

psol = ParametricNDSolve[{A'[t] == k1*A[t], A == 10,
WhenEvent[t < 10, k1 -> (k1 + s)],
WhenEvent[t < 20, k1 -> (k1 - s)]},
A, {t, 0, 100}, {k1 \[Element] Reals, s \[Element] Reals}];
(*Plot[Evaluate[A[0.1, 0.2][t] /. psol], {t, 0, 30}]*)


Note that even in the case the DE has two WhenEvents one can find the sensitivity of k1:

Plot[Evaluate[(A[0.1, 0.2][t] + {0, .1, -.1} D[A[k1, 0.2], k1][t] /.
k1 -> 0.1) /. psol], {t, 0, 30}, Filling -> {2 -> {3}}]


That's pretty cool! You don't need WhenEvent[] for this:

Manipulate[Plot[(A/. NDSolve[{A'[t] == (k1 + s HeavisidePi[1/10 (t - 15)]) A[t], A == 10},
A, {t, 0, 100}] [] )[x], {x, 0, 30}],
{k1, 0.0, 1.0}, {s, 0.0, 1.0}] You do not need WhenEvent here as stated. You can use it though but you have to treat k as a function of t, that is a discrete state variable k[t].

Manipulate[
DynamicModule[{
sol = NDSolveValue[{
y'[t] == k[t] y[t],
y == 10, k == k0,
WhenEvent[t > 10, k[t] -> k[t] + s],
WhenEvent[t < 20, k[t] -> k[t] - s]
}, y, {t, 0, 100},
DiscreteVariables -> k]},
Plot[sol[t], {t, 0, 30}]],
{{k0, .1}, 0, 1}, {{s, .2}, 0, 1}]

(* similar output *)
`