Reputation: 329
I have the following simplified pseudocode setup which involves a system of ODEs, which I attempt to solve with scipy's odeint.
from scipy.integrate import odeint
def diff_func(y, time, parms):
# Do stuff with parms that depends upon y and t.
new_parms = other_funcs(y,time, parms)
# Now calculate derivatives
dy1_dt = dy1_func(y, new_parms)
dy2_dt = dy2_func(y, new_parms)
# Setup up initial conditions
y_0 = [y_1_0, y_2_0]
time = np.linspace(0, 1000, 1000)
parms = list_o_constants
# Solve diffeq
yout, info = odeint(diff_func, y_0, time, args=(parms,), full_output=True)
Depending upon the inputs I give it, I can lead to nonsensical results - or crashes. I have narrowed down the problem to the y
inputs go negative occasionally, since one of them is temperature - it leads to all kinds of issues. The reason why it is going negative in the first place is unclear, and might be a stability issue.
I have attempted to change the diff function to include a check like:
def diff_func(y, time, parms):
if y[1] <= 0.1:
y[1] = 0.1
This seems to work okay, I am still testing it. But, I wanted to ask if: this is going to cause problems down the line, and if there is a better way to force odeint to only allow positive outputs (i.e., change step size if a negative is found).
Thanks!
Upvotes: 3
Views: 2102
Reputation: 8217
Please first look at my other answer that I posted recently.
What you want do do is to add a saturation constraint to your ODE. There are a few possibilities to achieve this behavior, however I recommend this one:
# calculate dy[1]
y1 = y[1]
if dy[1] < 0 and y1 <= 0.1 # or 0.0, depends on accuracy you wish to maintain
y1 = 0
dy1 = 0 # this prevents your variable from going further down
else
# normal routine
Let me know, if it suits you.
Best regards.
Upvotes: 1