Aşağıdakilerle ilgili birkaç sorum var:
1D Schrodinger denklemi krank nicolson ayrıklaştırma kullanarak sonuçlanan tridiagonal matris ters çevirerek çözmeye çalışıyorum. Benim sorunum şimdi periyodik sınır koşulları ile ilgili bir soruna dönüştü ve bu yüzden Sherman Morrison algoritmasını kullanmak için kodumu değiştirdim.
Varsayalım v
ben tridiagonal matrisinin tersini istediğinizde her zaman adımında benim RHS olduğunu. Boyutu, v
alan üzerinde sahip olduğum ızgara noktalarının sayısıdır. Periyodik durumumda gerektiği gibi ayarladığımda v[0]
ve v[-1]
denklemimde denklemim patlar. Bunun neden olduğunu anlatamıyorum. Denklemi çözmek için python2.7 ve scipy's built solve_banded kullanıyorum.
Bu beni ikinci soruma götürdü: Python kullandım çünkü en iyi bildiğim dil, ama oldukça yavaş buluyorum (numpy ve scipy tarafından sunulan optimizasyonlarda bile). Ben oldukça aşina olduğum gibi C ++ kullanarak denedim. BLAS için optimize edilmiş GSL kullanacağımı düşündüm, ancak karmaşık vektörler oluşturmak veya tridiagonal matrisi bu tür karmaşık değerli vektörlerle çözmek için hiçbir belge bulamadım.
Programımdaki nesneleri istiyorum, çünkü daha sonra genelleştirmenin dalga fonksiyonları arasında bağlantıyı dahil etmenin en kolay yolu olacağını hissediyorum, böylece bir nesne yönelimli dile bağlı kalıyorum.
Tridiagonal matris çözücüyü elle yazmayı deneyebilirim, ancak python'da bunu yaptığımda problemlerle karşılaştım. Daha uzun ve daha ince zaman adımlarıyla büyük zamanlar içinde geliştiğimde, hata birikti ve bana saçmalık verdi. Bunu akılda tutarak, yerleşik yöntemleri kullanmaya karar verdim.
Herhangi bir tavsiye çok takdir edilmektedir.
EDIT: İşte ilgili kod snippet'i. Gösterim, tridiagonal matris (TDM) denklemindeki Wikipedia sayfasından ödünç alınmıştır. v, her bir zaman adımında krank nicolson algoritmasının RHS'sidir. A, b ve c vektörleri TDM'nin köşegenleridir. Periyodik vaka için düzeltilmiş algoritma CFD Wiki'den . Biraz yeniden adlandırma yaptım. U dediklerini, v U, V (büyük harf) dedim. Ben q tamamlayıcı, y geçici çözüm ve gerçek çözüm self.currentState çağırdı. V [0] ve v [-1] ataması, buradaki soruna neden olan şeydir ve bu nedenle yorumlanmıştır. Gama faktörlerini göz ardı edebilirsiniz. Bunlar Bose Einstein Kondensatlarını modellemek için kullanılan doğrusal olmayan faktörlerdir.
for T in np.arange(self.timeArraySize):
for i in np.arange(0,self.spaceArraySize-1):
v[i] = Y*self.currentState[i+1] + (1-2*Y)*self.currentState[i] + Y*self.currentState[i-1] - 1j*0.5*self.timeStep*potential[i]*self.currentState[i] - self.gamma*1j*0.5*self.timeStep*(abs(self.currentState[i])**2)*self.currentState[i]
b[i] = 1+2*Y + 1j*0.5*self.timeStep*potential[i] + self.gamma*self.timeStep*1j*0.5*(abs(self.currentState[i])**2)
#v[0] = Y*self.currentState[1] + (1-2*Y)*self.currentState[0] + Y*self.currentState[-1] - 1j*0.5*self.timeStep*potential[0]*self.currentState[0]# - self.gamma*1j*0.5*self.timeStep*(abs(self.currentState[0])**2)*self.currentState[0]
#v[-1] = Y*self.currentState[0] + (1-2*Y)*self.currentState[-1] + Y*self.currentState[-2] - 1j*0.5*self.timeStep*potential[-1]*self.currentState[-1]# - self.gamma*1j*0.5*self.timeStep*(abs(self.currentState[-1])**2)*self.currentState[-1]
b[0] = 1+2*Y + 1j*0.5*self.timeStep*potential[0] + self.gamma*self.timeStep*1j*0.5*(abs(self.currentState[0])**2)
b[-1] = 1+2*Y + 1j*0.5*self.timeStep*potential[-1] + self.gamma*self.timeStep*1j*0.5*(abs(self.currentState[-1])**2)
diagCorrection[0], diagCorrection[-1] = - b[0], - c[-1]*a[0]/b[0]
tridiag = np.matrix([
c,
b - diagCorrection,
a,
])
temp = solve_banded((1,1), tridiag, v)
U = np.zeros(self.spaceArraySize, dtype=np.complex64)
U[0], U[-1] = -b[0], c[-1]
V = np.zeros(self.spaceArraySize, dtype=np.complex64)
V[0], V[-1] = 1, -a[0]/b[0]
complement = solve_banded((1,1), tridiag, U)
num = np.dot(V, temp)
den = 1 + np.dot(V, complement)
self.currentState = temp - (num/den)*complement