從PDE問題來看,我有一個複雜的值系統,Python中的odeint()無法處理它。我寫了一個RK4模塊來解決我的系統問題。它似乎工作,但是,計算值顯然不正確。在第二個時間步,整個計算值爲零。這裏是我的代碼:python中PDE的復值ODE
import matplotlib.pyplot as plt
import numpy as np
import drawnow
import time
import math
### Parameters ###
L = 20
n = 64
delta_t = 1.
tmax = 10
miu = 1e-6
x2 = np.linspace(-L/2,L/2, n+1)
x = x2[:n] # periodic B.C. #0 = #n
kx1 = np.linspace(0,n/2-1,n/2)
kx2 = np.linspace(1,n/2, n/2)
kx2 = -1*kx2[::-1]
kx = (2.*math.pi/L)*np.concatenate((kx1,kx2)); kx[0] = 1e-6
ky = kx; y = x
X, Y = np.meshgrid(x, y)
KX,KY = np.meshgrid(kx,ky)
K = KX**2 + KY**2
K2 = np.reshape(K, n**2,1)
### Initial Condition ###
vorticity = np.exp(-0.25*X**2 - 2.*Y**2)
wt = np.fft.fft2(vorticity)
wt2 = np.reshape(wt, n**2, 1) # wt2 is initial condition
### Define ODE ###
def yprime(t,rhs):
global miu, K, K2,n,KX, KY, wt2, wt
psit = -wt/ K
psix = np.real(np.fft.ifft2(1j*KX*psit))
psiy = np.real(np.fft.ifft2(1j*KY*psit))
wx = np.real(np.fft.ifft2(1j*KX*wt))
wy = np.real(np.fft.ifft2(1j*KY*wt))
rhs = -miu * K2 * wt2 + np.reshape(np.fft.fft2(wx*psiy - wy*psix), n**2,1)
return rhs
def RK4(domain,wt2,tmax):
w = np.empty((tmax+1,n**2))
w = w + 0j
t = np.empty(tmax+1) # length
w[0,:] = wt2 # enter initial conditions in y
t[0] = domain[0]
for i in range(1,tmax):
t[i+1] = t[i]+delta_t
w[i+1,:] = RK4Step(t[i], w[i,:],delta_t)
return w
def RK4Step(t,w,delta_t):
k1 = yprime(t,w)
k2 = yprime(t+0.5*delta_t, w+0.5*k1*delta_t)
k3 = yprime(t+0.5*delta_t, w+0.5*k2*delta_t)
k4 = yprime(t+delta_t, w+k3*delta_t)
return w + (k1+2*k2+2*k3+k4)*delta_t/6.
### Prediction ###
TimeStart = 0.
TimeEnd = tmax+1
TimeSpan = np.arange(TimeStart, TimeEnd, delta_t)
wt2_sol = RK4(TimeSpan, wt2, tmax)
for i in TimeSpan:
w = np.real(np.fft.ifft2(np.reshape(wt2_sol[i,:], (n, n))))
plt.pcolor(X,Y,w,shading = 'interp',cmap='jet')
drawnow
time.sleep(0.2)
plt.show()
任何想法爲什麼它不工作?另外,我喜歡根據解決方案製作短片。函數'drawnow'和'time.sleep()在這裏似乎不起作用。
謝謝!
你的微分方程似乎是一個簡單的時間積分。在'yprime(t,rhs)'中,右邊沒有對rhs的依賴。你是否也可以請你記錄你想要解決的PDE的「原始」形式? – LutzL
PDE的「原始」形式爲:dw/dt = miu * laplacian(w)-d(psi)/ dx * dw/dy + d(psi)/ dy * dw/dx。我使用光譜方法將此PDE轉換爲ODE。函數'yprime'中的'rhs'是這個PDE的'傅立葉變換'。所以,如果RK4工作,'wt2_sol = RK4(TimeSpan,wt2,tmax)'應該給我傅里葉空間的解。 @Lutzl – Jundong
然後用'def yprime(t,wt):'替換第一個'def yprime(t,rhs):',因爲'w' resp。 'wt'是你的狀態變量,'rhs'應該是'lhs'是結果。所以'wt,wt2'是局部變量。你應該注意'yprime'的輸入和輸出具有相同的格式,如果其中一個是矢量,那麼另一個應該是一個矢量,並且在它們之間有一對相反的'reshape'命令。但是可能你可以將它作爲一個二維的網格值數組,這樣就不需要在任何地方進行重塑。 – LutzL