目前,我正在尝试解决耦合的ODE系统。我正在使用scipy.integrate.ODE。该系统有4个耦合的ODE,它将室外温度与室内温度联系起来。目标是整合颂歌以获得室内温度并将其与实际室内温度相匹配。 &#t; t_out'其中一个ode功能在特定时间返回室外温度。这是我的代码:
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))
这是Temperature.csv数据的链接, https://drive.google.com/file/d/0B84_Z1V4nj9ScG5sa1BSM1lneVk/view?usp=sharing
数据包含60秒间隔的样本读数,ode中的t_out函数输出每个时间步长的数据读数。 (希望这是有道理的。)
绿线是室外温度,红线是计算出的室内温度,正如您所看到的那样,它并不接近实际室内温度(蓝线)。现在它可能是颂歌的参数,例如R1,R2 ......略有偏差,但它不应该对结果造成太大影响,我认为这是解决颂歌问题的方法。
我已经被困在这个问题上几天了,所以我可以得到任何帮助!