我对Python比较陌生,试图用它来解决二阶非线性微分方程,特别是电解质中的Poisson-Boltzmann方程。
phi''(r) + (2/r)*phi'(r) = (k^2)*sinh(phi(r))
基本上它描述了静电势(phi)远离电解质中带电表面的衰变,其衰减速率由参数k控制。
和边界条件
代码的问题如下
from scipy.integrate import odeint
from scipy.optimize import root
from pylab import * # for plotting commands
k = 0.5
phi = 5
dphi = -10
R = 21
def deriv(z,r): # return derivatives of the array z (where z = [phi, phi'])
return np.array([
(z[1]),
((k**2)*sinh(z[0]))-((2/r)*z[1])
])
result = odeint(deriv,np.array([phi,dphi]),np.linspace(1,R,1017), full_output = 1)
通常对于低k值,积分工作正常,我可以使用scipy.optimize中的root来解决它受边界条件限制,但是当我尝试使用相对较大的k值(0.5和更高)时,积分运行陷入问题并输出以下错误
Excess work done on this call (perhaps wrong Dfun type).
在使用full_output = 1运行它并查看tcur
参数时,它似乎可以顺利计算到某个点,然后从非常大的值大幅振荡到非常小的值。在同一点nfe
,函数评估的数量降至零。正确工作时,tcur参数从1到R顺利运行。任何人都可以告诉我为什么会发生这种情况?这是我的实施问题还是方程中存在不稳定性?
提前感谢您的帮助,
戴夫
答案 0 :(得分:0)
ODE可能不稳定。相关方程式
phi''(r) = (k^2)*sinh(phi(r))
有k=1
的解决方案(对于r = 1时的相应初始条件):
phi(r) = 2 arctanh(sin(r))
该解决方案在r=pi/2
处具有奇点。数值ODE求解器将无法将该等式积分超出此点。有一个类似的等式与一阶导数项(无论如何应该可以忽略不计,接近于奇点)的行为似乎是相似的。
你遇到的实际问题是使用ODE求解器的射击方法不是解决边界值问题的好方法 - 你应该使用相当稳定的搭配方法。参见例如http://www.scholarpedia.org/article/Boundary_value_problem及其中的参考资料。
对于Python软件,请参阅https://pypi.python.org/pypi?%3Aaction=search&term=boundary+value+problem&submit=search
自己编写这样的求解器通常也很容易,因为唯一需要的步骤是将问题离散化为一组(很多)方程,之后root
可以解决它们。