I want to solve a system of coupled ODEs using NDSolve with WhenEvent. But I'm having a hard time trying to index the state vector x[i][t] inside NDSolve.
Here is my code (wrong indexing for x[i][t]):
n = 2; a = 1.1;
vars = Table[x[i][t], {i, n}];
eqns = Table[x[i]'[t] == a - x[i][t], {i, n}];
initcond = Table[x[i][0] == 0.3*i, {i, n}];
sol = NDSolve[
{eqns, initcond,
WhenEvent[
x[i][t] == 1,
x[i][t] -> 0]},
vars, {t, 0, 10}
];
Plot[Evaluate[vars /. sol], {t, 0, 10}, PlotRange -> All]
I want to reset any x[i][t] to 0 when it reaches 1. Is there an automatic way to do it? Thanks in advance!
Answer
You need to construct an event for each i from 1 to n:
Block[{n = 2, a = 1.1},
vars = Table[x[i], {i, n}];
eqns = Table[x[i]'[t] == a - x[i][t], {i, n}];
initcond = Table[x[i][0] == 0.3*i, {i, n}];
evts = Table[With[{i = i}, WhenEvent[x[i][t] == 1, x[i][t] -> 0]], {i, n}];
sol = NDSolve[{eqns, initcond, evts}, vars, {t, 0, 10}];
]
Plot[Evaluate[Through[vars[t]] /. sol], {t, 0, 10}, PlotRange -> All]

(Since WhenEvent is HoldAll, we have to inject the value of i with With[{i = i},...]. See the section "Scope" in the docs for With.
Comments
Post a Comment