马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?我要加入
x
- // CFD_1D_1st.cpp
- // 一维激波管问题,采用二阶MacCormark格式,加入人工粘性以保证震荡稳定
- //
- // 最后修正2006.5.8
- # include <math.h>
- # include <iostream.h>
- # include <iomanip.h>//引用setw()函数
- //Max函数&Min函数,用于处理误差,保证健壮性
- # define max_abs(a,b) ((fabs(a) > fabs(b)) ? (a) : (b))
- # define min_abs(a,b) ((fabs(a) < fabs(b)) ? (a) : (b))
- //常量定义
- # define gama_ideal_gas 1.4//气体动力学中的常数,与气体类型有关,本值是相对理想气体而言
- # define tolerance 1e-6//定义计算中的误差大小,小于之将被视为零,以保证程序的健壮性
- # define L 0.2//经验的人工粘性系数,一般取0.6-3.0之间
- //符号说明dens=density,velc=velocity,ener=energy,pres=pressure
- void U_star_star (double *,double *,double *,double *,double *,double);
- double ener_comp(double,double,double);
- double pres_comp(double,double,double);
- long U_norm(double,double,double,double,double *);
- long F_fun_U(double *,double *);
- int main ()
- {
- // 网格参数 x_range[3],t_range[2],Stmp_X,CFL or Stmp_T
- const double Step_X=0.002,CFL=0.5,Step_T=Step_X*CFL;
- const double x_range[3]={-1,0,1};
- const double t_range[3]={0,0,0.3};
-
- const long MESH_X_P1=(long) floor( (x_range[1]-x_range[0])/Step_X )+1;
- const long MESH_X_P2=(long) floor( (x_range[2]-x_range[1])/Step_X )+1;
- const long MESH_X =MESH_X_P1+MESH_X_P2;
- const long MESH_T =(long) floor( (t_range[2]-t_range[0])/Step_T )+2;
-
- // 求解变量 dens[MESH_T][MESH_X],velc[][],ener[][],pres[][]
- double *dens=new double[ MESH_T * MESH_X ];
- double *velc=new double[ MESH_T * MESH_X ];
- double *ener=new double[ MESH_T * MESH_X ];
- double *pres=new double[ MESH_T * MESH_X ];
- //初始条件
- for(long i=0;i<MESH_X_P1;i++)
- {
- //第一层计算区域网格
- dens [i+MESH_X]=1;
- velc [i+MESH_X]=max_abs(0,tolerance);
- pres [i+MESH_X]=1;
- ener [i+MESH_X]=max_abs(ener_comp(pres[i+MESH_X],velc[i+MESH_X],dens [i+MESH_X]),tolerance);
- //第一层冗余网格
- dens [i]=1;
- velc [i]=max_abs(0,tolerance);
- pres [i]=1;
- ener [i]=max_abs(ener_comp(pres[i],velc[i],dens [i]),tolerance);
- }
- for(i=0;i<MESH_X_P2;i++)
- {
- //第一层计算区域网格
- dens [i+MESH_X_P1+MESH_X]=0.125;
- velc [i+MESH_X_P1+MESH_X]=max_abs(0,tolerance);
- pres [i+MESH_X_P1+MESH_X]=0.1;
- ener [i+MESH_X_P1+MESH_X]=max_abs(ener_comp(pres[i+MESH_X_P1+MESH_X],velc[i+MESH_X_P1+MESH_X],dens [i+MESH_X_P1+MESH_X]),tolerance);
- //第一层冗余网格
- dens [i+MESH_X_P1]=0.125;
- velc [i+MESH_X_P1]=max_abs(0,tolerance);
- pres [i+MESH_X_P1]=0.1;
- ener [i+MESH_X_P1]=max_abs(ener_comp(pres[i+MESH_X_P1],velc[i+MESH_X_P1],dens [i+MESH_X_P1]),tolerance);
- }
- //计算
-
- double *U_2_star=new double [3*MESH_X];//光滑前的U(n+1)(j)
- double Q;//开关函数,源于人工粘性滤波算法
- for(long n=1;n<MESH_T-1;n++)
- {
- if(n>1)
- { //开头与结尾的冗余网格,取前时刻本位置左(右)平均
- dens [n*MESH_X]=max_abs(0.5*(dens [(n-1)*MESH_X]+dens [(n-1)*MESH_X+1]),tolerance);
- velc [n*MESH_X]=max_abs(0.5*(velc [(n-1)*MESH_X]+velc [(n-1)*MESH_X+1]),tolerance);
- pres [n*MESH_X]=max_abs(0.5*(pres [(n-1)*MESH_X]+pres [(n-1)*MESH_X+1]),tolerance);
- ener [n*MESH_X]=max_abs(0.5*(ener [(n-1)*MESH_X]+ener [(n-1)*MESH_X+1]),tolerance);
- dens [(n+1)*MESH_X-1]=max_abs(0.5*(dens [n*MESH_X-1]+dens [n*MESH_X-2]),tolerance);
- velc [(n+1)*MESH_X-1]=max_abs(0.5*(velc [n*MESH_X-1]+velc [n*MESH_X-2]),tolerance);
- pres [(n+1)*MESH_X-1]=max_abs(0.5*(pres [n*MESH_X-1]+pres [n*MESH_X-2]),tolerance);
- ener [(n+1)*MESH_X-1]=max_abs(0.5*(ener [n*MESH_X-1]+ener [n*MESH_X-2]),tolerance);
- }
-
- //计算U_star_star向量
- for(long j=1;j<MESH_X-1;j++)
- {
- U_star_star(dens+j+n*MESH_X,velc+j+n*MESH_X,ener+j+n*MESH_X,pres+j+n*MESH_X,U_2_star+3*j,CFL);
- }
-
- //U(n+1)(j)计算,由U_star_star的函数表达,抹平U_star_star的震荡
- //其中U(n+1)(1)和U(n+1)(MESH_X-2)为两边边界,不可能有激波,不用抹平
- //U(n+1)(1)
- dens [(n+1)*MESH_X+1]=max_abs(U_2_star[3],tolerance);
- velc [(n+1)*MESH_X+1]=max_abs(U_2_star[4]/U_2_star[3],tolerance);
- ener [(n+1)*MESH_X+1]=max_abs(U_2_star[5],tolerance);
- pres [(n+1)*MESH_X+1]=max_abs(pres_comp(U_2_star[5],U_2_star[4],U_2_star[3]),tolerance);
- //U(n+1)(MESH_X-1)
- dens [(n+2)*MESH_X-2]=max_abs(U_2_star[3*(MESH_X-2)],tolerance);
- velc [(n+2)*MESH_X-2]=max_abs(U_2_star[3*(MESH_X-2)+1]/U_2_star[3*(MESH_X-2)],tolerance);
- ener [(n+2)*MESH_X-2]=max_abs(U_2_star[3*(MESH_X-2)+2],tolerance);
- pres [(n+2)*MESH_X-2]=max_abs(pres_comp(U_2_star[3*(MESH_X-2)+2],U_2_star[3*(MESH_X-2)+1],U_2_star[3*(MESH_X-2)]),tolerance);
- //U(n+1)(j)
- for(j=2;j<MESH_X-2;j++)
- {
- //开关函数Q
- //MacCormack定义的开关函数,比Harten好用,但仍会震荡,实际中用l限制其范围,有效果,但不明显
- //Q=fabs( ( pres[n*MESH_X+j+1] + pres[n*MESH_X+j-1] - 2*pres[n*MESH_X+j] ) / max_abs( (pres[n*MESH_X+j+1] + pres[n*MESH_X+j-1] + 2*pres[n*MESH_X+j]),1e-307 ) );
- //Q=min_abs(fabs(Q),L);Q=((fabs(Q) < fabs(tolerance)) ? (0) : (Q));//将Q限制到0-L之间
- Q=L;
- //Harten定义的开关函数,不好用,会出现无穷
- //Q=( fabs(pres[n*MESH_X+j+1]-pres[n*MESH_X+j])-fabs(pres[n*MESH_X+j]-pres[n*MESH_X+j-1]) ) / ( fabs(pres[n*MESH_X+j+1]-pres[n*MESH_X+j])+fabs(pres[n*MESH_X+j]-pres[n*MESH_X+j-1]) );
- //cout<<Q<<" "<<endl;用于Q调错
- double final_res[3];//U(n+1)(j)数据的临时保存
- for(short t=0;t<3;t++)//计算光滑过的U(n+1)(j)
- {final_res[t]=U_2_star[3*j+t]+0.5*Q*(U_2_star[3*(j+1)+t]+U_2_star[3*(j-1)+t]-2*U_2_star[3*j+t]);}
- //返回所求n+1时刻的dens,velc,ener,pres
- dens [(n+1)*MESH_X+j]=max_abs(final_res[0],tolerance);
- velc [(n+1)*MESH_X+j]=max_abs(final_res[1]/final_res[0],tolerance);
- ener [(n+1)*MESH_X+j]=max_abs(final_res[2],tolerance);
- pres [(n+1)*MESH_X+j]=max_abs(pres_comp(final_res[2],final_res[1],final_res[0]),tolerance);
- }
- }
-
- //结果输出
- for(n=1;n<MESH_T-1;n++)
- {
- cout<<n<<" 时刻"<<endl;
- for(long j=1;j<MESH_X-1;j++)
- {
- if(fabs(dens[n*MESH_X+j])<=tolerance){dens[n*MESH_X+j]=0;}
- if(fabs(velc[n*MESH_X+j])<=tolerance){velc[n*MESH_X+j]=0;}
- if(fabs(pres[n*MESH_X+j])<=tolerance){pres[n*MESH_X+j]=0;}
- if(fabs(ener[n*MESH_X+j])<=tolerance){ener[n*MESH_X+j]=0;}
- cout<<setw(15)<<dens[n*MESH_X+j]<<setw(15)<<velc[n*MESH_X+j]<<setw(15)<<pres[n*MESH_X+j]<<setw(15)<<ener[n*MESH_X+j]<<endl;
- }
- cout<<""<<endl;
- }
- return 0;
- }
- void U_star_star (double *dens1,double *velc1,double *ener1,double *pres1,double *res,double CFL1)
- {
- double U_data[18];//分别存放U(n+1)(j)_star,U(n)(j),U(n+1)(j),U(n)(j+1),U(n)(j-1),U(n+1)(j-1)_star
- double F_data[15];//分别存放F(n+1)(j)_star,F(n+1)(j-1)_star,F(n)(j),F(n)(j+1),F(n)(j-1)
- double U_data_tmp[3];//临时存放从U_norm()拿到的数据
- double F_data_tmp[3];//临时存放从F_fun_U()拿到的数据
-
- //计算U(n)(j),数据临时存在U_data_tmp里
- long err_flag=U_norm(*dens1,*velc1,*ener1,*pres1,U_data_tmp);
- U_data[3]=U_data_tmp[0];U_data[4]=U_data_tmp[1];U_data[5]=U_data_tmp[2];
- //计算U(n)(j+1),数据临时存在U_data_tmp里
- err_flag=U_norm(*(dens1+1),*(velc1+1),*(ener1+1),*(pres1+1),U_data_tmp);
- U_data[9]=U_data_tmp[0];U_data[10]=U_data_tmp[1];U_data[11]=U_data_tmp[2];
- //计算U(n)(j-1),数据临时存在U_data_tmp里
- err_flag=U_norm(*(dens1-1),*(velc1-1),*(ener1-1),*(pres1-1),U_data_tmp);
- U_data[12]=U_data_tmp[0];U_data[13]=U_data_tmp[1];U_data[14]=U_data_tmp[2];
- //计算F(n)(j)
- err_flag=F_fun_U(U_data+3,F_data_tmp);
- F_data[6]=F_data_tmp[0];F_data[7]=F_data_tmp[1];F_data[8]=F_data_tmp[2];
- //计算F(n)(j+1)
- err_flag=F_fun_U(U_data+9,F_data_tmp);
- F_data[9]=F_data_tmp[0];F_data[10]=F_data_tmp[1];F_data[11]=F_data_tmp[2];
-
- //计算F(n)(j-1)
- err_flag=F_fun_U(U_data+12,F_data_tmp);
- F_data[12]=F_data_tmp[0];F_data[13]=F_data_tmp[1];F_data[14]=F_data_tmp[2];
-
- //计算U(n+1)(j)_star
- U_data[0]=U_data[3]-CFL1*(F_data[9] -F_data[6]);
- U_data[1]=U_data[4]-CFL1*(F_data[10]-F_data[7]);
- U_data[2]=U_data[5]-CFL1*(F_data[11]-F_data[8]);
- //计算U(n+1)(j-1)_star
- U_data[15]=U_data[12]-CFL1*(F_data[6]-F_data[12]);
- U_data[16]=U_data[13]-CFL1*(F_data[7]-F_data[13]);
- U_data[17]=U_data[14]-CFL1*(F_data[8]-F_data[14]);
-
- //计算F(n+1)(j)_star
- err_flag=F_fun_U(U_data+0,F_data_tmp);
- F_data[0]=F_data_tmp[0];F_data[1]=F_data_tmp[1];F_data[2]=F_data_tmp[2];
-
- //计算F(n+1)(j-1)_star
- err_flag=F_fun_U(U_data+15,F_data_tmp);
- F_data[3]=F_data_tmp[0];F_data[4]=F_data_tmp[1];F_data[5]=F_data_tmp[2];
-
- //计算U(n+1)(j)
- U_data[6]=0.5*(U_data[3]+U_data[0])-0.5*CFL1*(F_data[0]-F_data[3]);
- U_data[7]=0.5*(U_data[4]+U_data[1])-0.5*CFL1*(F_data[1]-F_data[4]);
- U_data[8]=0.5*(U_data[5]+U_data[2])-0.5*CFL1*(F_data[2]-F_data[5]);
- //返回U_star_star
- res[0]=U_data[6];//dens
- res[1]=U_data[7];//velc*dens
- res[2]=U_data[8];//ener
- }
- //用rou,u,p,gama表达e
- double ener_comp(double pres_0,double velo_0,double dens_0)
- {
- return (pres_0/(gama_ideal_gas-1))+(0.5*dens_0*velo_0*velo_0);
- }
- //用rou,rou*u,e,gama表达p
- double pres_comp(double ener_1,double velo_multi_dens_1,double dens_1)
- {
- return (gama_ideal_gas-1)*(ener_1-0.5*velo_multi_dens_1*velo_multi_dens_1/dens_1);
- }
- //用rou,u,p,gama,e表达U
- long U_norm(double dens2,double velc2,double ener2,double pres2,double *U_data2)
- {
- U_data2[0]=dens2;
- U_data2[1]=dens2*velc2;
- U_data2[2]=ener_comp(pres2,velc2,dens2);
- return 0;
- }
- //F_fun_U是以U表达F的函数
- long F_fun_U(double *U_data3,double *F_data3)
- {
- double P_tmp=(gama_ideal_gas-1)*(U_data3[2]-0.5*U_data3[1]*U_data3[1]/U_data3[0]);
- F_data3[0]=U_data3[1];
- F_data3[1]=U_data3[1]*U_data3[1]/U_data3[0]+P_tmp;
- F_data3[2]=U_data3[1]/U_data3[0]*(U_data3[2]+P_tmp);
- return 0;
- }
复制代码 |