Python 使用Scipy ode求解器求解刚性耦合ode
目前,我正试图解决一个耦合常微分方程组。我正在使用scipy.integrate.ODE。该系统有4个耦合ODE,将室外温度与室内温度联系起来。目标是集成ode以获得室内温度,并将其与实际室内温度进行匹配。其中一个ode中的“t_out”功能返回特定时间的室外温度。这是我的代码: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
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。说,试着解决它。它可能会慢一些,但你会有一个独立的检查。