import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
%matplotlib inline
np.seterr(divide='ignore');
# Dynamics function
def simple_golf(t, z):
'''
z[0] = x(t)
z[1] = y(t)
z[3] = y'(t)
'''
# Vx is defined globally
return [Vx, z[2] , -9.81]
# IVP parameters
tspan = [0, 10]
y0 = [0, 0, 15]
Vx = 25.
# Call the numerical solver
sol = solve_ivp(simple_golf, tspan, y0, max_step=1)
sol.y[0]
# Plot the solution
plt.plot(sol.y[0], sol.y[1], 'ro-');
plt.title('Golf Ball Trajectory')
plt.xlabel('Distance (m)')
plt.ylabel('Height (m)');
sol.y[:,-1]
# Suppose we want to pass Vx as a parameter to our dynamics function, like this.
def simple_golf2(t, z, Vx):
'''
z[0] = x(t)
z[1] = y(t)
z[3] = y'(t)
'''
return [Vx, z[2] , -9.81]
# We can create a simple wrapper for our dynamics function, like this:
fun = lambda t,x: simple_golf2(t,x,20) # Vx will be passed through as a constant
sol = solve_ivp(fun, tspan, y0, max_step=1.)
# Plot
plt.plot(sol.y[0], sol.y[1], 'ro-');
plt.title('Golf Ball Trajectory')
plt.xlabel('Distance (m)')
plt.ylabel('Height (m)');
# Maximum step size (max_step)
sol = solve_ivp(simple_golf, tspan, y0, max_step=0.5)
plt.plot(sol.y[0], sol.y[1], 'ro-')
plt.xlabel('x'); plt.ylabel('y');
# Choosing solution timestamps (t_eval)
tt = np.linspace(tspan[0], tspan[1], 41)
sol = solve_ivp(simple_golf, tspan, y0, t_eval=tt)
plt.plot(sol.y[0], sol.y[1], 'ro-')
plt.xlabel('x'); plt.ylabel('y');
# Choosing error tolerances (rtol, atol)
fun = (lambda t,z: 2*z[0]*(1-z[0])/(1+t))
sol1 = solve_ivp(fun, [0,10], [0.3], rtol=1.e-2, atol=1.e-2)
sol2 = solve_ivp(fun, [0,10], [0.3], rtol=1.e-7, atol=1.e-7)
plt.plot(sol1.t, sol1.y[0], 'ro-')
plt.plot(sol2.t, sol2.y[0], 'bo-')
plt.xlabel('x'); plt.ylabel('y');
# Define the event function
def my_event(t,z):
return z[1]
# We want integration to terminate
my_event.terminal = True
# And we want only positive-to-negative crossings.
my_event.direction = -1
fun = lambda t,x: simple_golf2(t,x,10)
sol = solve_ivp(fun, tspan, y0, max_step=0.6, events=my_event)
plt.plot(sol.y[0], sol.y[1], 'ro-');
plt.title('Golf Ball Trajectory')
plt.xlabel('Distance (m)')
plt.ylabel('Height (m)');