吾生有涯 学海无涯
析模有界 知识无界

Julia CFD|03 CFL条件

在前面对流问题中,我们发现当网格网格数量增加时,数值计算会出现非物理解。

这里先写一个将网格数量作为参数的函数,以此来研究网格数量对计算结果的影响。

初始计算代码如下所示,这里采用固定的时间步长0.025 s。

using PyPlot
using Printf

function linearconv(nx)
dx = 2 / (nx - 1)
nt = 25
dt = 0.025
c = 1

u = ones(nx)
u[Base.floor(Int, 0.5 / dx):Base.floor(Int, 1 / dx)] .= 2
un = ones(nx)
PyPlot.plot(range(0, 2, length=nx), u, color="blue", linewidth=2.0, label="Time = 0.0s")

for n in 1:nt
un = copy(u)
for i in 2:nx
u[i] = un[i] - c * dt / dx * (un[i] - un[i - 1])
end
end

# 绘制结果数据
PyPlot.plot(range(0, 2, length=nx), u, color="red", linewidth=2.0, label=@sprintf("Time = %.3fs",nt*dt))
PyPlot.xlabel("x(m)")
PyPlot.ylabel("velocity(m/s)")
PyPlot.legend(loc=1)
PyPlot.title(@sprintf("Number of Grid:%d", nx))
PyPlot.show()
end

linearconv(82)

初始采用41个网格节点进行计算。

linearconv(41) #网格数为41

计算结果如下图所示。

这里用step1的参数计算结果作为参考,这里可以看到,波形存在较大的数值扩散,随时间推移,波形与初始形状偏离严重。理想状态是波形能够保持初始形状在物理空间上推进。

linearconv(61) #网格数为61

计算结果如修图所示。

随着网格数量增加,波形失真在减小。

linearconv(71)

计算结果如下图所示。

波形与初始形状越来越接近。

linearconv(81)

随着网格数量增加,波形失真越来越小,可以认为是计算越来越精确。

linearconv(91)

发生了什么情况,计算已经完全偏离了初始波形,出现了错误。这其中发生了什么呢?要回答这个问题,我们必须考虑一下代码中实际发生了什么。

在时间循环的每一次迭代中,我们使用当前时刻的波的数据来估计下一个时刻中的波的速度。最初,网格点数的增加返回了更准确的答案。数值扩散较少,波形看起来比第一个例子更像方波。

在每个时间步长内,波的传播距离必须小于网格尺寸dx。网格尺寸dx与总网格数量nx有关。因此,稳定计算条件需要满足下式:

其中是波速;称为Courant Number,该数值决定了计算是否稳定。当时,计算会发散。

按前面计算条件,m/s,s,可以计算得到临界m,则临界网格节点数量为,下面看看当网格节点数量为82时的计算结果。

linearconv(82)

计算结果如下图所示

与预料中的情况一直,可以看到计算已经出现了问题。在新版本的代码中,我们采用Courant数来根据dx来计算合适的dt。

下面改写代码:

using PyPlot
using Printf

function linearconv(nx, nt=25)
c = 1
dx = 2 / (nx - 1)
# nt = 25
sigma = 0.5
dt = sigma * dx / c

u = ones(nx)
u[Base.floor(Int, 0.5 / dx):Base.floor(Int, 1 / dx)] .= 2
un = ones(nx)
PyPlot.plot(range(0, 2, length=nx), u, color="blue", linewidth=2.0, label="Time = 0.0s")

for n in 1:nt
un = copy(u)
for i in 2:nx
u[i] = un[i] - c * dt / dx * (un[i] - un[i - 1])
end
end

# 绘制结果数据
PyPlot.plot(range(0, 2, length=nx), u, color="red", linewidth=2.0, label=@sprintf("Time = %.3fs",nt * dt))
PyPlot.xlabel("x(m)")
PyPlot.ylabel("velocity(m/s)")
PyPlot.legend(loc=1)
PyPlot.title(@sprintf("Number of Grid:%d", nx))
PyPlot.show()
end

测试一下新的程序代码:

linearconv_m(82,25)

可以看到在网格数量为82时未出现问题,由于Courant数取为0.5,导致时间步长为只有原来时间步长的一半,在时间步长不变的情况下总时间也减半。这里将时间步数提高到50再重新计算。

linearconv(82,50)

结果如下图所示,得到了与前面网格数量41时相同的计算结果。

改造一下代码,将时间步数和网格数量均设置为1000。

linearconv(1000,1000)

嗯,满足了CFL条件后,不管网格怎么加密,计算结果依然不会崩溃。在Fluent中的Run Calculation面板中就有利用CFL进行时间步长调整的搞法。

本篇文章来源于微信公众号: CFD之道

赞(1) 打赏
版权声明:未经允许,请勿随意用于商业用途。
文章名称:《Julia CFD|03 CFL条件》
文章链接:https://www.topcfd.cn/12703/
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。
分享到

说两句 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者吧

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫

微信扫一扫

登录

找回密码

注册