Reputation: 1
In my ODE function I need to iteratively solve an equation for a parameter until convergence at each time step. I'd like to pass the latest parameter value to be used as the initial value for the next time step so when the function does the iterative update of the parameter it will take less time. But I can't figure out how to do that. The code structure of the ODE function is like this:
from scipy.integrate import solve_ivp
def run(t, y):
if t==0:
a = 1e-8
nn = 0
while nn<=100:
nn = nn +1
#update a until convergence
return a*y
In some one language I can return the updated parameter to be used by the integrator, but I don't' see how that's possible with solve_ivp
Upvotes: 0
Views: 1859
Reputation: 26040
It's not clear what you're after: do you want to obtain a solution for an ODE at a series of parameter values (i.e. for each value of the parameter you solve the full ODE) or you are changing the parameter along with the ODE iterations (IOW, you want inner or outer iterations).
If the former, then just do a for loop over the parameters. If the latter, it's likely easier and cleaner to use solver classes which implement specific solvers (DOPRI, Radau, RK, BDF etc), which solve_ivp delegates the work to. They offer a step
method, which performs a single step. So that you can adjust you parameters, control convergence etc on a way that's most relevant to this particular case.
Upvotes: 1
Reputation: 402
I think what you are looking for is something in the following form:
class test:
a = 1e-8
def f(self, t, y):
## do iter on self.a
return self.a*y
t = test()
# solve_ivp(t.f, .....)
This way you can always use the last value of a
, since it is part of your instance of the test
class. This is not exactly what you are asking for, since this will call the iteration each time solve_ivp
evaluates f
, which will be multiple times per timestep. However, I think this is the closest you can get, since solve_ivp
does not appear to have a callback
function to invoke after each timestep
Upvotes: 1