I have a question on solving second order differential equations using RK4, considering additional constraints on the first derivative. I am doing the example shown here with some modifications
θ′′(t) + b θ′(t) + c sin(θ(t)) = 0
The additional constraint is:
when θi θ(i+1)<0, then θ′(i+1)=0.9θ′i,
where i is the steps of t, i+1 is one step after i. In the real world, it says when the direction of displacement reverses, its velocity is reduced to 90%.
Vectorially if y(t) = (θ(t), ω(t)), then the equation is ẏ = f(t,y), where f(t,y) = (y₂(t), −by₂(t) − cos(y₁(t))).
In this problem, how should I modify the code if I want to add constraints on ω or θ′(t) (which are the same thing)? Here is my code which didn't work. The additional condition makes θ′ non-continuous. The following "homemade" solution cannot update θ′ properly. I am new to Python and this is my first StackOverflow post. Any guidance is much appreciated.
def rungekutta4(f, y0, t, args=()):
n = len(t)
y = np.zeros((n, len(y0)))
y[0] = y0
for i in range(n - 1):
h = t[i+1] - t[i]
if y[i][0]*y[i+1][0]<0:
k1 = f(y[i], t[i], *args)
k2 = f(y[i] + k1 * h / 2., t[i] + h / 2., *args)
k3 = f(y[i] + k2 * h / 2., t[i] + h / 2., *args)
k4 = f(y[i] + k3 * h, t[i] + h, *args)
y[i+1] = y[i] + (h / 6.) * (k1 + 2*k2 + 2*k3 + k4)*0.9
else:
k1 = f(y[i], t[i], *args)
k2 = f(y[i] + k1 * h / 2., t[i] + h / 2., *args)
k3 = f(y[i] + k2 * h / 2., t[i] + h / 2., *args)
k4 = f(y[i] + k3 * h, t[i] + h, *args)
y[i+1] = y[i] + (h / 6.) * (k1 + 2*k2 + 2*k3 + k4)
return y
In the current formulation and taking the idea that each time the pendulum passes the vertical position its velocity is reduced by 10%, this can be approximately arranged as
for i in range(n - 1):
h = t[i+1] - t[i]
y[i+1] = RK4step(f,t[i],y[i],h, args)
if y[i+1,0]*y[i,0] < 0: y[i+1,1] *= 0.9
return y
that is, first compute the new value and then apply the condition. The time step should be small enough that the angle only changes a few degrees. For larger time steps you would have to split the step containing the zero crossing, using some root finding method like the secant method to find a more accurate time of the root.