使用 Numpy 和 SciPy solve_ivp 的时间相关一维薛定谔方程
Time Dependant 1D Schroedinger Equation using Numpy and SciPy solve_ivp
我正在尝试使用有限差分法求解一维时间相关的薛定谔方程,这是方程的外观以及它如何进行离散化
假设我有N个空间点(x_i从0到N-1),假设我的时间跨度是K个时间点。
我努力得到一个 K 乘 N 的矩阵。每行 (j) 将是时间 t_j
的函数
我怀疑我的问题是我以错误的方式定义了耦合方程组。
我的边界条件是 psi=0,或者盒子两侧的某个常数,所以我将 X 跨度两侧的 ode 设置为零
我的代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
#Defining the length and the resolution of our x vector
length = 2*np.pi
delta_x = .01
# create a vector of X values, and the number of X values
def create_x_vector(length, delta_x):
x = np.arange(-length, length, delta_x)
N = len(x)
return x, N
# create initial condition vector
def create_initial_cond(x,x0,Gausswidth):
psi0 = np.exp((-(x-x0)**2)/Gausswidth)
return psi0
#create the system of ODEs
def ode_system(psi,t,delta_x,N):
psi_t = np.zeros(N)
psi_t[0]=0
psi_t[N-1]=0
for i in range(1,N-1):
psi_t[i] = (psi[i+1]-2*psi[i]+psi[i-1])/(delta_x)**2
return psi_t
#Create the actual time, x and initial condition vectors using the functions
t = np.linspace(0,15,5000)
x,N= create_x_vector(length,delta_x)
psi0 = create_initial_cond(x,0,1)
psi = np.zeros(N)
psi= solve_ivp(ode_system(psi,t,delta_x,N),[0,15],psi0,method='Radau',max_step=0.1)
在 运行 之后我得到一个错误:
runfile('D:/Studies/Project/Simulation Test/Test2.py', wdir='D:/Studies/Project/Simulation Test')
Traceback (most recent call last):
File "<ipython-input-16-bff0a1fd9937>", line 1, in <module>
runfile('D:/Studies/Project/Simulation Test/Test2.py', wdir='D:/Studies/Project/Simulation Test')
File "C:\Users\Pasha\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 704, in runfile
execfile(filename, namespace)
File "C:\Users\Pasha\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 108, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "D:/Studies/Project/Simulation Test/Test2.py", line 35, in <module>
psi= solve_ivp(ode_system(psi,t,delta_x,N),[0,15],psi0,method='Radau',max_step=0.1)
File "C:\Users\Pasha\Anaconda3\lib\site-packages\scipy\integrate\_ivp\ivp.py", line 454, in solve_ivp
solver = method(fun, t0, y0, tf, vectorized=vectorized, **options)
File "C:\Users\Pasha\Anaconda3\lib\site-packages\scipy\integrate\_ivp\radau.py", line 288, in __init__
self.f = self.fun(self.t, self.y)
File "C:\Users\Pasha\Anaconda3\lib\site-packages\scipy\integrate\_ivp\base.py", line 139, in fun
return self.fun_single(t, y)
File "C:\Users\Pasha\Anaconda3\lib\site-packages\scipy\integrate\_ivp\base.py", line 21, in fun_wrapped
return np.asarray(fun(t, y), dtype=dtype)
TypeError: 'numpy.ndarray' object is not callable
更笼统地说,我怎样才能 python 求解 N 个节点而不手动定义每个节点?
我想要一个名为 xdot 的大向量,其中该向量中的每个单元格都是某些 X[i] 的函数,但我似乎无法做到这一点?或者也许我的方法是完全错误的?
我也觉得ivp_solve的"Vectorized"参数可能是可以连接的,但是我不明白SciPy文档中的解释。
问题可能是 solve_ivp
需要一个函数作为其第一个参数,而您提供的 ode_system(psi,t,delta_x,N)
结果是一个矩阵(因此您得到 type error - ndarray
)。
您需要提供 solve_ivp
一个接受两个变量的函数,t
和 y
(在您的例子中是 psi)。可以这样做:
def temp_function(t, psi):
return ode_system(psi,t,delta_x,N)
然后,你的最后一行应该是:
psi= solve_ivp(temp_function,[0,15],psi0,method='Radau',max_step=0.1)
这段代码解决了我的问题。
对于 shorthand 执行此操作的方法,您也可以使用 Lambda 编写内联函数:
psi= solve_ivp(lambda t,psi : ode_system(psi,t,delta_x,N),[0,15],psi0,method='Radau',max_step=0.1)
我正在尝试使用有限差分法求解一维时间相关的薛定谔方程,这是方程的外观以及它如何进行离散化
假设我有N个空间点(x_i从0到N-1),假设我的时间跨度是K个时间点。
我努力得到一个 K 乘 N 的矩阵。每行 (j) 将是时间 t_j
的函数我怀疑我的问题是我以错误的方式定义了耦合方程组。
我的边界条件是 psi=0,或者盒子两侧的某个常数,所以我将 X 跨度两侧的 ode 设置为零
我的代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
#Defining the length and the resolution of our x vector
length = 2*np.pi
delta_x = .01
# create a vector of X values, and the number of X values
def create_x_vector(length, delta_x):
x = np.arange(-length, length, delta_x)
N = len(x)
return x, N
# create initial condition vector
def create_initial_cond(x,x0,Gausswidth):
psi0 = np.exp((-(x-x0)**2)/Gausswidth)
return psi0
#create the system of ODEs
def ode_system(psi,t,delta_x,N):
psi_t = np.zeros(N)
psi_t[0]=0
psi_t[N-1]=0
for i in range(1,N-1):
psi_t[i] = (psi[i+1]-2*psi[i]+psi[i-1])/(delta_x)**2
return psi_t
#Create the actual time, x and initial condition vectors using the functions
t = np.linspace(0,15,5000)
x,N= create_x_vector(length,delta_x)
psi0 = create_initial_cond(x,0,1)
psi = np.zeros(N)
psi= solve_ivp(ode_system(psi,t,delta_x,N),[0,15],psi0,method='Radau',max_step=0.1)
在 运行 之后我得到一个错误:
runfile('D:/Studies/Project/Simulation Test/Test2.py', wdir='D:/Studies/Project/Simulation Test')
Traceback (most recent call last):
File "<ipython-input-16-bff0a1fd9937>", line 1, in <module>
runfile('D:/Studies/Project/Simulation Test/Test2.py', wdir='D:/Studies/Project/Simulation Test')
File "C:\Users\Pasha\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 704, in runfile
execfile(filename, namespace)
File "C:\Users\Pasha\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 108, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "D:/Studies/Project/Simulation Test/Test2.py", line 35, in <module>
psi= solve_ivp(ode_system(psi,t,delta_x,N),[0,15],psi0,method='Radau',max_step=0.1)
File "C:\Users\Pasha\Anaconda3\lib\site-packages\scipy\integrate\_ivp\ivp.py", line 454, in solve_ivp
solver = method(fun, t0, y0, tf, vectorized=vectorized, **options)
File "C:\Users\Pasha\Anaconda3\lib\site-packages\scipy\integrate\_ivp\radau.py", line 288, in __init__
self.f = self.fun(self.t, self.y)
File "C:\Users\Pasha\Anaconda3\lib\site-packages\scipy\integrate\_ivp\base.py", line 139, in fun
return self.fun_single(t, y)
File "C:\Users\Pasha\Anaconda3\lib\site-packages\scipy\integrate\_ivp\base.py", line 21, in fun_wrapped
return np.asarray(fun(t, y), dtype=dtype)
TypeError: 'numpy.ndarray' object is not callable
更笼统地说,我怎样才能 python 求解 N 个节点而不手动定义每个节点?
我想要一个名为 xdot 的大向量,其中该向量中的每个单元格都是某些 X[i] 的函数,但我似乎无法做到这一点?或者也许我的方法是完全错误的?
我也觉得ivp_solve的"Vectorized"参数可能是可以连接的,但是我不明白SciPy文档中的解释。
问题可能是 solve_ivp
需要一个函数作为其第一个参数,而您提供的 ode_system(psi,t,delta_x,N)
结果是一个矩阵(因此您得到 type error - ndarray
)。
您需要提供 solve_ivp
一个接受两个变量的函数,t
和 y
(在您的例子中是 psi)。可以这样做:
def temp_function(t, psi):
return ode_system(psi,t,delta_x,N)
然后,你的最后一行应该是:
psi= solve_ivp(temp_function,[0,15],psi0,method='Radau',max_step=0.1)
这段代码解决了我的问题。
对于 shorthand 执行此操作的方法,您也可以使用 Lambda 编写内联函数:
psi= solve_ivp(lambda t,psi : ode_system(psi,t,delta_x,N),[0,15],psi0,method='Radau',max_step=0.1)