I am using NDSolver and WhenEvent to solve a system of differential equations. I get this message:
NDSolve::ndsz: At t == 49169.954923435114`, step size is effectively zero; singularity or stiff system suspected.
The solution I get is pretty stable until that time, then blows off completely. At each evaluation I get the same behaviour at different times.
I understand that the problem might lie with the fact that I am solving for very long times, and eventually the algorithm just starts having problems handling all the data.
Is there a way to stop the solver as soon as the error comes up?
Answer
First, a test case:
sol = NDSolve[{x'[t] == -1/x[t], x[0] == -1}, x, {t, 0, 2}]
NDSolve::ndsz: At t == 0.499999735845871`, step size is effectively zero; singularity or stiff system suspected. >>
Consult What's inside InterpolatingFunction[{{1., 4.}}, <>]? or InterpolatingFunctionAnatomy and you will discover that InterpolatingFunction
comes with lots of utilities and methods that give access to a wealth of information. In particular, the method "Domain"
will yield the domain of the InterpolatingFunction
, which in this case will be the interval over which NDSolve
successfully integrated the ODE (up to the point where stiffness stopped it).
{tstart, tstop} = Flatten[x["Domain"] /. sol]
(* {0.`, 0.499999735845871`} *)
A couple of ways to plot. Note for ListLinePlot
, you don't need to know the domain; it and ListPlot
handle InterpolatingFunction
as a special case.
ListLinePlot[x /. sol]
Plot @@ {{x[t], x'[t]} /. First[sol], Flatten@{t, x["Domain"] /. sol}}
By default, going past the ends of the domain results in extrapolation.
Plot[x[t] /. First[sol], {t, 0, 2}]
One can use the option, mentioned in a comment in the linked question, "ExtrapolationHandler"
to override the default extrapolation.
sol2 = NDSolve[{x'[t] == -1/x[t], x[0] == -1}, x, {t, 0, 10},
"ExtrapolationHandler" -> {Indeterminate &}];
Plot[x[t] /. First[sol2], {t, 0, 2}]
NDSolve::ndsz: At t == 0.4999997164125506`....
Comments
Post a Comment