4、时间步长与CFL条件:显式与隐式时间推进、CFL数选取原则、自适应时间步长、瞬态仿真的时间分辨率
时间步长怎么选?这个问题我几乎每次培训都会被问到。
说实话,我刚入行那会儿也踩过坑。有一次算一个高超声速进气道,时间步长设得太大,结果激波直接穿过了壁面——嗯,算出来的结果我自己都不敢信。后来才明白,时间步长不是拍脑袋定的,背后有个硬约束叫CFL条件。
4.1 显式时间推进:简单但“短腿”
显式格式,说白了就是“用当前时刻的值,直接算出下一时刻”。
它的优点是实现简单,每步计算量小。但缺点也很明显——稳定性受CFL条件严格限制。
显式格式的CFL条件:
CFL = u · Δt / Δx ≤ CFL_max
对于大多数显式格式,CFL_max ≈ 1.0
什么意思呢?就是你的时间步长不能太大,否则数值上就“炸”了。我见过一个新手做LES,网格加密后忘了调时间步长,结果残差直接飞到10^10——那画面,啧啧。
注意:显式格式的CFL上限因空间离散格式而异。中心差分通常CFL_max ≈ 1.0,迎风格式可能到0.8,高阶格式甚至只有0.3~0.5。别拿一个值到处套。
4.2 隐式时间推进:稳,但代价高
隐式格式就不一样了。它用“未来时刻”的值来算,每步都要解一个大型线性方程组。
代价是每步计算量大,但好处是——理论上无条件稳定。你想想看,这意味着你可以用大时间步长,快速算到稳态。
我的经验:做稳态计算时,我习惯用隐式格式配合大CFL数(比如5~100)。但做瞬态计算时,千万别为了省时间把CFL设太大——时间精度会丢,涡结构都给你抹平了。
我曾经帮一个团队调试涡轮叶栅的算例。他们用隐式格式,CFL设到200,结果算出来的总压损失比实验值低了30%。后来我把CFL降到10,结果就对上了。为什么?因为时间离散误差把流动的细节给“平均”掉了。
4.3 CFL数选取原则:不是越大越好
CFL数到底怎么选?我总结了一个“三步法”:
- 看问题类型:稳态还是瞬态?稳态可以大CFL(隐式),瞬态必须小CFL。
- 看网格质量:网格长宽比大、扭曲严重的地方,CFL要打折。我一般打五折起步。
- 看物理特征:有激波、火焰面、相界面这些强间断,CFL要小。我通常从0.5开始试。
| 应用场景 | 推荐CFL(显式) | 推荐CFL(隐式) |
|---|---|---|
| 稳态不可压 | 0.5~1.0 | 5~50 |
| 稳态可压缩(无激波) | 0.3~0.8 | 10~100 |
| 稳态可压缩(有激波) | 0.1~0.5 | 1~10 |
| 瞬态LES/DES | 0.3~0.8 | 0.5~2 |
| 瞬态DNS | 0.1~0.3 | 0.2~0.5 |
核心原则:CFL数不是越大越好,也不是越小越好。它是在“计算效率”和“时间精度”之间找平衡。
4.4 自适应时间步长:让求解器自己“踩油门”
手动调时间步长?太累了。尤其是非定常流动,流场变化剧烈的时候,一个固定步长要么浪费计算资源,要么算不准。
自适应时间步长就是让求解器根据当前流场状态,自动调整Δt。
常见的策略有:
- 基于CFL数:设定目标CFL,每步根据最大速度/声速反算Δt。
- 基于残差变化:残差下降快就增大Δt,下降慢就减小。
- 基于物理时间尺度:比如涡脱落周期、火焰传播时间等。
// 伪代码示例:基于CFL的自适应步长
double compute_dt(mesh, fields, target_cfl) {
double dt_min = 1e10;
for (each cell) {
double u = |velocity| + speed_of_sound;
double dx = cell_characteristic_length;
double dt_local = target_cfl * dx / u;
dt_min = min(dt_min, dt_local);
}
return dt_min;
}
我的习惯:做LES时,我通常设目标CFL=0.5~0.8,然后让求解器自动调。但我会加一个上限和下限,防止它“抽风”。比如Δt_max = 1e-4,Δt_min = 1e-8。
4.5 瞬态仿真的时间分辨率:别让时间步长毁了你的涡
瞬态仿真最怕什么?时间分辨率不够。
你想想看,一个涡脱落周期是0.01秒,你时间步长设了0.005秒——一个周期才两个点,能看出什么?
我一般遵循“20步原则”:
- 一个物理周期内,至少要有20个时间步。
- 对于湍流统计量,至少需要50~100步/周期。
- 对于声学计算,需要100~200步/周期。
避坑指南:我曾经算一个圆柱绕流,Strouhal数约0.2,来流速度1m/s,圆柱直径0.1m。我一开始用Δt=0.01s,结果涡脱落频率算出来差了15%。后来把Δt降到0.002s,结果才收敛。记住:时间步长收敛性验证,和网格无关性验证一样重要。
4.6 知识体系:一张图说清楚
下面这张图是我自己整理的,把时间步长和CFL条件的核心逻辑串起来了。你看一遍,应该能有个整体印象。
这张图从左到右、从上到下,把显式/隐式、CFL约束、选取原则、自适应和分辨率串在了一起。你保存下来,以后调时间步长的时候拿出来对照一下,应该能少走不少弯路。
最后说一句:时间步长这东西,理论是基础,经验是升华。我建议你每做一个新算例,都做一次时间步长无关性验证——哪怕只算三个步长(粗、中、细),也比拍脑袋强十倍。
公众号:蓝海资料掘金营,微信deep3321