3
$\begingroup$

I have an NDSolve problem that needs a list of a large number of events that are generated programmatically. Here is a simple example that demonstrates the problem on Mathematica 7 and 8 (the versions I have access to):

NDSolve[
  {y''[t] == 10, y[0] == 0, y'[0] == 0},
  {y},
  {t, 0, 1},
  Method -> {"EventLocator",
    "Event" :> {y[t] - 2, y[t] - 1},
    "EventAction" :>(*{Throw[Print["i=",1],"StopIntegration"],Throw[
     Print["i=",2],"StopIntegration"]}*)
     Table[Throw[Print["i=", i], "StopIntegration"], {i, 3}]
    }
  ];

The code as it is does not work (the second event should be triggered first, and it prints i=1), but if I use the commented block in EventAction, it does work, and prints i=2.

What is the right syntax to make this work? Thanks for any help!

$\endgroup$

1 Answer 1

3
$\begingroup$

What is happening is that the RuleDelayed (:>) keeps the Table from being evaluated. When NDSolve detects an event, it evaluates the appropriate event action. In your code, the "EventAction" option is not (yet) an expression with head List, but an expression with head Table. So instead of picking the corresponding part, NDSolve assumes that the whole expression should be evaluated for every event. Table gets as far as i = 1 and encounters Throw, which exits Table after printing i = 1.

You can check that the event y[t] - 1 is the one that triggered the "StopIntegration" action as follows.

sol = NDSolve[{y''[t] == 10, y[0] == 0, y'[0] == 0}, {y}, {t, 0, 1}, 
  Method -> {"EventLocator", "Event" :> {y[t] - 2, y[t] - 1}, 
    "EventAction" :>(*{Throw[Print["i=",1],"StopIntegration"],Throw[
     Print["i=",2],"StopIntegration"]}*)
     Table[Throw[Print["i=", i], "StopIntegration"], {i, 3}]}]
(*
  i=1

  {{y -> InterpolatingFunction[{{0., 0.447214}}, <>]}}
*)

{{ti, tf}} = y["Domain"] /. First[sol]
(*
  {{0., 0.447214}}
*)

y[tf] /. First[sol]
(*
   1.
*)

It's probably easiest to list the actions explicitly.


If you need to use Table, you could do it this way:

sol = NDSolve[{y''[t] == 10, y[0] == 0, y'[0] == 0}, {y},
  {t, 0, 1},
  Method -> {"EventLocator",
    "Event" :> {y[t] - 2, y[t] - 1}, 
    With[{acts = Table[With[{i = i}, Hold@Throw[Print["i=", i], "StopIntegration"]], {i, 2}]},
     ("EventAction" :> acts) /. Hold[x_] :> x
     ]
    }]
$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.