Python牛顿迭代法的应用
追赶法(Thomas) 雅克比迭代(Jacobi) 高斯迭代(Gauss) 的C++实现
变分原理与边值问题的计算机处理
计算物理专题:双向打靶法解决本征值问题
计算物理专题:有限差分法解决本征值问题
Numerov算法解一维无限深势阱的问题 (含量子力学导论)
Python数值分析案例01--------四阶龙格库塔法解抛体运动
常微分方程的龙格库塔显式与隐式解法
自洽可分的哈密顿系统的辛算法
计算物理专题:高维Romberg数值积分方法
import numpy as np
import matplotlib.pyplot as plt
#\frac{\partial u}{\partial t} = \lambda(
#\frac{\partial^2 u}{\partial x^2} +
#\frac{\partial^2 u}{\partial y^2}
#) + q_v
class projequation2D():
def __init__(self, Lambda=1, qv = lambda t, x, y:0,
X_start=0, X_end=1,
Y_start=0, Y_end=1,
T_start=0, T_end=1,
dx = 0.05,
dy = 0.05,
dt = 0.01):
#c = lambda x,y,t:(?)
self.Lambda = Lambda
self.qv = qv
self.dx = dx
self.dy = dy
self.dt = dt
self.X_start = X_start
self.Y_start = Y_start
self.T_start = T_start
self.X_end = X_end
self.Y_end = Y_end
self.T_end = T_end
self.X = np.arange(X_start, X_end, dx)
self.Y = np.arange(Y_start, Y_end, dy)
self.T = np.arange(T_start, T_end, dt)
self.results = np.zeros((len(self.T), len(self.X), len(self.Y)))
self.startresults()
def initcondition_0(self):
X_num = len(self.X)
Y_num = len(self.Y)
test_fun = lambda x,y: np.sin(5*x)*np.cos(5*y)
for ix in range(X_num):
for iy in range(Y_num):
self.results[0][ix][iy] == test_fun(self.X[ix], self.Y[iy])
def boundarycondition_left(self):
Y_num = len(self.Y)
T_num = len(self.T)
for it in range(T_num):
for iy in range(Y_num):
self.results[it][0][iy] = 25
def boundarycondition_right(self):
Y_num = len(self.Y)
T_num = len(self.T)
for it in range(T_num):
for iy in range(Y_num):
self.results[it][-1][iy] = 25
def boundarycondition_up(self):
X_num = len(self.X)
T_num = len(self.T)
for it in range(T_num):
for iy in range(X_num):
self.results[it][iy][-1] = 25
def boundarycondition_down(self):
X_num = len(self.X)
T_num = len(self.T)
for it in range(T_num):
for iy in range(X_num):
self.results[it][iy][0] = 25
def startresults(self):
self.initcondition_0()
self.boundarycondition_left()
self.boundarycondition_right()
self.boundarycondition_up()
self.boundarycondition_down()
def Upwind3P(self):
for Ti in range(1, len(self.T)):
for Xi in range(1, len(self.X)-1):
for Yi in range(1, len(self.Y)-1):
rx = self.Lambda * self.dt/(self.dx)**2
ry = self.Lambda * self.dt/(self.dy)**2
self.results[Ti][Xi][Yi] = \
rx * (self.results[Ti-1][Xi-1][Yi]+self.results[Ti-1][Xi+1][Yi])+\
2* (1-rx-ry) *self.results[Ti-1][Xi][Yi]+\
ry * (self.results[Ti-1][Xi][Yi-1]+self.results[Ti-1][Xi][Yi+1])-\
self.results[Ti-2][Xi][Yi]
return self.results
def show_wave(self):
fig = plt.figure(figsize=(8,8))
ax1 = fig.add_subplot(111, projection='3d')
x, y = np.meshgrid(self.X, self.Y)
for time in range(len(self.T)):
ax1.plot_surface(x, y, self.results[time, :, :],
rstride=2, cstride=2, cmap='rainbow')
plt.title("time:" + str(self.T[time]))
plt.pause(0.5)
plt.cla()
c = projequation2D()
u = c.Upwind3P()
c.show_wave()
import numpy as np
import matplotlib.pyplot as plt
#\frac{\partial^2 u}{\partial t^2} = c^2 (
#\frac{\partial^2 u}{\partial x^2} +
#\frac{\partial^2 u}{\partial y^2}
#)
class waveequation2D():
def __init__(self, c,
X_start=0, X_end=1,
Y_start=0, Y_end=1,
T_start=0, T_end=1.01,
dx = 0.01,
dy = 0.01,
dt = 0.01):
#c = lambda x,y,t:(?)
self.c = c
self.dx = dx
self.dy = dy
self.dt = dt
self.X_start = X_start
self.Y_start = Y_start
self.T_start = T_start
self.X_end = X_end
self.Y_end = Y_end
self.T_end = T_end
self.X = np.arange(X_start, X_end, dx)
self.Y = np.arange(Y_start, Y_end, dy)
self.T = np.arange(T_start, T_end, dt)
self.results = np.zeros((len(self.T), len(self.X), len(self.Y)))
self.startresults()
def initcondition_0(self, x, y):
return np.sin(10*x)
def initcondition_1(self, x, y):
return np.sin(10*x)
def boundarycondition_left(self, t, x, y):
return (np.sin(10*y))[0]
def boundarycondition_right(self, t, x, y):
return (np.sin(10*y))[0]
def boundarycondition_up(self, t, x, y):
return (np.sin(10*x))[0]
def boundarycondition_down(self, t, x, y):
return (np.sin(10*x))[0]
def startresults(self):
x, y = np.meshgrid(self.X, self.Y)
self.results[0] = self.initcondition_0(x, y)
self.results[1] = self.initcondition_1(x, y)
t, x, y = np.meshgrid(self.T, self.X, self.Y)
self.results[:, 0, :] = self.boundarycondition_left(t, self.X_start, y)
self.results[:, -1, :] = self.boundarycondition_right(t, self.X_end, y)
self.results[:, :, -1] = self.boundarycondition_up(t, x, self.Y_end)
self.results[:, :, 0] = self.boundarycondition_down(t, x, self.Y_start)
def test_stability(self, x, y, t):
test = 4*self.dt**2*self.c(x, y, t)**2/(self.dx**2 + self.dy**2)
if test<=1:
return True
else:
print("unstable in x:", x, "y:", y, "t:", t)
return False
def Upwind3P(self):
for Ti in range(2, len(self.T)):
for Xi in range(1, len(self.X)-1):
for Yi in range(1, len(self.Y)-1):
rx = self.c(self.X[Xi], self.Y[Yi], self.T[Ti])**2 * self.dt**2/self.dx**2
ry = self.c(self.X[Xi], self.Y[Yi], self.T[Ti])**2 * self.dt**2/self.dy**2
self.results[Ti][Xi][Yi] = \
rx * (self.results[Ti-1][Xi-1][Yi]+self.results[Ti-1][Xi+1][Yi])+\
2* (1-rx-ry) *self.results[Ti-1][Xi][Yi]+\
ry * (self.results[Ti-1][Xi][Yi-1]+self.results[Ti-1][Xi][Yi+1])-\
self.results[Ti-2][Xi][Yi]
## self.test_stability(self.X[Xi],self.Y[Yi],self.T[Ti])
return self.results
def show_wave(self):
fig = plt.figure(figsize=(8,12))
ax1 = fig.add_subplot(121, projection='3d')
ax2 = fig.add_subplot(122, projection='3d')
x, y = np.meshgrid(self.X, self.Y)
for time in range(len(self.T)):
ax1.plot_surface(x, y, self.results[time, :, :],
rstride=2, cstride=2, cmap='rainbow')
ax2.plot_wireframe(x, y, self.results[time, :, :],
rstride=2, cstride=2, linewidth=1, cmap='rainbow')
plt.title("time:" + str(self.T[time]))
plt.pause(0.01)
plt.cla()
def test_fun(x, y, t):
return 1
c = waveequation2D(c=test_fun)
u = c.Upwind3P()
c.show_wave()
典型的偏微分方程数值解法
二维Poisson方程五点差分格式与Python实现