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

news2025/6/8 16:35:51

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+1un+un+1xun+1=ϵx22un+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}. xu2dxui+1ui1.
∂ 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}. x22udx2ui+12ui+ui1.

差分格式

综合时间离散和空间离散,得到差分格式:
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+1uin+uin+12dxui+1n+1ui1n+1=ϵdx2ui+1n+12uin+1+ui1n+1.

数值求解过程

为了读者方便,下面我们先给出 Matlab 差分法解 Burgers 方程的代码实现:

% The solution surface of Burgers Equations
% Variables:
% x-space variable, t-time variable.
% Output:
% Solution surface of u_{t}+uu_x=\epsilon u_{xx}

% 参数设置  
epsilon = 0.05;  
dx = 5e-2; % 空间步长  
dt = 5e-3; % 时间步长  
x = -1:dx:1; % 空间网格  
t = 0:dt:1;  % 时间网格  
Nx = length(x);  
Nt = length(t);  

% 初始条件  
u = -sin(pi * x);  

% 边界条件函数(这里假设为常数边界条件)  
Leftbdry = @(t) 0;  
Rightbdry = @(t) 0;  

% 初始化解矩阵  
U = zeros(Nx, Nt);  
U(:, 1) = u; % 初始条件  

% 向后欧拉迭代求解  
for n = 1:Nt-1  
    u_n = U(:, n); % 当前时间步的解  
    u_np1 = u_n;   % 下一时间步的解,初始猜测为当前时间步的解  
    
    % 迭代求解隐式方程  
    max_iter = 100;  
    tol = 1e-6;  
    for iter = 1:max_iter  
        % 计算u_x和u_xx(这里使用简单的二阶中心差分,注意边界处理)  
        u_x = zeros(Nx, 1);
        u_xx = zeros(Nx, 1);
        
        % 中心差分
        u_x(2:end-1) = (u_np1(3:end) - u_np1(1:end-2)) / (2 * dx);
        u_xx(2:end-1) = (u_np1(3:end) - 2 * u_np1(2:end-1) + u_np1(1:end-2)) / (dx^2);
        
        % 边界处理
        u_x(1) = (u_np1(2) - u_np1(1)) / dx;
        u_x(end) = (u_np1(end) - u_np1(end-1)) / dx;
        
        u_xx(1) = (u_np1(2) - 2 * u_np1(1) + Leftbdry(t(n+1))) / (dx^2);
        u_xx(end) = (Rightbdry(t(n+1)) - 2 * u_np1(end) + u_np1(end-1)) / (dx^2);

        % 计算u*u_x  
        uu_x = u_np1 .* u_x;  

        % 向后欧拉方程  
        u_np1_new = u_n - dt * (uu_x - epsilon * u_xx);  

        % 检查收敛性  
        if norm(u_np1_new - u_np1, inf) < tol  
            break;  
        end  
        u_np1 = u_np1_new;  
    end  

    % 更新解矩阵  
    U(:, n+1) = u_np1;  

    % 边界条件修正(如果需要)  
    U(1, n+1) = Leftbdry(t(n+1));  
    U(end, n+1) = Rightbdry(t(n+1));  
end  

% 使用 meshgrid 生成网格数据
[T, X] = meshgrid(t, x);

  
% 绘图显示数值解
figure;
% 将 T, X, U 转换为列向量
% T_vec = T(:);
% X_vec = X(:);
% U_vec = U(:);
surf(T, X, U);hold on;
scatter3(T(:),X(:),U(:),'.' )
xlabel('t')  
ylabel('x')  
zlabel('u(x,t)')  
title('Burgers Equation Solution using Backward Euler Method')

求解结果:
在这里插入图片描述

考虑到 Python 用户较多,笔者也实现了 Python 版本的代码供大家参考:

import numpy as np
import matplotlib.pyplot as plt

# 参数设置
epsilon = 0.05
dx = 5e-2  # 空间步长
dt = 5e-3  # 时间步长
x = np.arange(-1, 1 + dx, dx)  # 空间网格
t = np.arange(0, 1 + dt, dt)  # 时间网格
Nx = len(x)
Nt = len(t)

# 初始条件
u = -np.sin(np.pi * x)

# 边界条件函数(这里假设为常数边界条件)
def Leftbdry(t):
    return 0

def Rightbdry(t):
    return 0

# 初始化解矩阵
U = np.zeros((Nx, Nt))
U[:, 0] = u  # 初始条件

# 向后欧拉迭代求解
for n in range(Nt - 1):
    u_n = U[:, n]  # 当前时间步的解
    u_np1 = u_n  # 下一时间步的解,初始猜测为当前时间步的解
    
    # 迭代求解隐式方程
    max_iter = 100
    tol = 1e-6
    for iter in range(max_iter):
        # 计算 u_x 和 u_xx(这里使用简单的二阶中心差分,注意边界处理)
        u_x = np.zeros(Nx)
        u_xx = np.zeros(Nx)
        
        # 中心差分
        u_x[1:-1] = (u_np1[2:] - u_np1[:-2]) / (2 * dx)
        u_xx[1:-1] = (u_np1[2:] - 2 * u_np1[1:-1] + u_np1[:-2]) / (dx**2)
        
        # 边界处理
        u_x[0] = (u_np1[1] - u_np1[0]) / dx
        u_x[-1] = (u_np1[-1] - u_np1[-2]) / dx
        
        u_xx[0] = (u_np1[1] - 2 * u_np1[0] + Leftbdry(t[n+1])) / (dx**2)
        u_xx[-1] = (Rightbdry(t[n+1]) - 2 * u_np1[-1] + u_np1[-2]) / (dx**2)

        # 计算 u * u_x
        uu_x = u_np1 * u_x

        # 向后欧拉方程
        u_np1_new = u_n - dt * (uu_x - epsilon * u_xx)

        # 检查收敛性
        if np.linalg.norm(u_np1_new - u_np1, np.inf) < tol:
            break
        u_np1 = u_np1_new

    # 更新解矩阵
    U[:, n+1] = u_np1

    # 边界条件修正(如果需要)
    U[0, n+1] = Leftbdry(t[n+1])
    U[-1, n+1] = Rightbdry(t[n+1])

# 使用 meshgrid 生成网格数据
T, X = np.meshgrid(t, x)

# 绘图显示数值解
fig = plt.figure(figsize=(12, 12))

# 第一个视角
ax1 = fig.add_subplot(221, projection='3d')
ax1.plot_surface(T, X, U, cmap='viridis', edgecolor='none')
ax1.set_title('View from angle 1')
ax1.set_xlabel('t')
ax1.set_ylabel('x')
ax1.set_zlabel('u(x,t)')
ax1.view_init(elev=30, azim=45)

# 第二个视角
ax2 = fig.add_subplot(222, projection='3d')
ax2.plot_surface(T, X, U, cmap='viridis', edgecolor='none')
ax2.set_title('View from angle 2')
ax2.set_xlabel('t')
ax2.set_ylabel('x')
ax2.set_zlabel('u(x,t)')
ax2.view_init(elev=30, azim=135)

# 第三个视角
ax3 = fig.add_subplot(223, projection='3d')
ax3.plot_surface(T, X, U, cmap='viridis', edgecolor='none')
ax3.set_title('View from angle 3')
ax3.set_xlabel('t')
ax3.set_ylabel('x')
ax3.set_zlabel('u(x,t)')
ax3.view_init(elev=60, azim=45)

# 第四个视角
ax4 = fig.add_subplot(224, projection='3d')
ax4.plot_surface(T, X, U, cmap='viridis', edgecolor='none')
ax4.set_title('View from angle 4')
ax4.set_xlabel('t')
ax4.set_ylabel('x')
ax4.set_zlabel('u(x,t)')
ax4.view_init(elev=60, azim=135)

plt.suptitle('Burgers Equation Solution from Multiple Angles')
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 为整个图像添加总标题,并显示图像。

数值结果如下:

在这里插入图片描述
效果不错!


本专栏致力于普及各种偏微分方程的不同数值求解方法,所有文章包含全部可运行代码。欢迎大家支持、关注!

作者 :计算小屋
个人主页 : 计算小屋的主页

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1956390.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在react中如何计算本地存储体积

1.定义useLocalStorageSize钩子函数 // 计算localStorage大小 function useLocalStorageSize() {const [size, setSize] useState(0);useEffect(() > {const calculateSize () > {let totalSize 0;for (let key in localStorage) {//过滤掉继承自原型链的属性if (loc…

Profinet转EtherNet/IP协议转化网关(功能与配置)

怎么样把Profinet和EtherNet/IP两个协议连接起来?有很多朋友想要了解这个问题&#xff0c;那么作者在这里统一说明一下。其实有一个不错的设备产品可以很轻易地解决这个问题&#xff0c;名为JM-PN-EIP。接下来作者就从该设备的功能及配置详细说明一下。 一&#xff0c;设备主…

力扣高频SQL 50题(基础版)第二十二题

文章目录 力扣高频SQL 50题&#xff08;基础版&#xff09;第二十二题1084 销售分析题目说明思路分析实现过程准备数据实现方式结果截图 力扣高频SQL 50题&#xff08;基础版&#xff09;第二十二题 1084 销售分析 题目说明 表&#xff1a; Product --------------------- …

Scraperr能从网页中抓取数据

什么是 Scraperr &#xff1f; Scraperr 是一个自托管的 Web 应用程序&#xff0c;允许用户通过 XPath 指定元素从网页中抓取数据。用户可以提交要抓取的 URL 和相应元素&#xff0c;结果将显示在表格中。用户可以下载作业结果的 Excel 表&#xff0c;以及重新运行该作业的选项…

在这个只有病人去的场所,你看到了哪些意料之外的举动?--医者仁心:医院里的温情奇迹

在这个只有病人去的场所&#xff0c;你看到了哪些意料之外的举动? --医者仁心&#xff1a;医院里的温情奇迹 在繁忙与喧嚣交织的医院里&#xff0c;每一天都上演着生与死的较量&#xff0c;但在这片看似冷漠的土地上&#xff0c;却也悄然绽放着无数温暖人心的花朵。今天&…

prompt输入框模拟禁用弹窗

this.$prompt(确认取消申报申请吗?, 提示, {confirmButtonText: 确定,cancelButtonText: 取消,

新款 GPT-4o mini、Llama 3.1、Mistral NeMo 12B 和其他 GenAI 趋势指南

作者使用 GPT-4o 创建的图像&#xff0c;用于表示不同的模型 欢迎来到雲闪世界。自 2022 年 11 月推出 ChatGPT 以来&#xff0c;几乎每周都会出现新的模型、新颖的提示方法、创新的代理框架或其他令人兴奋的 GenAI 突破。2024 年 7 月也不例外&#xff1a;仅在本月&#xff0c…

UDP connect 内核源码分析

1 从诡异开始 最近遇到一个线上问题&#xff0c;client 发了一个 udp 请求&#xff0c;服务器回了一个响应&#xff0c;但诡异的是&#xff0c;client 的 log 却看不到对应的处理日志。抓包发现内核发出了一个指示 udp 目的端口不可达的 icmp 报文&#xff0c;类似这样的&#…

【基于PSINS】UKF/SSUKF对比的MATLAB程序

UKF与SSUKF UKF是&#xff1a;无迹卡尔滤波 SSUKF是&#xff1a;简化超球面无迹卡尔曼滤波 UKF 相较于传统的KF算法&#xff0c;UKF能够更好地处理非线性系统&#xff0c;并且具有更高的估计精度。它适用于多种应用场景&#xff0c;如机器人定位导航、目标跟踪、信号处理等。…

机器学习 | 计算分类算法的ROC和AUC曲线以随机森林为例

受试者工作特征&#xff08;ROC&#xff09;曲线和曲线下面积&#xff08;AUC&#xff09;是常用的分类算法评价指标&#xff0c;本文将讨论如何计算随机森林分类器的ROC 和 AUC。 ROC 和 AUC是量化二分类区分阳性和阴性类别能力的度量。ROC曲线是针对不同分类阈值的真阳性率&…

Mac电脑 系统监测工具 System Dashboard Pro【简单操作,小白轻松上手】

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功 三、运行测试安装完成&#xff01;&#xff01;&#xff01; 效果 一、下载软件 下载软件…

opencascade AIS_PlaneTrihedron 源码学习

AIS_PlaneTrihedron 前言 构建一个可选择的2D轴系在3D绘图中。 这个轴系可以放置在3D系统中的任何位置&#xff0c;提供一个用于在平面中绘制曲线和形状的坐标系。 有三种选择模式&#xff1a; 模式0 选择整个平面“trihedron” 模式1 选择平面“trihedron”的原点 模式2 选择…

Nuxt.js 路由管理:useRouter 方法与路由中间件应用

title: Nuxt.js 路由管理&#xff1a;useRouter 方法与路由中间件应用 date: 2024/7/28 updated: 2024/7/28 author: cmdragon excerpt: 摘要&#xff1a;本文介绍了Nuxt 3中useRouter方法及其在路由管理和中间件应用中的功能。内容包括使用useRouter添加、移除路由&#xf…

Cesium高性能渲染海量矢量建筑

0、数据输入为类似Geojson的压缩文件和纹理图片&#xff0c;基于DrawCommand命令绘制&#xff1b; 1、自定义建筑几何&#xff0c;包括顶点、法线、纹理等&#xff1b; 2、自定义纹理贴图&#xff0c;包括按建筑高度贴图、mipmap多级纹理&#xff1b; 3、自定义批处理表&…

我的新书《Android系统多媒体进阶实战》正式发售了!!!

我的新书要正式发售了&#xff0c;把链接贴在下面&#xff0c;感兴趣的朋友可以支持下。 ❶发售平台&#xff1a;当当&#xff0c;京东&#xff0c;抖音北航社平台&#xff0c;小红书&#xff0c;b站 ❷目前当当和京东已开启预售 ❸当当网 https://u.dangdang.com/KIDHJ ❹…

22 B端产品经理与MySQL基本查询、排序(2)

MySQL基本常识 MySQL&#xff1a;一种关系型数据库管理系统。是按照数据结构来组织、存储和管理数据的仓库。 数据库&#xff1a;是一些关联数据表的集合。 数据表&#xff1a;表是数据的矩阵&#xff0c;看起来像电子表格&#xff0c;如下图&#xff1a;user表和admin表。 …

⌈ 传知代码 ⌋ 红外小目标检测

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

keil5导入程序到stm32的开发板

如图&#xff0c; 1&#xff0c;安装mdk_514.exe 2&#xff0c;安装Keil.STM32F1xx_DFP.1.0.5.pack 3&#xff0c;注册方法&#xff08;仅限学生使用&#xff09;&#xff1a;http://www.openedv.com/thread-69384-1-1.html 点击keil程序的上面魔法棒&#xff0c; 在device中…

类中的function无法正确被matlab所识别,该怎么操作呢?

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

【Linux】CentOS更换国内阿里云yum源(超详细)

目录 1. 前言2. 打开终端3. 确保虚拟机已经联网4. 备份现有yum配置文件5. 下载阿里云yum源6. 清理缓存7. 重新生成缓存8. 测试安装gcc 1. 前言 有些同学在安装完CentOS操作系统后&#xff0c;在系统内安装比如&#xff1a;gcc等软件的时候出现这种情况&#xff1a;&#xff08…