确定一维Riemann问题数值解,据此开发构建Python程序实现问题数值解求解计算

一维Riemann问题是一类常见的流体力学问题,用于研究流体在初始条件下的解的行为。它涉及到一个由两个恒定状态(称为左状态和右状态)分隔的界面,其中流体在界面两侧具有不同的性质。

在一维Riemann问题中,假设气体以压缩性欧拉方程(通常是Euler方程)描述,这些方程可以描述流体的质量、动量和能量守恒。在给定左右状态的密度、速度和压力之后,Riemann问题的目标是求解出界面上各个位置的物理量随时间的变化情况,例如密度、速度和压力等。

求解一维Riemann问题是一个非线性问题,最常用的方法之一是使用数值通量分裂方法,例如Godunov方法或HLL(Harten-Lax-van Leer)方法。这些方法通过将流体的基本守恒方程分离为左右两个通量,并根据波的传播速度来计算数值通量。通过在空间和时间上进行离散化,可以使用数值方法来逼近一维Riemann问题的解。

一维Riemann问题的解可以提供有关激波、间断、稀疏波等流体行为的重要信息,对于理解和模拟各种物理现象具有重要意义,例如爆炸、冲击波传播、流体的相变等。它在计算流体动力学(CFD)和计算气体动力学等领域中具有广泛的应用。

 核心代码实现:

Gamma=1.4  # 气体常数
Pi=np.pi
L=1  #计算区域
T=0.14 #总时间
ST=0.8 #时间步长因子
J=101 #节点总数
dX=L/(J-1)
U=np.zeros((3,J))#定义二维零数组
FU=U.copy();U_1=U.copy() #同样定义Ef,Uf 为二维零数组
X=np.zeros(J)

Tools.initial(U,J,Gamma)
SumT=0
dT=0.0005
while SumT<=T:
    dT=Tools.SetTimeStep(U,J,dX,Gamma)
    SumT+=dT
    print('T=%.10f, dT=%.10f'%(SumT,dT))
    Tools.MacCormack(U,FU,U_1,dT,dX,J,Gamma)
    # Tools.Steger_Warming(U,dT,dX,J,Gamma)
    Tools.Boundary(U,J)
Tools.Output(U,J,dX,Gamma)

实现流通矢量 Steger_Warming 分裂法 

def StegerWarming(U,dT,dX,J,Gamma):
    rho=np.zeros(J)
    u=np.zeros(J)
    p=np.zeros(J)
    c=np.zeros(J)
    Lampida=np.zeros((3,J))
    Lampida_Plus=np.zeros((3,J))
    Lampida_Minus=np.zeros((3,J))
    F_Plus=np.zeros((3,J))
    F_Minus=np.zeros((3,J))
    epso=1e-8
    for i in range(0,J):
        rho[i]=U[0][i]
        u[i]=U[1][i]/rho[i]
        p[i]=(Gamma-1)*(U[2][i]-0.5*rho[i]*u[i]*u[i])
        c[i]=np.sqrt(Gamma*p[i]/rho[i])
        Lampida[0][i]==u[i]
        Lampida[1][i]==u[i]-c[i]
        Lampida[2][i]=u[i]+c[i]
        for d in range(0,3):
            Lampida_Plus[d][i]=0.5*(Lampida[d][i]+np.sqrt(Lampida[d][i]**2+epso**2))
            Lampida_Minus[d][i]=0.5*(Lampida[d][i]-np.sqrt(Lampida[d][i]**2+epso**2))
    for i in range(0,J):
        temp=rho[i]/(2*Gamma)
        w=(3-Gamma)/(2*Gamma-2)*(Lampida_Plus[1][i]+Lampida_Plus[2][i])*c[i]**2
        F_Plus[0][i]=temp*(2*(Gamma-1)*Lampida_Plus[0][i]+Lampida_Plus[1][i]+Lampida_Plus[2][i])
        F_Plus[1][i]=temp*(2*(Gamma-1)*Lampida_Plus[0][i]*u[i]+Lampida_Plus[1][i]*(u[i]-c[i]) +Lampida_Plus[2][i]*(u[i]+c[i]))
        F_Plus[2][i]=temp*((Gamma-1)*Lampida_Plus[0][i]*u[i]**2+0.5*Lampida_Plus[1][i]*(u[i]-c[i])**2+0.5*Lampida_Plus[2][i]*(u[i]+c[i])**2+w)

        w=(3-Gamma)/(2*Gamma-2)*(Lampida_Minus[1][i]+Lampida_Minus[2][i])*c[i]**2

        F_Minus[0][i]=temp*(2*(Gamma-1)*Lampida_Minus[0][i]+Lampida_Minus[1][i]+Lampida_Minus[2][i])
        F_Minus[1][i]=temp*(2*(Gamma-1)*Lampida_Minus[0][i]*u[i]+Lampida_Minus[1][i]*(u[i]-c[i]) +Lampida_Minus[2][i]*(u[i]+c[i]))        
    F_Minus[2][i]=temp*((Gamma-1)*Lampida_Minus[0][i]*u[i]**2+0.5*Lampida_Minus[1][i]*(u[i]-c[i])**2+0.5*Lampida_Minus[2][i]*(u[i]+c[i])**2+w)
    for i in range(1,J-1):
        r=dT/dX
        U[0][i]-=r*((F_Plus[0][i]-F_Plus[0][i-1])+(F_Minus[0][i+1]-F_Minus[0][i]))
        U[1][i]-=r*((F_Plus[1][i]-F_Plus[1][i-1])+(F_Minus[1][i+1]-F_Minus[1][i]))
        U[2][i]-=r*((F_Plus[2][i]-F_Plus[2][i-1])+(F_Minus[2][i+1]-F_Minus[2][i]))

结果输出与可视化:

def Output(U,J,dX,Gamma):
    fp=open('ShockTubePython.txt','w')
    X=np.zeros(J)
    rho=np.zeros(J)
    u=np.zeros(J)
    p=np.zeros(J)
    for i in range(0,J,1):
        X[i]=i*dX
        rho[i]=U[0][i]
        u[i]=U[1][i]/rho[i]
        p[i]=(Gamma-1)*(U[2][i]-0.5*U[0][i]*u[i]*u[i])
        fp.write('%d %.4f %.10f %.10f %.10f %.10f\n'%(i,X[i],rho[i],u[i],p[i],U[2][i]))
    fp.close()
    plt.figure(figsize=(8,8))
    plt.subplot(221)
    plt.plot(X,rho,color='black',linewidth=2)
    plt.title('Density', fontsize=12)
    plt.ylabel(r'$\rho (x)$', fontsize=14)
    plt.xlim(0,1)
    plt.ylim(-0.1,1.1)

    plt.subplot(222)
    plt.plot(X,u,color='blue',linewidth=2)
    plt.title('Velocity', fontsize=12)
    plt.ylabel(r'$v(x)$', fontsize=12)
    plt.xlim(0,1)
    plt.ylim(-0.1,1.1)
    plt.subplot(223)
    plt.plot(X,p,color='red',linewidth=2)
    plt.title('Pressure', fontsize=12)
    plt.ylabel(r'$p(x)$', fontsize=12)
    plt.xlim(0,1)
    plt.ylim(-0.1,1.1)
    plt.subplot(224)
    plt.plot(X,U[2][:],color='pink',linewidth=2)
    plt.title('Energy', fontsize=12)
    plt.ylabel(r'$E(x)$', fontsize=12)
    plt.xlim(0,1)
    plt.ylim(-0.1,2.6)
    plt.savefig('ShockTube1.jpg')
    plt.show()

结果可视化如下所示:

猜你喜欢

转载自blog.csdn.net/Together_CZ/article/details/131340975