# Tag Info

## Hot answers tagged event-detection

18

There are two problems with the original post, both can be solved by referring to the documentation for handling discontinuity events: 1) As described under Changing State Variables section, the change in multiple state variables should either be attempted through a single rule with a list of variables or through multiple rules. Multiple rules have the ...

15

There are other approaches to achieve what you have described. As I guess this is only a simplification of what you really need, here is how you would do it with WhenEvent: equation = x'[t] + (x[t] - λ[t]) == 0; sol = NDSolveValue[{equation, x == 0, λ == 1, WhenEvent[x'[t] == 0.25, λ[t] -> x[t]]}, x, {t, 0, 5}, DiscreteVariables -> {λ}] ...

14

WhenEvent is triggered but does apparently not apply correctly the reflection. The following works (note that it uses only one WhenEvent). The Print["bounce"] is of course to be removed, I kept it just to check that the bouncing condition is triggered. refl[x_?NumericQ, y_, xp_, yp_] := vreflect /. x[t] -> x /. y[t] -> y /. x'[t] -> xp /. y'[t] -&...

13

From WhenEvent: Examples of events and how $t_a$ is determined include: ... f == 0 && pred -- f crosses zero and pred is True I believe that the same special case is applied to And for forms f > 0 && pred, etc. So WhenEvent[Abs[x[t]] > 1 && x[t] > 2, {x'[t] -> -3 x'[t]}] means the event will be triggered when Abs[x[t]]...

12

I have been unsuccessful at getting the automatic discontinuity handling to work. (I get the errors "Failure to project onto the discontinuity surface when computing Filippov continuation".) But manually handling it with WhenEvent works, although it complains about slow convergence to the event locations. Perhaps the discontinuity conditions are ...

12

reworked into vector form: surf[x_] = Sin[x] + (0.2 Cos[4 x + Sin[4 x]]) - 0.2 x + 3; n[x_] = Normalize[{-D[surf[x], x], 1}]; c = 0.99; vreflect[v : {_?NumericQ, _?NumericQ}, x : {_?NumericQ, _?NumericQ}] := (-(1 + c) (v.n[x[]]) n[x[]] + v); bounce[x : {_?NumericQ, _?NumericQ}] := (x[] < surf[x[]]) sol = First@NDSolve[{ ...

12

Events are processed in special ways Consider the general form: WhenEvent[ A && B , code; actions, options...] ^event ^ Though the title suggests options are a key interest in the OP, they are not the main problem underlying the error. One may put code before the actions, which are rules or keyword strings. I use it below, but it, too, ...

11

Edit: Using a helper function fh will result in no messages and no need to set extra options. σ[t_] := 40000 Sin[0.02 t] C1 = 80000; C2 = 20000; σgr = 15000; fh[t_?NumericQ, x_, y_] := Piecewise[{{C1/(C1 + C2)*y, (σ[t]*y > 0) && ((σ[t] - C2*x >= σgr) || (σ[t] - C2*x <= -σgr))}}, 0] sol = NDSolve[{s[t] == σ[t]/C1 + sep[t], sep'[t] == fh[...

11

I'm not sure how to explain this behavior, but I've found a solution. Just move the condition to 2nd argument of WhenEvent: WhenEvent[Mod[t, 2 π] == 0, If[t > 50, Sow@{t, x[t], x'[t]}]]

9

I think the OP is trying to demonstrate hysteresis. WhenEvent has an example of an on-off controller, which is an example of a bistable system. Unfortunately, my understanding is, that an event must be a function of time only and cannot have local spatial dependence. The essence of the Numerical Method of Lines is to turn a time-dependent PDE into a system ...

8

WhenEvent[cond, act] works in time, i.e., an event happens only when a time step causes the condition cond to change from False to True, save the special cases such as f == c described in the documentation. Those subtleties aside, the main thing to understand in using WhenEvent in the method of lines is what is substituted for the dependent variables such ...

8

This might be useful if your actual event is more complicated, use a discrete variable as a flag: sols = NDSolve[{(1 + 25 Exp[-u[s]^2] u[s]^2) u'[s]^2 == u[s]^2, u == 0.5, a == 1, WhenEvent[u[s] == 4, a[s] -> 0], WhenEvent[a[s] == 0, "StopIntegration"] }, {u, a}, {s, 0, 20}, DiscreteVariables -> {a[s]}] u /. Select[sols,...

7

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.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[...

7

Here is a workaround suggested by the response I received from WRI: {sol} = NDSolve[{x'[t] == -0.08 x[t], x == 1., WhenEvent[Norm[{x'[t]}] < 0.0001, {x[t] -> 1.}]}, {x}, {t, 0, 200}, Method -> {"EquationSimplification" -> "Residual"} ] Plot[x[t] /. sol, {t, 0, 200}] Warning: This option works by converting the system to a DAE, for ...

7

s = NDSolve[{y'[t] == {{.1, -.2}, {-.1, .2}}.y[t], y == {1, 1}, WhenEvent[Norm[y[t] - {0.9460552574072016, 1.053944742592798}] <= .01, y[t] -> {1, 1}]} , y[t], {t, 0, 1}] Plot[y[t] /. s[] /. t -> u, {u, 0, 1}]

7

Here is a solution : u[t_]:=Piecewise[{{0,t<1},{10 (t-1),t<1.1},{1,True}}] rsw[t_]:=Piecewise[{{1,t<2},{1+ 90 (t-2),t<2.1},{10,True}}] l=0.3; r=1; res=NDSolveValue[{ l i'[t]==u[t]-r i[t] - (i[t]- 10^-14 Exp[vdiode[t]/0.025]) rsw[t], vdiode[t] + l i'[t] + r i[t]==0, vdiode==0, i==-1/2 10^-14 }, {i,vdiode}, {t,0,3} ] Plot[Evaluate[Join[{u[t]...

7

From the documentation of DSolve, this is classified as a hybrid-differential equation. You need to specify the range of t something like {0, 10} DSolve[{f == 0, f'[t] == 2, WhenEvent[f[t] == 5, f[t] -> 10]}, f[t], {t, 0, 10}]

7

I do not see what the problem is. t1 = 1; t2 = 2; t3 = 3; L = 10; T = 10; bc = {P[t, 0] == 0, P[t, L] == UnitStep[t - t1] - UnitStep[t - t2]/2 - UnitStep[t - t3]/4}; a[p_] := Piecewise[{{1, p < .3}, {2, .3 <= p < .5}, {1/2, True}}] ic = {P[0, x] == 0}; eq = D[P[t, x], t] - a[P[t, x]]*D[P[t, x], x, x] == 0; sol = NDSolveValue[{eq, ic, bc}, ...

6

The proper way to generate events is to symbolically refer to vector elements, that is: using Indexed (since v10). Here I assume that the vector length n can change (in that case one must adjust the matrix used in y'[t] also), and I also use a programmatic way to set up events for all vector elements (see this answer). ClearAll[y, t]; n = 2; (* vector ...

6

This is in part some minor improvements in speed for ChrisK's good answer (+1), and in part an extended comment. To begin, using Subscript variables generally is not a good idea in computations. Also, building Tables inside NDSolve often is slow, although it does not matter much here. With these changes, the question's code as optimized by ChrisK becomes ...

5

Here is my solution, just change the WhenEvent part to WhenEvent[First@y[t] == 0, y[t] -> {1, Last@y[t]}] sol = NDSolve[{y'[t] == {{.1, -.2}, {-.1, .2}}.y[t], y == {1, 1}, WhenEvent[First@y[t] == 0, y[t] -> {1, Last@y[t]}]}, y, {t, 0, 10}] Plot[Evaluate[y[t] /. sol], {t, 0, 10}] Mathematica gives

5

Changing parameter values during integration works better with DiscreteVariables. But I think the problem with OP's code, in the question and the OP's answer, has more to do with Mathematica numerics. My solution Clear[bind]; zdot = 1/2 (1 - z[t]); ydot = 1/20*y[t] + z[t] - x[t]; xdotbind = D[Solve[-ydot - zdot == 0, x[t]][[1, 1, 2]], t] /. {y'[t] -> ...

5

Another way, stopping the forward integration if the backward integration is found to be periodic: (*solves the system*) periodicQ = False; {solDAE} = NDSolve[{sysDAE0, WhenEvent[Evaluate@isPeriodic[varst, ic], periodicQ = True; "StopIntegration"], WhenEvent[Positive[t] && periodicQ, (* was t > \$MachineEpsilon && ...

5

First, one must realize that integration starts from the initial condition, which in the OP's case is at x == 0. Second, the event y[x] < 0 is detected when y[x] changes from positive to negative, and not when it changes from negative to positive. Since initial condition y is negative, the event won't happen unless y[x] becomes negative again, after ...

5

Cassinis solution is one possibility to solve your problem and he is right in assuming that it has to do with evaluation order. The following is a summary of techniques which I found helpful when investigating situations when NDSolve doesn't behave as one would expect. WhenEvent does have the attribute HoldAll and I guess that is the reason why you did put ...

5

NDSolve does not work well for an infinite integration range, perhaps because it uses the range to set the initial step size. Instead, use a large upper bound, for instance, 1000. It also is unnecessary to specify Method and MaxSteps. ζ = 0.01; p = 0.010; q = 0.003; A = 0.01; τ = 4.67; ω = 0.9; eqn = {x''[t] + 2 ζ x'[t] + x[t] + p (x[t] - x[t - τ]) - ...

5

I solved the problem without using WithEvent function but using If function. I thought I will share the solution. Np = 4; classes = 2; eps = 0.01; Xa = RandomReal[{1, 2}, {2, 2}]; Xb = RandomReal[{3, 4}, {2, 2}]; Plotxa = ListPlot[Xa, PlotStyle -> {Thick, Black}]; Plotxb = ListPlot[Xb, PlotStyle -> {Thick, Red}]; Plotx = Show[Plotxa, Plotxb, PlotRange ...

5

That Boole worries me, so here's an approach that avoids it. I define another DiscreteVariable for each equation called Subscript[sw,i][t] that is either 0 or 1 and acts as a switch on the Subscript[u, i]'[t] equations. I also add another WhenEvent that turns the switch back off at time t==Subscript[r, i][t]. AbsoluteTiming[sol = NDSolve[Table[With[{i = i}...

5

The code has three issues. First, μk cannot be changed during the computation unless it is designated by DiscreteVariables. Second, the list of actions to be taken by WhenEvent needs to be separated by commas, not semicolons. Third, the upper limit of integration cannot be infinity. With these changes, the code becomes g = 9.81; R = 1; ti = 0; m = 0.3; ...

5

To constrain NDSolve to keep one of the variables in bounds, I add an indicator variable in[t] that changes from 1 to 0 at the boundary and back to 1 when z'[t] becomes negative again, using two WhenEvents. df = 4. (0.07 z[t] Sqrt[600. - p[t]] - 0.005 Sqrt[p[t] p[t] - 100.]); dz = (-0.3 df + 0.4 (170. - p[t])); de = {p'[t] == df, z'[t] == in[t] dz}; ic = {p[...

Only top voted, non community-wiki answers of a minimum length are eligible