I solved numerically, in Python, the general (nonlinear) pengulum using 4th-order Runge-Kutta method previously. And here is a question related to this, Attempt to solve the nonlinear pendulum 2nd order differential equation using 4th order Runge-Kutta method, not getting expected result, it contains details about the code and processes.
I have also tried to solve a 'spin' system, made of three simultaneous differential equations, using the same method. And it was also successful.
But, both of these questions dealt with a single particle.
Now what if I have is a number of particles. So I need to solve the same differential equations for each of the particles (no interactions). Maybe I can try it by writing the same steps for all the particles, but that's cumbursome. Also, in that case I can't change the particle number as may be required, I have to rewrite the whole thing.
I am not that familier with NumPy, also I can't wait to learn it in detail first.
Let's say for the single particle/oscillator, we have the following functions:
def f1(t,x,y): return y
def f2(t,x,y): return -k*sin(x)
Then there is the initial values:
k=1.0 #parameter
t,x,y=0,8.0*pi/9.0,0 #initial values (t: second, x: radian, y: radian/second)
h=0.01 #increment in t
And the RK4 loop:
T,X,Y=[t],[x],[y] #lists to store data
# Loop:
for i in range(2000):
a1=h*f1(t,x,y)
b1=h*f2(t,x,y)
a2=h*f1(t+0.5*h,x+0.5*a1,y+0.5*b1)
b2=h*f2(t+0.5*h,x+0.5*a1,y+0.5*b1)
a3=h*f1(t+0.5*h,x+0.5*a2,y+0.5*b2)
b3=h*f2(t+0.5*h,x+0.5*a2,y+0.5*b2)
a4=h*f1(t+h,x+a3,y+b3)
b4=h*f2(t+h,x+a3,y+b3)
x=x+(1/6)*(a1+2*a2+2*a3+a4) # apprx. value of x1 for t+h
y=y+(1/6)*(b1+2*b2+2*b3+b4) # apprx. value of y1 for t+h
t=t+h # current value of independent variable t
T.append(t)
X.append(x)
Y.append(y)
Now what to do if, let's say, we have two particles/oscillator in an 1D array, or, say, 2x2=4 oscillators in a 2D array?
How can we achive our task by using elementary numpy techniques?
I thought of something as follows:
def f1(t,x[i][j],y[i][j]): return y[i][j]
def f2(t,x[i][j],y[i][j]): return -k*sin(x[i][j])
k=1.0 #parameter
t,x[i][j],y[i][j]=0,8.0*pi/9.0,0 #initial values (t: second, x: radian, y: radian/second)
h=0.01 #increment in t
But several errors are being shown, and I know I am missing a lot of stuff.
That's why I can't proceed to the loop part at all.
What things need to be added?
Rather than dealing with multi-dimensional arrays, you can use a single 1d numpy array of size 2N (where N is the number of oscillators).
Here you store POSITIONS in
y[0], y[2], y[4], ...and velocities iny[1], y[3], y[5], ...This has the advantage that you can keep the same fully-vectorised Runge-Kutta routine.