求一个二维和三维的对流扩散方程Python的程序 要求有误差分析和解析解和数值解的比较 事成六张
2条回答 默认 最新
盒子里的加菲猫 2023-05-12 18:02关注对流扩散方程是一类常见的偏微分方程,其数值求解方法有很多种,包括有限差分方法、有限元方法、谱方法等。下面是一个使用有限差分方法求解二维和三维对流扩散方程的 Python 程序,并包含误差分析和解析解和数值解的比较。
二维对流扩散方程的数值求解:
import numpy as np import matplotlib.pyplot as plt # 空间区间和步长设置 Lx, Ly = 1.0, 1.0 dx, dy = 0.01, 0.01 Nx, Ny = int(Lx/dx), int(Ly/dy) # 时间区间和步长设置 T, dt = 1.0, 0.001 Nt = int(T/dt) # 物理参数设置 rho, mu, kappa = 1.0, 0.001, 0.001 # 初始条件设置 u0 = np.zeros((Nx, Ny)) u0[int(Nx/4):int(3*Nx/4), int(Ny/4):int(3*Ny/4)] = 1.0 # 数值解计算 u = u0.copy() for n in range(Nt): u[1:Nx-1,1:Ny-1] += dt*(-rho*u[1:Nx-1,1:Ny-1]*(u[2:Nx,1:Ny-1]-u[0:Nx-2,1:Ny-1])/dx -rho*u[1:Nx-1,1:Ny-1]*(u[1:Nx-1,2:Ny]-u[1:Nx-1,0:Ny-2])/dy +mu*(u[2:Nx,1:Ny-1]-2*u[1:Nx-1,1:Ny-1]+u[0:Nx-2,1:Ny-1])/dx**2 +mu*(u[1:Nx-1,2:Ny]-2*u[1:Nx-1,1:Ny-1]+u[1:Nx-1,0:Ny-2])/dy**2) # 解析解计算 x = np.linspace(0, Lx, Nx) y = np.linspace(0, Ly, Ny) X, Y = np.meshgrid(x, y) u_exact = np.exp(-2*rho/kappa*T)*np.sin(np.pi*X)*np.sin(np.pi*Y) # 误差分析和比较 error = np.linalg.norm(u_exact - u, ord=2)/(Nx*Ny) print('L2误差:', error) plt.figure(figsize=(12, 4)) plt.subplot(1, 2, 1) plt.imshow(u_exact, cmap='jet', extent=[0, Lx, 0, Ly]) plt.colorbar() plt.title('解析解') plt.subplot(1, 2, 2) plt.imshow(u, cmap='jet', extent=[0, Lx, 0, Ly]) plt.colorbar() plt.title('数值解') plt.show()三维对流扩散方程的数值求解:
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 空间区间和步长设置 Lx, Ly, Lz = 1.0, 1.0, 1.0 dx, dy, dz = 0.01, 0.01, 0.01 Nx, Ny, Nz = int(Lx/dx), int(Ly/dy), int(Lz/dz) # 时间区间和步长设置 T, dt = 1.0, 0.001 Nt = int(T/dt) # 物理参数设置 rho, mu, kappa = 1.0, 0.001, 0.001 # 初始条件设置 u0 = np.zeros((Nx, Ny, Nz)) u0[int(Nx/4):int(3*Nx/4), int(Ny/4):int(3*Ny/4), int(Nz/4):int(3*Nz/4)] = 1.0 # 数值解计算 u = u0.copy() for n in range(Nt): u[1:Nx-1,1:Ny-1,1:Nz-1] += dt*(-rho*u[1:Nx-1,1:Ny-1,1:Nz-1]*(u[2:Nx,1:Ny-1,1:Nz-1]-u[0:Nx-2,1:Ny-1,1:Nz-1])/dx -rho*u[1:Nx-1,1:Ny-1,1:Nz-1]*(u[1:Nx-1,2:Ny,1:Nz-1]-u[1:Nx-1,0:Ny-2,1:Nz-1])/dy -rho*u[1:Nx-1,1:Ny-1,1:Nz-1]*(u[1:Nx-1,1:Ny-1,2:Nz]-u[1:Nx-1,1:Ny-1,0:Nz-2])/dz +mu*(u[2:Nx,1:Ny-1,1:Nz-1]-2*u[1:Nx-1,1:Ny-1,1:Nz-1]+u[0:Nx-2,1:Ny-1,1:Nz-1])/dx**2 +mu*(u[1:Nx-1,2:Ny,1:Nz-1]-2*u[1:Nx-1,1:Ny-1,1:Nz-1]+u[1:Nx-1,0:Ny-2,1:Nz-1])/dy**2 +mu*(u[1:Nx-1,1:Ny-1,2:Nz]-2*u[1:Nx-1,1:Ny-1,1:Nz-1]+u[1:Nx-1,1:Ny-1,0:Nz-2])/dz**2) # 解析解计算 x = np.linspace(0, Lx, Nx) y = np.linspace(0, Ly, Ny) z = np.linspace(0, Lz, Nz) X, Y, Z = np.meshgrid(x, y, z) u_exact = np.exp(-3*rho/kappa*T)*np.sin(np.pi*X)*np.sin(np.pi*Y)*np.sin(np.pi*Z) # 误差分析和比较 error = np.linalg.norm(u_exact - u, ord=2)/(Nx*Ny*Nz) print('L2误差:', error) fig = plt.figure(figsize=(12, 6)) ax = fig.add_subplot(1, 2, 1, projection='3d') ax.plot_surface(X, Y, u_exact[:,:,int(Nz/2)], cmap='jet') ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('u') ax.set_title('解析解') ax = fig.add_subplot(1, 2, 2, projection='3d') ax.plot_surface(X, Y, u[:,:,int(Nz/2)], cmap='jet') ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('u') ax.set_title('数值解') plt.show()这里使用了 NumPy 和 Matplotlib 库来进行数值计算和可视化,其中 np.linalg.norm 函数用于计算 L2 范数,plt.imshow 函数用于显示二维图像,Axes3D.plot_surface 函数用于显示三维图像。通过比较解析解和数值解的可视化效果和 L2 误差,可以评估数值求解的精度和准确性。
解决 无用评论 打赏 举报