问题
Here is a code simulating the simplest falling ball:
%pylab
from scipy.integrate import odeint
ts = linspace(0, 1)
def f(X, t):
dx0 = X[1]
dx1 = -9.8
return [dx0, dx1]
X = odeint(f, [2, 0], ts)
plot(ts, X[:, 0])
But how about a ball bouncing at y=0?
I know that, in general, collision is a difficult part of physics simulations. However, I wonder if it's really not possible to simulate this simple system, hopefully with odeint.
回答1:
The simplest way is just to add a big force that kicks the particle out from the forbidden region. This requires an ODE solver that is able to handle "stiff" problems, but luckily odeint
uses lsoda
which automatically switches to a mode suitable for such problems.
For example,
F(x) = { 0 if x > 0
{ big_number if x < 0
The numerical solver will have slightly easier time if the step function is rounded a bit, for example, F(x) = big_number / (1 + exp(x/width))
:
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
big_number = 10000.0
width = 0.0001
ts = np.linspace(0, 10, 2000)
def f(X, t):
dx0 = X[1]
dx1 = -9.8
dx1 += big_number / (1 + np.exp(X[0]/width))
return [dx0, dx1]
with np.errstate(over='ignore'):
# don't print overflow warning messages from exp(),
# and limit the step size so that the solver doesn't step too deep
# into the forbidden region
X = odeint(f, [2, 0], ts, hmax=0.01)
plt.plot(ts, X[:, 0])
plt.show()
来源:https://stackoverflow.com/questions/28639400/how-to-simulate-bouncing-ball-odeint-not-applicable