'Change initial condition (add more mass) with time events in scipy `solve_ivp`
I'm trying to add more mass to the system when the time advanced. I'm trying to obtain the solution for a decay equation: \frac{dy}{dt} = -0.32 * y
The initial condition y(t=0) = 100. I want also at t=6 to add 100 to the solution. I tried doing this in events but without any luck. Any suggestions?
def one(t, y, ke):
ydot = -ke * y
return ydot
def dose(t, y, ke):
return y[0] + 100*(t==6)
tspan = [0.0, 12.0]
teval = np.array([0, 2, 4, 6,8, 10, 12])
y0 = [100.0]
ke = 0.32
D = 100
sol = solve_ivp(one, tspan, y0, t_eval=teval, args=(ke,), events=(dose), dense_output=True)
sol.y
plt.plot(sol.t, sol.y[0])
Thanks!
Solution 1:[1]
A way to change the output at a given point is to add an impulse to its derivative, here an example with a gaussian pulse (sigma adjusts the width of the pulse). I also used BDF method instead of the default Runge-Kutta, in order to be able to handle narrower pulses, but the limitation of this approach is that a very narrow pulse will not be noticed by the ODE integration
import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
def one(t, y, ke):
sigma = 0.1
ydot = -ke * y + 100/(sigma*np.sqrt(2*np.pi))*np.exp(-(t - 6)**2/(2*sigma**2))
return ydot
tspan = [0.0, 12.0]
teval = np.array([0, 2, 4, 6,8, 10, 12])
y0 = [100.0]
ke = 0.32
D = 100
sol = solve_ivp(one, tspan, y0, t_eval=np.linspace(0, 12, 1000),
args=(ke,), dense_output=True, method='BDF')
sol.y
plt.plot(sol.t, sol.y[0])
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Bob |
