# NDSolve with a limiting condition on dependent variable

I want to solve $x'(t)=f(g(x),t), ~x(0)=0$, where $f$ is a function and $g(x)$ is an interpolating function (obtained in Mathematica as a result of some previous calculation) defined only over the interval $[0,x_0]$. The reason for this limitation on $g(x)$ is that finding data points requires numerical integration and beyond $x_0$, NIntegrate converges too slowly. How do I use NDSolve so that it stops integrating $x'(t)=f(g(x),t)$ as soon as $x$ reaches $x_0$? Is there some simple modification of the following code: NDSolveValue[ {x'[t]==f[g[x[t]],t], x[0]=0}, x, {t,0,SomeTimeValue}] that will do the trick?

• What exactly is $f(x,t)$? – zhk Apr 29 '17 at 7:04
• @zhk $f(x,t)$ is actually velocity of a particle in an unsteady flow. It is obtained by interpolation of fluid velocity at different points in space-time. The actual problem is more complicated and two dimensional, so $f$ depends on y coordinate as well. But I have simplified the problem here to its bare essentials. In summary $f$ involves an interpolating function $g(x)$ obtained from Mathematica, so actually I should be writing $f(g(x),t)$. – Deep Apr 29 '17 at 7:08
• @zhk In the wake of your comment I have edited my question to make it more clear. – Deep Apr 29 '17 at 7:16

Theoretically, WhenEvent is the obvious tool, and practically, it should be acceptable. Given the discretization of numerical algorithms, one cannot guarantee that the NDSolve will not step past $x_0$. Indeed, it will normally have to, since a discrete step is unlikely to land directly on $x_0$; further, most methods evaluate the ODE at several points in a neighborhood containing each step. So using WhenEvent almost certainly will evaluate g[x[t]] outside its domain. But normally it will only be slightly outside the domain and the extrapolated value(s) should not have a great error.

g = NDSolveValue[{y'[x] == y[x]/4, y[0] == 1}, y, {x, 0, 5},
InterpolationOrder -> All]

Block[{f},
f[x_, t_] := x^2 + t^2;
xIF = NDSolveValue[{x'[t] == f[g[x[t]], t], x[0] == 0,
WhenEvent[x[t] == 5, "StopIntegration"]},
x, {t, 0, 10}]
];


InterpolatingFunction::dmval: Input value {5.05353} lies outside the range of data in the interpolating function. Extrapolation will be used.

InterpolatingFunction::dmval: Input value {5.05353} lies outside the range of data in the interpolating function. Extrapolation will be used.