Runge-Kutta 4 zum Lösen von ODEs Python-Systemen
Ich habe Code für Runge-Kutta 4 zum Lösen von ODE-Systemen geschrieben.
Es funktioniert gut für 1-D-ODE, aber wenn ich versuche zu lösen, habe x'' + kx = 0ich ein Problem beim Versuch, eine vektorielle Funktion zu definieren:
Lassen Sie u1 = xund u2 = x' = u1', dann sieht das System aus wie:
u1' = u2
u2' = -k*u1
Wenn u = (u1,u2)und f(u, t) = (u2, -k*u1), dann müssen wir lösen:
u' = f(u, t)
def f(u,t, omega=2):
u, v = u
return np.asarray([v, -omega**2*u])
Mein gesamter Code lautet:
import numpy as np
def ode_RK4(f, X_0, dt, T):
N_t = int(round(T/dt))
# Create an array for the functions ui
u = np.zeros((len(X_0),N_t+1)) # Array u[j,:] corresponds to the j-solution
t = np.linspace(0, N_t*dt, N_t + 1)
# Initial conditions
for j in range(len(X_0)):
u[j,0] = X_0[j]
# RK4
for j in range(len(X_0)):
for n in range(N_t):
u1 = f(u[j,n] + 0.5*dt* f(u[j,n], t[n])[j], t[n] + 0.5*dt)[j]
u2 = f(u[j,n] + 0.5*dt*u1, t[n] + 0.5*dt)[j]
u3 = f(u[j,n] + dt*u2, t[n] + dt)[j]
u[j, n+1] = u[j,n] + (1/6)*dt*( f(u[j,n], t[n])[j] + 2*u1 + 2*u2 + u3)
return u, t
def demo_exp():
import matplotlib.pyplot as plt
def f(u,t):
return np.asarray([u])
u, t = ode_RK4(f, [1] , 0.1, 1.5)
plt.plot(t, u[0,:],"b*", t, np.exp(t), "r-")
plt.show()
def demo_osci():
import matplotlib.pyplot as plt
def f(u,t, omega=2):
# u, v = u Here I've got a problem
return np.asarray([v, -omega**2*u])
u, t = ode_RK4(f, [2,0], 0.1, 2)
for i in [1]:
plt.plot(t, u[i,:], "b*")
plt.show()
Im Voraus danke.
Antworten
Sie sind auf dem richtigen Weg, aber wenn Sie Zeitintegrationsmethoden wie RK auf vektorwertige ODEs anwenden, tun Sie im Wesentlichen genau das Gleiche wie im skalaren Fall, nur mit Vektoren.
Auf diese Weise überspringen Sie die for j in range(len(X_0))Schleife und die zugehörige Indexierung und stellen sicher, dass Sie Anfangswerte als Vektoren (Numpy-Arrays) übergeben.
Bereinigte auch die Indexierung tein wenig und speicherte die Lösung in einer Liste.
import numpy as np
def ode_RK4(f, X_0, dt, T):
N_t = int(round(T/dt))
# Initial conditions
usol = [X_0]
u = np.copy(X_0)
tt = np.linspace(0, N_t*dt, N_t + 1)
# RK4
for t in tt[:-1]:
u1 = f(u + 0.5*dt* f(u, t), t + 0.5*dt)
u2 = f(u + 0.5*dt*u1, t + 0.5*dt)
u3 = f(u + dt*u2, t + dt)
u = u + (1/6)*dt*( f(u, t) + 2*u1 + 2*u2 + u3)
usol.append(u)
return usol, tt
def demo_exp():
import matplotlib.pyplot as plt
def f(u,t):
return np.asarray([u])
u, t = ode_RK4(f, np.array([1]) , 0.1, 1.5)
plt.plot(t, u, "b*", t, np.exp(t), "r-")
plt.show()
def demo_osci():
import matplotlib.pyplot as plt
def f(u,t, omega=2):
u, v = u
return np.asarray([v, -omega**2*u])
u, t = ode_RK4(f, np.array([2,0]), 0.1, 2)
u1 = [a[0] for a in u]
for i in [1]:
plt.plot(t, u1, "b*")
plt.show()
Das Modell lautet wie folgt: Geben Sie hier die Bildbeschreibung ein
Aus dem Buch Programming for Computations - Python von Langtangen.