均匀格点与对数格点上的Numerov方法

摘要

本文在两种数值格点(均匀格点和对数格点)上推导了Numerov方法的递推方程, 给出了简单的Python实现.

背景

Numerov方法是数值求解常微分方程(ODE)的一种方法, 适用于不含一阶项的二阶ODE

$$begin{equation}
y’’ + f(r)y = s(r).
end{equation}label{eq:numerov-ode}
$$

在物理上有很多方程满足这种形式, 其中与我最为相关的是薛定谔方程(SE), 更确切的是三维有心势下的径向薛定谔方程(rSE). 原子单位下, rSE写成

$$
left[-frac{d^2}{d r^2} + frac{l(l+1)}{r^2} + 2V(r)right]R_l(r) = E_lR_l(r)
$$

其中$R_l$是定义在一维实空间$r$上的波函数$u_l$与矢径长$r$的积, $R_l(r)=ru_l(r)$, $E_l$是能量, $l$是角量子数. 这个方程满足Numerov方程要求的ODE形式

$$
begin{cases}
f(r) = -frac{l(l+1)}{r^2} - 2V(r) + E_l \
s(r) = 0
end{cases}
$$

因此可以用该方法数值求解. 本文首先在两种格点方案, 均匀格点和对数格点上推导Numerov方法的核心方程, 即格点递推公式, 然后给出简单的Python实现.

推导

均匀格点

首先在均匀格点上推导一下Numerov方法. 在$r$点附近对函数$y$作Taylor展开

$$
begin{equation}label{eq:deriv-1}
y(rpm h) = y(r) pm hy’(r) + frac{h^2}{2}y’’(r) pm frac{h^3}{6}y’’’(r) + frac{h^4}{24}y’’’’(r) + cdots
end{equation}
$$

将正负两式相加

$$
begin{equation}label{eq:deriv-2}
y(r-h)+y(r+h) = 2y(r) + h^2y’’(r) + frac{h^4}{12}y’’’’(r) + mathcal{O}(h^6)
end{equation}
$$

由于

$$
y’’’’(r) = frac{d^2}{d r^2}left[f(r)y(r)-s(r)right],
$$

定义$p(r):=f(r)y(r)-s(r), p=y’’, p’’=y’’’’$, 可以采用与式$eqref{eq:deriv-1}eqref{eq:deriv-2}$类似的办法处理$p$, 得到

$$
begin{equation}label{eq:deriv-3}
p(r-h)+p(r+h) = 2p(r) + h^2 p’’(r) + frac{h^4}{12}p’’’’(r) + mathcal{O}(h^6).
end{equation}
$$

把$p, p’’$表达式$eqref{eq:deriv-3}$回代到式$eqref{eq:deriv-2}$中,

$$
y(r-h)+y(r+h) = 2y(r) + h^2p(r) + frac{h^4}{12}left[p(r-h)+p(r+h)-2p(r)right] + mathcal{O}(h^6).
$$

稍作整理, 得到

$$
begin{aligned}
left[1+frac{h^2}{12}f(r-h)right]y(r-h) +& left[1+frac{h^2}{12}f(r+h)right]y(r+h) = \
&2left[1+frac{h^2}{12}f(r)right]y(r) - h^2f(r)y(r) + frac{h^2}{12}left[s(r-h)+10s(r)+s(r+h)right] + mathcal{O}(h^6).
end{aligned}
$$

这就是Numerov方法的一般方程. 特别的, 对于齐次方程, $s=0$, 式子可以化简成

$$
left[1+frac{h^2}{12}f(r+h)right]y(r+h) = 2left[1+frac{h^2}{12}f(r)right]y(r) - left[1+frac{h^2}{12}f(r-h)right]y(r-h) - h^2f(r)y(r) + mathcal{O}(h^6).
$$

取间距为$h$的均匀格点, 此时上式化成三点递推方程,

$$
(1+frac{h^2}{12}f_{n+1})y_{n+1} = 2(1+frac{h^2}{12}f_n)y_n - (1+frac{h^2}{12}f_{n-1})y_{n-1} - h^2f_n y_n
$$

精确到步长的六次方. 实际应用当中, 我们需要先确定前两个格点上的值, 然后就可以用上式推出第三点及之后所有格点上的函数值.

对数格点

除了实空间均匀格点, 我们也可以使用对数均匀格点(logarithmic grid), 其上第n个实空间格点为

$$
r_n = r_0 e^{nh}
$$

上面的Numerov方法不能直接用于格点${r_n}$, 因为这种情况下格点$r$间距是变化的, 但是我们可以通过代数变换使之成为可能. 首先定义变量替换$xmapsto r$

$$
r(x) = r_0e^x
$$

及定义$Y(x)$为

$$begin{equation}
y(r) = r_0e^{x/2}Y(x).
end{equation}label{eq:log-trans-y}$$

从而

$$
begin{aligned}
frac{d^2}{d r^2}y(r) &= frac{1}{r_0e^x}frac{d}{dx}left[frac{1}{e^x}frac{d}{d x}left(e^{x/2}Y(x)right)right] \
&=frac{1}{r_0e^x}left[-frac{1}{4}e^{-x/2}Y(x) + e^{-x/2}Y’’(x)right] \
end{aligned}
$$

其中撇号代表对$x$求导而非$r$. 代回到式$eqref{eq:numerov-ode}$的ODE中

$$
begin{aligned}
frac{1}{r_0}e^{-3x/2}left[-frac{1}{4}Y(x) + Y’’(x)right] + f(r)r_0e^{x/2}Y(x) &= s(r)\
Y’’ + left[f(r)r^2_0e^{2x}-frac{1}{4}right]Y(x) &= r_0e^{3x/2}s(r).
end{aligned}
$$

$$begin{equation}
begin{aligned}
F(x):=&f(r)r^2_0e^{2x}-frac{1}{4}= f(r(x))r(x)^2-frac{1}{4} \
S(x):=&r_0e^{3x/2}s(r) = sqrt{frac{r(x)^3}{r_0}}s(r(x))
end{aligned}
end{equation}label{eq:log-trans-f-s}$$

于是得到ODE

$$
Y’’(x) + F(x)Y(x) = S(x)
$$

这与原始ODE$eqref{eq:numerov-ode}$相似, 但它定义在变量$x$上而非实空间$r$上. 由于格点$x$是均匀的, 我们可以应用前面均匀格点的算法解出$Y(x)$, 然后再通过式$eqref{eq:log-trans-y}$变换回$y(r)$.

Python实现

以下是忽略了s后, Numerov方法在均匀格点和对数格点上的Python实现. Numba装饰器用于编译优化.

首先是均匀格点上的实现numerov, 参考了Kristjan Haule的代码.

1234567891011121314151617181920212223242526
def (f, h, y0, dy0):    '''Solve y''(r) + f(r)y(r)=0 by Numerov method on a linear r grid

    Args:        f (1d-array): f        h (float): the step size of linear grid        y0 (float): y value at the first grid point        dy0 (float): first-order derivaitve at the first grid point    '''    y = np.zeros(len(f))    y[0] = y0    y[1] = y0 + h * dy0    h2 = h**2    h2d12 = h2/12.0    w0 = y0 * (1 + h2d12 * f[0])    w1 = y[1] * (1 + h2d12 * f[1])    yn = y[1]    fn = f[1]    for n in range(2, len(f)):        w2 = 2 * w1 - w0 - h2 * fn * yn        fn = f[n]        yn = w2 / (1 + h2d12 * fn)        y[n] = yn        w0, w1 = w1, w2    return y

然后是对数格点上的实现numerov_log:

12345678910111213141516171819202122
def numerov_log(r, f, y0, dy0):    '''Solve y''(r) + f(r)y(r) = 0 by Numerov method on an exponential r grid

    Args:        r (1d-array): the logarithmic grid        f (1d-array)        y0 (float): y at the first grid        dy0 (float): first-order derivaitve at the first grid    '''    r0 = r[0]

    F = np.multiply(f, np.power(r, 2)) - 0.25E0    x = np.log(r/r0)    # step size in x    hx = x[1] - x[0]    # convert boundary condition of y to Y    Y0 = y0 / r0    dY0 = - Y0/2 + dy0 * r0    # call Numerov on linear grid x    Y = numerov(F, hx, Y0, dY0)    return Y * np.sqrt(r * r0)

原文:大专栏  均匀格点与对数格点上的Numerov方法

原文地址:https://www.cnblogs.com/petewell/p/11584796.html

时间: 2024-10-10 10:25:12

均匀格点与对数格点上的Numerov方法的相关文章

MFC List Control控件添加单元格编辑和单元格下拉列表项以适用于数据库相关操作

作为现代的软件,往往是连着数据库的,而连着和用户方便地操作之间,还有着界面这道坎.MFC是Windows上比较好开发用户界面的框架,然而其自带的控件中没有对于数据库表格支持较好的控件,而使用网上提到的 DataGrid 等控件在本人的win8.1+VS2013平台上老出现找不到控件或者头文件的问题,搞的烦死人.最后想到 List Control 控件只要稍作修改,加上单元格编辑和单元格下拉列表,其实就能和数据库进行良好的对接,一百度,果然有人已经做了这件事,实在是太让人感动了!       

DevGridControl单元格背景色和单元格文字颜色设置

1.拖一个gridControl控件在 窗体上 2.添加三列 分别是 BgColor,BgColor2 , FontColor  分别显示单元格颜色 单元格渐变颜色 单元格字体颜色 public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { List<object> list = new Li

请教 JTable 里的单元格如何使得双击进入单元格后,单元格的内容处于全选中状态

http://bbs.csdn.net/topics/390195204 ———————————————————————————————————————— java 达人, 最近在开发一个 java 模块,用到了 JTable.现在对 JTable 里的单元格的操作中,在双击进入单元格后,单元格的内容不是全选中状态. 请问有啥办法使得双击进入单元格后,单元格的内容处于全选中状态?如下面的图片所示 十分感谢! 下面是已经写好的代码: Java code? 1 2 3 4 5 6 7 8 9 10

ASP.NET 4.0尚未在 Web 服务器上注册 解决方法

ASP.NET 4.0尚未在 Web 服务器上注册 解决方法 使用VS2010创建web应用程序时出现如下提示ASP.NET 4.0尚未在 Web 服务器上注册.为了使网站正确运行,可能需要手动将 Web 服务器配置为使用 ASP.NET 4.0,按 F1 可了解更多详细信息 解决方法: 首先设置IIS应用程序池 net framework版本为4.0 然后  开始->所有程序->附件->鼠标右键点击“命令提示符”->以管理员身份运行->%windir%\Microsoft.

iOS 网络请求 NSURLSession 的上传文件方法

NSURLSession/NSURLConnection的上传文件方法 此篇文章的理论基础主要是与HTTP网络通信协议相关.为集中精力,可以先把TCP/IP协议这些置之不理,也就是先只关注HTTP的请求和响应的结构.HTTP完整的原理内容就此略过.在此只略提相关内容.文中涉及的设计源码可以通过这里获取 https://github.com/wuqingjian2015/uploadHelper,有意者可以去看看. HTTP是干什么用的呢? 先考虑一下以下应用过程: 从客户端向服务器端发起一个请求

IE8升级新版Flash Player ActiveX14导致的discuz图片附件无法上传 解决方法

之前发的这篇文章被编辑之后丢失了,无奈从百度快照找来重新发布,不知道csdn抽啥风 架不住sb adobe的频繁升级提示,手欠升级到了了flash player 14,结果IE8下所有discuz论坛中都无法看到上传图片的按钮了 没办法,遇到问题就解决吧 刚好在解决IE11遇到编辑器不显示问题的时候看到discuz编辑器文件上传有非flash解决方案 所以这个问题看上去就不难了,把普通上传给打开就行了 编辑discuz文件/template/default/forum/editor_menu_f

Effective JavaScript Item 51 在类数组对象上重用数组方法

Array.prototype对象上的标准方法被设计为也可以在其它对象上重用 - 即使不是继承自Array的对象.因此,在JavaScript中存折一些类数组对象(Array-like Objects). 一个典型的例子是函数的arguments对象,在Item 22中对它进行过介绍.该对象并不继承自Array.prototype,所以我们不能直接调用arguments.forEach来对其中的元素进行遍历.但是,我们可以通过首先得到forEach方法的对象,然后调用call方法(可以参考Ite

unity3d游戏无法部署到windows phone8手机上的解决方法

今天搞了个unity3d游戏,准备部署到自己的lumia 920上,数据线连接正常,操作正常,但是"build"以后,始终无法部署到手机上,也没有在选择的目录下生产任何相关文件. 但是提示有一个错误: Error building Player: Exception: Error: method `System.Byte[] System.IO.File::ReadAllBytes(System.String)` doesn't exist in target framework. I

微信小程序实现多张图片同时上传的方法

对于微信小程序上传图片其实很麻烦的,每次只能上传一张,所有很多朋友就会问想要多张图片上传怎么办?这里使用递归,当上传完一张图片后重新执行这个函数,直到所有的图片都上传完成后,就不再调用该函数了.具体的实现方法来为大家分享一下.示例代码如下: wx.chooseImage({success: function(res) {var tempFilePaths = res.tempFilePathswx.uploadFile({url: 'http://example.weixin.qq.com/up