2
$\begingroup$

I am trying to impose multiple action based on two conditions I have an If statement inside a WhenEevent.

The problem I am facing is that I can only impose one action a(t) or b(t) if I impose the two action the code doesn't recognize it.

a(t) and b(t) are discrete variables that I want them to change every single time x(t)==0 and x'(t)<0 as they accumulate everytime they change as shown in the WhenEvent function. Should I use the Block function?

Is there an alternative way of imposing multiple conditions inside the If function because it only seem capable of doing 1 action at a time. Thank you

IC = {x[0] == 1, x'[0] == 0, a[0] == 10, b[0] == 0.1};

sol=NDSolve[
   {x''[t] + b[t] x'[t] + a[t] x[t] == 0,
    WhenEvent[x[t] == 0, If[x'[t] < 0, a[t] -> 3 - x[t] && b[t] -> 0.1 - x'[t]]],
    IC}, 
   {x[t], a[t], x'[t], b[t]}, {t, 0, 5}, DiscreteVariables -> {a[t], b[t]}]
Plot[{x[t], a[t]} /. sol, {t, 0, 5}]
Plot[{x'[t], b[t]} /. sol, {t, 0, 5}]
$\endgroup$
  • 1
    $\begingroup$ Welcome to Mathematica.SE! I suggest the following: 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Take the tour! 3) When you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. Also, please remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign! $\endgroup$ – Michael E2 Mar 7 '17 at 23:54
3
$\begingroup$

An action in WhenEvent should be a Rule or a keyword string (see docs), or a list of these. Instead of If to impose a condition on an event, use And: WhenEvent[event && condition, action].

IC = {x[0] == 1, x'[0] == 0, a[0] == 10, b[0] == 0.1};

sol = NDSolve[{x''[t] + b[t] x'[t] + a[t] x[t] == 0,
   WhenEvent[x[t] == 0 && x'[t] < 0, {a[t] -> 3 - x[t], b[t] -> 0.1 - x'[t]}],
   IC},
  {x[t], a[t], x'[t], b[t]}, {t, 0, 5}, 
  DiscreteVariables -> {a[t], b[t]}]
Plot[{x[t], a[t]} /. sol, {t, 0, 5}]
Plot[{x'[t], b[t]} /. sol, {t, 0, 5}]

Mathematica graphics

$\endgroup$
  • $\begingroup$ Thank you I understand that but I am wanting to do it with If instead of only WhenEvent $\endgroup$ – K.s Mar 8 '17 at 19:42
1
$\begingroup$

Inside If, separate statements with a semicolon, not &&, the code does something. But, it is wrong, and I don't yet know why it is giving wrong output.

 IC = {x[0] == 1, x'[0] == 0, a[0] == 10, b[0] == 1/10};
sol = NDSolve[{x''[t] + b[t] x'[t] + a[t] x[t] == 0, 
    WhenEvent[x[t] == 0, 
     If[x'[t] < 0, a[t] -> 3 - x[t]; b[t] -> 0.1 - x'[t]]], IC}, {x, 
    a, b}, {t, 0, 5}, DiscreteVariables -> {a, b}];
Plot[{x[t], a[t]} /. sol, {t, 0, 5}]
Plot[{x'[t], b[t]} /. sol, {t, 0, 5}]

It looks like a sequence of actions written within If command doesn't work well, thus using two WhenEvent makes it work.

IC = {x[0] == 1, x'[0] == 0, a[0] == 10, b[0] == 1/10};
sol = NDSolve[{x''[t] + b[t] x'[t] + a[t] x[t] == 0, 
    WhenEvent[x[t] == 0, If[x'[t] < 0, b[t] -> 0.1 - x'[t]]], 
    WhenEvent[x[t] == 0, If[x'[t] < 0, a[t] -> 3 - x[t]]], IC}, {x, a,
     b}, {t, 0, 5}, DiscreteVariables -> {a, b}];
Plot[{x[t], a[t]} /. sol, {t, 0, 5}]
Plot[{x'[t], b[t]} /. sol, {t, 0, 5}]
$\endgroup$
  • $\begingroup$ What makes you think it works? The discrete variables a[t] and b[t] should change at the same time, but they do not. $\endgroup$ – Michael E2 Jul 11 at 19:22
  • $\begingroup$ @MichaelE2 I made a mistake, I did not check the result. Sorry about this. I don't know why it doesn't work though, trying to figure it out. $\endgroup$ – Himalaya Senapati Jul 17 at 13:36
  • $\begingroup$ I think the reason the first answer does not work is that in the value of the CompoundExpression in the If statement, a[t] -> 3 - x[t]; b[t] -> 0.1 - x'[t], is the last expression b[t] -> 0.1 - x'[t]; any expressions before a semicolon are ignored except for any side effects they have through setting a variable's value, but a Rule such as a[t] -> 3 - x[t] has no such side effect. That said, WhenEvent does rewrite the code, so you can't always count on things being as they seem. You might try a List instead of CompoundExpression: { a[t] -> 3 - x[t], b[t] -> 0.1 - x'[t]} $\endgroup$ – Michael E2 Jul 18 at 0:21
  • $\begingroup$ @MichaelE2 Thank you very much for this CompoundExpression. It works well, and resolved few issues for me. $\endgroup$ – Himalaya Senapati Jul 20 at 12:09

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.