N.J Abel
N.J Abel

Reputation: 51

Wave on a string analysis

I am trying to analyse a wave on a string by solving the wave equation with Python. Here are my requirements for the solution.

1) I model reflective ends by using much larger masses on first and last point on the string -> Large inertia

2)No spring on edges. Then k[0] and k[-1] will be ZERO.

I have problem with indices. In my 2nd loop I get y[i,j-1], k[i-1], y[i-1,j]. In the first iteration the loop will then use y[0,-1], k[-1], y[-1,0]. These are my last points and not my first points. How can I avoid this problem?

Upvotes: 0

Views: 1141

Answers (1)

keepAlive
keepAlive

Reputation: 6655

What you need is initiating your mass array with one additional element. I mean

...
m = [mi]*N # mass array   [!!!] instead of (N-1)  [!!!]
...

Idem for your springs

...
k = [ki]*N
...

Consequently, you can keep k[0] equal to 10. since you model reflective ends. You may thus want to comment or drop this line

...
##k[0] = 0
...


For aesthetic considerations you may want to fill the gap at the end of the x-axis. In this case, simply do

N = 201 # Number of mass points

Your code thus becomes

from numpy import *
from  matplotlib.pyplot import *

# Variables
N = 201 # Number of mass points
nT = 1200 # Number of time points
mi = 0.02 # mass in kg
m = [mi]*N # mass array
m[-1] = 100 # Large last mass reflective edges
m[0] = 100 # Large first mass  reflective edges
ki = 10.#spring 
k = [ki]*N
k[-1] = 0
dx = 0.2
kappa = ki*dx
my = mi/dx
c = sqrt(kappa/my) # velocity 

dt = 0.04

#  3 vectors
x = arange( N )*dx # x points
t = arange( N )*dt # t points


y = zeros( [N, nT ] )# 2D array
# Loop over initial condition
for i in range(N-1):
    y[i,0] = sin((7.*pi*i)/(N-1)) # Initial condition dependent on mass point


# Iterating over time and position to find next position of wave
for j in range(nT-1):

    for i in range(N-1):
        y[i,j+1] = 2*y[i,j] - y[i,j-1] + (dt**2/m[i])*(k[i-1]*y[i+1,j] -2*k[i-1]*y[i,j] + k[i]*y[i-1,j] )

    #check values of edges
    print y[:2,j+1],y[-2:,j+1]

    # Creates an animation
    cla()
    ylabel("Amplitude")
    xlabel("x")    
    ylim(-10,10)
    plot(x,y[:,j-2])
    pause(0.001)
close()

which produces

enter image description here


Following your comment, I think that if you want to see the wave traveling along the string before reflection, you should not initiate conditions everywhere (in space). I mean, e.g., doing

...
# Loop over initial condition
for i in range(N-1):
    ci_i = sin(7.*pi*i/(N-1)) # Initial condition dependent on mass point
    if np.sign(ci_i*y[i-1,0])<0:
        break
    else:
        y[i,0] = ci_i
...

produces

enter image description here

New attempt after answers:

from numpy import *
from  matplotlib.pyplot import *

N = 201
nT = 1200
mi = 0.02
m = [mi]*(N)
m[-1] = 1000
m[0] = 1000
ki = 10.
k = [ki]*N
dx = 0.2
kappa = ki*dx
my = mi/dx
c = sqrt(kappa/my) 
dt = 0.04


x = arange( N )*dx
t = arange( N )*dt


y = zeros( [N, nT ] )

for i in range(N-1):
    y[i,0] = sin((7.*pi*i)/(N-1))



for j in range(nT-1):

    for i in range(N-1):
        if j == 0: # if j = 0 then ...  y[i,j-1]=y[i,j]
            y[i,j+1] = 2*y[i,j] - y[i,j] + (dt**2/m[i])*(k[i-1]*y[i+1,j] -2*k[i-1]*y[i,j] + k[i]*y[i-1,j] )
        else:
            y[i,j+1] = 2*y[i,j] - y[i,j-1] + (dt**2/m[i])*( k[i-1]*y[i+1,j] -2*k[i-1]*y[i,j] + k[i]*y[i-1,j] )

    cla()

    ylim(-1,1)
    plot(x,y[:,j-2])
    pause(0.0001)

    ylabel("Amplitude")
    xlabel("x")

    print len(x), len(t), N,nT

Here is a plot of the new attempt at solution with |amplitude| of anti node equal 1.0. Will this do anything with further solving the issue with indices?

enter image description here

Upvotes: 2

Related Questions