Python 使用Scipy ode求解器求解刚性耦合ode

Python 使用Scipy ode求解器求解刚性耦合ode,python,scipy,ode,Python,Scipy,Ode,目前,我正试图解决一个耦合常微分方程组。我正在使用scipy.integrate.ODE。该系统有4个耦合ODE,将室外温度与室内温度联系起来。目标是集成ode以获得室内温度,并将其与实际室内温度进行匹配。其中一个ode中的“t_out”功能返回特定时间的室外温度。这是我的代码: import pandas as pd import numpy as np from scipy.integrate import ode from matplotlib import pyplot as plt

目前,我正试图解决一个耦合常微分方程组。我正在使用scipy.integrate.ODE。该系统有4个耦合ODE,将室外温度与室内温度联系起来。目标是集成ode以获得室内温度,并将其与实际室内温度进行匹配。其中一个ode中的“t_out”功能返回特定时间的室外温度。这是我的代码:

import pandas as pd
import numpy as np
from scipy.integrate import ode
from matplotlib import pyplot as plt

time_step = 60

ending = 1300

n=0

df = pd.read_csv("Temperature.csv").loc[0:ending+51,]
df['Tsol (HKO)'] = df['Tsol (HKO)']+273
df['Temp_In'] = df['Temp_In']+273
t_out_list = df['Tsol (HKO)'].tolist() #Assign outdoor temperature
t_in_list = df['Temp_In'].tolist() #Assign actual indoor temperature


def initial_temp():
    t_in, t_out = t_in_list, t_out_list
    t1 = t_in[0] - (t_in[0] - t_out[0])/3
    t2 = t_in[0] - (t_in[0] - t_out[0])*2/3
    t_im = t_in = t_in[0]
#    return [t_in[0], t_in[0], t_in[0], t_in[0]]
    return[t_in, t1, t2, t_im]



def t_out(t):
    index = int(t/time_step)
    upper_t, lower_t = t_out_list[index+1], t_out_list[index]
    return (upper_t-lower_t)*(t/60.0-index) + lower_t



def fun(t, u, R1, R2, R3, R_IM, C1, C2, C_IN, C_IM):

    global sol, ttt
    sol.append(u[0])
    ttt.append(t/time_step)

    T_in, T1, T2, T_im = u[0], u[1], u[2], u[3]
    dT_in = ((T2 - T_in)/R3 + (T_im - T_in)/R_IM)/C_IN
    dT1 = ((t_out(t) - T1)/R1 - (T1 - T2)/R2)/C1
    dT2 = ((T1 - T2)/R2 - (T2 - T_in)/R3)/C2
    dT_im = ((T_im - T_in)/R_IM)/C_IM

#    print(dT_in, dT1, dT2, dT_im)
    return [dT_in, dT1, dT2, dT_im]


def jacobian_fun(t, u, R1, R2, R3, R_IM, C1, C2, C_IN, C_IM):

    return [ [ -1/(R3*C_IN) , 0 , 1/(R3*C_IN) , 1/(R_IM*C_IN) ] , 
             [ 0 , -1/(R1*C1)-1/(R2*C1) , 1/(R2*C1) , 0 ] , 
             [ 1/(R3*C2) , 1/(R2*C2) ,-1/(R2*C2)-1/(R3*C2), 0 ] ,
             [ -1/(R_IM*C_IM), 0 , 0 , 1/(R_IM*C_IM) ] ]


def thermal_ode_error(g):

    R1, R2, R3, R_IM, C1, C2, C_IN, C_IM = g
    A = u0 = initial_temp()
    r = ode(fun, jacobian_fun).set_integrator('vode', nsteps=500, method='bdf', with_jacobian = True)
    r.set_initial_value(u0, 0.0).set_f_params(R1, R2, R3, R_IM, C1, C2, C_IN, C_IM).set_jac_params(R1, R2, R3, R_IM, C1, C2, C_IN, C_IM)

    j = ending*time_step

    while r.successful() and r.t < j:
        r.integrate(r.t+time_step)
        A = np.vstack([A, r.y])
    return A[:,0]


sol = []
ttt = []


g = [0.03, 0.05, 0.16, 0.02, 444046, 111695, 529127.0, 42000.0]
T_in_calculated = thermal_ode_error(g)

fig = plt.figure()
fig.set_size_inches(15, 4)

del ttt[1], sol[1]

plt.plot([x for x in range(0,len(t_in_list))], t_in_list)
plt.plot([x for x in range(0,len(t_out_list))], t_out_list, color='g')
plt.plot(ttt, sol, color='r')
plt.plot([x for x in range(0,len(T_in_calculated))], T_in_calculated, '*--')

x1,x2,y1,y2 = plt.axis()
plt.axis((0,300,295, 302))
将熊猫作为pd导入
将numpy作为np导入
从scipy.integrate导入ode
从matplotlib导入pyplot作为plt
时间步长=60
结束=1300
n=0
df=pd.read_csv(“Temperature.csv”).loc[0:end+51,]
df['Tsol(HKO)]=df['Tsol(HKO)]+273
df['Temp_In']=df['Temp_In']+273
t_out_list=df['Tsol(HKO)].tolist()#分配室外温度
t_in_list=df['Temp_in']。tolist()#指定实际室内温度
def初始温度()
输入,输出=输入列表,输出列表
t1=t_in[0]-(t_in[0]-t_out[0])/3
t2=t_in[0]-(t_in[0]-t_out[0])*2/3
t_im=t_in=t_in[0]
#返回[t_in[0],t_in[0],t_in[0],t_in[0]]
返回[t_in,t1,t2,t_im]
def t_输出(t):
索引=int(t/时间步长)
上排,下排=上排列表[索引+1],上排列表[索引]
收益率(上下)*(t/60.0指数)+下
def fun(t、u、R1、R2、R3、R_IM、C1、C2、C_IN、C_IM):
全球信保通
sol.append(u[0])
ttt.追加(t/时间步)
T_-in,T1,T2,T_-im=u[0],u[1],u[2],u[3]
dT_in=((T2-T_in)/R3+(T_im-T_in)/R_im)/C_in
dT1=((t_out(t)-T1)/R1-(T1-T2)/R2)/C1
dT2=((T1-T2)/R2-(T2-T_-in)/R3)/C2
dT_im=((T_im-T_in)/R_im)/C_im
#打印(dtu输入、dT1、dT2、dtu输入)
返回[dtu-in,dT1,dT2,dtu-im]
def jacobian_-fun(t,u,R1,R2,R3,R_-IM,C1,C2,C_-IN,C_-IM):
返回[-1/(R3*C_IN),0,1/(R3*C_IN),1/(R_IM*C_IN)],
[0,-1/(R1*C1)-1/(R2*C1),1/(R2*C1),0],
[1/(R3*C2),1/(R2*C2),-1/(R2*C2)-1/(R3*C2),0],
[1/(R_IM*C_IM),0,0,1/(R_IM*C_IM)]]
def热异常错误(g):
R1,R2,R3,R_-IM,C1,C2,C_-IN,C_-IM=g
A=u0=初始温度()
r=ode(fun,jacobian\u-fun)。设置积分器('vode',nsteps=500,method='bdf',其中,jacobian=True)
r、 设置初始值(u0,0.0)。设置参数(R1,R2,R3,r_-IM,C1,C2,C_-IN,C_-IM)。设置参数(R1,R2,R3,r_-IM,C1,C2,C_-IN,C_-IM)
j=结束*时间步长
当r.successful()和r.t
这是指向Temperature.csv数据的链接,

数据包含60秒间隔的样本读数,ode中的t_out函数在每个时间步输出数据读数。(希望这有意义。)

这是我得到的结果。

绿线是室外温度,红线是计算出的室内温度,正如你所看到的,它与实际的室内温度(蓝线)相差甚远。现在可能是ode的参数,例如R1、R2。。。有点不对劲,但应该不会对结果有太大影响,我认为这是我解决ode的方法有问题


我已经被困在这个问题上好几天了,所以任何我能得到的帮助都是欢迎的

你检查你的方程式了吗?总是先这样做。雅可比矩阵是错误的,T_im的方程可能是错误的(很难说,因为没有指定模型)。除了@pv。说,试着解决它。它可能会慢一些,但你会有一个独立的检查。