3
$\begingroup$

I have a 'WhenEvent' where I want two actions to be performed. I thought the actions should be in a list but this does not seem to work. Here is an example there are two actions in the 'WhenEvent'.

   (* Preliminary definition *)
ClearAll[ip, v1, v2];
ip[t_] := 
  Piecewise[{{Sin[2 \[Pi] t/(2 0.1)], t < 0.1}, {0, 0.1 <= t}}];

(* The differential equations *)
eqn = {986. y[t] + 6. Derivative[1][y][t] + y''[t] ==
     986 ip[t] + 6. ip'[t], z''[t] == -9.81`,
   WhenEvent[{z[t] - y[t] <= -0.125, z[t] - y[t] >= 0.125},
    v1 = 0.9 (0.95 y'[t] + 0.15 z'[t]);
    v2 = 0.9 (1.5  y'[t] - 0.4 z'[t]);
    {Derivative[1][y][t] -> v1, Derivative[1][z][t] -> v2}],
   y[0] == 0, Derivative[1][y][0] == 0, z[0] == 0, 
   Derivative[1][z][0] == 0};

(*Sove the equation *)
sol = First@NDSolve[eqn, {y, z}, {t, 0, 0.04}];

(*Plot the result *)
Plot[Evaluate[z[t] - y[t] /. sol], {t, 0, 0.04}, 
 Epilog -> {Pink, InfiniteLine[{0, -0.125}, {1, 0}]}]

enter image description here

By putting in 'Print[]' I can see that the ''WhenEvent' has been identified but no actions have been implemented.

If I modify my code with two 'WhenEvent's each with one action then I get what I want.

(* Preliminary definition *)
ClearAll[ip, v1, v2];
ip[t_] := 
  Piecewise[{{Sin[2 \[Pi] t/(2 0.1)], t < 0.1}, {0, 0.1 <= t}}];
(* The differential equations *)
eqn = {986. y[t] + 6. Derivative[1][y][t] + y''[t] ==
     986 ip[t] + 6. ip'[t], z''[t] == -9.81`,
   WhenEvent[{z[t] - y[t] <= -0.125, z[t] - y[t] >= 0.125},
    v1 = 0.9 (0.95 y'[t] + 0.15 z'[t]);
    v2 = 0.9 (1.5  y'[t] - 0.4 z'[t]);
    Derivative[1][y][t] -> v1],
   WhenEvent[{z[t] - y[t] <= -0.125, z[t] - y[t] >= 0.125},
    v1 = 0.9 (0.95 y'[t] + 0.15 z'[t]);
    v2 = 0.9 (1.5  y'[t] - 0.4 z'[t]);
    Derivative[1][z][t] -> v2],
   y[0] == 0, Derivative[1][y][0] == 0, z[0] == 0, 
   Derivative[1][z][0] == 0};

(*Sove the equation *)
sol = First@NDSolve[eqn, {y, z}, {t, 0, 0.04}];

(*Plot the result *)
Plot[Evaluate[z[t] - y[t] /. sol], {t, 0, 0.04}, 
 Epilog -> {Pink, InfiniteLine[{0, -0.125}, {1, 0}]}]

enter image description here

How can I have several actions associated with one 'WhenEvent'? Am I doing something silly here or is this deeper?

Edit - problem fixed -simple error

I have found the error. It seems that the events must be in one list and the actions in another list. Further, and what eluded me, any associated calculations must also be within the list.

Here is the corrected code.

(* Preliminary definition *)
ClearAll[ip, v1, v2];
ip[t_] := 
  Piecewise[{{Sin[2 \[Pi] t/(2 0.1)], t < 0.1}, {0, 0.1 <= t}}];
(* The differential equations *)
eqn = {986. y[t] + 6. Derivative[1][y][t] + (y^\[Prime]\[Prime])[t] ==
     986 ip[t] + 6. ip'[t], (z^\[Prime]\[Prime])[t] == -9.81`,
   WhenEvent[{z[t] - y[t] <= -0.125, z[t] - y[t] >= 0.125}, {
     v1 = 0.9 (0.95 y'[t] + 0.15 z'[t]);
     v2 = 0.9 (1.5  y'[t] - 0.4 z'[t]);,
     Derivative[1][y][t] -> v1, Derivative[1][z][t] -> v2}],
   y[0] == 0, Derivative[1][y][0] == 0, z[0] == 0, 
   Derivative[1][z][0] == 0};

(*Sove the equation *)
sol = First@NDSolve[eqn, {y, z}, {t, 0, 0.04}];

(*Plot the result *)
Plot[Evaluate[z[t] - y[t] /. sol], {t, 0, 0.04}, 
 Epilog -> {Pink, InfiniteLine[{0, -0.125}, {1, 0}]}]

enter image description here

So problem solved. But I still have to work out why the last two pictures are different. Sorry if I waisted your time.

$\endgroup$
4
  • $\begingroup$ It's helpful to post code in raw input form, so that it can be copied and run. (The posted code gives errors for me.) See mathematica.meta.stackexchange.com/questions/1584/… $\endgroup$
    – Michael E2
    Commented Jan 23, 2023 at 18:27
  • $\begingroup$ In the first "working" code, only one of the two actions are taken at each event; in the last "working" code, both actions are taken at each event. I think that's the difference. $\endgroup$
    – Michael E2
    Commented Jan 23, 2023 at 18:42
  • $\begingroup$ We can directly write (y^\[Prime]\[Prime]) as y'' $\endgroup$
    – cvgmt
    Commented Jan 24, 2023 at 2:41
  • $\begingroup$ @cvgmt Thanks. Yes, I do use y'' but that fell apart in my posting and became '(y^[Prime][Prime])' Not sure what happened there. I will correct. $\endgroup$
    – Hugh
    Commented Jan 24, 2023 at 16:52

1 Answer 1

4
$\begingroup$

Edit

If we want to use v1 and v2,we can use With to enclose the WhenEvent

Clear["Global`*"];
(*Preliminary definition*)ClearAll[ip, v1, v2];
ip[t_] := 
  Piecewise[{{Sin[2 π t/(2 0.1)], t < 0.1}, {0, 0.1 <= t}}];
(*The differential equations*)
eqn = {986. y[t] + 6. Derivative[1][y][t] + y''[t] == 
    986 ip[t] + 6. ip'[t], z''[t] == -9.81`, 
   With[{v1 = 0.9 (0.95 y'[t] + 0.15 z'[t]), 
     v2 = 0.9 (1.5 y'[t] - 0.4 z'[t])}, 
    WhenEvent[{z[t] - y[t] <= -0.125, 
      z[t] - y[t] >= 0.125}, {Derivative[1][y][t] -> v1, 
      Derivative[1][z][t] -> v2}]], y[0] == 0, 
   Derivative[1][y][0] == 0, z[0] == 0, Derivative[1][z][0] == 0};

(*Sove the equation*)
sol = First@NDSolve[eqn, {y, z}, {t, 0, 0.04}];

(*Plot the result*)
Plot[Evaluate[z[t] - y[t] /. sol], {t, 0, 0.04}, 
 Epilog -> {Pink, InfiniteLine[{0, -0.125}, {1, 0}]}]

enter image description here

Original

When we remove v1,v2, all of them work fine.

(*Preliminary definition*)ClearAll[ip, v1, v2];
ip[t_] := 
  Piecewise[{{Sin[2 π t/(2 0.1)], t < 0.1}, {0, 0.1 <= t}}];
(*The differential equations*)
eqn = {986. y[t] + 6. Derivative[1][y][t] + y''[t] == 
    986 ip[t] + 6. ip'[t], z''[t] == -9.81`, 
   WhenEvent[{z[t] - y[t] <= -0.125, 
     z[t] - y[t] >= 0.125}, {Derivative[1][y][t] -> 
      0.9 (0.95 y'[t] + 0.15 z'[t]), 
     Derivative[1][z][t] -> 0.9 (1.5 y'[t] - 0.4 z'[t])}], y[0] == 0, 
   Derivative[1][y][0] == 0, z[0] == 0, Derivative[1][z][0] == 0};

(*Sove the equation*)
sol = First@NDSolve[eqn, {y, z}, {t, 0, 0.04}];

(*Plot the result*)
Plot[Evaluate[z[t] - y[t] /. sol], {t, 0, 0.04}, 
 Epilog -> {Pink, InfiniteLine[{0, -0.125}, {1, 0}]}]

enter image description here

$\endgroup$
2
  • $\begingroup$ Very helpful simplification. I actually need to do something more complicated so need to write a module within the 'WhenEvent'. Hopefully, this will work. $\endgroup$
    – Hugh
    Commented Jan 24, 2023 at 16:57
  • $\begingroup$ Thanks. Using With[] is an excellent approach. Adds much more flexibility to subsequent actions. I will experiment. $\endgroup$
    – Hugh
    Commented Jan 25, 2023 at 6:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.