追赶法(Thomas) 雅克比迭代(Jacobi) 高斯迭代(Gauss) 的C++实现
Numerov算法解一维无限深势阱的问题 (含量子力学导论)
Python数值分析案例01--------四阶龙格库塔法解抛体运动
- 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()