Message Boards Message Boards

0
|
1762 Views
|
3 Replies
|
2 Total Likes
View groups...
Share
Share this post:

How do I define and use variables within WhenEvent in NDSolve

Posted 11 months ago

Hi!

I'm having a really bizarre issue with WhenEvent--when I define a variable as some equation involving the variables that are defined and used in NDSolve, I get the following error: NDSolve::nbnum1: The function value Abs[x[t]-y[t]]>0.01 is not True or False when the arguments are {0.,0.3,0.2,0.3,0.2}.

However, when I input the equation as it is (not previously defined as a variable), the solver runs fine. Here's a simplified version of my code.

variable = Sqrt[Abs[x[t] - y[t]]^2]
times = {};
Print["Current time step in ODE solution ="];
Monitor[
  s = NDSolve[{x'[t] == x[t], y'[t] == y[t], y[0] == 0.2, x[0] == 0.3,
      WhenEvent[variable > 0.01, Print[2]]}, {x[t], y[t]}, {t, 0, 
     tAnneal}, Method -> {"EquationSimplification" -> "Residual"}, 
    EvaluationMonitor :> AppendTo[times, t]], times[[-1]] ];

This version throws an error. However, when I input

times = {};
Print["Current time step in ODE solution ="];
Monitor[
  s = NDSolve[{x'[t] == x[t], y'[t] == y[t], y[0] == 0.2, x[0] == 0.3,
      WhenEvent[Sqrt[Abs[x[t] - y[t]]^2] > 0.01, Print[2]]}, {x[t], 
     y[t]}, {t, 0, tAnneal}, 
    Method -> {"EquationSimplification" -> "Residual"}, 
    EvaluationMonitor :> AppendTo[times, t]], times[[-1]] ];

it works fine. This is an issue for me because I have a big datastructure with such equations for many different variables, and I need to be able to call an element of that list rather than writing in the equation itself.

Thank you for any help you all can give me!
Kaden

POSTED BY: Kaden Tro
3 Replies

Use:

With[{variable = variable}, WhenEvent[variable > 0.01, Print[2]]]

or

WhenEvent[Evaluate[variable > 0.01], Print[2]]

NDSolve makes a literal analysis of the code, replacing occurrences of state variables like x[t] and y[t] by symbols that represent their values at each time step. Since WhenEvent has the attribute HoldAll, the code in the first argument of WhenEvent[variable > 0.1,...] is literally the unevaluated variable > 0.1. So when NDSolve sets up the internal handler for the event, there appear to be no instances of x[t] or y[t] to be replaced, Later variable is evaluated, but the values have been mapped to internal variables. The expressions x[t] etc. remain x[t] etc., and you get an error "Abs[x[t]-y[t]]>0.01 is not True or False".

The trick above in both cases above is to replace the unevaluated variable with its value.

POSTED BY: Michael Rogers

Thank you so much! I figured there was something wrong about the order in which it replaced x[t] vs other variables but I had no idea how to fix it. I really appreciate it!

POSTED BY: Kaden Tro

You're welcome!

POSTED BY: Michael Rogers
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract