使用Scipy ode求解器来解决僵硬的耦合颂歌

时间:2015-12-02 07:32:18

标签: python scipy ode

目前,我正在尝试解决耦合的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函数输出每个时间步长的数据读数。 (希望这是有道理的。)

这是我得到的结果。 enter image description here

绿线是室外温度,红线是计算出的室内温度,正如您所看到的那样,它并不接近实际室内温度(蓝线)。现在它可能是颂歌的参数,例如R1,R2 ......略有偏差,但它不应该对结果造成太大影响,我认为这是解决颂歌问题的方法。

我已经被困在这个问题上几天了,所以我可以得到任何帮助!

0 个答案:

没有答案