发布时间:2026/9/4 13:17:26
一维无粘 Burgers 方程的激波形成问题:MacCormack 格式求解 一维无粘 Burgers 方程是研究可压缩流激波捕捉格式时最经典的一维原型问题。本文完整介绍初值间断如何演化成一条向右传播的激波这一经典算例出处J.D. Anderson《Computational Fluid Dynamics: The Basics with Applications》第 7 章内容包括问题描述、CFD 理论背景、MATLAB 与 C 源码、运行结果数据与可视化图像。1. 问题描述1.1 控制方程在一维均匀网格上求解非线性双曲型方程无黏 Burgers 方程∂u/∂t ∂/∂x (u²/2) 0, 0 ≤ x ≤ 2其中f(u) u²/2为通量未知量u可理解为速度无黏 Burgers 方程与可压缩 Euler 方程的非线性结构同源是后者的标量原型。1.2 初始条件Riemann 问题初值在x 1处存在一个间断u(x, 0) 1.0, 0 ≤ x ≤ 1 u(x, 0) 0.5, 1 x ≤ 21.3 边界条件Dirichletu(0, t) 1.0, u(2, t) 0.51.4 理论解Rankine–Hugoniot 激波位置左侧高速流体u 1不断追赶右侧低速流体u 0.5初值间断将演化成一条向右传播的激波。由 Rankine–Hugoniot 关系激波速度为两侧状态的平均特征速度s (a(u_L) a(u_R)) / 2 (1 0.5) / 2 0.75激波位置随时间线性右移x_s(t) 1 s·t 1 0.75·t1.5 数值参数计算域 L 2 网格节点 nx 81Δx L/(nx-1) 0.025 时间步数 nt 120Δt 0.0125模拟至 t 1.5 s CFL 数 ν max|u|·Δt/Δx 1×0.0125/0.025 0.5≤ 1稳定2. CFD 理论背景2.1 无粘 Burgers 方程最简的非线性双曲守恒律一维守恒律的标准形式为∂u/∂t ∂f(u)/∂x 0当通量取f(u) u²/2时即为一维无粘 Burgers 方程。它是非线性的即使初值光滑特征线也会在有限时间内相交形成梯度趋于无穷的间断激波即弱解。因此它是理解可压缩 Euler 方程中激波捕捉问题的最小原型也是 Anderson 教材里从线性对流方程过渡到非线性方程组Euler 方程的桥梁算例。本题初值是典型的 Riemann 问题左右两个常状态由一个间断隔开。两侧特征速度a(u) u分别为 1 与 0.5左侧更快因此该间断必然演化成激波而非稀疏波若左侧慢于右侧则退化为稀疏波。激波传播速度取两侧状态的算术平均s 0.752.2 MacCormack 预估–校正格式MacCormack 格式是一种显式、二阶精度的时间/空间离散实现非常简单先做一次后差预估再做一次前差校正并取平均。记F u²/2。预估步后差通量F_i^n 0.5·(u_i^n)² ū_i u_i^n − (Δt/Δx)·(F_i^n − F_{i−1}^n) F̄_i 0.5·(ū_i)²校正步前差通量u_i^{n1} 0.5·[ u_i^n ū_i − (Δt/Δx)·(F̄_{i1} − F̄_i) ]在内点区间i 2, …, nx−1做预估i 1, …, nx−1做校正之外两端节点每步被 Dirichlet 边界值1.0 / 0.5重新赋值“钉扎”。整个时间步推进可紧凑地写成整向量形式ubar[1.0,u(2:80)-(dt/dx)*(F(2:80)-F(1:79)),0.5];% 预估内点 2..80边界钉扎Fbar0.5*(ubar.*ubar);unew0.5*(u(1:80)ubar(1:80)-(dt/dx)*(Fbar(2:81)-Fbar(1:80)));% 校正内点 1..80u[unew,0.5];2.3 CFL 稳定性条件对显式格式时间步必须满足CFL 条件ν max_i |u_i| · Δt / Δx ≤ 1本题取Δt 0.0125、Δx 0.025得ν 0.5格式稳定程序运行全程不发散。2.4 数值耗散与色散Gibbs 型振荡/过冲MacCormack 格式二阶精度、不含人工耗散在强间断附近会产生典型的小幅Gibbs 型振荡/过冲Anderson 称之为色散误差。尤其当激波在t ≈ 1.33 s后离开右边界而右边界仍被钉扎在u 0.5时末段节点会积累较明显的过冲见第 5 节数据。这正是后来引入人工黏性、通量限制器TVD以及 Riemann 求解器Godunov 族等技术的动机。3. MATLAB 源码以下给出该算例的完整 MATLAB 实现网格与参数 → MacCormack 时间推进并保存 t 0 / 0.25 / 0.5 / 1.0 / 1.5 五个快照→ 多时刻剖面绘图 → 激波位置数值检测并与 Rankine–Hugoniot 理论值对比。可直接在 MATLAB / Octave 中运行。%% % 一维无粘 Burgers 方程 —— 激波形成问题% MacCormack 预估-校正格式% 参考: J.D. Anderson, CFD: The Basics with Applications, Ch.7%% clear;clc;close all;%% 1. 网格与时间参数L2;% 计算域长度nx81;% 网格节点数nt120;% 时间步数dxL/(nx-1);% 空间步长dt0.0125;% 时间步长xlinspace(0,L,nx);% 网格坐标CFLmax(1)*dt/dx;% 初始 CFL 数fprintf(CFL %.3f (1 即稳定)\n,CFL);%% 2. 初始条件Riemann 问题u0.5*ones(1,nx);u(x1)1.0;% 保存若干时刻用于画图snap_t[00.250.51.01.5];% 想要观察的物理时刻snap_ucell(numel(snap_t),1);snap_u{1}u;% t 0isnap1;t_now0;%% 3. 时间推进MacCormackforn1:nt F0.5*u.^2;% 当前时刻通量% ---- 预估步空间后差 ----ubaru;ubar(2:end)u(2:end)-dt/dx*(F(2:end)-F(1:end-1));ubar(1)1.0;ubar(end)0.5;% 边界保持Fbar0.5*ubar.^2;% 预估通量% ---- 校正步空间前差 ----unewu;unew(1:end-1)0.5*(u(1:end-1)ubar(1:end-1)...-dt/dx*(Fbar(2:end)-Fbar(1:end-1)));unew(end)0.5;% 更新uunew;t_nowt_nowdt;% 保存特定时刻的解ifisnapnumel(snap_t)abs(t_now-snap_t(isnap1))dt/2isnapisnap1;snap_u{isnap}u;endend%% 4. 结果可视化figure(Color,w,Position,[100100700450]);hold on;colorslines(numel(snap_t));fork1:numel(snap_t)plot(x,snap_u{k},LineWidth,1.8,Color,colors(k,:),...DisplayName,sprintf(t %.2f,snap_t(k)));endgrid on;box on;xlabel(x);ylabel(u(x,t));title(一维 Burgers 方程激波形成);legend(Location,northeast);ylim([0.31.1]);%% 5. 激波位置与理论值对比Rankine–Hugoniotxs_numx(u(1.00.5)/2[diff(u)0,0]);% 数值激波位置xs_theory10.75*max(snap_t);% 理论位置fprintf(\n t%.2f 时数值激波位置 x_s%.3f, 理论值 x_s%.3f\n,...snap_t(end),xs_num(1),xs_theory);4. C 源码本节给出与上述 MATLAB 数值逻辑完全等价的 C 实现便于工程集成与批量运行。工程由 5 个文件组成文件作用burgers_vec.h入口函数声明burgers_vec.cpp数值求解主体时间推进 激波检测main.cpp程序入口main()rtwtypes.h跨平台基础类型定义CMakeLists.txt可选的 CMake 构建脚本以上 5 个文件构成一个完整工程入口函数为main()其输出见第 5 节。4.1burgers_vec.h/* * burgers_vec.h * 一维无粘 Burgers 方程激波形成问题MacCormack 预估-校正——头文件 */#ifndefBURGERS_VEC_H#defineBURGERS_VEC_H#includecmath#includecfloat#includecstddef#includecstdlib#includecstdio#includertwtypes.h#includevector#includestring/* 入口函数声明 */externvoidburgers_vec();#endif4.2burgers_vec.cpp/* * burgers_vec.cpp * 一维无粘 Burgers 方程激波形成问题MacCormack 预估-校正——数值实现 * 与第 3 节 MATLAB 实现的数值逻辑一致 * 预估步后差、校正步前差、端点每步钉扎边界值 1.0 / 0.5 */#includeburgers_vec.h#includecmathvoidburgers_vec(){doubleL;/* 计算域长度 */intnx;/* 网格节点数 */intnt;/* 时间步数 */doubledx;/* 空间步长 */doubledt;/* 时间步长 */doublex[81];/* 网格坐标 */doubleCFL;/* CFL 数 */doubleu[81];/* 解向量 */intn;/* 时间步循环 */doubleF[81];/* 当前通量 */doubleubar[81];/* 预估解 */doubleFbar[81];/* 预估通量 */doubleunew[80];/* 校正后的内点 */doublexs_num;/* 数值激波位置 */intfound;/* 是否已找到 */inti;doublexs_theory;/* 理论激波位置 */L2.0;nx81;nt120;dxL/(nx-1);/* 0.025 */dt0.0125;doubletv1(L-0.0)/(double)(nx-1);/* linspace(0,L,nx) 步长 */for(intk0;k81;k){x[k]0.0(double)k*tv1;}CFLdt/dx;printf(CFL %.3f (1 stable)\n,CFL);/* 初始条件u 0.5 全域x 1 处再加 0.5 - 1.0 */for(intk0;k81;k){u[k]0.5;}for(intk0;k81;k){u[k]u[k]0.5*(x[k]1.0);}/* MacCormack 时间推进 */for(n1;n120;n){/* 当前通量 F u.^2 / 2 */for(intk0;k81;k){F[k]0.5*(u[k]*u[k]);}/* 预估步后差内点 k1..79两端钉扎 */ubar[0]1.0;for(intk1;k80;k){ubar[k]u[k]-(dt/dx)*(F[k]-F[k-1]);}ubar[80]0.5;/* 预估通量 */for(intk0;k81;k){Fbar[k]0.5*(ubar[k]*ubar[k]);}/* 校正步前差内点 k0..79最右端钉扎 */for(intk0;k80;k){unew[k]0.5*((u[k]ubar[k])-(dt/dx)*(Fbar[k1]-Fbar[k]));}for(intk0;k80;k){u[k]unew[k];}u[80]0.5;}/* 激波位置数值检测第一个满足 u(i)0.75 且 u(i1)u(i) 的网格点 */xs_num0.0;found0;for(i1;i81;i){/* 内点 1..80 */if(u[i]0.75){if(u[i1]u[i]){if(found0){xs_numx[i];found1;}}}}xs_theory1.00.75*1.5;/* x_s(1.5) 1 0.75×1.5 */printf(t %.2f: numerical x_s %.3f, theory x_s %.3f\n,1.5,xs_num,xs_theory);}说明C 中数组下标为 0-based对应 MATLAB 的 1-based 节点偏移 1预估/校正均只在 79~80 个内点上计算两端节点每步由边界值重写因此与 MATLAB 切片写法逐点等价。x 1的逻辑判断在 C 中返回 0/1与 MATLAB 中(x1)用作数值一样。4.3main.cpp/* main.cpp —— 程序入口 */#includeburgers_vec.hintmain(){burgers_vec();return0;}4.4rtwtypes.h/* rtwtypes.h —— 跨平台基础类型定义 */#ifndefRTWTYPES_H#defineRTWTYPES_H#includecstddef#includecstdinttypedefdoublereal_T;typedeffloatreal32_T;typedefintint32_T;typedefint16_tint16_T;typedefint8_tint8_T;typedefuint32_tuint32_T;typedefuint16_tuint16_T;typedefuint8_tuint8_T;typedefuint8_tboolean_T;typedefcharchar_T;#endif/* RTWTYPES_H */4.5CMakeLists.txtcmake_minimum_required(VERSION 3.10) project(burgers_solver CXX) set(CMAKE_CXX_STANDARD 14) add_executable(burgers_app main.cpp burgers_vec.cpp ) target_include_directories(burgers_app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})5. 运行结果与数据5.1 程序输出运行第 4 节的 C 实现数值格式与第 3 节 MATLAB 实现一致两者关键数值输出相同得到CFL 0.500 (1 stable) t 1.50: numerical x_s 0.450, theory x_s 2.125即CFL dt/dx 0.0125 / 0.025 0.500 显式格式稳定ν ≤ 1 理论激波 x_s(t1.5) 1 0.75×1.5 2.125 Rankine–Hugoniot 关系 数值检测 x_s 0.450 判据第一个命中的网格点见 5.3 说明5.2 各快照时刻剖面数据各时刻剖面的最小/最大值max u已包含 MacCormack 格式的过冲时刻 t (s)min umax u含过冲形态0.000.51.000000阶跃初值x 1 处间断1.0/0.50.250.51.157157间断处出现数值抹平与小幅振荡0.500.51.130594波形左陡右缓、整体向右推进1.000.51.131811波形逼近右边界1.500.51.331206激波已离开右边界末段节点出现明显过冲5.3 结果说明1CFL 与稳定性。ν 0.5 ≤ 1满足显式格式的稳定条件程序运行全程不发散解的单调推进行为与理论一致。2激波位置检测为何输出 0.450而不是理论值 2.125理论激波位置x_s(t) 1 0.75·t在t 1.5时为2.125已大于右边界x 2。这意味着激波其实在t_exit ≈ (2 − 1) / 0.75 ≈ 1.333 s就已经离开计算域t 1.5 时理论上激波位于域外。而程序中的检测判据只能返回网格坐标最大 2.0同时t 1.5 时u 1的高位平台上布满约1e-12量级的浮点噪声扫描会先在这些噪声处命中u(i1) u(i)于是输出了第一个命中点x 0.450第 19 号节点。也就是说激波位置判据本身受网格坐标上限 平台噪声影响输出的 0.450 不能直接当作物理激波位置物理上激波以s 0.75匀速右移并在约 1.33 s 时离开计算域。若需在激波出域后继续跟踪应把判据限定在波形前缘靠近右端附近或改为记录每个时间步的传播前沿。3MacCormack 格式的过冲。t 1.5 时末段节点最大过冲u_max − 1 ≈ 0.331。这是二阶无耗散格式在激波推出边界 Dirichlet 钉扎条件下的典型色散振荡与 2.4 节的理论背景吻合在更长时间积分或更粗网格下会变得更明显工程中常配合人工黏性 / 通量限制器使用。6. 可视化结果以下图像由运行数据绘制左图为 t 0 / 0.25 / 0.5 / 1.0 / 1.5 五个时刻的整场剖面右图为 t 1.5 时刻最终剖面与激波检测结果。图 1不同时刻的速度剖面激波的形成与传播图 2t 1.5 s 最终剖面与激波检测图中可见完整物理过程初始阶跃 → 间断处轻微的 Gibbs 型振荡 → 波形整体向右推进并逐渐逼近右边界t 1.5 时高位平台几乎贯穿全域理论激波位置2.125已超出右边界图中以竖线标出离散判据先命中了平台噪声点x 0.450。7. 小结该算例完整展示了非线性双曲守恒律从初值间断 → 激波形成 → 传播/离开计算域的物理过程是理解可压流激波捕捉格式TVD、WENO、Godunov 等最直接的入门原型。MacCormack 格式实现简洁、二阶精度但本身不含耗散在强间断处会产生振荡/过冲——这正是后续引入人工黏性、通量限制器或 Riemann 求解器的动机。通过 MATLAB 与 C 两套等价实现可以清晰对照向量化切片写法与逐点循环写法的对应关系两套代码的关键数值输出完全一致结果可复现、可审计。8. 参考资料J.D. Anderson,Computational Fluid Dynamics: The Basics with Applications, McGraw-Hill, 1995第 7 章激波捕捉与 Burgers 方程算例。R.J. LeVeque,Numerical Methods for Conservation Laws, Birkhäuser, 1992守恒律数值方法与 Riemann 问题。

相关新闻

2026/9/4 13:12:25

Czkawka 重复文件清理实战:零上传扫出硬盘里的 20 GB 冗余

Czkawka 重复文件清理实战:零上传扫出硬盘里的 20 GB 冗余 【免费下载链接】czkawka Multi functional app to find duplicates, empty folders, similar images etc. 项目地址: https://gitcode.com/GitHub_Trending/cz/czkawka Czkawka 是一款用 Rust 编写…

2026/9/4 13:12:25

STM32F103驱动ICM20948九轴传感器:DMP移植与姿态解算实战

简介:本资源是一套专为STM32F103微控制器适配ICM20948九轴传感器的完整DMP驱动库,面向嵌入式初学者、智能硬件开发者及运动感知类项目实践者,解决在Cortex-M3平台高效调用ICM20948内置数字运动处理器(DMP)的技术门槛问…

2026/9/4 14:02:31

Krokiet:免费的一站式磁盘清理工具完整指南

Krokiet:免费的一站式磁盘清理工具完整指南 【免费下载链接】czkawka Multi functional app to find duplicates, empty folders, similar images etc. 项目地址: https://gitcode.com/GitHub_Trending/cz/czkawka Krokiet 是一款用 Rust 编写的免费开源磁盘…

2026/9/4 14:02:31

FancyZones 分屏布局完整教程:3 种布局搞定多屏窗口管理

FancyZones 分屏布局完整教程:3 种布局搞定多屏窗口管理 【免费下载链接】PowerToys Microsoft PowerToys is a collection of utilities that supercharge productivity and customization on Windows 项目地址: https://gitcode.com/GitHub_Trending/po/PowerTo…

2026/9/4 14:02:31

PPT Master AI 生成原生 PowerPoint 完整指南

PPT Master AI 生成原生 PowerPoint 完整指南 【免费下载链接】ppt-master AI turns documents or topics into real, native PowerPoint decks—with native shapes, transitions and animations, data-backed charts and tables on demand, audio narration from speaker not…

2026/9/4 14:02:31

原生PHP如何日志记录以确保应用的安全性?

原生PHP进行日志记录主要是为了跟踪和记录应用程序中的事件,特别是与安全性相关的事件。这样,如果发生任何不寻常或可疑的活动,我们可以通过检查日志来找出问题的根源。底层原理:日志记录的底层原理其实很简单。当我们的程序运行时…

2026/9/3 18:28:26

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/9/3 14:29:47

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/9/3 14:30:35

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/9/4 0:00:58

STM32H743 SPI从机DMA双缓冲通信实战

简介:本资源是面向嵌入式开发工程师与STM32进阶学习者的SPI DMA双机通信从机端完整实现方案,聚焦STM32H743高性能Cortex-M7单片机在工业控制与高速数据交互场景下的从机通信开发痛点。压缩包含1355个文件,主体为599个C源码与321个头文件&…

2026/9/4 0:00:58

CPU开盖降温教程:20元成本让温度直降30度的原理与实践

最近很多朋友都在抱怨,自己的电脑一到夏天就变成"烤箱",玩游戏时CPU温度动不动就飙到90度以上,风扇噪音堪比直升机。更让人头疼的是,明明配置不错,却因为高温降频导致性能大打折扣。如果你也遇到了类似问题&…

2026/9/4 0:00:58

ArkTS 表单工程:场地预约页的三态场次 Grid 与校验

ArkTS 表单工程:场地预约页的三态场次 Grid 与校验 App 14「运动场地预约」场地 Tab(Func1Tab),是整 App 交互最丰富的页面——场地横向切换 三色图例 渐变预约预览卡 快捷模板 今日场次 Grid(可选/已选/已满三态&…

2026/9/3 20:43:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/3 17:51:43

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/3 21:06:57

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…