TransWikia.com

How to increase the speed of NDsolve when using WhenEvent

Mathematica Asked on October 1, 2020

I am trying to solve a set of ODE’s with switching. I implemented using WhenEvents.

xd = {1/√6, √5/√6};
x0 = {1/√2, 1/√2};
min = -0.0001;
max = 0.0001;
tmax = 10;
sol = NDSolve[{
   x1'[t] == -x2[t]*u1[t],
   x2'[t] == x1[t]*u1[t],
   WhenEvent[xd[[1]]* x2[t] - xd[[2]] x1[t] > max, u1[t] -> -1],
   WhenEvent[xd[[1]]* x2[t] - xd[[2]] x1[t] < min, u1[t] -> 1],
   x1[0] == x0[[1]], x2[0] == x0[[2]], u1[0] == -1},
  {x1, x2, x3, u1}, {t, 0, tmax}, DiscreteVariables -> {u1}]
Plot[{xd[[1]], xd[[2]], x1[t] /. sol, x2[t] /. sol}, {t, 0, tmax}, 
 PlotPoints -> 10000]
Plot[u1[t] /. sol, {t, 0, tmax}, PlotPoints -> 10000]

It performs as intended!

How ever, I need to another event WhenEvent[ xd[[1]]* x2[t] - xd[[2]] x1[t] < max && xd[[1]]* x2[t] - xd[[2]] x1[t] > min, u1[t] -> 0], it takes hours and does not produce results.

I think, the last event is raising too many events, so it’s taking a lot of time. Is there a work around for this?

One Answer

It seems to be related to the event location method. I used foo to indicate when an event was detected, and murf to show when a step is taken. With the default "LocationMethod", the integration gets stuck on the first event. This happens even when the other two events are removed. It also happens only if the event action is u[t] -> 0; change it to another nonzero value, and everything works fine. (I guess this makes sense. NDSolve is trying to find where the event occurs, but each time it steps across the event, the system stops moving, since u[t] == 0 sets all derivatives equal to zero. I guess that's confusing the root-finding algorithm.)

foo = murf = 0.;
PrintTemporary@
  Dynamic@{foo, Style[murf, PrintPrecision -> 17], Clock@Infinity};
xd = {1/√6, √5/√6};
x0 = {1/√2, 1/√2};
min = -0.0001;
max = 0.0001;
tmax = 10;
sol = NDSolve[{x1'[t] == -x2[t]*u1[t], x2'[t] == x1[t]*u1[t],
   WhenEvent[
    xd[[1]]*x2[t] - xd[[2]] x1[t] > min && 
     xd[[1]]*x2[t] - xd[[2]] x1[t] < max,
    foo = t; u1[t] -> 0, "LocationMethod" -> "LinearInterpolation"],
   WhenEvent[xd[[1]]*x2[t] - xd[[2]] x1[t] > max,(*foo=t;*)
    u1[t] -> -1],
   WhenEvent[xd[[1]]*x2[t] - xd[[2]] x1[t] < min,(*foo=t;*)u1[t] -> 1],
   x1[0] == x0[[1]], x2[0] == x0[[2]], u1[0] == -1},
  {x1, x2, x3, u1}, {t, 0, tmax}, 
  DiscreteVariables -> {u1 ∈ {-1, 0, 1}}, 
  StepMonitor :> (murf = t), MaxSteps -> 1000]

Of course it's stops pretty soon:

Plot[{xd[[1]], xd[[2]], x1[t] /. sol, x2[t] /. sol}, {t, 0, tmax}]
Plot[u1[t] /. sol, {t, 0, tmax}, PlotPoints -> 100]

enter image description here

Correct answer by Michael E2 on October 1, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP