一维黎曼问题数值解与计算程序文档格式.docx
《一维黎曼问题数值解与计算程序文档格式.docx》由会员分享,可在线阅读,更多相关《一维黎曼问题数值解与计算程序文档格式.docx(16页珍藏版)》请在冰豆网上搜索。
![一维黎曼问题数值解与计算程序文档格式.docx](https://file1.bdocx.com/fileroot1/2022-10/11/365824c0-be58-4bbc-a20b-e4d9a6a2ae3d/365824c0-be58-4bbc-a20b-e4d9a6a2ae3d1.gif)
理想气体状态方程:
(A.3)
初始条件:
;
。
边界条件:
和处为自由输出条件,,。
3.二阶精度差分格式
两步差分格式:
(A.4)
其中。
计算实践表明,两步差分格式不能抑制激波附近非物
理振荡。
因此在计算激波时,必须采用人工黏性滤波方法:
(A.5)
为了在激波附近人工黏性起作用,而在光滑区域人工黏性为零,需要引入一个与密度(或者压力)相关的开关函数:
(A.6)
由式(A.6)可以看出,在光滑区域,密度变化很缓,因此值也很小;
而在激波附近密度变化很陡,值就很大。
带有开关函数的前置人工黏性滤波方法为:
(A.7)
其中参数往往需要通过实际试算来确定,也可采用线性近似方法得到:
(A.8)
由于声速不会超过3,所以取,在本计算中取。
4.计算结果分析
计算分别采用标准的语言和语言编写程序。
计算中网格数取,计算总时间为。
计算得到在时刻的密度、速度和压力分布如图A.2(语言计算结果)和图A.3(语言计算结果)所示。
采用两种不同语言编写程序所得到的计算结果完全吻合。
从图A.2和图A.3中可以发现,两步差分格式能很好地捕捉激波,计算得到的激波面很陡、很窄,计算激波精度是很高的。
采用带开关函数的前置人工滤波法能消除激波附近的非物理振荡,计算效果很好。
从图A.2和图A.3中可以看出通过激波后气体的密度、压力和速度都是增加的;
在压力分布中存在第二个台阶,表明在这里存在一个接触间断,在接触间断两侧压力是有间断的,而密度和速度是相等的。
这个计算结果正确地反映了一维问题的物理特性,并被激波管实验所验证。
A-2一维问题数值计算源程序
1.语言源程序
//MacCormack1D.cpp:
定义控制台应用程序的入口点。
//
/*-----------------------------------------------------------------------------------------------------
*利用差分格式求解一维激波管问题(语言版本)
*-------------------------------------------------------------------------------------------------------*/
//#include"
stdafx.h"
#include<
stdio.h>
stdlib.h>
math.h>
#defineGAMA1.4//气体常数
#definePI3.141592654
#defineL2.0//计算区域
#defineTT0.4//总时间
#defineSf0.8//时间步长因子
#defineJ1000//网格数
//全局变量
doubleU[J+2][3],Uf[J+2][3],Ef[J+2][3];
/*-------------------------------------------------------
计算时间步长
入口:
U,当前物理量,dx,网格宽度;
返回:
时间步长。
---------------------------------------------------------*/
doubleCFL(doubleU[J+2][3],doubledx)
{
inti;
doublemaxvel,p,u,vel;
maxvel=1e-100;
for(i=1;
i<
=J;
i++)
{
u=U[i][1]/U[i][0];
p=(GAMA-1)*(U[i][2]-0.5*U[i][0]*u*u);
vel=sqrt(GAMA*p/U[i][0])+fabs(u);
if(vel>
maxvel)maxvel=vel;
}
returnSf*dx/maxvel;
}
初始化
无;
出口:
U,已经给定的初始值,
dx,网格宽度。
voidInit(doubleU[J+2][3],double&
dx)
doublerou1=1.0,u1=0.0,p1=1.0;
//初始条件
doublerou2=0.125,u2=0.0,p2=0.1;
dx=L/J;
for(i=0;
=J/2;
U[i][0]=rou1;
U[i][1]=rou1*u1;
U[i][2]=p1/(GAMA-1)+rou1*u1*u1/2;
for(i=J/2+1;
=J+1;
U[i][0]=rou2;
U[i][1]=rou2*u2;
U[i][2]=p2/(GAMA-1)+rou2*u2*u2/2;
边界条件
dx,网格宽度;
U,已经给定的边界。
voidbound(doubleU[J+2][3],doubledx)
intk;
//左边界
for(k=0;
k<
3;
k++)U[0][k]=U[1][k];
//右边界
k++)U[J+1][k]=U[J][k];
根据U计算E
U,当前U矢量;
E,计算得到的E矢量,
U、E的定义见Euler方程组。
voidU2E(doubleU[3],doubleE[3])
doubleu,p;
u=U[1]/U[0];
p=(GAMA-1)*(U[2]-0.5*U[1]*U[1]/U[0]);
E[0]=U[1];
E[1]=U[0]*u*u+p;
E[2]=(U[2]+p)*u;
一维差分格式求解器
U,上一时刻的U矢量,Uf、Ef,临时变量,
dx,网格宽度,dt,时间步长;
U,计算得到的当前时刻U矢量。
voidMacCormack_1DSolver(doubleU[J+2][3],doubleUf[J+2][3],doubleEf[J+2][3],doubledx,doubledt)
inti,k;
doubler,nu,q;
r=dt/dx;
nu=0.25;
q=fabs(fabs(U[i+1][0]-U[i][0])-fabs(U[i][0]-U[i-1][0]))
/(fabs(U[i+1][0]-U[i][0])+fabs(U[i][0]-U[i-1][0])+1e-100);
//开关函数
k++)
Ef[i][k]=U[i][k]+0.5*nu*q*(U[i+1][k]-2*U[i][k]+U[i-1][k]);
//人工黏性项
}
k++)
i++)U[i][k]=Ef[i][k];
i++)U2E(U[i],Ef[i]);
Uf[i][k]=U[i][k]-r*(Ef[i+1][k]-Ef[i][k]);
//U(n+1/2)(i+1/2)
i++)U2E(Uf[i],Ef[i]);
//E(n+1/2)(i+1/2)
U[i][k]=0.5*(U[i][k]+Uf[i][k])-0.5*r*(Ef[i][k]-Ef[i-1][k]);
//U(n+1)(i)
输出结果,用数据格式画图
U,当前时刻U矢量,dx,网格宽度;
无。
voidOutput(doubleU[J+2][3],doubledx)
FILE*fp;
doublerou,u,p;
fp=fopen("
result.txt"
"
w"
);
rou=U[i][0];
u=U[i][1]/rou;
fprintf(fp,"
%20f%20.10e%20.10e%20.10e%20.10e\n"
i*dx,rou,u,p,U[i][2]);
fclose(fp);
主函数
voidmain()
doubleT,dx,dt;
Init(U,dx);