Determine the numerical solution of the one-dimensional Riemann problem, and then develop and build a Python program to realize the calculation of the numerical solution of the problem

The one-dimensional Riemann problem is a common class of fluid mechanics problems, which is used to study the behavior of fluid solutions under initial conditions. It involves an interface separated by two constant states (called the left state and the right state), where the fluid has different properties on either side of the interface.

In the one-dimensional Riemann problem, the gas is assumed to be described by compressible Euler equations (usually Euler equations), which can describe the mass, momentum, and energy conservation of the fluid. After the density, velocity, and pressure of the left and right states are given, the goal of the Riemann problem is to solve the change of physical quantities at each position on the interface with time, such as density, velocity, and pressure.

Solving the one-dimensional Riemann problem is a nonlinear problem, and one of the most commonly used methods is to use a numerical flux splitting method, such as the Godunov method or the HLL (Harten-Lax-van Leer) method. These methods work by separating the fundamental conservation equations of the fluid into left and right fluxes, and computing the numerical fluxes from the propagation speed of the waves. By discretizing in space and time, numerical methods can be used to approximate the solution of the one-dimensional Riemann problem.

The solution to the one-dimensional Riemann problem can provide important information about fluid behavior such as shock waves, discontinuous waves, and sparse waves, and is of great significance for understanding and simulating various physical phenomena, such as explosions, shock wave propagation, and phase transitions of fluids. It has wide applications in fields such as Computational Fluid Dynamics (CFD) and Computational Gas Dynamics.

 Core code implementation:

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)

Realize the circulation vector Steger_Warming split method 

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]))

Result output and visualization:

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()

The resulting visualization looks like this:

 

Guess you like

Origin blog.csdn.net/Together_CZ/article/details/131340975