采用有限差分法求解一维欧拉方程:三阶R-K时间推进——三阶迎风差分(Steger-Warming)

#最近看了李新亮老师的OpenCFD一维差分格式验证的求解器代码,对通量的求法有了一些新的认识,过去自己使用的要么是一阶的,精度差,要么就没考虑到激波问题。在实际求解器中,会使用一些方法来构造高精度的差分格式并避免激波问题,这就需要学习各种差分格式的构造方程,于是有此文章,全当记录。#


一、问题描述

针对一维Sod激波管问题:

其控制方程可以写为:

\frac{\partial \mathbf{U}}{\partial t}+\frac{\partial \mathbf{F(U})}{\partial x}=0

\mathbf{U}=\begin{bmatrix} \rho \\ \rho u \\ E \end{bmatrix}        \mathbf{F(U)}=\begin{bmatrix} \rho \\ \rho u^{2}+p \\ (E+p)u \end{bmatrix}

二、求解思路

Step 1:初始化。划分网格,初始化u,p ,\rho

Step 2:计算通量。采用三阶迎风格式构造构造通量。由于迎风格式需要知道方向,即正负,这里已经把通量分为了正值和负值,在第三步会处理。

\phi _{j}=\frac{(F_{j+1/2}^{+}+F_{j+1/2}^{-})-(F_{j-1/2}^{+}+F_{j-1/2}^{-})}{\Delta x}

对于三阶迎风格式:

F_{j+1/2}^{+}=-\frac{1}{6}F_{j-1}^{+}+\frac{5}{6}F_{j}^{+}+\frac{2}{6}F_{j+1}^{+} ; F_{j+1/2}^{-}=\frac{2}{6}F_{j-1}^{-}+\frac{5}{6}F_{j}^{-}-\frac{1}{6}F_{j+1}^{-}

F_{j-1/2}^{+}=-\frac{1}{6}F_{j-2}^{+}+\frac{5}{6}F_{j-1}^{+}+\frac{2}{6}F_{j}^{+} ; F_{j-1/2}^{-}=\frac{2}{6}F_{j-2}^{-}+\frac{5}{6}F_{j-1}^{-}-\frac{1}{6}F_{j}^{-}

Step 3:通量分裂处理。为了采用高阶的迎风格式,需要对通量进行处理,这里采用Steger-Warming方法分裂通量,避免出现间断。其思路是将通量分为正值和负值,然后将二者相加,即得到了总通量,即:

F_{j+1/2}=F_{j+1/2}^{+}+F_{j+1/2}^{ -}

由上一步可知:

F_{j+1/2}^{+}=-\frac{1}{6}F_{j-1}^{+}+\frac{5}{6}F_{j}^{+}+\frac{2}{6}F_{j+1}^{+} ; F_{j+1/2}^{-}=\frac{2}{6}F_{j-1}^{-}+\frac{5}{6}F_{j}^{-}-\frac{1}{6}F_{j+1}^{-}

F_{j-1/2}^{+}=-\frac{1}{6}F_{j-2}^{+}+\frac{5}{6}F_{j-1}^{+}+\frac{2}{6}F_{j}^{+} ; F_{j-1/2}^{-}=\frac{2}{6}F_{j-2}^{-}+\frac{5}{6}F_{j-1}^{-}-\frac{1}{6}F_{j}^{-}

因此我们需要求出F_{j}^{\pm }, 过程网上很多人都有介绍如(https://zhuanlan.zhihu.com/p/148377847),这里我们不做推导,只给出结果:

F_{j}^{\pm }=\frac{\rho_{j}}{2\gamma }\begin{bmatrix} 2(\gamma-1)\lambda _{j,1}^{\pm }+\lambda _{j,2}^{\pm }+\lambda _{j,3}^{\pm }\\ 2(\gamma-1)\lambda _{j,1}^{\pm }u_{j}+\lambda _{j,2}^{\pm }(u_{j}-c_{j})+\lambda _{j,3}^{\pm }(u_{j}+c_{j}) \\ (\gamma-1)\lambda _{j,1}^{\pm }u_{j}^{2}+\lambda _{j,2}^{\pm }(u_{j}-c_{j})^{2}/2+\lambda _{j,3}^{\pm }(u_{j}+c_{j})/2+w_{j}^{\pm} \end{bmatrix}

w_{j}^{\pm}=\frac{(3-\gamma)(\lambda _{j,2}^{\pm }+\lambda _{j,3}^{\pm })c_{j}^{2}}{2(\gamma-1)}

式中:

\lambda _{j,k}^{\pm }=(\lambda _{j,k}\pm \left | \lambda _{j,k} \right |)/2\; \; \; (k=1,2,3\; ;j=1,2,3,4,5,...,N) 

为了避免导数在间断处不连续,一般会写成这种形式:

\lambda _{j,k}^{\pm }=(\lambda _{j,k}\pm \sqrt{\lambda_{j,k}^{2}+\varepsilon ^{2}}\,\,)/2 \, \,\, \, \,\, \, \,\varepsilon =10^{-3} \, \, \, to\, \, \,10^{-6}

其中\lambda _{j,1}=u_{j}\; \; \; \; \lambda _{j,2}=u_{j}-c_{j}\; \; \; \;\lambda _{j,3}=u_{j}+c_{j}

Step 4 :时间推进求解。这里采用三阶Runge-Kutta法进行时间推进。

经过我们上述的处理,我们可以得到常微分方程如下:

\frac{\partial U_{j}}{\partial t}+\phi _{j}=0

进一步地,将其展开处理:

\frac{U_{j}^{n+1}-U_{j}^{n}}{\Delta t}=-\phi _{j}^{n}=L(U_{j}^{n})

采用三阶RK方法进行时间推进,可分为三个子步:

U_{j}^{(1)}=U_{j}^{n}+\Delta tL(U_{j}^{n})

U_{j}^{(2)}=3/4U_{j}^{n}+1/4[U_{j}^{(1)}+\Delta tL(U_{j}^{(1)})]

U_{j}^{n+1}=1/3U_{j}^{n}+2/3[U_{j}^{(2)}+\Delta tL(U_{j}^{(2)})]

至此,我们已经通过当前时间步U_{j}^{n},获得了下一时间步的U_{j}^{n+1},遍历整个网格,即可得到所有网格节点上的值U_{N}^{n+1}

重复Step2——Step4,直到达到停止时刻。


  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一个基于有限差分法求解二维非线性Klein-Gordon方程的Matlab求解代码: ```matlab % 设置求解区域和时间范围 Lx = 50; % 求解区域的长度 Ly = 50; % 求解区域的宽度 T = 100; % 求解时间的范围 % 设置网格参数 Nx = 101; % x方向上的网格数 Ny = 101; % y方向上的网格数 Nt = 1000; % 时间步数 dx = Lx/(Nx-1); % x方向上的网格间距 dy = Ly/(Ny-1); % y方向上的网格间距 dt = T/Nt; % 时间步长 % 初始化变量 u = zeros(Nx,Ny,Nt); % 存储解 x = linspace(0,Lx,Nx); y = linspace(0,Ly,Ny); t = linspace(0,T,Nt); % 设置初始条件 [X,Y] = meshgrid(x,y); u(:,:,1) = exp(-((X-Lx/2).^2+(Y-Ly/2).^2)/10); % 设置边界条件 u(1,:,:) = u(Nx,:,:); u(Nx,:,:) = u(1,:,:); u(:,1,:) = u(:,Ny,:); u(:,Ny,:) = u(:,1,:); % 求解 for n = 1:Nt-1 % 使用中心差分求解x方向上的二阶导数 uxx = (u(1:Nx-2,:,n)-2*u(2:Nx-1,:,n)+u(3:Nx,:,n))/(dx^2); % 使用中心差分求解y方向上的二阶导数 uyy = (u(:,1:Ny-2,n)-2*u(:,2:Ny-1,n)+u(:,3:Ny,n))/(dy^2); % 计算非线性项 f = u(:,:,n).^3-u(:,:,n); % 更新解 u(2:Nx-1,2:Ny-1,n+1) = u(2:Nx-1,2:Ny-1,n)+dt*(uxx+uyy+f(2:Nx-1,2:Ny-1)); % 使用边界条件更新解 u(1,:,:) = u(Nx,:,:); u(Nx,:,:) = u(1,:,:); u(:,1,:) = u(:,Ny,:); u(:,Ny,:) = u(:,1,:); end % 绘制解在不同时间的图像 for n = 1:100:Nt contourf(x,y,u(:,:,n),20); colorbar; title(['t = ' num2str(t(n))]); axis([0 Lx 0 Ly]); xlabel('x'); ylabel('y'); pause(0.01); end ``` 在这个代码中,我们使用了中心差分法来求解二维非线性Klein-Gordon方程。在每个时间步长内,我们首先使用中心差分求解x方向和y方向上的二阶导数,然后计算非线性项,并使用欧拉方法更新解。最后,我们使用边界条件更新解,并绘制解在不同时间的图像。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值