具有周期边界条件的薛定inger方程


9

我有以下几个问题:

我正在尝试使用曲柄nicolson离散化解决一维Schrodinger方程,然后求反三对角矩阵。我的问题现在演变为周期性边界条件的问题,因此我修改了代码以使用Sherman Morrison算法。

假设v当我希望反转三对角矩阵时,在每个时间步中都存在我的RHS。的大小v是我在空间上拥有的网格点的数量。当我设定v[0]v[-1]按照我的周期性情况的要求互相称呼时,我的方程式崩溃了。我不知道为什么会这样。我正在使用python2.7和scipy的内置solve_banded来求解方程。

这引出了我的第二个问题:我使用python是因为它是我最了解的语言,但是我发现它运行起来很慢(即使使用numpy和scipy提供的优化)。我已经尝试使用C ++,因为我对此相当熟悉。我以为我会使用经过BLAS优化的GSL,但没有找到任何文档来创建复杂向量或使用此类复杂值向量求解三对角矩阵。

我希望在程序中使用对象,因为我觉得这是以后进行泛化以包含波动函数之间的耦合的最简单方法,因此我坚持使用面向对象的语言。

我可以尝试手动编写三对角矩阵求解器,但是在python中编写时遇到了问题。随着时间的推移,随着时间的推移,我逐渐发展,错误不断累积,使我无聊。考虑到这一点,我决定使用内置方法。

任何建议深表感谢。

编辑:这是相关的代码段。该符号是从Wikipedia的页面上引用的三对角矩阵(TDM)公式。v是每个时间步长的crank nicolson算法的RHS。向量a,b和c是TDM的对角线。定期案例的校正算法来自CFD Wiki。我做了一些重命名。他们所说的u,v我称之为U,V(大写)。我称q为补数,y为临时解,而实际解为self.currentState。v [0]和v [-1]的分配是引起问题的原因,因此已被注释掉。您可能会忽略伽玛系数。它们是用于建模Bose Einstein冷凝物的非线性因子。

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

3
乍一看,这听起来像是您的周期性边界条件中的错误。想要发布代码段吗?
David Ketcheson 2012年

2
欢迎使用Stack Exchange!将来,如果您有几个问题,可能要分别询问。
2012年

另外:“将v [0]和v [-1]彼此相对设置”到底是什么意思?您是在求解后将向量元素设置为彼此相等,还是使用非对角线元素将它们耦合?
2012年

我在上面添加了我的代码。如果有任何不清楚的地方,请告诉我。我会记得下次再发表单独的问题。
WiFO215 2012年

谢谢!由于格式(很长的行),很难阅读代码。另外,注释掉您希望人们注意的那部分也是令人困惑的。您是否可以使用与代码相同的符号写下您正在求解的方程式(使用MathJax)?
David Ketcheson 2012年

Answers:


2

第二个问题

调用Scipy / Numpy的代码通常只有在可以向量化的情况下才是快速的。您在python循环中不应该有任何“慢”的东西。即使那样,它也至少会比使用类似语言的编译库慢一些。

for i in np.arange(0,self.spaceArraySize-1):
            v[i] = Y*self.currentState[i+1] + (1-2*Y)*self.currentState[i]   ...
            b[i] = 1+2*Y + 1j*0.5*self.timeStep*potential[i] + ...

这就是我所说的“ python循环慢”。for对于大多数数值应用程序,Python的速度慢得令人无法接受,而Scipy / Numpy根本不影响这一点。如果要使用python,则此内部循环应表示为一个或两个Numpy / Scipy函数,这些库可能提供也可能不提供。如果它们没有提供允许您迭代这样的数组并访问相邻元素的工具,则python是您想要执行的操作的错误工具。

另外,您正在执行反演而不是矩阵向量求解。矩阵求逆,然后是矩阵-向量乘法,是比矩阵矢量解决慢。几乎可以肯定,这是使您的代码变慢的最重要因素。

如果您想使用C / C ++,那么在复杂的线性代数方面就缺少GSL。我建议直接使用BLAS或LAPACK,或使用类似PETSc或Trilinos的库。如果您安装了MKL,也可以使用它。您可能还需要查看面向对象的Fortran 2008。

您的矩阵是稀疏的,因此您需要确保使用稀疏库。

我还要说的是,您在这里所做的工作似乎很底层,因此面向对象可能不是您的主要关注点。Fortran 90+阵列可能非常符合您的需求,F90编译器可以自动并行化某些循环。

另外,您可能想查看具有此sparse()功能的Octave或Matlab 。如果使用得当,它们应该能够很快运行。


我肯定会研究Fortran2008。我已经有了“几乎三对角线”的矩阵。上面我提到我正在使用Sherman Morrison算法。
WiFO215 2012年

更新:我一直在尝试阅读ScaLAPACK,因为它看起来非常有趣。它允许人们使用我一直在“并行”听到很多的流行语来对矩阵求逆。我所知道的是它使用了我所有的处理器,因此运行速度更快,但是除此之外,我不了解它的含义。来自物理学背景,我唯一接触过计算的知识是使用Python和C开设了101门课程。学习如何使用它需要时间。该文档本身并不适合阅读。
WiFO215 2012年

更新2:伙计!这ScaLAPACK事情看起来真的很复杂。我不了解网站内容的开头或结尾。我只是在浏览所有信息。
WiFO215 2012年

更新3:好吧,我已经审议了PETSc和Trilinos的其他建议。我的最后电话是,我认为我现在不会使用它们,因为它们看起来非常复杂。这并不意味着我不会阅读它们。我现在将开始阅读它们,但是到我理解并能够执行它们时,就已经过去了几个月。由于遇到上述问题,我将为上面的问题打开一个单独的线程。现在,我回来了,以解决只是时间问题1
WiFO215

我已经更新了答案。
2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.