8
$\begingroup$

Often in computation with an NDSolve-type solver, one hopes to know about its progress. To this end, I am using StepMonitor as follows,

NDSolve[eqn, y, {x, 0, L}, {t, 0, tm}, StepMonitor :> (Print["t=", t]; s++), Method -> method]

where the DE is about y[x,t], and s is a counter for time step for reference.

This is ok for short calculations, but for long ones with a big terminal time tm, especially with a stiff problem, the output from StepMonitor is going to be extremely long due to small time steps. This makes the notebook very long and hard to scroll up and down. Sometimes, the notebook even breaks down!! Also, I believe the long output consumes a certain amount of memory.

So, I really need an appropriate method to get feedback about the solver's progress. For example, if tm=1000 is it possible to get a time step printed out on the notebook every $\Delta t=50$ approximately. Consider the time steps cannot be an exact integer, so just to print out a time step when it runs up to t>~50, t>~100, t>~150, .... Thank you very much!

$\endgroup$

2 Answers 2

9
$\begingroup$

I usually use something like this:

PrintTemporary@Dynamic@{Clock@Infinity, foo};
NDSolve[<ode>, y, {t, 0, 10}, ..., StepMonitor :> (foo = t)]

I've also used it to gather other data, like the time of a WhenEvent as well as the integration time, along the lines of this:

foo = murf = 0.;
PrintTemporary@Dynamic@
  {foo, Style[murf, PrintPrecision -> 17], Clock@Infinity};
sol = NDSolve[{...,
    WhenEvent[..., foo = t; y[t] -> 0]},
  ..., StepMonitor :> (murf = t)]

These and similar examples may be found in my answers here:

I gave a small explanation of this approach and the usefulness of the running timer Clock@Infinity although not in conjunction with NDSolve here:

Note also the use of PrintPrecision in the second example. This allows one to see when the step size gets extremely small.

$\endgroup$
0
6
$\begingroup$

You could use Dynamic to show the value of your independent variable increasing as evaluation proceeds in NDSolve, perhaps combined with ProgressIndicator for display:

Clear[x, y, i]

ProgressIndicator[Dynamic[i], {0, 10}]

NDSolve[
  {y'[x] == y[x], y[0]==1}, y, {x, 0, 10},
  StepMonitor :> (Pause[0.05]; i = x)
]

In this example I am purposefully slowing down the evaluation using Pause[0.05] in the StepMonitor, just for visual effect. Of course you would omit that part in your own code.

$\endgroup$

Your Answer

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

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