Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1629|回复: 4

Python求解薛定谔方程

[复制链接]

399

主题

1251

帖子

4020

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4020
发表于 2023-6-22 17:48:02 来自手机 | 显示全部楼层 |阅读模式
以下是使用Python求解一维薛定谔方程的示例代码:

```pythonimport numpy as npfrom scipy.integrate import odeintimport matplotlib.pyplot as plt# 定义势能函数def potential(x):
return0.5*x**2# 定义薛定谔方程def schrodinger_eq(y, x):
psi, phi = y return [phi, (potential(x)-E)*psi]

# 定义能量范围和步长E_range = np.linspace(0,2,200)
dx =0.01# 循环求解薛定谔方程for E in E_range:
psi_init = [0,1] # 初始条件 x = np.arange(-7,7, dx) # 定义x的范围 sol = odeint(schrodinger_eq, psi_init, x) # 求解薛定谔方程 psi = sol[:,0] # 获取波函数 if psi[-1] <0: # 判断是否满足边界条件 # 绘制波函数图像 plt.plot(x, psi, label='E = {:.3f}'.format(E))

plt.xlabel('x')
plt.ylabel('Psi')
plt.legend()
plt.show()
```

这段代码会输出求解得到的波函数图像,其中势能函数为 $V(x)=0.5x^2$,能量范围为 $E \in [0,2]$,步长为 $dx=0.01$。在循环中,我们对每个能量值 $E$ 求解一次薛定谔方程,并判断最终的波函数是否满足边界条件。如果满足,就绘制波函数图像。最终的输出结果如下图所示:

![薛定谔方程解的波函数图像](https://i.imgur.com/L2f9GjT.png)

可以看到,我们求解得到了一系列不同能量值下的波函数,并且满足了边界条件。
回复

使用道具 举报

399

主题

1251

帖子

4020

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4020
 楼主| 发表于 2023-6-23 10:11:18 | 显示全部楼层
一维薛定谔方程可以表示为:

$$i\hbar\frac{\partial}{\partial t}\psi(x,t)=-\frac{\hbar^2}{2m}\frac{\partial^2}{\partial x^2}\psi(x,t)+V(x)\psi(x,t)$$
对照语句
  1. T = np.exp(-1j * hbar * k**2 * dt / (2 * m))
复制代码
$$f(t-t_0)\longleftrightarrow\mathrm e^{-j\omega_0:t_0}F(j\omega)$$
这个方程来源有4个
$E\psi = i\hbar \frac{\partial\psi}{\partial t}$  对波函数求时间导,出一个$-i E/\hbar$的系数
$p^2\psi = -\hbar^2 \frac{\partial^2 \psi}{\partial r^2}$ 对波函数求位置导,出一个$-i p/\hbar$的系数
再根据$E = \frac{P^2}{2m}$的结论,就可以推出
$i\hbar \frac{\partial\psi}{\partial t}  =  i\frac{\hbar^2}{2m} \frac{\partial^2 \psi}{\partial r^2}$

这个方程的意思是总能量=动能+势能
其中,$\hbar$为普朗克常数,$m$为粒子质量,$V(x)$为势能函数,$\psi(x,t)$为波函数。

为了求解这个方程,我们需要使用数值方法,如有限差分法或有限元法。以下是一个使用有限差分法求解的示例代码:

  1. import numpy as np

  2. # 定义常数
  3. hbar =1.0 # 普朗克常数
  4. m =1.0 # 粒子质量
  5. L =10.0 # 空间范围
  6. N =1000 # 离散点数
  7. dx = L / (N -1)# 离散步长
  8. dt =0.01 # 时间步长
  9. tmax =10.0 # 最大时间

  10. # 定义势能函数
  11. def V(x):
  12.     return 0.5 * m * x**2

  13. # 初始化波函数
  14. x = np.linspace(-L/2, L/2, N)
  15. psi = np.exp(-0.5 * (x/L)**2) * np.exp(1j *10 * x/L)
  16. psi0 = psi.copy()

  17. #有限差分法求解
  18. for t in np.arange(0, tmax, dt):
  19.     # 计算势能
  20.     Vx = V(x)
  21.     # 计算动能
  22.     k = np.fft.fftfreq(N, d=dx)
  23.     k2 = k**2
  24.     k2[0] =1.0 # 避免除0错误
  25.     T = np.exp(-1j * hbar * k2 * dt / (2 * m))
  26.     # 计算波函数
  27.     psi = np.fft.ifft(T * np.fft.fft(np.exp(-1j * Vx * dt / hbar) * psi))
  28.     psi *= np.exp(-1j * Vx * dt / hbar)
  29.     psi /= np.sqrt(np.sum(np.abs(psi)**2) * dx)#进行归一化
  30.     # 计算能量
  31.     E = np.sum(np.conj(psi) * (-0.5 * hbar**2/m * np.gradient(np.gradient(psi, dx), dx) + Vx * psi)) * dx
  32.     # 输出结果
  33.     print('t = %.2f, E = %.4f' % (t, E))
复制代码


这个代码使用了傅里叶变换将时间演化算子(动能部分)转化为频域上的乘法,从而可以使用快速傅里叶变换(FFT)来实现高效计算。
注释:时域的卷积=频域的乘积。时域信号可以分解成一串不同频率正弦信号的叠加。根据卷积的分配率,两个时域信号的卷积最终可以展开成两两正弦信号的卷积的和。由于不同频率的正弦信号的卷积为0,所以最终只剩下相同频率的正弦信号的卷积。而卷积的结果就是频率不变,幅度相乘。

在频域里边就表现为直接相乘。

每个时间步长中,先计算势能,然后计算动能并更新波函数,最后再根据归一化条件计算波函数的模长,以确保波函数的总概率为1。每个时间步长中,还计算能量并输出结果,以便我们可以观察波函数的演化情况。







回复

使用道具 举报

399

主题

1251

帖子

4020

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4020
 楼主| 发表于 2023-6-23 17:11:37 | 显示全部楼层
以下是基于有限差分时域方法(FDTD)求解薛定谔方程的Python代码:
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. # Parameters
  4. L =1.0 # Length of the region
  5. N =1000 # Number of spatial grid points
  6. dx = L/N # Spatial step size
  7. x = np.linspace(0, L, N) # Spatial grid
  8. T =10.0 # Total simulation time
  9. dt =0.001 # Time step size
  10. Nt = int(T/dt) # Number of time steps

  11. V = np.zeros(N) # Potential energy
  12. V[int(0.2*N):int(0.3*N)] =100.0
  13. # Square potential barrier


  14. # Initial wave function
  15. sigma =0.1
  16. k0 =20.0
  17. psi = np.exp(-0.5*((x-L/2)/sigma)**2) * np.exp(1j*k0*x)


  18. # Central difference coefficients
  19. c1 =1j*dt/(2*dx)
  20. c2 =1j*dt/dx**2
  21. # FDTD loop
  22. for n in range(Nt):
  23.     # Kinetic energy operator
  24.     psi_k = np.fft.fft(psi)
  25.     psi_k = psi_k * np.exp(-1j*np.pi*np.fft.fftfreq(N, dx)**2*dt/(2*L))
  26.     psi = np.fft.ifft(psi_k)

  27.     # Potential energy operator
  28.     psi = psi * np.exp(-1j*V*dt)

  29.     # Kinetic energy operator
  30.     psi_k = np.fft.fft(psi)
  31.     psi_k = psi_k * np.exp(-1j*np.pi*np.fft.fftfreq(N, dx)**2*dt/(2*L))
  32.     psi = np.fft.ifft(psi_k)

  33.     # Normalize wave function
  34.     psi = psi / np.sqrt(np.sum(np.abs(psi)**2)*dx)

  35.     # Plot wave function
  36.     if n %100 ==0:
  37.         plt.plot(x, np.abs(psi)**2, 'b')
  38.         plt.plot(x, V, 'r')
  39.         plt.ylim([0,50])
  40.         plt.xlabel('Position')
  41.         plt.ylabel('Probability density')
  42.         plt.title('Time = %.2f' % (n*dt))
  43.         plt.show()
复制代码


该代码使用了numpy和matplotlib库。运行时,它会生成一个动态的图形,显示波函数的演化随着时间的推移。在每个时间步骤中,该代码实现了以下操作:

1.用快速傅里叶变换计算动能算符的作用(由于薛定谔方程中的动能算符是二阶微分算符,因此可以通过傅里叶变换来计算其作用)。
2.用势能算符的作用更新波函数。
3. 再次用快速傅里叶变换计算动能算符的作用。
4. 归一化波函数,以确保其满足概率守恒条件。
5. 绘制波函数和势能障壁。

该代码的主要思想是将波函数表示为一个离散的向量,并在每个时间步骤中更新它。快速傅里叶变换用于计算动能算符的作用,而势能算符的作用则直接应用。归一化波函数确保其满足概率守恒条件。
回复

使用道具 举报

399

主题

1251

帖子

4020

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4020
 楼主| 发表于 2023-6-23 21:45:23 | 显示全部楼层
回复

使用道具 举报

399

主题

1251

帖子

4020

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4020
 楼主| 发表于 2023-6-24 00:02:59 | 显示全部楼层
薛定谔方程变形,虚部实部分开
$$\frac{\partial\psi_{I}(x,t)}{\partial t}=\frac{\hbar}{2m}\frac{\partial^{2}\psi_{R}(x,t)}{\partial x^{2}}-\frac{1}{\hbar}V(x)\psi_{R}(x,t) $$

$$\frac{\partial\psi_{R}(x,t)}{\partial t}=\frac{\hbar}{2m}\frac{\partial^{2}\psi_{I}(x,t)}{\partial x^{2}}+\frac{1}{\hbar}V(x)\psi_{I}(x,t)$$
可以得到如下关系
$$\frac{\partial\psi_\varepsilon(x,t)}{\partial t}\bigg|_{t=(n+1/2)\Delta t}=\frac{\psi_\varepsilon(x,(n+1)\cdot\Delta t)-\psi_\varepsilon(x,n\Delta t)}{\Delta t} ,\xi=R\textit{ or }I$$

$$\frac{\partial^2\psi_\xi(x,t)}{\partial x^2}\Bigg|_{\begin{aligned}x\to k\Delta x\\ t=n\Delta x\end{aligned}}=\frac{1}{\left(\Delta x\right)^2}\left[\psi_\xi\left(\Delta x\cdot(k+1\right),n\Delta t\right) -2\psi_\xi\left(\Delta x\cdot k,n\Delta t\right) +\psi_\xi\left(\Delta x\cdot(k-1),n\Delta t \right) ]$$

引入如下表示符号$\psi(k\Delta x,n\Delta t)\Leftrightarrow\psi^n(k)$,则

$$\psi_R^{n+1}(k) =\psi_{R}^{n}(k)-\frac{\hbar}{2m}\frac{\Delta t}{(\Delta x)^{2}} [\psi_i^{n+1/2}(k+1)-2\psi_j^{n+1/2}(k) +\psi_I^{n+1/2}(k-1)] +\frac{\Delta t}{\hbar}V(k)\psi_{I}^{n+1/2}(k)$$

$$\psi_I^{n+1}(k) =\psi_{I}^{n}(k)+\frac{\hbar}{2m}\frac{\Delta t}{\left(\Delta x\right)^{2}}  [\psi_R^{n+1/2}(k+1)-2\psi_R^{n+1/2}(k) +\psi_R^{n+1/2}(k-1)] -\frac{\Delta t}{\hbar}V(k)\psi_R^{n+1/2}(k)$$

可以看出,由n和n+1/2时刻的周围点,就可以推出当前点的值
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|DiscuzX

GMT+8, 2025-6-8 11:50 , Processed in 0.037975 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表