Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用scipy solve_bvp求解一个边值问题(扩散反应方程)_Python_Scipy_Numerical Methods_Differential Equations - Fatal编程技术网

Python 用scipy solve_bvp求解一个边值问题(扩散反应方程)

Python 用scipy solve_bvp求解一个边值问题(扩散反应方程),python,scipy,numerical-methods,differential-equations,Python,Scipy,Numerical Methods,Differential Equations,我正在努力解决以下二阶边值问题: y'' + 2/x*y' + k**2.0*F(y) = 0 y(x=1)=1, y'(x=0)=0 F(y) = -y or F(y) = -y*exp(AB*(1-y)/(1+B(1-y)) 不知何故,我未能正确设置边界条件。我通过以下方式定义了F(y)=y的函数和边界条件: def fun(x, y, p): k = p[0] return np.vstack((y[1], -2.0/x*y[1] + k**2.0*y[0])) def bc

我正在努力解决以下二阶边值问题:

y'' + 2/x*y' + k**2.0*F(y) = 0

y(x=1)=1,  y'(x=0)=0

F(y) = -y or F(y) = -y*exp(AB*(1-y)/(1+B(1-y))
不知何故,我未能正确设置边界条件。我通过以下方式定义了
F(y)=y的函数和边界条件:

def fun(x, y, p):
 k = p[0]
 return np.vstack((y[1], -2.0/x*y[1] + k**2.0*y[0]))

def bc(ya, yb, p):
     return np.array([ya[0], yb[0],ya[1]])

y[0,:] = 1
y[1,0] = 0
sol = solve_bvp(fun, bc, x, y, p=[40])
我应该得到的结果肯定是错误的,改变初始条件并不能使事情变得更好。我想我的问题是与x=0时的零梯度边界条件有什么关系。有人知道我做错了什么吗

编辑: 这里是MWE,当k=0.01时,该值应为常数1。但对于k=5,x=0时的值应约为0.06:

def fun(x, y, p):
     k = p[0]
     return np.vstack((y[1], -2.0/x*y[1] + k**2.0*y[0]))

def bc(ya, yb, p):
     return np.array([ya[0], yb[0]-1.0,yb[1]])

x = np.linspace(1e-3, 1, 100)
y = np.zeros((2, x.size))
y[0,:] = 1

from scipy.integrate import solve_bvp
sol = solve_bvp(fun, bc, x, y, p=[1000])
x_plot = np.linspace(0, 1, 100)
y_plot = sol.sol(x_plot)[0]
plt.figure()
plt.plot(x_plot, y_plot)
考虑这种情况
F(y)=y
。很容易看出,这种线性常微分方程的基本解是sin(k*x)/x和cos(kx/x)
。类似地,对于
F(y)=-y
我们得到
sinh(k*x)/x
cosh(k*x)/x
。这意味着大多数解在
x=0时具有奇点。对于标准ODE解算器来说,这种奇点几乎不可能立即处理。我们必须在奇点处帮助解算器,正常程序在离奇点一定距离处再次应用

你能做的就是在
x=0
处分析情况,然后稍微离开一点。 你可以通过差商的极限得到

y''(0) + 2*y''(0) + k^2*F(y(0)) = 0
可以计算二次泰勒多项式。因此,使用ODE解算器使用奇点延拓法解决
[a,1]
上的问题
y(x)=y(0)-k**2/6*F(y(0))*x**2
上的
[0,a]

y0=y(0)
作为参数,最容易建立
x=a
处的边界条件。然后是ODE和BC函数

def ode(x,y,y0):返回[y[1],-2*y[1]/x-k**2*F(y[0])]
defbc(ya,yb,y0):y2=-k**2*F(y0)/6;返回[ya[0]-y0-y2*a**2,ya[1]-2*y2*a,yb[0]-1]
在问题中讨论的案例中,这给出了

a=1e-2
def F(y):返回-y
对于[0.01,5]中的k:
res=求解bvp(常微分方程,bc[a,1],[1,1],[0,0]],p=[1],tol=1e-5)
print(f'k={k}:{res.message},y0={res.p[0]},理论:{k/np.sinh(k)}'))
如果成功:
y0=res.p[0]
x=np.linspace(a,1,61);
plt.plot(x,res.sol(x)[0])
plt.绘图([0],[y0],'o',res.x,res.y[0],'+',ms=4)
plt.title(f'k={k}');plt.grid();plt.show()
结果

k=0.01:算法收敛到所需精度,y0=0.999983335277726,理论值:0.999983335277757

k=5:算法收敛到所需精度,y0=0.06738256929427147,理论值:0.06738252915294544

考虑这种情况
F(y)=y
。很容易看出,这种线性常微分方程的基本解是sin(k*x)/x和cos(kx/x)
。类似地,对于
F(y)=-y
我们得到
sinh(k*x)/x
cosh(k*x)/x
。这意味着大多数解在
x=0时具有奇点。对于标准ODE解算器来说,这种奇点几乎不可能立即处理。我们必须在奇点处帮助解算器,正常程序在离奇点一定距离处再次应用

你能做的就是在
x=0
处分析情况,然后稍微离开一点。 你可以通过差商的极限得到

y''(0) + 2*y''(0) + k^2*F(y(0)) = 0
可以计算二次泰勒多项式。因此,使用ODE解算器使用奇点延拓法解决
[a,1]
上的问题
y(x)=y(0)-k**2/6*F(y(0))*x**2
上的
[0,a]

y0=y(0)
作为参数,最容易建立
x=a
处的边界条件。然后是ODE和BC函数

def ode(x,y,y0):返回[y[1],-2*y[1]/x-k**2*F(y[0])]
defbc(ya,yb,y0):y2=-k**2*F(y0)/6;返回[ya[0]-y0-y2*a**2,ya[1]-2*y2*a,yb[0]-1]
在问题中讨论的案例中,这给出了

a=1e-2
def F(y):返回-y
对于[0.01,5]中的k:
res=求解bvp(常微分方程,bc[a,1],[1,1],[0,0]],p=[1],tol=1e-5)
print(f'k={k}:{res.message},y0={res.p[0]},理论:{k/np.sinh(k)}'))
如果成功:
y0=res.p[0]
x=np.linspace(a,1,61);
plt.plot(x,res.sol(x)[0])
plt.绘图([0],[y0],'o',res.x,res.y[0],'+',ms=4)
plt.title(f'k={k}');plt.grid();plt.show()
结果

k=0.01:算法收敛到所需精度,y0=0.999983335277726,理论值:0.999983335277757

k=5:算法收敛到所需精度,y0=0.06738256929427147,理论值:0.06738252915294544


如果您提供了一个。上一个术语中的(暗示)符号将从公式变为代码,那么有人会更容易帮助您。哪个版本是正确的?如果代码变量是正确的,也就是说,
F(y)=-y
,那么实际上
k=5
会导致
y0=0.06743870030718753
。实际上,我是对的。我错过了上面等式中的负号。我想这也会影响你下面的答案。如果你提供了一个符号,别人会更容易帮助你。上一个术语中的(暗示)符号会从公式变为代码。哪个版本是正确的?如果代码变量是正确的,也就是说,
F(y)=-y
,那么实际上
k=5
会导致
y0=0.06743870030718753
。实际上,我是对的。我错过了上面等式中的负号。我想这也会影响你下面的答案。谢谢你卢茨的解释!它在
F(y)
为y或-y时工作良好。但是
F(y)=-y exp(ab(1-y)/(1+beta*(1-y))
存在一些问题,我得到了奇异的雅可比矩阵,或者对于
k的高值,我用完了网格点。我想是复杂形式的
F(y)
导致了这些问题。你对此有什么想法吗?我稍后会尝试增加网格点。你能给出一些k和A,B或alpha,beta的典型值吗?