差分法求解 Burgers 方程(附完备MATLAB 及 Python代码)

打印 上一主题 下一主题

主题 1751|帖子 1751|积分 5253

Burgers 方程的数值解及偏差分析

弁言

Burgers 方程是一个非线性偏微分方程,在流体力学、非线性声学和交通流理论中有广泛应用。本文将通过数值方法求解带粘性的 Burgers 方程,并分析其偏差。
方程模子

Burgers 方程的情势为:
                                                    u                               t                                      +                            u                                       u                               x                                      =                            ϵ                                       u                                           x                                  x                                                 ,                                  u_t + u u_x = \epsilon u_{xx},                     ut​+uux​=ϵuxx​,
其中,                                   u                              u                  u 是待求函数,                                   x                              x                  x 是空间变量,                                   t                              t                  t 是时间变量,                                   ϵ                              \epsilon                  ϵ 是黏性系数。
初始条件和界限条件

为了求解方程,我们需要指定初始条件和界限条件。在本文中,我们选择如下初始条件:
                                         u                            (                            x                            ,                            0                            )                            =                            −                            sin                            ⁡                            (                            π                            x                            )                            ,                                  u(x, 0) = -\sin(\pi x),                     u(x,0)=−sin(πx),
界限条件设定为常数界限条件:
                                         u                            (                            −                            1                            ,                            t                            )                            =                            0                            ,                                     u                            (                            1                            ,                            t                            )                            =                            0.                                  u(-1, t) = 0, \quad u(1, t) = 0.                     u(−1,t)=0,u(1,t)=0.
数值方法

我们使用向后欧拉法进行时间离散,并使用中央差分法进行空间离散。时间步长为                                    d                         t                              dt                  dt,空间步长为                                    d                         x                              dx                  dx。
时间离散

向后欧拉法的时间离散情势为:
                                                                             u                                                   n                                        +                                        1                                                           −                                               u                                     n                                                                  d                                  t                                                 +                                       u                                           n                                  +                                  1                                                                        ∂                                               u                                                   n                                        +                                        1                                                                               ∂                                  x                                                 =                            ϵ                                                                ∂                                     2                                                           u                                                   n                                        +                                        1                                                                               ∂                                               x                                     2                                                                   \frac{u^{n+1} - u^n}{dt} + u^{n+1} \frac{\partial u^{n+1}}{\partial x} = \epsilon \frac{\partial^2 u^{n+1}}{\partial x^2}                     dtun+1−un​+un+1∂x∂un+1​=ϵ∂x2∂2un+1​
空间离散

中央差分法用于空间离散,                                             u                            x                                       u_x                  ux​ 和                                              u                                       x                               x                                                 u_{xx}                  uxx​ 的差分格式为:
                                                                ∂                                  u                                                      ∂                                  x                                                 ≈                                                                u                                                   i                                        +                                        1                                                           −                                               u                                                   i                                        −                                        1                                                                               2                                  d                                  x                                                 .                                  \frac{\partial u}{\partial x} \approx \frac{u_{i+1} - u_{i-1}}{2 dx}.                     ∂x∂u​≈2dxui+1​−ui−1​​.
                                                                             ∂                                     2                                              u                                                      ∂                                               x                                     2                                                             ≈                                                                u                                                   i                                        +                                        1                                                           −                                  2                                               u                                     i                                              +                                               u                                                   i                                        −                                        1                                                                               d                                               x                                     2                                                             .                                  \frac{\partial^2 u}{\partial x^2} \approx \frac{u_{i+1} - 2u_i + u_{i-1}}{dx^2}.                     ∂x2∂2u​≈dx2ui+1​−2ui​+ui−1​​.
差分格式

综合时间离散和空间离散,得到差分格式:
                                                                             u                                     i                                                   n                                        +                                        1                                                           −                                               u                                     i                                     n                                                                  d                                  t                                                 +                                       u                               i                                           n                                  +                                  1                                                                                     u                                                   i                                        +                                        1                                                                n                                        +                                        1                                                           −                                               u                                                   i                                        −                                        1                                                                n                                        +                                        1                                                                               2                                  d                                  x                                                 =                            ϵ                                                                u                                                   i                                        +                                        1                                                                n                                        +                                        1                                                           −                                  2                                               u                                     i                                                   n                                        +                                        1                                                           +                                               u                                                   i                                        −                                        1                                                                n                                        +                                        1                                                                               d                                               x                                     2                                                             .                                  \frac{u_i^{n+1} - u_i^n}{dt} + u_i^{n+1} \frac{u_{i+1}^{n+1} - u_{i-1}^{n+1}}{2 dx} = \epsilon \frac{u_{i+1}^{n+1} - 2u_i^{n+1} + u_{i-1}^{n+1}}{dx^2}.                     dtuin+1​−uin​​+uin+1​2dxui+1n+1​−ui−1n+1​​=ϵdx2ui+1n+1​−2uin+1​+ui−1n+1​​.
数值求解过程

为了读者方便,下面我们先给出 Matlab 差分法解 Burgers 方程的代码实现:
  1. % The solution surface of Burgers Equations
  2. % Variables:
  3. % x-space variable, t-time variable.
  4. % Output:
  5. % Solution surface of u_{t}+uu_x=\epsilon u_{xx}
  6. % 参数设置  
  7. epsilon = 0.05;  
  8. dx = 5e-2; % 空间步长  
  9. dt = 5e-3; % 时间步长  
  10. x = -1:dx:1; % 空间网格  
  11. t = 0:dt:1;  % 时间网格  
  12. Nx = length(x);  
  13. Nt = length(t);  
  14. % 初始条件  
  15. u = -sin(pi * x);  
  16. % 边界条件函数(这里假设为常数边界条件)  
  17. Leftbdry = @(t) 0;  
  18. Rightbdry = @(t) 0;  
  19. % 初始化解矩阵  
  20. U = zeros(Nx, Nt);  
  21. U(:, 1) = u; % 初始条件  
  22. % 向后欧拉迭代求解  
  23. for n = 1:Nt-1  
  24.     u_n = U(:, n); % 当前时间步的解  
  25.     u_np1 = u_n;   % 下一时间步的解,初始猜测为当前时间步的解  
  26.    
  27.     % 迭代求解隐式方程  
  28.     max_iter = 100;  
  29.     tol = 1e-6;  
  30.     for iter = 1:max_iter  
  31.         % 计算u_x和u_xx(这里使用简单的二阶中心差分,注意边界处理)  
  32.         u_x = zeros(Nx, 1);
  33.         u_xx = zeros(Nx, 1);
  34.         
  35.         % 中心差分
  36.         u_x(2:end-1) = (u_np1(3:end) - u_np1(1:end-2)) / (2 * dx);
  37.         u_xx(2:end-1) = (u_np1(3:end) - 2 * u_np1(2:end-1) + u_np1(1:end-2)) / (dx^2);
  38.         
  39.         % 边界处理
  40.         u_x(1) = (u_np1(2) - u_np1(1)) / dx;
  41.         u_x(end) = (u_np1(end) - u_np1(end-1)) / dx;
  42.         
  43.         u_xx(1) = (u_np1(2) - 2 * u_np1(1) + Leftbdry(t(n+1))) / (dx^2);
  44.         u_xx(end) = (Rightbdry(t(n+1)) - 2 * u_np1(end) + u_np1(end-1)) / (dx^2);
  45.         % 计算u*u_x  
  46.         uu_x = u_np1 .* u_x;  
  47.         % 向后欧拉方程  
  48.         u_np1_new = u_n - dt * (uu_x - epsilon * u_xx);  
  49.         % 检查收敛性  
  50.         if norm(u_np1_new - u_np1, inf) < tol  
  51.             break;  
  52.         end  
  53.         u_np1 = u_np1_new;  
  54.     end  
  55.     % 更新解矩阵  
  56.     U(:, n+1) = u_np1;  
  57.     % 边界条件修正(如果需要)  
  58.     U(1, n+1) = Leftbdry(t(n+1));  
  59.     U(end, n+1) = Rightbdry(t(n+1));  
  60. end  
  61. % 使用 meshgrid 生成网格数据
  62. [T, X] = meshgrid(t, x);
  63.   
  64. % 绘图显示数值解
  65. figure;
  66. % 将 T, X, U 转换为列向量
  67. % T_vec = T(:);
  68. % X_vec = X(:);
  69. % U_vec = U(:);
  70. surf(T, X, U);hold on;
  71. scatter3(T(:),X(:),U(:),'.' )
  72. xlabel('t')  
  73. ylabel('x')  
  74. zlabel('u(x,t)')  
  75. title('Burgers Equation Solution using Backward Euler Method')
复制代码
求解效果:

思量到 Python 用户较多,笔者也实现了 Python 版本的代码供各人参考:
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. # 参数设置
  4. epsilon = 0.05
  5. dx = 5e-2  # 空间步长
  6. dt = 5e-3  # 时间步长
  7. x = np.arange(-1, 1 + dx, dx)  # 空间网格
  8. t = np.arange(0, 1 + dt, dt)  # 时间网格
  9. Nx = len(x)
  10. Nt = len(t)
  11. # 初始条件
  12. u = -np.sin(np.pi * x)
  13. # 边界条件函数(这里假设为常数边界条件)
  14. def Leftbdry(t):
  15.     return 0
  16. def Rightbdry(t):
  17.     return 0
  18. # 初始化解矩阵
  19. U = np.zeros((Nx, Nt))
  20. U[:, 0] = u  # 初始条件
  21. # 向后欧拉迭代求解
  22. for n in range(Nt - 1):
  23.     u_n = U[:, n]  # 当前时间步的解
  24.     u_np1 = u_n  # 下一时间步的解,初始猜测为当前时间步的解
  25.    
  26.     # 迭代求解隐式方程
  27.     max_iter = 100
  28.     tol = 1e-6
  29.     for iter in range(max_iter):
  30.         # 计算 u_x 和 u_xx(这里使用简单的二阶中心差分,注意边界处理)
  31.         u_x = np.zeros(Nx)
  32.         u_xx = np.zeros(Nx)
  33.         
  34.         # 中心差分
  35.         u_x[1:-1] = (u_np1[2:] - u_np1[:-2]) / (2 * dx)
  36.         u_xx[1:-1] = (u_np1[2:] - 2 * u_np1[1:-1] + u_np1[:-2]) / (dx**2)
  37.         
  38.         # 边界处理
  39.         u_x[0] = (u_np1[1] - u_np1[0]) / dx
  40.         u_x[-1] = (u_np1[-1] - u_np1[-2]) / dx
  41.         
  42.         u_xx[0] = (u_np1[1] - 2 * u_np1[0] + Leftbdry(t[n+1])) / (dx**2)
  43.         u_xx[-1] = (Rightbdry(t[n+1]) - 2 * u_np1[-1] + u_np1[-2]) / (dx**2)
  44.         # 计算 u * u_x
  45.         uu_x = u_np1 * u_x
  46.         # 向后欧拉方程
  47.         u_np1_new = u_n - dt * (uu_x - epsilon * u_xx)
  48.         # 检查收敛性
  49.         if np.linalg.norm(u_np1_new - u_np1, np.inf) < tol:
  50.             break
  51.         u_np1 = u_np1_new
  52.     # 更新解矩阵
  53.     U[:, n+1] = u_np1
  54.     # 边界条件修正(如果需要)
  55.     U[0, n+1] = Leftbdry(t[n+1])
  56.     U[-1, n+1] = Rightbdry(t[n+1])
  57. # 使用 meshgrid 生成网格数据
  58. T, X = np.meshgrid(t, x)
  59. # 绘图显示数值解
  60. fig = plt.figure(figsize=(12, 12))
  61. # 第一个视角
  62. ax1 = fig.add_subplot(221, projection='3d')
  63. ax1.plot_surface(T, X, U, cmap='viridis', edgecolor='none')
  64. ax1.set_title('View from angle 1')
  65. ax1.set_xlabel('t')
  66. ax1.set_ylabel('x')
  67. ax1.set_zlabel('u(x,t)')
  68. ax1.view_init(elev=30, azim=45)
  69. # 第二个视角
  70. ax2 = fig.add_subplot(222, projection='3d')
  71. ax2.plot_surface(T, X, U, cmap='viridis', edgecolor='none')
  72. ax2.set_title('View from angle 2')
  73. ax2.set_xlabel('t')
  74. ax2.set_ylabel('x')
  75. ax2.set_zlabel('u(x,t)')
  76. ax2.view_init(elev=30, azim=135)
  77. # 第三个视角
  78. ax3 = fig.add_subplot(223, projection='3d')
  79. ax3.plot_surface(T, X, U, cmap='viridis', edgecolor='none')
  80. ax3.set_title('View from angle 3')
  81. ax3.set_xlabel('t')
  82. ax3.set_ylabel('x')
  83. ax3.set_zlabel('u(x,t)')
  84. ax3.view_init(elev=60, azim=45)
  85. # 第四个视角
  86. ax4 = fig.add_subplot(224, projection='3d')
  87. ax4.plot_surface(T, X, U, cmap='viridis', edgecolor='none')
  88. ax4.set_title('View from angle 4')
  89. ax4.set_xlabel('t')
  90. ax4.set_ylabel('x')
  91. ax4.set_zlabel('u(x,t)')
  92. ax4.view_init(elev=60, azim=135)
  93. plt.suptitle('Burgers Equation Solution from Multiple Angles')
  94. plt.show()
复制代码
详细阐明:



  • 参数设置:界说 epsilon、dx、dt、x 和 t.
  • 初始条件:设置初始条件为                                         u                            (                            x                            ,                            0                            )                            =                            −                            sin                            ⁡                            (                            π                            x                            )                                  u(x, 0) = -\sin(\pi x)                     u(x,0)=−sin(πx).
  • 界限条件:界说常数界限条件函数 Leftbdry 和 Rightbdry.
  • 初始化解矩阵:创建 U 矩阵,并设置初始条件。
  • 向后欧拉迭代求解:
    对每个时间步,初始推测下一时间步的解。
    使用迭代方法求解隐式方程,盘算 u_x 和 u_xx,并处置惩罚界限条件。
    盘算 uu_x 和更新 u_np1.
    查抄收敛性,如果满足收敛条件则跳出循环。
  • 更新解矩阵:将 u_np1 的值存储到解矩阵中,并处置惩罚界限条件。
  • 天生网格数据:使用 meshgrid 天生 T 和 X.
  • 绘图:
    创建一个包罗四个子图的 3D 图像,每个子图展示从不同视角观察的解。设置各个子图的坐标轴标签、标题和视角。
    使用 plt.suptitle 为整个图像添加总标题,并表现图像。
数值效果如下:


效果不错!

本专栏致力于普及各种偏微分方程的不同数值求解方法,全部文章包罗全部可运行代码。欢迎各人支持、关注!
作者 :盘算小屋
个人主页 : 盘算小屋的主页

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天空闲话

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表