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

CFD Julia|02 传热方程:Runge-Kutta法

内容纲要

一维热传导方程为:

式中,为场变量;为时间;为介质扩散率。

前面的课程中使用的FTCS格式中,对时间项采用的向前差分格式只有一阶精度,我们可以想办法构造更高精度的时间格式,如本文后面将要使用的Runge-Kutta方法。

1 离散方程

Runge-Kutta法试图在时间点之间应用更多的中间点计算来提高时间项离散精度。这里采用文献[16]所提供的一种三阶精度的Runge-Kutta格式来离散传热方程的时间项。对于空间项依然使用二阶中心差分格式。这种Runge-Kutta离散方法的离散误差为

三阶Runge-Kutta格式对传热方程时间项进行离散后得到的方程为:

2 程序代码

可以编写程序代码:

using Printf
# -------------------基础测试数据------------------------#
# x_l与x_r分别为计算域坐标
# dx,dt分别为空间网格尺寸与时间步长
# t为最终时刻
x_l = -1.0
x_r = 1.0
dx = 0.025
dt = 0.001
t = 1.0

# nx与nt分别为网格数量与时间步数
nx = Int64((x_r - x_l) / dx)
nt = Int64(t / dt)

# alpha为物性参数
alpha = 1 / (pi * pi)

u = Array{Float64}(undef, nx + 1, nt + 1)
x = Array{Float64}(undef, nx + 1)
u_e = Array{Float64}(undef, nx + 1)
u_error = Array{Float64}(undef, nx + 1)

for i = 1:nx+1
x[i] = x_l + dx * (i - 1) # 得到网格点的x坐标
u_e[i] = -exp(-t) * sin(pi * x[i]) # 得到理论值用于后面比较
end
# --------------------------------------------------------------#

# 利用中心差分计算方程的右侧项
# r = α ∂2u/∂x2
function rhs(nx, dx, u, r, alpha)
for i = 2:nx
r[i] = alpha * (u[i+1] - 2 * u[i] + u[i-1]) / (dx * dx)
end
end 

# 三阶龙格库塔法时间离散
function numerical(nx, nt, dx, dt, x, u, alpha)
un = Array{Float64}(undef, nx + 1) # 存储每个时间步的数值解
ut = Array{Float64}(undef, nx + 1) # 存储RK积分的临时数组
r = Array{Float64}(undef, nx)

k = 1 
for i = 1:nx+1
un[i] = -sin(pi * x[i])
u[i, k] = un[i]
end

# 边界条件
un[1] = 0.0
un[nx+1] = 0.0
ut[1] = 0.0
ut[nx+1] = 0.0

for j = 2:nt+1
rhs(nx, dx, un, r, alpha)
for i = 2:nx
ut[i] = un[i] + dt * r[i]
end

rhs(nx, dx, un, r, alpha)
for i = 2:nx
ut[i] = 0.75 * un[i] + 0.25 * ut[i] + 0.25 * dt * r[i]
end

rhs(nx, dx, un, r, alpha)
for i = 2:nx
un[i] = (1.0 / 3.0) * un[i] + (2.0 / 3.0) * ut[i] + (2.0 / 3.0) * dt * r[i]
end

k = k + 1
u[:, k] = un[:]
end
end

# -----------------------------------------------------------#

numerical(nx, nt, dx, dt, x, u, alpha)
u_error = u[:, nt+1] - u_e

# 将数据写入到文件中
field_final = open("field_final1.csv", "w");
write(field_final, "x", " ", "ue", " ", "un", " ", "uerror", " n")

for i = 1:nx+1
write(field_final, @sprintf("%.16f", x[i]), " ", @sprintf("%.16f", u_e[i]), " ",
@sprintf("%.16f", u[i, nt+1]), " ", @sprintf("%.16f", u_error[i]), " n")
end

close(field_final)

计算结果及离散误差如下图所示。

3 尝试

对程序代码进行以下修改并观察计算结果:

  • 网格尺寸不变,将时间步长dt成倍增大
  • 时间步长不变,将网格尺寸dx成倍增大或减小
  • 组合时间步长及网格尺寸

这里所使用的三阶Runge-Kutta方法依然是一种显式算法,因此在计算过程中时间步长不能太大,若想要使用大的时间步长,只能通过增大网格尺寸来维持计算稳定。

4 参考文献

[16] Gottlieb, S.; Shu, C.W. Total variation diminishing Runge-Kutta schemes. Math. Comput. Am. Math. Soc.1998, 67, 73–85.


(本文结束)

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

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

说两句 抢沙发

评论前必须登录!

 

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

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

支付宝扫一扫

微信扫一扫

登录

找回密码

注册