用diag直接使用错误_用python学量子力学(1)
华中师范大学 hahakity
在网上看到一个使用 Matlab 教量子力学的文章,很有意思。这里用 python 语言实现一遍, 让同学们对量子力学,对偏微分方程的差分近似解法有一个更直观的理解。
学习目标:
- 理解量子力学的波函数表示与矩阵表示的等价性
- 学会用向量表示函数,用矩阵表示算符(一阶微分,二阶微分)
- 学会数值求解任意势阱下定态薛定谔方程的能级与波函数
预备知识:
- 微分的差分近似
- 量子力学基础(薛定谔方程)
波函数的向量表示
在用 python 画图时,我们一般先将区间离散化,计算出离散坐标上的函数值,然后画折线图。比如对于函数
# np.linspace 将区间 [-2, 2] 离散化为 100 个坐标点
x = np.linspace(-2, 2, 100)
# 计算 100 个坐标点上的函数值 f
f = np.sin(x) / x
plt.plot(x, f)
将波函数表示为离散坐标点上的实数或复数,写为列向量
回忆微分的有限差分近似,对于一阶微分,
对于二阶微分,
对区间 [a, b] 所有离散坐标上的 f(x) 微分和二阶微分可以矩阵化,
算符的矩阵表示
当 f(x) 用列向量
因此波动力学与矩阵力学统一。
一阶微分
二阶微分
对于随便给定的函数
解定态薛定谔方程
注意在量子力学里,动能项里的动量 p 换成了微分算符,进一步用 Laplacian 矩阵表示,势能 U(x) 在区间离散化后,填充在矩阵的对角元上。
如果是多粒子系统,比如考虑多个电子两两之间的库伦相互作用,则两粒子势能
定态薛定谔方程的数值解
这里我用 python 把一维定态薛定谔方程的数值解封装成一个类,后面研究不同势能下的薛定谔方程比较方便。
class Schrodinger:def __init__(self, potential_func, mass = 1, hbar=1,xmin=-5, xmax=5, ninterval=1000):self.x = np.linspace(xmin, xmax, ninterval) self.U = np.diag(potential_func(self.x), 0) self.Lap = self.laplacian(ninterval) self.H = - hbar**2 / (2*mass) * self.Lap + self.U self.eigE, self.eigV = self.eig_solve()def laplacian(self, N):'''构造二阶微分算子:Laplacian'''dx = self.x[1] - self.x[0]return (-2 * np.diag(np.ones((N), np.float32), 0)+ np.diag(np.ones((N-1), np.float32), 1)+ np.diag(np.ones((N-1), np.float32), -1))/(dx**2)def eig_solve(self):'''解哈密顿矩阵的本征值,本征向量;并对本征向量排序'''w, v = np.linalg.eig(self.H) idx_sorted = np.argsort(w) return w[idx_sorted], v[:, idx_sorted]def wave_func(self, n=0):return self.eigV[:, n]def eigen_value(self, n=0):return self.eigE[n]def check_eigen(self, n=7):'''check wheter H|psi> = E |psi> '''with plt.style.context(['science', 'ieee']):HPsi = np.dot(self.H, self.eigV[:, n])EPsi = self.eigE[n] * self.eigV[:, n]plt.plot(self.x, HPsi, label=r'$H|psi_{%s} rangle$'%n)plt.plot(self.x, EPsi, '-.', label=r'$E |psi_{%s} rangle$'%n)plt.legend(loc='upper center')plt.xlabel(r'$x$')plt.ylim(EPsi.min(), EPsi.max() * 1.6)def plot_density(self, n=7):with plt.style.context(['science', 'ieee']):rho = self.eigV[:, n] * self.eigV[:, n]plt.plot(self.x, rho)plt.title(r'$E_{%s}=%.2f$'%(n, self.eigE[n]))plt.ylabel(r'$rho_{%s}(x)=psi_{%s}^*(x)psi_{%s}(x)$'%(n, n, n))plt.xlabel(r'$x$')def plot_potential(self):with plt.style.context(['science', 'ieee']):plt.plot(self.x, np.diag(self.U))plt.ylabel(r'potential')plt.xlabel(r'$x$')
谐振子势
# 定义谐振子势
def harmonic_potential(x, k=100):return 0.5 * k * x**2# 创建谐振子势下的薛定谔方程
schro_harmonic = Schrodinger(harmonic_potential)
从上面例子可以看到,封装的比较完整,对任意 1 维势调用很简单。先来可视化谐振子势能,
schro_harmonic.plot_potential()
schro_harmonic.check_eigen(n=1)
再用上面这条命令检查一下薛定谔方程的解是否准确,具体来说就是本征方程
还可以看看粒子在谐振子势阱中的分布概率密度,
# 这里随便选了一个能级 n = 9
schro_harmonic.plot_density(n=9)
如果亲自尝试一下,你会发现在上面这个谐振子势下,数值解的能级与解析解非常接近
对比解析解,
其中
解析解中,n=0 时,
Woods Saxon 势能
在核物理领域,原子核中一大团核子所产生的势能接近于 Woods Saxon 函数形式。这里看看Woods Saxon 势阱中一个核子的能级分布。势阱函数形式为,
def woods_saxon_potential(x, R0=6.2, surface_thickness=0.5):sigma = surface_thicknessreturn -1 / (1 + np.exp((np.abs(x) - R0)/sigma))
用这个势阱构造薛定谔方程,
ws_schro = Schrodinger(woods_saxon_potential)
先画一下势阱的样子,
ws_schro.plot_potential()
再画一下 Woods Saxon 势阱中核子的波函数和能级,
对于基态 n=0
ws_schro.plot_density(n=0)
第 n=9 激发态
与谐振子势阱的结果有相当大差别。
双势阱
def double_well(x, xmax=5, N=100):w = xmax / Na = 3 * wreturn -100 * (np.heaviside(x + w - a, 0.5) - np.heaviside(x - w - a, 0.5)+np.heaviside(x + w + a, 0.5) - np.heaviside(x - w + a, 0.5))dw = lambda x: double_well(x, xmax=5, N=1000)
dw_shro = Schrodinger(double_well)
双势阱中前几个能级下粒子的概率密度分布,
dw_shro.plot_density(n=0)
dw_shro.plot_density(n=1)
dw_shro.plot_density(n=2)
dw_shro.plot_density(n=4)
双势阱中粒子概率密度分布的随时间演化
下面这个问题考虑一个粒子被捕获在上例所示的有限深方势阱中,初态为基态与第一激发态的叠加态,观察粒子的概率密度分布随时间的演化。初态为,
这里画图看一下基态
psi0 = dw_shro.wave_func(n=0)
psi1 = dw_shro.wave_func(n=1)
psi = 1 / np.sqrt(2) * (psi0 + psi1)with plt.style.context(['science', 'ieee']):plt.plot(dw_shro.x, psi0, 'r--', label=r'$|Psi_{E_0} rangle$')plt.plot(dw_shro.x, psi1, 'b:', label=r'$|Psi_{E_1} rangle$')plt.plot(dw_shro.x, psi, 'k-', label=r'$|Psi(t=0)rangle = (|Psi_{E_0}rangle + |Psi_{E_1}rangle) / sqrt{2}$')plt.legend(loc='best')plt.xlabel(r'$x$')plt.ylim(-0.3, 0.3)plt.xlim(-2, 2)
如下图所示,初始时刻基态与第一激发态在右边势阱处相消,导致叠加态的波函数在左边势阱处有峰值结构。后面演示此峰如何随时间在两个势阱间振荡。
叠加态波函数的时间演化直接用时间演化算符,
def psit(t, hbar=1):'''基态与第一激发态的叠加态波函数,随时演化'''psi0 = dw_shro.wave_func(n=0)psi1 = dw_shro.wave_func(n=1)E0 = dw_shro.eigen_value(0)E1 = dw_shro.eigen_value(1)return 1/np.sqrt(2) * (psi0 * np.exp(-1j * E0 * t/hbar)+ psi1 * np.exp(-1j * E1 * t/hbar))
注意我们用 Dirac
当
下面是概率密度在两个势阱间震荡间振荡的动画,
知乎视频www.zhihu.com
# 动画代码
%matplotlib notebook
from matplotlib.animation import FuncAnimation
class UpdateDist:def __init__(self, ax, x):self.success = 0self.line, = ax.plot([], [], 'k-')self.x = xself.ax = ax# Set up plot parametersself.ax.set_xlim(-0.6, 0.6)self.ax.set_ylim(-0.02, 0.1)self.ax.grid(True)def __call__(self, i):time = i * 0.01psi = psit(t = time)density = np.real(np.conjugate(psi) * psi) self.line.set_data(self.x, density)return self.line,# 画缩放了的双势阱
potential = double_well(dw_shro.x) * 1.0E-4
fig, ax = plt.subplots()
ax.plot(dw_shro.x, potential, ':')
ax.set_xlabel(r'$x$')
ud = UpdateDist(ax, x=dw_shro.x)
anim = FuncAnimation(fig, ud, frames=1000, interval=100, blit=True)
#anim.save('../htmls/images/double_well_evolution.mp4')
plt.show()
总结:
使用微分的有限差分近似可以将波函数表示为向量,将微分算子化为矩阵,将定态薛定谔方程的求解化为哈密顿矩阵的本征值,本征向量求解问题。实现了 python 版本的一维薛定谔方程数值解的封装,方便对自定义的势阱计算能级与波函数。
参考文献:
【1】https://arxiv.org/pdf/0704.1622.pdf
【2】Teaching Quantum Mechanics with MATLAB
注:画图用到了 matplotlib 库,要得到本文画图风格,需要安装 SciencePlots 库。
pip install SciencePlots
如果出错,开启 no-latex 选项。
with plt.style.context(["science", "ieee", "no-latex"]):
用diag直接使用错误_用python学量子力学(1)相关推荐
- python求解薛定谔方程_用python学量子力学(1)
华中师范大学 hahakity 在网上看到一个使用 Matlab 教量子力学的文章,很有意思.这里用 python 语言实现一遍, 让同学们对量子力学,对偏微分方程的差分近似解法有一个更直观的理解. ...
- python @符号_用Python学数学之Sympy代数符号运算
在我们初.高中和大学近10年的学习时间里,数学一直占据着非常大的分量,但是回忆过去可以发现,我们把大量的时间都花在反复解题.不断运算上,计算方法.运算技巧.笔算能力以及数学公式的记忆仿佛成了我们学习数 ...
- python数学符号代码_用Python学数学之Sympy代数符
在我们初.高中和大学近10年的学习时间里,数学一直占据着非常大的分量,但是回忆过去可以发现,我们把大量的时间都花在反复解题.不断运算上,计算方法.运算技巧.笔算能力以及数学公式的记忆仿佛成了我们学习数 ...
- python 微积分 函数_用Python学微积分(2)---复合函数
函数的复合(Composition) 定义:设函数y=f(u)和u=g(x)u=g(x),则函数y=f[g(x)]称为由y=f(u)和u=g(x)复合而成的复合函数,其中函数y=f(u)常常称为外函数 ...
- python符号计算_用Python学数学之Sympy代数符号运算
在我们初.高中和大学近10年的学习时间里,数学一直占据着非常大的分量,但是回忆过去可以发现,我们把大量的时间都花在反复解题.不断运算上,计算方法.运算技巧.笔算能力以及数学公式的记忆仿佛成了我们学习数 ...
- python用泰勒级数计算圆周率_用Python学微积分(4)---泰勒级数
泰勒级数(Taylor Sries) 现在是时候说明指数函数和三角函数那些奇妙的多项式形式了. 这些多项式实际为这些函数在x=0处展开的泰勒级数. 下面我先不加预告地列出函数f(x)在x=0处展开地泰 ...
- python自动翻译导学案_变量python学案
●掌握常用的关系和逻辑运算符 ●掌握 Python 中的变量及其赋值 ●数字化学习与...●学生任务二: 阅读学案,计算一下表达式的值,把结果填在学习网站上. 练习算术...... 初中八年级信息技术 ...
- 用python学编程_用Python学编程
第1部分 引 论 第1章 关于本书 1.1 什么人要学编程 1.2 本书的内容 1.3 为什么选择Python 1.4 如何阅读本书 1.5 本书内容的组织 第2章 学习编程的要求 2.1 关于编程者 ...
- python人工智能决策系统_用Python学人工智能
spContent=本课程是教育部-百度产学合作协同育人项目成果,课程将介绍智能计算机系统设计的基本思想和技术,具体重点将放在使用Python语言实现上述的智能系统.课程中学习的技术适用于各类人工智能 ...
最新文章
- Java集合篇:fail-fast机制 与 fail-safe
- 设计模式:迭代器模式(Iterator)
- wxpython界面切换_Python图形界面开发—wxPython库的布局管理及页面切换
- One Shot Learning with Siamese Networks
- GCC弱符号的一个应用示例
- xp 系统不能够通过网络访问解决方法
- Windows 必备纯净软件
- PPT幻灯片放映计时器
- 软件测试常见面试题合集(内附详细答案)
- HTML、js实现图片绕中心旋转
- RocketMq之一条消息在commitlog文件中如何存储验证
- 有 4 件事,我很后悔
- 【第1期】腾讯云的1001种玩法征集,Ipad mini和Kindle 等你拿!(文章评审中)
- 20050714日记
- MEC — 边缘网络
- 《把时间当作朋友》读书笔记
- Java 17 新特性
- 路帮网的加油站开放接口
- 第二证券|家用储能设备出口暴增,储能概念发力走高,派能科技等大涨
- Layui时间插件laydate只选择时分
热门文章
- SAP UI5 Routing 路由介绍
- RxJS CombineLatest operator 的一个具体使用例子
- SAP Spartacus B2B List里的listData$设计原理
- TypeScript的类型断言,有点像ABAP的强制类型转换
- 将S/4HANA的自定义BO功能以Web Service的方式暴露给第三方
- why I need register Apache CXF as servlet
- SAP CRM中间件下载时数据库表CRMATAB为空的处理方法
- myNote app debug - page render
- SAP UI5 Fiori flower动画效果的实现明细
- Leo的AR代码学习之create-react-class