简体   繁体   中英

1D Finite Difference Wave Equation Modeling

I am attempting to model a 1D wave created by a Gaussian point source using the finite difference approximation method. Below is my code.

import matplotlib.pyplot as plt
import numpy as np

########Pre-Defining Values########
# spacial extent
lox = -1000
upx = 1000

# space sampling interval (km)
dx = 2.0
dx2inv = 1/(dx*dx)

# temporal extent
lot = 0
upt = 60

# time sampling interval (s)
dt = 0.5
dt2 = dt*dt

x = np.arange(lox,upx,dx)
t = np.arange(lot,upt,dt)

# pressure source location
psx = 0

# velocity (km/s)
v = 2.0
v2 = v*v

# density change location
pcl = 500

# density
p1 = 1
p1inv = 1/p1
p2 = 0.2
p2inv = 1/p2
pinv = np.zeros_like(x)
p = np.zeros_like(x)
for i in range(0,(int)((upx+pcl)/dx),1):
  pinv[i] = p1inv
  p[i] = p1
for i in range((int)((upx+pcl)/dx),len(pinv),1):
  pinv[i] = p2inv
  p[i] = p2


# waveform
f = np.zeros((len(t),len(x)))

# source
amp = 20 
mu = 0
sig = 10/dx
s = np.zeros_like(f)
s[0] = 1/(sig*np.sqrt(2*np.pi)) * np.exp(-(x-mu)*(x-mu)/2/sig/sig)
maxinv = 1/np.amax(s[0])
for i in range(1,len(s[0])):
  s[0][i] *= amp*maxinv


########Calculating Waveform########
h = np.zeros_like(f)
n1 = len(f)
n2 = len(f[0])

def fdx(i1):
  for i2 in range(1,n2-1):
    gi  = f[i1][i2  ]
    gi -= f[i1][i2-1]
    gi *= pinv[i2]
    h[i1][i2-1] -= gi
    h[i1][i2  ]  = gi

#f[0] = s[0]
fdx(0)
for i2 in range(0,n2):
  f[1][i2] = 2*f[0][i2] + (s[0][i2] - h[0][i2] * dx2inv) * p[i2] * v2 * dt2
for i1 in range(1,n1-1):
  fdx(i1)
  for i2 in range(0,n2):
    f[i1+1][i2] = 2*f[i1][i2] - f[i1-1][i2] + (s[i1][i2] - h[i1][i2] * dx2inv) * p[i2] * v2 * dt2

########Plotting########
plt.plot(x,f[50])

maxf = 1.5*amp
minf = -1.5*amp
plt.axis([lox,upx,minf,maxf])
plt.xlabel('x')
plt.ylabel('f(x,t)')

# vertical colored bars representing density
plt.axvspan(lox, pcl, facecolor='g', alpha=0.1)
plt.axvspan(pcl, upx, facecolor='g', alpha=0.2)

# text with density values
plt.text(pcl-0.2*upx,0.8*maxf,r'$\rho = $%s'%(p1),fontsize=15)
plt.text(pcl+0.05*upx,0.8*maxf,r'$\rho = $%s'%(p2),fontsize=15)

plt.show()

Unfortunately this code does not produce the correct result (two Gaussian pulses traveling left and right away from x=0). It instead produces one Gaussian pulse that grows with time. Does anyone know what error I am making?

Thank you very much.

It has been some time since you posted this, but if it is of any help, here is a code to generate Gaussian pulses. I am not good at programming so i am sorry if this code is obfuscating. I have used 1D FDTD wave propagation equation for an EM wave (unitless) :

import numpy as np                      
import matplotlib.pyplot as plt
import matplotlib.animation as animation

#defining dimensions
xdim=720
time_tot = 500
xsource = xdim/2

#stability factor
S=1

#Speed of light
c=1
epsilon0=1
mu0=1

delta =1
deltat = S*delta/c

Ez = np.zeros(xdim)
Hy = np.zeros(xdim)

epsilon = epsilon0*np.ones(xdim)
mu = mu0*np.ones(xdim)

fig , axis = plt.subplots(1,1)
axis.set_xlim(len(Ez))
axis.set_ylim(-3,3)
axis.set_title("E Field")
line, = axis.plot([],[])

def init():
    line.set_data([],[])
    return line,

def animate(n, *args, **kwargs):
    Hy[0:xdim-1] = Hy[0:xdim-1]+(delta/(delta*mu[0:xdim-1]))*(Ez[1:xdim]-Ez[0:xdim-1])
    Ez[1:xdim]= Ez[1:xdim]+(delta/(delta*epsilon[1:xdim]))*(Hy[1:xdim]-Hy[0:xdim-1])
    Ez[xsource] = Ez[xsource] + 30.0*(1/np.sqrt(2*np.pi))*np.exp(-(n-80.0)**2/(100))
    ylims = axis.get_ylim()
    if (abs(np.amax(Ez))>ylims[1]):
        axis.set_ylim(-(np.amax(Ez)+2),np.amax(Ez)+2)
    line.set_data(np.arange(len(Ez)),Ez)
    return line,

ani = animation.FuncAnimation(fig, animate, init_func=init, frames=(time_tot), interval=10, blit=False, repeat =False)
fig.show()

I hope it helps. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM