What is a fast way of checking which event has been triggered in scipy.solve_ivp()? For context, I am simulating a double pendulum. I want to check if either the first rod or the second rod has been flipped. I have created two event functions for each, but once the event is triggered, is there any way I can retrieve which event has been triggered? Thanks :)
Oops, I see there's an answer. Might as well post, since it's already written:
There are two terminal events in the following code, which represents a simple harmonic oscilator.
import numpy as np
from scipy import integrate
def dy(t, y):
return [y[1], -y[0]]
def event1(t, y):
return y[0]
event1.terminal = True
def event2(t, y):
return y[1]
event2.terminal = True
tspan = [0, 10]
y0 = [0.1, -0.1]
sol = integrate.solve_ivp(dy, tspan, y0, events=[event1, event2])
According to the solve_ivp
documentation, sol.t_events
is a list of arrays of times at which an event occured. The first array in the list corresponds with the first event; the second array corresponds with the second event. In case some of the events are non-terminal, create a list with time of the last event in each array:
last_events = [(t_event[-1] if len(t_event) else tspan[0]) for t_event in sol.t_events]
The event which occured is the argmax
of these.
np.argmax(last_events) # 0
In this case, the first event (event 0) occured, which means that the "position" y[0]
has crossed zero. You can change the initial "velocity" to y0[1] = -y0[1]
to see that the argmax becomes 1
, so the second event (event 1) occurs, which means that the velocity has crossed zero.