1
$\begingroup$

My code is based on the suggestion in this discussion by Michael E2 And when I'm using the same definitions the WhenEvent function locates only the first time the event occurs.

slopeα = 0.01; Tend = 10; L = 1;
us[m_, P_] := (1 + Tanh[m (P)])/2;
α1 = 1; α2 = 8; elementNum = 25; ΔPsnap = 0.25;
maxval[if_: InterpolatingFunction[___][x_]] := Max[if /. {x -> "ValuesOnGrid"}];
fnew[if : InterpolatingFunction[___][x_]] := ConstantArray[1, Length[if /. x -> "Grid"]]; 
opts = Method -> {"MethodOfLines",
                  "SpatialDiscretization" -> {"TensorProductGrid",
                                              "MinPoints" -> (elementNum - 1)}};
Pup = 0.7; t0 = 1;
α1 = 1; α2 = 8;
sol1 = NDSolve[{D[P[x, t], t] - α[x, t] D[P[x, t], {x, 2}] == 0, P[x, 0] == 0,
                P[0, t] == UnitStep[t - t0], P[L, t] == 0, α[x, 0] == α2,
                D[α[x, t], t] == 0, WhenEvent[maxval[P[x, t]] >= Pup, Print[t]]},
               {P[x, t], α[x, t]}, {t, 0, Tend}, {x, 0, L}, opts];
Manipulate[Plot[{P[x, t] /. sol1} /. {t -> tt}, {x, 0, L},
           PlotRange -> {{0, L}, {0, 1}}, ImageSize -> Medium], {tt, 0, Tend}]

and the print output is 2.20493 although the value of $P[x,t]$ remains higher than $Pup$ for at all times.

Can't find the reason for this issue. Thanks a lot, Ofek.

$\endgroup$
  • 1
    $\begingroup$ WhenEvent only detects the change from False->Trueof the condition ! $\endgroup$ – Ulrich Neumann Jan 4 at 10:41
  • $\begingroup$ Oh, I'm surprised I've missed that, Thanks!! Maybe you know a way to "force" WhenEvent to check every step? $\endgroup$ – Ofek Peretz Jan 4 at 10:43
  • 1
    $\begingroup$ The WhenEvent in your simulation doesn't affect NDSolve, so you could check the conditions after the simulation is completed!? $\endgroup$ – Ulrich Neumann Jan 4 at 10:47
  • $\begingroup$ I have excluded the part that this effect takes place since its too long and maybe have some errors itself, so, unfortunately, that's now the case. $\endgroup$ – Ofek Peretz Jan 4 at 10:49
  • $\begingroup$ If I understand your problem right the ode "changes" when the event occurs? If so you could define a DiscreteVariable ->switch and switch between the different ode's. $\endgroup$ – Ulrich Neumann Jan 4 at 11:05
1
$\begingroup$

Here is a simple realization switching the coefficient of an ode:

{X, S} = NDSolveValue[{x''[t] + s[t] x[t] == 0, s[0] == 1, x[0] == 0,x'[0] == 1, WhenEvent[x[t] > 0.5, s[t] -> 2],WhenEvent[x[t] < 0.5, s[t] -> 1]}, {x, s}, {t, 0, 10},DiscreteVariables -> s];

{X, S} = NDSolveValue[{x''[t] + s[t] x[t] == 0, s'[t] == 0, s[0] == 1,x[0] == 0, x'[0] == 1, WhenEvent[x[t] > 0.5, s[t] -> 2], WhenEvent[x[t] < 0.5, s[t] -> 1]}, {x, s}, {t, 0, 10}];

In both variants you need two WhenEvents!

Plot[{X[t], S[t]}, {t, 0, 10}]

enter image description here

Hope it helps solving your problem!

$\endgroup$

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.