[英]Runge-Kutta : error while solving a second order differential equation
I am trying to solve a third order non linear differential equation.我正在尝试求解三阶非线性微分方程。 I have tried to transform it and I've obtained this problem which is a second order problem:
我试图改变它,我得到了这个问题,这是一个二阶问题:
I am trying to implement a fourth order Range-Kutta algorithm in order to solve it by writing it like this:我正在尝试实现四阶 Range-Kutta 算法,以便通过这样编写来解决它:
Here is my code for the Range-Kutta algorithm:这是我的 Range-Kutta 算法代码:
import numpy as np
import matplotlib.pyplot as plt
''''X,Y = integrate(F,x,y,xStop,h).
4th-order Runge-Kutta method for solving the initial value problem {y}' = {F(x,{y})}, where {y} = {y[0],y[1],...,y[n-1]}.
x,y = initial conditions
xStop = terminal value of x
h = increment of x used in integration
F = user-supplied function that returns the
array F(x,y) = {y'[0],y'[1],...,y'[n-1]}.
'''
def integrate(F,x,y,xStop,h):
def run_kut4(F,x,y,h):
K0 = h*F(x,y)
K1 = h*F(x + h/2.0, y + K0/2.0)
K2 = h*F(x + h/2.0, y + K1/2.0)
K3 = h*F(x + h, y + K2)
return (K0 + 2.0*K1 + 2.0*K2 + K3)/6.0
X =[]
Y =[]
X.append(x)
Y.append(y)
while x < xStop:
h = min(h,xStop - x)
y = y + run_kut4(F,x,y,h)
x = x + h
X.append(x)
Y.append(y)
return np.array(X),np.array(Y)
It works fine for other differential equations.它适用于其他微分方程。
In this case the function F is defined as:在这种情况下,function F 定义为:
And the main code is:主要代码是:
def F(x,y):
F = np.zeros(2)
F[0] = y[1]
F[1] = (2*(1-x)/x**3)*y[0]**(-1/2)
return F
x = 1.0
xStop = 20
y = np.array([0,0])
h = 0.2
X,Y = integrate(F,x,y,xStop,h)
plt.plot(X,Y)
plt.grid()
plt.show()
Unfortunately, I got this error:不幸的是,我收到了这个错误:
<ipython-input-8-8216949e6888>:4: RuntimeWarning: divide by zero encountered in power
F[1] = (2*(1-x)/x**3)*y[0]**(-1/2)
<ipython-input-8-8216949e6888>:4: RuntimeWarning: divide by zero encountered in double_scalars
F[1] = (2*(1-x)/x**3)*y[0]**(-1/2)
It's related to the fact that the initial value of the function is 0 but I don't know how to get rid of it in order to simplify the problem again...这与function的初始值为0有关,但我不知道如何摆脱它以再次简化问题......
Could someone help me to find an other alternative?有人可以帮我找到其他选择吗?
Thank you for your help,谢谢您的帮助,
you y
is [0,0]
and in y[0]**(-1/2)
there is division operation with 0
in the denominator which is giving ZeroDivision warning and invalid value encountered in double_scalars is due to expression y[0]**(-1/2)
changed to NaN
.您的
y
是[0,0]
并且在y[0]**(-1/2)
中存在分母中为0
的除法运算,这会给出 ZeroDivision 警告,并且在 double_scalars 中遇到的无效值是由于表达式y[0]**(-1/2)
更改为NaN
。 however, those are warnings and F
is returning value array([ 0., nan])
.但是,这些是警告,
F
正在返回值array([ 0., nan])
。 you need to replace y[0]**(-1/2)
as negative powers of zero are undefined or you can use an extremely small value near zero if it suits your need.您需要替换
y[0]**(-1/2)
因为零的负幂是未定义的,或者如果适合您的需要,您可以使用接近零的极小值。 maybe your equation is not continuous at (1,0).也许您的方程在 (1,0) 处不连续。
You can test approximate solutions close to the initial point that are powers of (1-x)
or power series in this difference.您可以测试接近初始点的近似解,即
(1-x)
的幂或此差异中的幂级数。 In the simplest case you get y(x)=(1-x)^2
for x <= 1
.在最简单的情况下,您会得到
y(x)=(1-x)^2
for x <= 1
。 To get solutions for x>1
you need to take the other sign in the square root.要获得
x>1
的解决方案,您需要在平方根中取另一个符号。 In total this gives a far-field behavior of x(t)=1+c*exp(-t)
.总的来说,这给出了
x(t)=1+c*exp(-t)
的远场行为。
Now you can follow two strategies,现在你可以遵循两种策略,
x=1-h
with y(1-h)=h^2
, y'(1-h)=-2h
, along with a time integration dt/dx=y(x)^(-1/2)
where t(1-h)
is arbitrary, orx=1-h
的简化方程与y(1-h)=h^2
, y'(1-h)=-2h
以及时间积分dt/dx=y(x)^(-1/2)
积分dt/dx=y(x)^(-1/2)
其中t(1-h)
是任意的,或t=T
with conditions following the derivatives of x(t)=1+c*exp(Tt)
, that is, x(T)=1+c
with arbitrary small c
, x'(t)=-c
, x''(T)=c
.t=T
的原始方程与x(t)=1+c*exp(Tt)
的导数之后的条件积分,即x(T)=1+c
与任意小的c
, x'(t)=-c
, x''(T)=c
。 In theory they should be the same, practically with fixed-step RK4 in both cases there will be differences. Make a cut across all approaches.切入所有方法。 Close to the asymptote
x(t)=1
the solution is monotonous and thus time can be expressed in terms of x-1
.接近渐近线
x(t)=1
的解是单调的,因此时间可以用x-1
表示。 This means that the derivative can (probably) be expressed as power series in x-1
这意味着导数可以(可能)表示为
x-1
中的幂级数
x' (t) = c_1 * (x-1) + c_2 * (x-1)^2 + ...
x'' (t) = c_1 * x'(t) + 2c_2 * (x-1)*x' + ...
= (c_1 + 2c_2*(x-1)+...)*(c_1+c_2*(x-1)+..)*(x-1)
= c_1^2*(x-1)+3c_1c_2*(x-1)^2 + ...
x'''(t) = (c_1^2+6c_1c_2*(x-1)+...)*(c_1+c_2*(x-1)+..)*(x-1)
= c_1^3*(x-1) + 7c_1^2c_2*(x-1)^2 + ...
and
(1-x)/x^3 = -(x-1)*(1+(x-1))^(-3)=-(x-1)+3*(x-1)^2 + ...
so equating coefficients
c_1^3=-1 ==> c_1 = -1
7c_1^2c_2 = 3 ==> c_2 = 3/7
Given x(T) close enough to 1, the other initial values have to be
x'(T)=-(x(T)-1) + 3/7*(x(T)-1)^2
x''(T)=x(T)-1 -9/7*(x(T)-1)^2
Then the far-field approximation due to these first two terms is the solution to那么由于前两项的远场近似是
x'(t) = -(x-1) + 3/7 * (x-1)^2
Substitute u(t) = (x-1)^(-1) - 3/7
u'(t) = u(t)
(x(t)-1)^(-1) - 3/7 = ((x(T)-1)^(-1) - 3/7) * exp(t-T)
x(t) = 1 + (x(T)-1)*exp(T-t) / ( 1 - 3/7*(x(T)-1)*(1-exp(T-t)) )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.