Python 了解scipy.integrate.odeint中的时间步

Python 了解scipy.integrate.odeint中的时间步,python,scipy,odeint,Python,Scipy,Odeint,我正在尝试使用odeint和直线法求解PDE。我的代码肯定是错的,我正试图找出哪里出了问题 我使用odeint(odefunc,y0,tspan)调用ode解算器,其中tspan=np.linspace(0.0,0.5,5)和y0=1.0*np.ones(3) 我试着在odefunc中打印t,结果被输出搞糊涂了。尽管我求解的t=0.5,但最后要打印的t值是0.015081203121127767。输出的数量与tspan匹配,但我看不出当de函数中的最后一次时间为0.015时,它怎么可能解到t=0

我正在尝试使用odeint和直线法求解PDE。我的代码肯定是错的,我正试图找出哪里出了问题

我使用
odeint(odefunc,y0,tspan)
调用ode解算器,其中
tspan=np.linspace(0.0,0.5,5)
y0=1.0*np.ones(3)

我试着在
odefunc
中打印
t
,结果被输出搞糊涂了。尽管我求解的t=0.5,但最后要打印的t值是
0.015081203121127767
。输出的数量与tspan匹配,但我看不出当de函数中的最后一次时间为0.015时,它怎么可能解到t=0.5。我错过了什么

我的DE依赖于时间,因此很难找出哪里出了问题,因为我似乎没有看到任何事情都失败的时候

ETA-这是失败的,但是在没有一些不相关的东西的情况下运行它,我会得到警告
ODEintWarning:在这个调用上做了过多的工作(可能是错误的Dfun类型)。运行full_output=1以获取定量信息。
,我假设这是问题的一部分,但它似乎并没有停止代码

MWE

将numpy导入为np
从scipy.integrate导入odeint
将matplotlib.pyplot作为plt导入
输入数学
导入系统
plt.interactive(假)
西格玛=2320
rho=1000
重力=9.81#[m/s^2]
g=重力*3600*3600#[m/小时^2]
S=0.01
沉降速度=0.02#[m/s]
ws=沉降速度*3600#[m/小时]
n=0.04#[SI]
J=400#[Ws/m]
k=0.02
Cstar=0.2*sigma#[kg/m^3]
W=2#[m]
D0=1.2
Lw=20
L=100
倾向=0.5#小时
tspan=np.linspace(0.0,趋势,5)
定义d(t):#米
如果t<50:#小时
返回0.5
其他:
返回0.05
def Q(t):
返回3600*(数学sqrt(S)/n)*((W*d(t))**(5/3))/(2*d(t)+W)**(2/3))
def h(t):
返回d(t)/2
defβ(t):
返回(σ-rho)*g*h(t)/σ
defω(t):
返回rho*g*S*Q(t)#[W/m]
def PSI时间(t):
返回rho*g*Q(t)*(D0-d(t))/(Lw)
N=10
X=np.linspace(0,L,N)
delX=L/(N-1)
定义odefunc(y,t):
德夫泽泰(t):
返回k*(PsiTime(t)+ω(t))/(J+β(t))
德夫泽塔乌(t):
返回值(2*d(t)/(W+2*d(t))*k*Omega(t)/(J+beta(t))
德夫泽塔(t):
收益率(W/(W+2*d(t))*k*Omega(t)/(β(t))
德夫泽塔夫(t,i):
收益率(W/(W+2*d(t))*k*Omega(t)/(J+beta(t))
C=y[:N]
M=y[N:]
打印(“时间:,t)
dCdt=np.零(X.形)
dMdt=np.零(X.形)
dCdt[0]=(#dCdx的正向差分
-Q(t)/(W*d(t))*(C[1]-C[0])/delX
+(zetaEh(t)/(W*d(t))*((Cstar-C[0])/Cstar)
-(ws*C[0]*(beta(t))/(d(t)*(J+beta(t)))
)
dMdt[0]=0
#沟渠
对于范围(1,N-1)内的i:#中心差
如果M[i]+W*C[i]*ws-zetaR(t)*(Cstar-C[i])/Cstar<0:
reMass=M[i]+W*C[i]*ws
dCdt[i]=(
-Q(t)/(W*d(t))*(C[i+1]-C[i-1])/(2*delX)
+1/(W*d(t))*((zetaEW(t)+zetaEF(t,i))*(Cstar-C[i])/Cstar
+剩余*(1-(β(t))/(J+β(t)))
-C[i]*ws/d(t)
)
dMdt[i]=-M[i]
其他:
dCdt[i]=(
-Q(t)/(W*d(t))*(C[i+1]-C[i-1])/(2*delX)
+1/(W*d(t))*(zetaEW(t)+zetaR(t))*(Cstar-C[i])/Cstar
-C[i]*ws/d(t)
)
dMdt[i]=W*C[i]*ws-zetaR(t)*(Cstar-C[i])/Cstar
#最终节点-向后差分
如果M[N-1]+W*C[N-1]*ws-zetaR(t)*(Cstar-C[N-1])/Cstar<0:
reMass=M[N-1]+W*C[N-1]*ws
dCdt[N-1]=(
-Q(t)/(W*d(t))*(C[N-1]-C[N-2])/delX
+1/(W*d(t))*(zetaEW(t)+zetaEF(t,i))*(Cstar-C[N-1])/Cstar
+剩余*(1-(β(t))/(J+β(t)))
-C[i]*ws/d(t)
)
dMdt[N-1]=-M[N-1]
其他:
dCdt[N-1]=(
-Q(t)/(W*d(t))*(C[N-2]-C[N-1])/delX
+1/(W*d(t))*(zetaEW(t)+zetaR(t))*(Cstar-C[N-1])/Cstar
-C[N-1]*ws/d(t)
)
dMdt[N-1]=W*C[N-1]*ws-zetaR(t)*(Cstar-C[N-1])/Cstar
dydt=np.ravel([dCdt,dMdt])
回程差
初始C=0.0*np.one(X.shape)
初始M=0.0*np.one(X.shape)
init=np.ravel([init_C,init_M])
sol=odeint(odefunc、init、tspan)
conc=sol[:,:N]

您能否提供足够的代码,以便其他人可以复制此问题?什么是
odefunc
?我正在尝试一个不长3页的最小示例-还没有弄清楚到底是什么导致它没有像我预期的那样起作用。我希望我遗漏了一些明显的东西,可以缩短这个过程。@DrBwts-我提供了一个例子,可以复制我看到的东西(我试图删掉不相关的东西,所以这一个打印最后的t大约为0.02)。函数有点长,以便更好地“猜测”。您可以尝试在tspan中使用更多元素吗<例如,code>tspan=np.linspace(0.0,tend,100)
odeint
tspan[0]
tspan[1]
(当然,下一点相同)之间的间隔划分为较小的间隔,在此间隔内,方程可以以足够的精度求解。这个细分有一个固定的限制,因此我的建议。@pierredebyl-我想我可能理解
tspan
中的
odeint
错误。我认为
tspan
是报告解决方案的时间点,因此该算法确保它在这些时间点进行计算,但除非重新计算
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
import math
import sys

plt.interactive(False) 

sigma = 2320
rho = 1000
gravity = 9.81  # [m/s^2]
g = gravity*3600*3600  # [m/hour^2]
S = 0.01
settlingVelocity = 0.02  # [m/s]
ws = settlingVelocity*3600  # [m/hour]
n = 0.04 # [SI]

J = 400  # [Ws/m]
k = 0.02
Cstar = 0.2 * sigma  # [kg/m^3]
W = 2  # [m]

D0 = 1.2 
Lw = 20   
L = 100  

tend = 0.5  # in hours
tspan = np.linspace(0.0, tend, 5)


def d(t):  # metres
    if t < 50:  # hours
        return 0.5
    else:
        return 0.05

def Q(t):
    return 3600 * (math.sqrt(S)/n)*((W*d(t))**(5/3))/((2*d(t) + W)**(2/3))

def h(t):
    return d(t)/2

def beta(t):
    return (sigma - rho) * g * h(t)/sigma

def Omega(t):
    return rho * g * S * Q(t)  # [W/m]

def PsiTime(t):
    return rho * g * Q(t) * (D0 - d(t))/(Lw)

N = 10
X = np.linspace(0, L, N)
delX = L/ (N-1)

def odefunc(y, t):

    def zetaEh(t):
        return k * (PsiTime(t) + Omega(t)) / (J + beta(t))

    def zetaEW(t): 
        return (2*d(t)/(W + 2*d(t))) * k * Omega(t)/(J + beta(t))

    def zetaR(t):  
        return (W/(W + 2*d(t))) * k*Omega(t)/(beta(t))

    def zetaEF(t,i):
        return (W/(W + 2*d(t))) * k * Omega(t) / (J + beta(t))

    C = y[:N]
    M = y[N:]

    print("time: ", t)

    dCdt = np.zeros(X.shape)
    dMdt = np.zeros(X.shape)

    dCdt[0] = (  # forward difference for dCdx
                -Q(t) / (W*d(t)) * (C[1] - C[0]) / delX
                  + (zetaEh(t) / (W * d(t))) * ((Cstar - C[0]) / Cstar)
                - (ws * C[0] * (beta(t))) / (d(t) * (J + beta(t)))
        )
    dMdt[0] = 0

     # gully channel
    for i in range (1, N-1):  # central difference
        if M[i] + W *C[i] * ws - zetaR(t) * (Cstar - C[i]) / Cstar < 0:
            reMass = M[i] + W * C[i] * ws

            dCdt[i] = (
                    -Q(t) / (W*d(t)) * (C[i+1] - C[i - 1]) / (2*delX)
                        + 1 / (W * d(t)) * ((zetaEW(t) + zetaEF(t,i)) * (Cstar - C[i]) / Cstar
                                            + reMass * (1 - (beta(t))/ (J + beta(t))))
                        - C[i] * ws/d(t)
             )
            dMdt[i] = -M[i]
        else:
            dCdt[i] = (
                    -Q(t) / (W*d(t)) * (C[i+1] - C[i - 1]) / (2*delX)
                      + 1 / (W * d(t)) * (zetaEW(t) + zetaR(t)) * (Cstar - C[i]) / Cstar
                      - C[i] * ws / d(t)
                       )
            dMdt[i] = W * C[i] * ws - zetaR(t) * (Cstar - C[i]) / Cstar

    # Final node - backward difference
    if M[N-1] + W * C[N-1] * ws - zetaR(t) * (Cstar - C[N-1]) / Cstar < 0: 
        reMass = M[N-1] + W * C[N-1] * ws
        dCdt[N-1] = (
                -Q(t) / (W * d(t)) * (C[N-1] - C[N-2]) / delX
                + 1 / (W * d(t)) * ((zetaEW(t) + zetaEF(t, i)) * (Cstar - C[N-1]) / Cstar
                                    + reMass * (1 - (beta(t)) / (J + beta(t))))
                - C[i] * ws / d(t)
        )
        dMdt[N-1] = -M[N-1]

    else:
        dCdt[N-1] = (
                -Q(t) / (W * d(t)) * (C[N-2] - C[N - 1]) / delX
                + 1 / (W * d(t)) * (zetaEW(t) + zetaR(t)) * (Cstar - C[N-1]) / Cstar
                - C[N-1] * ws / d(t)
        )
        dMdt[N-1] = W * C[N-1] * ws - zetaR(t) * (Cstar - C[N-1]) / Cstar
    dydt = np.ravel([dCdt, dMdt])
    return dydt


init_C = 0.0 * np.ones(X.shape)
init_M = 0.0 * np.ones(X.shape)
init= np.ravel([init_C, init_M])

sol = odeint(odefunc, init, tspan)

conc = sol[:, :N]