Python 如何使用scipy.odeint求解微分方程组

Python 如何使用scipy.odeint求解微分方程组,python,scipy,odeint,Python,Scipy,Odeint,我想用odeint解方程组,得到以下错误: File "C:", line 45, in <module> C_B = odeint(dC_Bdt,C_B0,t) File "C:\Anaconda3\envs\ChemEng\lib\site-packages\scipy\integrate\odepack.py", line 233, in odeint int(bool(tfirst))) RuntimeError: The array return

我想用
odeint
解方程组,得到以下错误:

  File "C:", line 45, in <module>
    C_B = odeint(dC_Bdt,C_B0,t)

  File "C:\Anaconda3\envs\ChemEng\lib\site-packages\scipy\integrate\odepack.py", line 233, in odeint
    int(bool(tfirst)))

RuntimeError: The array return by func must be one-dimensional, but got ndim=2.
文件“C:”,第45行,在
C_B=odeint(dC_Bdt,C_B0,t)
文件“C:\Anaconda3\envs\ChemEng\lib\site packages\scipy\integrate\odepack.py”,第233行,在odeint中
int(bool(tfirst)))
RuntimeError:func返回的数组必须是一维的,但得到的ndim=2。
我的代码是:

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

# Create time domain
t = np.linspace(0,100,100)

# Parameters 
A = 1*10**(13) # Arrhenius constant
T = 293.15 # Temperature [K]
E_a= 80000 # Activation energy [J/mol]
R = 8.31 # Ideal gas constant [J/molK]
rho = 1000 # density [kg/m3]
F_in = 0.2 # Inlet flowrate [m3/s]
h = 2.1 # Height of reactor
A_= 1 # Cross-sectional area of reactor [m2]


# Initial condition
C_A0 = 3 # Initial concentration [mol/m3]
C_B0 = 0 # Initial concentration [mol/m3]
m0 = 0 # Initial mass in tank [kg]

def dmdt(F_out,t): # Mass balance
    return rho*(F_in-F_out)

def dC_Adt(C_A,t): # Concentration balance for A
    dC_Adt = (F_in*C_A-F_out*C_A)/V-k*C_A
    return dC_Adt

def dC_Bdt(C_B,t): # Concentration balance for B
    dC_Bdt = (F_in*C_B-F_out*C_B)/V+k*C_A
    return dC_Bdt #<-- needs to be 1D but is 2D


V = A_*h # Reactor volume [m3]
k=A*np.exp(-E_a/(R*T)) # Reaction rate constant
F_out = F_in # Steady state
dmdt = odeint(dmdt,m0,t)
C_A = odeint(dC_Adt,C_A0,t)
C_B = odeint(dC_Bdt,C_B0,t)

# Plot
plt.figure()
plt.plot(t,C_A,'b-',label='C_A')
plt.plot(t,C_B,'r--',label='C_B')
plt.legend(loc='best')
plt.grid(True)
plt.xlabel('Time [s]')
plt.ylabel('Concentration [mol/m3]')
将numpy导入为np
将matplotlib.pyplot作为plt导入
从scipy.integrate导入odeint
#创建时域
t=np.linspace(0100)
#参数
A=1*10**(13)#阿累尼乌斯常数
T=293.15#温度[K]
E_a=80000#活化能[J/mol]
R=8.31#理想气体常数[J/molK]
rho=1000#密度[kg/m3]
F_in=0.2#入口流量[m3/s]
h=2.1#反应器高度
A=1#反应器的横截面积[m2]
#初始条件
C_A0=3#初始浓度[mol/m3]
C_B0=0#初始浓度[mol/m3]
m0=0#储罐中的初始质量[kg]
def dmdt(F#u out,t):#质量平衡
返回rho*(F_in-F_out)
def dC#U Adt(C#A,t):#A的浓度平衡
dC_Adt=(F_in*C_A-F_out*C_A)/V-k*C_A
返回dC_Adt
def dC_Bdt(C_B,t):#B的浓度平衡
dC_Bdt=(F_in*C_B-F_out*C_B)/V+k*C_A

return dC_Bdt#我修改了您的代码,以解三个耦合的方程:

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

# Parameters 
A = 1e13 # Arrhenius constant
T = 293.15 # Temperature [K]
E_a = 80000 # Activation energy [J/mol]
R = 8.31 # Ideal gas constant [J/molK]
rho = 1000 # density [kg/m3]
F_in = 0.2 # Inlet flowrate [m3/s]
h = 2.1 # Height of reactor
A_ = 1 # Cross-sectional area of reactor [m2]

V = A_*h  # Reactor volume [m3]
k = A*np.exp(-E_a/(R*T)) # Reaction rate constant
F_out = F_in # Steady state

def dUdt(U, t):
    m, C_A, C_B = U

    dmdt = rho*(F_in - F_out)
    dC_Adt = ( F_in*C_A - F_out*C_A )/ V-k*C_A
    dC_Bdt = ( F_in*C_B - F_out*C_B )/ V+k*C_A

    return [dmdt, dC_Adt, dC_Bdt]

# Create time domain
t_span = np.linspace(0, 100, 30)

# Initial condition
C_A0 = 3 # Initial concentration [mol/m3]
C_B0 = 0 # Initial concentration [mol/m3]
m0 = 0 # Initial mass in tank [kg]

Uzero = [m0, C_A0, C_B0]

solution = odeint(dUdt, Uzero, t_span)

# plot
plt.plot(t_span, solution[:, 0], label='masse');
plt.plot(t_span, solution[:, 1], label='C_A');
plt.plot(t_span, solution[:, 2], label='C_B');
plt.legend();
plt.xlabel('time'); 

我修改了您的代码,以解三个耦合的方程:

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

# Parameters 
A = 1e13 # Arrhenius constant
T = 293.15 # Temperature [K]
E_a = 80000 # Activation energy [J/mol]
R = 8.31 # Ideal gas constant [J/molK]
rho = 1000 # density [kg/m3]
F_in = 0.2 # Inlet flowrate [m3/s]
h = 2.1 # Height of reactor
A_ = 1 # Cross-sectional area of reactor [m2]

V = A_*h  # Reactor volume [m3]
k = A*np.exp(-E_a/(R*T)) # Reaction rate constant
F_out = F_in # Steady state

def dUdt(U, t):
    m, C_A, C_B = U

    dmdt = rho*(F_in - F_out)
    dC_Adt = ( F_in*C_A - F_out*C_A )/ V-k*C_A
    dC_Bdt = ( F_in*C_B - F_out*C_B )/ V+k*C_A

    return [dmdt, dC_Adt, dC_Bdt]

# Create time domain
t_span = np.linspace(0, 100, 30)

# Initial condition
C_A0 = 3 # Initial concentration [mol/m3]
C_B0 = 0 # Initial concentration [mol/m3]
m0 = 0 # Initial mass in tank [kg]

Uzero = [m0, C_A0, C_B0]

solution = odeint(dUdt, Uzero, t_span)

# plot
plt.plot(t_span, solution[:, 0], label='masse');
plt.plot(t_span, solution[:, 1], label='C_A');
plt.plot(t_span, solution[:, 2], label='C_B');
plt.legend();
plt.xlabel('time'); 

它看起来像一个耦合的方程组,而不是3个独立的方程组,在这种情况下,只需使用一个
odeint
,只有一个
dUdt
函数,它返回一个数组
[dmdt,dCAdt,dCBdt]
您需要注意函数输入/输出的类型和尺寸。也许加上诊断指纹。
dC\u Adt
得到什么?标量
C_A
还是数组?什么是
C\u A
(不要将其与
dC\u Adt
中使用的参数混淆)。在
dC_Bdt
中,它是全局变量(数组?),而不是像
C_B
C_a
那样的局部参数,在第一个
ode_int
之后是一个(100,1)数组。这样的数组不属于
dC\u Bdt
函数,是吗<传递给该函数的code>C_B
是(1,)形数组。它看起来像一个耦合的方程组,而不是3个独立的方程,在这种情况下,只需使用一个
odeint
,只有一个
dUdt
函数,返回数组
[dmdt,dCAdt,dCBdt]
您需要注意功能输入/输出的类型和尺寸。也许加上诊断指纹。
dC\u Adt
得到什么?标量
C_A
还是数组?什么是
C\u A
(不要将其与
dC\u Adt
中使用的参数混淆)。在
dC_Bdt
中,它是全局变量(数组?),而不是像
C_B
C_a
那样的局部参数,在第一个
ode_int
之后是一个(100,1)数组。这样的数组不属于
dC\u Bdt
函数,是吗<传递给该函数的是(1,)形数组。