以下について、いくつか質問があります。
私は、クランクニコルソンの離散化を使用して1Dでシュレディンガー方程式を解き、続いて結果の三重対角行列を反転させようとしています。私の問題は周期的な境界条件の問題に発展したため、シャーマンモリソンアルゴリズムを使用するようにコードを変更しました。
仮定しv
、私は三重対角行列を反転したいとき、各時間ステップでの私のRHSです。のサイズv
は、スペース上にあるグリッドポイントの数です。私が設定するv[0]
とv[-1]
、私の定期的な状況で必要とされるように、お互いに関して、私の方程式は爆発します。なぜこれが起こっているのかわかりません。私はpython2.7とscipyの組み込みのsolve_bandedを使用して方程式を解いています。
これは私の2番目の質問につながります。Pythonは私が最もよく知っている言語であるため使用しましたが、(numpyとscipyによって提供される最適化を使用しても)かなり遅いと感じます。C ++に慣れているので、C ++を使用してみました。BLAS最適化されるGSLを使用すると思いましたが、複雑なベクトルを作成したり、そのような複雑な値のベクトルで三重対角行列を解いたりするためのドキュメントが見つかりませんでした。
私は、波動関数間の結合を含めるために後で一般化する最も簡単な方法であり、したがってオブジェクト指向言語に固執していると思うので、プログラムにオブジェクトを入れたいと思います。
三重対角行列ソルバーを手動で作成することもできましたが、Pythonで作成すると問題が発生しました。細かく細かいタイムステップで長い時間をかけて進化していくと、エラーが蓄積し、無意味なものになってしまいました。これを念頭に置いて、組み込みのメソッドを使用することにしました。
アドバイスは大歓迎です。
編集:関連するコードスニペットは次のとおりです。この表記法は、Wikipediaのページの三重対角行列(TDM)方程式から借用したものです。vは、各タイムステップでのクランクニコルソンアルゴリズムのRHSです。ベクトルa、b、cはTDMの対角線です。定期的なケースの修正されたアルゴリズムは、CFD Wikiからのものです。少し名前を変更しました。彼らがu、vと呼んでいるものをU、V(大文字)と呼んでいます。私はqを補数、yを一時的なソリューション、実際のソリューションをself.currentStateと呼んでいます。ここでv [0]とv [-1]の割り当てが問題を引き起こしているため、コメント化されています。ガンマの要素は無視してかまいません。これらは、ボーズアインシュタイン凝縮のモデル化に使用される非線形因子です。
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