Determine la solución numérica del problema de Riemann unidimensional y luego desarrolle y construya un programa Python para realizar el cálculo de la solución numérica del problema.

El problema de Riemann unidimensional es una clase común de problemas de mecánica de fluidos, que se utiliza para estudiar el comportamiento de soluciones fluidas en condiciones iniciales. Se trata de una interfaz separada por dos estados constantes (llamados estado izquierdo y estado derecho), donde el fluido tiene diferentes propiedades a cada lado de la interfaz.

En el problema de Riemann unidimensional, se supone que el gas se describe mediante ecuaciones de Euler de compresión (generalmente ecuaciones de Euler), que pueden describir la conservación de la masa, el momento y la energía del fluido. Después de dar la densidad, la velocidad y la presión de los estados izquierdo y derecho, el objetivo del problema de Riemann es resolver el cambio de las cantidades físicas en cada posición de la interfaz con el tiempo, como la densidad, la velocidad y la presión.

Resolver el problema de Riemann unidimensional es un problema no lineal, y uno de los métodos más utilizados es utilizar un método de división de flujo numérico, como el método de Godunov o el método HLL (Harten-Lax-van Leer). Estos métodos funcionan separando las ecuaciones fundamentales de conservación del fluido en flujos izquierdo y derecho, y calculando los flujos numéricos a partir de la velocidad de propagación de las ondas. Al discretizar en el espacio y el tiempo, se pueden usar métodos numéricos para aproximar la solución del problema de Riemann unidimensional.

La solución al problema de Riemann unidimensional puede proporcionar información importante sobre el comportamiento de fluidos, como ondas de choque, ondas discontinuas y ondas dispersas, y es de gran importancia para comprender y simular varios fenómenos físicos, como explosiones, propagación de ondas de choque y transiciones de fase de los fluidos. Tiene amplias aplicaciones en campos como la dinámica de fluidos computacional (CFD) y la dinámica de gases computacional.

 Implementación del código central:

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)

Realice el método de división del vector de circulación 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]))

Salida de resultados y visualización:

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

La visualización resultante se ve así:

 

Supongo que te gusta

Origin blog.csdn.net/Together_CZ/article/details/131340975
Recomendado
Clasificación