1 次元リーマン問題の数値解を求め、問題の数値解の計算を実現する Python プログラムを開発および構築します。

1 次元リーマン問題は流体力学の問題の一般的なクラスであり、初期条件下での流体溶液の挙動を研究するために使用されます。これには、2 つの一定の状態 (左の状態と右の状態と呼ばれる) によって分離された界面が含まれます。この場合、流体は界面の両側で異なる特性を持ちます。

1 次元リーマン問題では、気体は圧縮性オイラー方程式 (通常はオイラー方程式) で記述されると想定され、流体の質量、運動量、エネルギー保存を記述できます。リーマン問題の目的は、左右の状態の密度、速度、圧力が与えられた後、界面上の各位置における密度、速度、圧力などの物理量の時間変化を解くことです。

1 次元リーマン問題を解くことは非線形問題であり、最も一般的に使用される方法の 1 つは、ゴドゥノフ法や HLL (Harten-Lax-van Leer) 法などの数値磁束分割法を使用することです。これらの方法は、流体の基本的な保存方程式を左右の流束に分離し、波の伝播速度から流束の数値を計算することによって機能します。空間と時間で離散化することにより、数値的手法を使用して 1 次元リーマン問題の解を近似することができます。

1 次元リーマン問題の解は、衝撃波、不連続波、疎波などの流体の挙動に関する重要な情報を提供することができ、爆発、衝撃波の伝播、衝撃波などのさまざまな物理現象の理解とシミュレーションにとって非常に重要です。流体の相転移。数値流体力学 (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