【发布时间】:2019-07-07 17:24:27
【问题描述】:
我正在尝试在没有势场的盒子模拟中做一个粒子。我花了一些时间才发现简单的显式和隐式方法会破坏酉时间演化,所以我求助于应该是酉的曲柄尼科尔森。但是当我尝试它时,我发现它仍然不是这样。我不确定我错过了什么。我使用的公式是这样的:
其中 T 是 x 和 x 的二阶导数的三对角 Toeplitz 矩阵
系统简化为
A 和 B 矩阵是:
我只是使用稀疏模块为 解决这个线性系统。数学是有道理的,我在一些论文中发现了相同的数字方案,这让我相信我的代码就是问题所在。
到目前为止,这是我的代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import toeplitz
from scipy.sparse.linalg import spsolve
from scipy import sparse
# Spatial discretisation
N = 100
x = np.linspace(0, 1, N)
dx = x[1] - x[0]
# Time discretisation
K = 10000
t = np.linspace(0, 10, K)
dt = t[1] - t[0]
alpha = (1j * dt) / (2 * (dx ** 2))
A = sparse.csc_matrix(toeplitz([1 + 2 * alpha, -alpha, *np.zeros(N-4)]), dtype=np.cfloat) # 2 less for both boundaries
B = sparse.csc_matrix(toeplitz([1 - 2 * alpha, alpha, *np.zeros(N-4)]), dtype=np.cfloat)
# Initial and boundary conditions (localized gaussian)
psi = np.exp((1j * 50 * x) - (200 * (x - .5) ** 2))
b = B.dot(psi[1:-1])
psi[0], psi[-1] = 0, 0
for index, step in enumerate(t):
# Within the domain
psi[1:-1] = spsolve(A, b)
# Enforce boundaries
# psi[0], psi[N - 1] = 0, 0
b = B.dot(psi[1:-1])
# Square integration to show if it's unitary
print(np.trapz(np.abs(psi) ** 2, dx))
【问题讨论】:
-
如果
T是反对称的,那么你只能得到单一的步骤,如果转置相应。T的伴随是-T。这可能发生在一个简单的输运方程上,但很可能不会发生在一个包含二阶导数的薛定谔方程上。 -
Crank-Nicolson 适用于热方程,它是一个扩散方程。它们都产生三对角对称 Toeplitz 矩阵。唯一的区别是统一性要求和复杂的条款。你能指出我可以阅读你提到的反对称要求的地方吗?
-
也许我得修改一下前面的说法,因为薛定谔方程中的拉普拉斯算子有一个因子
i,这样才能实现反对称。然后我想知道为什么你的矩阵A,B不是三对角线,如果我正确理解了构造命令。 -
"如果没有给出r,则假定r == conjugate(c)。" 这种情况下是错误的,一般中间条目应该是
[.., -alpha, 1+2*alpha, -alpha, ...],但是使用alphaimaginary 你会得到一个不需要的符号翻转。
标签: python numpy scipy numerical-methods