# Monitoring the Evaluation of NDSolve: time to finish estimation

My problem is quite simple: I run a NDSolve with a system of many ODEs, a calculation that will run for many hours, and I would like to know the progress of the calculation while it goes on.

More precisely, calling f[n][t] the functions to be solved in the interval {tin,tfin}, It will be sufficient to print at regular intervals t the value of Sum[f[n][t]] for example, and possibly to save them as well. As a side effect, this will also give me an idea of when the calculation is going to end.

However I don't want to sacrifice a significant amount of runtime for this monitoring. One option could be really to split the calculation in intervals (a table of NDSolve) and print the intermediate results at each point. But I am afraid to have a significant overhead due to the reconstruction of the system of equations every time (I also use the method "EquationSimplification"->"Solve" which I believe transforms symbolically the system before integrating it) so I hope that some wizards among you could help me out providing an efficient solution to this problem using perhaps EvaluationMonitor or EventLocator or StateData ?

Any example will be appreciated.

EDIT: here is an example I just invented (the real example is more complicated).

M = 100;
Clear[P];
eqns := Table[
P[k]'[t] == -(1/k) P[k][t] -
P[k][t]^2 Sum[Exp[-(k - q)^2/M] P[q][t], {q, 1, M}]
, {k, 1, M}];

initial = Table[P[k][0] == 0.2, {k, 1, M}];

spos = NDSolve[Join[{eqns, initial}],
Table[P[k], {k, 1, M}], {t, 0, 100},
Method -> {"EquationSimplification" -> "Solve"},
PrecisionGoal -> 3, AccuracyGoal -> 3];

-
A (simplified) version of your problem would be most helpful to us for helping you solve your problem... – J. M. Jun 5 '13 at 2:22
Ok edited! Thanks – Davide Venturelli Jun 5 '13 at 4:26

showStatus[status_] :=
SetNotebookStatusLine[FrontEndEvaluationNotebook[],
ToString[status]]];
clearStatus[] := showStatus[""];
clearStatus[]


and use an EvaluationMonitor like this:

spos = NDSolve[{eqns, initial}, Table[P[k], {k, 1, M}], {t, 0, 100},
Method -> {"EquationSimplification" -> "Solve"}, PrecisionGoal -> 3,
AccuracyGoal -> 3,
EvaluationMonitor :> showStatus["t = " <> ToString[CForm[t]]]]


As side note an alternative:

tEnd = 100;
ProgressIndicator[Dynamic[currentTime], {0, tEnd}]
(* and ..., EvaluationMonitor :> (currentTime = t;) *).


To use a state object you could use the following:

Start with ProcessEquations which will do as much as possible for the pre processing.

{state} =
NDSolveProcessEquations[{eqns, initial},
Table[P[k], {k, 1, M}], {t, 0, 100},
Method -> {"EquationSimplification" -> "Solve"}, PrecisionGoal -> 3,
AccuracyGoal -> 3]


The generates state object can then be used with Iterate which you can give a second argument until when it should iterate. The you could use a Table or some such (Do) to iterate over the intermediate halt points.

Table[NDSolveIterate[state, i]; Print[i], {i, 0, 100, 10}];


Note that you could also specify something like this:

Table[..., {i, {1,7,8,9,17,45,99}}]


to generate arbitrary stop points. Not sure how useful that is though, since if you are a point in time tp that does not allow you to conclude when tEnd will be reached.

To get the solution you post process the state object like this:

sol = NDSolveProcessSolutions[state]


Note that you can do much with NDSolve state objects, like reinitializing. You find more on the topic of NDSolve state objects in the Components and Data structure section of tutorial/NDSolveOverview

-
is there a good reason why you don't just use the documented SetOptions[EvaluationNotebook[],WindowStatusArea->status] but the undocumented LinkWrite[_,SetNotebookStatusLine[...]]? I have a suspicion but am not sure... – Albert Retey Jun 6 '13 at 21:55
@AlbertRetey, no not really, it's just that old habits die hard. I have never used the documented one, so I would not know about possible issues. – user21 Jun 7 '13 at 5:01